aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-08-20 05:38:31 -0400
committerTakashi Iwai <tiwai@suse.de>2012-08-20 05:38:31 -0400
commitfa2f5bf09610d3c216d4c74855edbe00d636467c (patch)
tree93e78707b392845d771dbcbb82f6ba0b1fd70532
parentc86b93628e5649fd7bb0574b570a51b2b02d586c (diff)
parentc41999a23929f30808bae6009d8065052d4d73fd (diff)
Merge branch 'topic/ca0132-fix' into for-linus
This is a series of fixes for CA0132, especially the missing SPDIF I/O and the mixer build errors.
-rw-r--r--sound/pci/hda/hda_codec.c69
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/patch_ca0132.c174
3 files changed, 99 insertions, 145 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 629131ad7b8b..c3077d5dec6e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1386,6 +1386,44 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1386} 1386}
1387EXPORT_SYMBOL_HDA(snd_hda_codec_configure); 1387EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
1388 1388
1389/* update the stream-id if changed */
1390static void update_pcm_stream_id(struct hda_codec *codec,
1391 struct hda_cvt_setup *p, hda_nid_t nid,
1392 u32 stream_tag, int channel_id)
1393{
1394 unsigned int oldval, newval;
1395
1396 if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
1397 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
1398 newval = (stream_tag << 4) | channel_id;
1399 if (oldval != newval)
1400 snd_hda_codec_write(codec, nid, 0,
1401 AC_VERB_SET_CHANNEL_STREAMID,
1402 newval);
1403 p->stream_tag = stream_tag;
1404 p->channel_id = channel_id;
1405 }
1406}
1407
1408/* update the format-id if changed */
1409static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p,
1410 hda_nid_t nid, int format)
1411{
1412 unsigned int oldval;
1413
1414 if (p->format_id != format) {
1415 oldval = snd_hda_codec_read(codec, nid, 0,
1416 AC_VERB_GET_STREAM_FORMAT, 0);
1417 if (oldval != format) {
1418 msleep(1);
1419 snd_hda_codec_write(codec, nid, 0,
1420 AC_VERB_SET_STREAM_FORMAT,
1421 format);
1422 }
1423 p->format_id = format;
1424 }
1425}
1426
1389/** 1427/**
1390 * snd_hda_codec_setup_stream - set up the codec for streaming 1428 * snd_hda_codec_setup_stream - set up the codec for streaming
1391 * @codec: the CODEC to set up 1429 * @codec: the CODEC to set up
@@ -1400,7 +1438,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1400{ 1438{
1401 struct hda_codec *c; 1439 struct hda_codec *c;
1402 struct hda_cvt_setup *p; 1440 struct hda_cvt_setup *p;
1403 unsigned int oldval, newval;
1404 int type; 1441 int type;
1405 int i; 1442 int i;
1406 1443
@@ -1413,29 +1450,13 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1413 p = get_hda_cvt_setup(codec, nid); 1450 p = get_hda_cvt_setup(codec, nid);
1414 if (!p) 1451 if (!p)
1415 return; 1452 return;
1416 /* update the stream-id if changed */ 1453
1417 if (p->stream_tag != stream_tag || p->channel_id != channel_id) { 1454 if (codec->pcm_format_first)
1418 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); 1455 update_pcm_format(codec, p, nid, format);
1419 newval = (stream_tag << 4) | channel_id; 1456 update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
1420 if (oldval != newval) 1457 if (!codec->pcm_format_first)
1421 snd_hda_codec_write(codec, nid, 0, 1458 update_pcm_format(codec, p, nid, format);
1422 AC_VERB_SET_CHANNEL_STREAMID, 1459
1423 newval);
1424 p->stream_tag = stream_tag;
1425 p->channel_id = channel_id;
1426 }
1427 /* update the format-id if changed */
1428 if (p->format_id != format) {
1429 oldval = snd_hda_codec_read(codec, nid, 0,
1430 AC_VERB_GET_STREAM_FORMAT, 0);
1431 if (oldval != format) {
1432 msleep(1);
1433 snd_hda_codec_write(codec, nid, 0,
1434 AC_VERB_SET_STREAM_FORMAT,
1435 format);
1436 }
1437 p->format_id = format;
1438 }
1439 p->active = 1; 1460 p->active = 1;
1440 p->dirty = 0; 1461 p->dirty = 0;
1441 1462
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index c422d330ca54..7fbc1bcaf1a9 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -861,6 +861,7 @@ struct hda_codec {
861 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ 861 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
862 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ 862 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
863 unsigned int no_jack_detect:1; /* Machine has no jack-detection */ 863 unsigned int no_jack_detect:1; /* Machine has no jack-detection */
864 unsigned int pcm_format_first:1; /* PCM format must be set first */
864#ifdef CONFIG_SND_HDA_POWER_SAVE 865#ifdef CONFIG_SND_HDA_POWER_SAVE
865 unsigned int power_on :1; /* current (global) power-state */ 866 unsigned int power_on :1; /* current (global) power-state */
866 int power_transition; /* power-state in transition */ 867 int power_transition; /* power-state in transition */
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index d0d3540e39e7..49750a96d649 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -246,7 +246,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
246 AC_VERB_SET_AMP_GAIN_MUTE, 246 AC_VERB_SET_AMP_GAIN_MUTE,
247 AMP_OUT_UNMUTE); 247 AMP_OUT_UNMUTE);
248 } 248 }
249 if (dac) 249 if (dac && (get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
250 snd_hda_codec_write(codec, dac, 0, 250 snd_hda_codec_write(codec, dac, 0,
251 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); 251 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
252} 252}
@@ -261,7 +261,7 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
261 AC_VERB_SET_AMP_GAIN_MUTE, 261 AC_VERB_SET_AMP_GAIN_MUTE,
262 AMP_IN_UNMUTE(0)); 262 AMP_IN_UNMUTE(0));
263 } 263 }
264 if (adc) 264 if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP))
265 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, 265 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
266 AMP_IN_UNMUTE(0)); 266 AMP_IN_UNMUTE(0));
267} 267}
@@ -275,6 +275,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
275 int type = dir ? HDA_INPUT : HDA_OUTPUT; 275 int type = dir ? HDA_INPUT : HDA_OUTPUT;
276 struct snd_kcontrol_new knew = 276 struct snd_kcontrol_new knew =
277 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); 277 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
278 if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) {
279 snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid);
280 return 0;
281 }
278 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); 282 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
279 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 283 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
280} 284}
@@ -286,6 +290,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
286 int type = dir ? HDA_INPUT : HDA_OUTPUT; 290 int type = dir ? HDA_INPUT : HDA_OUTPUT;
287 struct snd_kcontrol_new knew = 291 struct snd_kcontrol_new knew =
288 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); 292 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
293 if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) {
294 snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid);
295 return 0;
296 }
289 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); 297 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
290 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 298 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
291} 299}
@@ -464,50 +472,17 @@ exit:
464} 472}
465 473
466/* 474/*
467 * PCM stuffs 475 * PCM callbacks
468 */ 476 */
469static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, 477static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo,
470 u32 stream_tag, 478 struct hda_codec *codec,
471 int channel_id, int format) 479 struct snd_pcm_substream *substream)
472{ 480{
473 unsigned int oldval, newval; 481 struct ca0132_spec *spec = codec->spec;
474 482 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
475 if (!nid) 483 hinfo);
476 return;
477
478 snd_printdd("ca0132_setup_stream: "
479 "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
480 nid, stream_tag, channel_id, format);
481
482 /* update the format-id if changed */
483 oldval = snd_hda_codec_read(codec, nid, 0,
484 AC_VERB_GET_STREAM_FORMAT,
485 0);
486 if (oldval != format) {
487 msleep(20);
488 snd_hda_codec_write(codec, nid, 0,
489 AC_VERB_SET_STREAM_FORMAT,
490 format);
491 }
492
493 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
494 newval = (stream_tag << 4) | channel_id;
495 if (oldval != newval) {
496 snd_hda_codec_write(codec, nid, 0,
497 AC_VERB_SET_CHANNEL_STREAMID,
498 newval);
499 }
500}
501
502static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
503{
504 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
505 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
506} 484}
507 485
508/*
509 * PCM callbacks
510 */
511static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 486static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
512 struct hda_codec *codec, 487 struct hda_codec *codec,
513 unsigned int stream_tag, 488 unsigned int stream_tag,
@@ -515,10 +490,8 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
515 struct snd_pcm_substream *substream) 490 struct snd_pcm_substream *substream)
516{ 491{
517 struct ca0132_spec *spec = codec->spec; 492 struct ca0132_spec *spec = codec->spec;
518 493 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
519 ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); 494 stream_tag, format, substream);
520
521 return 0;
522} 495}
523 496
524static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 497static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
@@ -526,92 +499,45 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
526 struct snd_pcm_substream *substream) 499 struct snd_pcm_substream *substream)
527{ 500{
528 struct ca0132_spec *spec = codec->spec; 501 struct ca0132_spec *spec = codec->spec;
529 502 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
530 ca0132_cleanup_stream(codec, spec->dacs[0]);
531
532 return 0;
533} 503}
534 504
535/* 505/*
536 * Digital out 506 * Digital out
537 */ 507 */
538static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 508static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
539 struct hda_codec *codec, 509 struct hda_codec *codec,
540 unsigned int stream_tag, 510 struct snd_pcm_substream *substream)
541 unsigned int format,
542 struct snd_pcm_substream *substream)
543{ 511{
544 struct ca0132_spec *spec = codec->spec; 512 struct ca0132_spec *spec = codec->spec;
545 513 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
546 ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format);
547
548 return 0;
549} 514}
550 515
551static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 516static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
552 struct hda_codec *codec,
553 struct snd_pcm_substream *substream)
554{
555 struct ca0132_spec *spec = codec->spec;
556
557 ca0132_cleanup_stream(codec, spec->dig_out);
558
559 return 0;
560}
561
562/*
563 * Analog capture
564 */
565static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
566 struct hda_codec *codec, 517 struct hda_codec *codec,
567 unsigned int stream_tag, 518 unsigned int stream_tag,
568 unsigned int format, 519 unsigned int format,
569 struct snd_pcm_substream *substream) 520 struct snd_pcm_substream *substream)
570{ 521{
571 struct ca0132_spec *spec = codec->spec; 522 struct ca0132_spec *spec = codec->spec;
572 523 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
573 ca0132_setup_stream(codec, spec->adcs[substream->number], 524 stream_tag, format, substream);
574 stream_tag, 0, format);
575
576 return 0;
577} 525}
578 526
579static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 527static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
580 struct hda_codec *codec, 528 struct hda_codec *codec,
581 struct snd_pcm_substream *substream) 529 struct snd_pcm_substream *substream)
582{ 530{
583 struct ca0132_spec *spec = codec->spec; 531 struct ca0132_spec *spec = codec->spec;
584 532 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
585 ca0132_cleanup_stream(codec, spec->adcs[substream->number]);
586
587 return 0;
588} 533}
589 534
590/* 535static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
591 * Digital capture 536 struct hda_codec *codec,
592 */ 537 struct snd_pcm_substream *substream)
593static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
594 struct hda_codec *codec,
595 unsigned int stream_tag,
596 unsigned int format,
597 struct snd_pcm_substream *substream)
598{ 538{
599 struct ca0132_spec *spec = codec->spec; 539 struct ca0132_spec *spec = codec->spec;
600 540 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
601 ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format);
602
603 return 0;
604}
605
606static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
607 struct hda_codec *codec,
608 struct snd_pcm_substream *substream)
609{
610 struct ca0132_spec *spec = codec->spec;
611
612 ca0132_cleanup_stream(codec, spec->dig_in);
613
614 return 0;
615} 541}
616 542
617/* 543/*
@@ -621,6 +547,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = {
621 .channels_min = 2, 547 .channels_min = 2,
622 .channels_max = 2, 548 .channels_max = 2,
623 .ops = { 549 .ops = {
550 .open = ca0132_playback_pcm_open,
624 .prepare = ca0132_playback_pcm_prepare, 551 .prepare = ca0132_playback_pcm_prepare,
625 .cleanup = ca0132_playback_pcm_cleanup 552 .cleanup = ca0132_playback_pcm_cleanup
626 }, 553 },
@@ -630,10 +557,6 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = {
630 .substreams = 1, 557 .substreams = 1,
631 .channels_min = 2, 558 .channels_min = 2,
632 .channels_max = 2, 559 .channels_max = 2,
633 .ops = {
634 .prepare = ca0132_capture_pcm_prepare,
635 .cleanup = ca0132_capture_pcm_cleanup
636 },
637}; 560};
638 561
639static struct hda_pcm_stream ca0132_pcm_digital_playback = { 562static struct hda_pcm_stream ca0132_pcm_digital_playback = {
@@ -641,6 +564,8 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = {
641 .channels_min = 2, 564 .channels_min = 2,
642 .channels_max = 2, 565 .channels_max = 2,
643 .ops = { 566 .ops = {
567 .open = ca0132_dig_playback_pcm_open,
568 .close = ca0132_dig_playback_pcm_close,
644 .prepare = ca0132_dig_playback_pcm_prepare, 569 .prepare = ca0132_dig_playback_pcm_prepare,
645 .cleanup = ca0132_dig_playback_pcm_cleanup 570 .cleanup = ca0132_dig_playback_pcm_cleanup
646 }, 571 },
@@ -650,10 +575,6 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = {
650 .substreams = 1, 575 .substreams = 1,
651 .channels_min = 2, 576 .channels_min = 2,
652 .channels_max = 2, 577 .channels_max = 2,
653 .ops = {
654 .prepare = ca0132_dig_capture_pcm_prepare,
655 .cleanup = ca0132_dig_capture_pcm_cleanup
656 },
657}; 578};
658 579
659static int ca0132_build_pcms(struct hda_codec *codec) 580static int ca0132_build_pcms(struct hda_codec *codec)
@@ -928,18 +849,16 @@ static int ca0132_build_controls(struct hda_codec *codec)
928 spec->dig_out); 849 spec->dig_out);
929 if (err < 0) 850 if (err < 0)
930 return err; 851 return err;
931 err = add_out_volume(codec, spec->dig_out, "IEC958"); 852 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
932 if (err < 0) 853 if (err < 0)
933 return err; 854 return err;
855 /* spec->multiout.share_spdif = 1; */
934 } 856 }
935 857
936 if (spec->dig_in) { 858 if (spec->dig_in) {
937 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); 859 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
938 if (err < 0) 860 if (err < 0)
939 return err; 861 return err;
940 err = add_in_volume(codec, spec->dig_in, "IEC958");
941 if (err < 0)
942 return err;
943 } 862 }
944 return 0; 863 return 0;
945} 864}
@@ -961,6 +880,9 @@ static void ca0132_config(struct hda_codec *codec)
961 struct ca0132_spec *spec = codec->spec; 880 struct ca0132_spec *spec = codec->spec;
962 struct auto_pin_cfg *cfg = &spec->autocfg; 881 struct auto_pin_cfg *cfg = &spec->autocfg;
963 882
883 codec->pcm_format_first = 1;
884 codec->no_sticky_stream = 1;
885
964 /* line-outs */ 886 /* line-outs */
965 cfg->line_outs = 1; 887 cfg->line_outs = 1;
966 cfg->line_out_pins[0] = 0x0b; /* front */ 888 cfg->line_out_pins[0] = 0x0b; /* front */
@@ -988,14 +910,24 @@ static void ca0132_config(struct hda_codec *codec)
988 910
989 /* Mic-in */ 911 /* Mic-in */
990 spec->input_pins[0] = 0x12; 912 spec->input_pins[0] = 0x12;
991 spec->input_labels[0] = "Mic-In"; 913 spec->input_labels[0] = "Mic";
992 spec->adcs[0] = 0x07; 914 spec->adcs[0] = 0x07;
993 915
994 /* Line-In */ 916 /* Line-In */
995 spec->input_pins[1] = 0x11; 917 spec->input_pins[1] = 0x11;
996 spec->input_labels[1] = "Line-In"; 918 spec->input_labels[1] = "Line";
997 spec->adcs[1] = 0x08; 919 spec->adcs[1] = 0x08;
998 spec->num_inputs = 2; 920 spec->num_inputs = 2;
921
922 /* SPDIF I/O */
923 spec->dig_out = 0x05;
924 spec->multiout.dig_out_nid = spec->dig_out;
925 cfg->dig_out_pins[0] = 0x0c;
926 cfg->dig_outs = 1;
927 cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF;
928 spec->dig_in = 0x09;
929 cfg->dig_in_pin = 0x0e;
930 cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
999} 931}
1000 932
1001static void ca0132_init_chip(struct hda_codec *codec) 933static void ca0132_init_chip(struct hda_codec *codec)