diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-13 10:41:01 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-13 10:41:01 -0400 |
commit | 78890b5989d96ddce989cde929c45ceeded0fcaf (patch) | |
tree | 4e2da81fc7c97f11aee174b1eedac110c9a68b3a /sound/pci/hda/patch_ca0132.c | |
parent | 1959ec5f82acbdf91425b41600f119ebecb5f6a8 (diff) | |
parent | 55d512e245bc7699a8800e23df1a24195dd08217 (diff) |
Merge commit 'v3.6-rc5' into next
* commit 'v3.6-rc5': (1098 commits)
Linux 3.6-rc5
HID: tpkbd: work even if the new Lenovo Keyboard driver is not configured
Remove user-triggerable BUG from mpol_to_str
xen/pciback: Fix proper FLR steps.
uml: fix compile error in deliver_alarm()
dj: memory scribble in logi_dj
Fix order of arguments to compat_put_time[spec|val]
xen: Use correct masking in xen_swiotlb_alloc_coherent.
xen: fix logical error in tlb flushing
xen/p2m: Fix one-off error in checking the P2M tree directory.
powerpc: Don't use __put_user() in patch_instruction
powerpc: Make sure IPI handlers see data written by IPI senders
powerpc: Restore correct DSCR in context switch
powerpc: Fix DSCR inheritance in copy_thread()
powerpc: Keep thread.dscr and thread.dscr_inherit in sync
powerpc: Update DSCR on all CPUs when writing sysfs dscr_default
powerpc/powernv: Always go into nap mode when CPU is offline
powerpc: Give hypervisor decrementer interrupts their own handler
powerpc/vphn: Fix arch_update_cpu_topology() return value
ARM: gemini: fix the gemini build
...
Conflicts:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/rapidio/devices/tsi721.c
Diffstat (limited to 'sound/pci/hda/patch_ca0132.c')
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 174 |
1 files changed, 53 insertions, 121 deletions
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 | */ |
469 | static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 477 | static 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 | |||
502 | static 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 | */ | ||
511 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 486 | static 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 | ||
524 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 497 | static 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 | */ |
538 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 508 | static 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 | ||
551 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 516 | static 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 | */ | ||
565 | static 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 | ||
579 | static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | 527 | static 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 | /* | 535 | static 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) |
593 | static 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 | |||
606 | static 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 | ||
639 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { | 562 | static 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 | ||
659 | static int ca0132_build_pcms(struct hda_codec *codec) | 580 | static 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 | ||
1001 | static void ca0132_init_chip(struct hda_codec *codec) | 933 | static void ca0132_init_chip(struct hda_codec *codec) |