Commit a7301fcc123a82baa0b9451612fd512a8f073e5a
Exists in
master
and in
20 other branches
Merge tag 'sound-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "Nothing too serious here: a couple of compress-offload core fixes, Haswell HDMI audio fix, a fixup for new MacBook Airs and a few COEF setups for ALC283 mic problems" * tag 'sound-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - Enable internal mic on a Thinkpad machine with ALC283 ALSA: hda - Fix Internal Mic boost can't control with ALC283 ALSA: hda - Add documentation for CS4208 fixups ALSA: hda - Add fixup for MacBook Air 6,1 and 6,2 with CS4208 codec ALSA : hda - not use assigned converters for all unused pins ALSA: compress: Make sure we trigger STOP before closing the stream. ALSA: compress: Fix compress device unregister.
Showing 5 changed files Side-by-side Diff
Documentation/sound/alsa/HD-Audio-Models.txt
... | ... | @@ -296,6 +296,12 @@ |
296 | 296 | imac27 IMac 27 Inch |
297 | 297 | auto BIOS setup (default) |
298 | 298 | |
299 | +Cirrus Logic CS4208 | |
300 | +=================== | |
301 | + mba6 MacBook Air 6,1 and 6,2 | |
302 | + gpio0 Enable GPIO 0 amp | |
303 | + auto BIOS setup (default) | |
304 | + | |
299 | 305 | VIA VT17xx/VT18xx/VT20xx |
300 | 306 | ======================== |
301 | 307 | auto BIOS setup (default) |
sound/core/compress_offload.c
... | ... | @@ -139,6 +139,18 @@ |
139 | 139 | static int snd_compr_free(struct inode *inode, struct file *f) |
140 | 140 | { |
141 | 141 | struct snd_compr_file *data = f->private_data; |
142 | + struct snd_compr_runtime *runtime = data->stream.runtime; | |
143 | + | |
144 | + switch (runtime->state) { | |
145 | + case SNDRV_PCM_STATE_RUNNING: | |
146 | + case SNDRV_PCM_STATE_DRAINING: | |
147 | + case SNDRV_PCM_STATE_PAUSED: | |
148 | + data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP); | |
149 | + break; | |
150 | + default: | |
151 | + break; | |
152 | + } | |
153 | + | |
142 | 154 | data->stream.ops->free(&data->stream); |
143 | 155 | kfree(data->stream.runtime->buffer); |
144 | 156 | kfree(data->stream.runtime); |
... | ... | @@ -837,7 +849,8 @@ |
837 | 849 | struct snd_compr *compr; |
838 | 850 | |
839 | 851 | compr = device->device_data; |
840 | - snd_unregister_device(compr->direction, compr->card, compr->device); | |
852 | + snd_unregister_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card, | |
853 | + compr->device); | |
841 | 854 | return 0; |
842 | 855 | } |
843 | 856 |
sound/pci/hda/patch_cirrus.c
... | ... | @@ -111,6 +111,9 @@ |
111 | 111 | /* 0x0009 - 0x0014 -> 12 test regs */ |
112 | 112 | /* 0x0015 - visibility reg */ |
113 | 113 | |
114 | +/* Cirrus Logic CS4208 */ | |
115 | +#define CS4208_VENDOR_NID 0x24 | |
116 | + | |
114 | 117 | /* |
115 | 118 | * Cirrus Logic CS4210 |
116 | 119 | * |
... | ... | @@ -223,6 +226,16 @@ |
223 | 226 | {} /* terminator */ |
224 | 227 | }; |
225 | 228 | |
229 | +static const struct hda_verb cs4208_coef_init_verbs[] = { | |
230 | + {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ | |
231 | + {0x24, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ | |
232 | + {0x24, AC_VERB_SET_COEF_INDEX, 0x0033}, | |
233 | + {0x24, AC_VERB_SET_PROC_COEF, 0x0001}, /* A1 ICS */ | |
234 | + {0x24, AC_VERB_SET_COEF_INDEX, 0x0034}, | |
235 | + {0x24, AC_VERB_SET_PROC_COEF, 0x1C01}, /* A1 Enable, A Thresh = 300mV */ | |
236 | + {} /* terminator */ | |
237 | +}; | |
238 | + | |
226 | 239 | /* Errata: CS4207 rev C0/C1/C2 Silicon |
227 | 240 | * |
228 | 241 | * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf |
... | ... | @@ -295,6 +308,8 @@ |
295 | 308 | /* init_verb sequence for C0/C1/C2 errata*/ |
296 | 309 | snd_hda_sequence_write(codec, cs_errata_init_verbs); |
297 | 310 | snd_hda_sequence_write(codec, cs_coef_init_verbs); |
311 | + } else if (spec->vendor_nid == CS4208_VENDOR_NID) { | |
312 | + snd_hda_sequence_write(codec, cs4208_coef_init_verbs); | |
298 | 313 | } |
299 | 314 | |
300 | 315 | snd_hda_gen_init(codec); |
... | ... | @@ -434,6 +449,29 @@ |
434 | 449 | {} /* terminator */ |
435 | 450 | }; |
436 | 451 | |
452 | +static const struct hda_pintbl mba6_pincfgs[] = { | |
453 | + { 0x10, 0x032120f0 }, /* HP */ | |
454 | + { 0x11, 0x500000f0 }, | |
455 | + { 0x12, 0x90100010 }, /* Speaker */ | |
456 | + { 0x13, 0x500000f0 }, | |
457 | + { 0x14, 0x500000f0 }, | |
458 | + { 0x15, 0x770000f0 }, | |
459 | + { 0x16, 0x770000f0 }, | |
460 | + { 0x17, 0x430000f0 }, | |
461 | + { 0x18, 0x43ab9030 }, /* Mic */ | |
462 | + { 0x19, 0x770000f0 }, | |
463 | + { 0x1a, 0x770000f0 }, | |
464 | + { 0x1b, 0x770000f0 }, | |
465 | + { 0x1c, 0x90a00090 }, | |
466 | + { 0x1d, 0x500000f0 }, | |
467 | + { 0x1e, 0x500000f0 }, | |
468 | + { 0x1f, 0x500000f0 }, | |
469 | + { 0x20, 0x500000f0 }, | |
470 | + { 0x21, 0x430000f0 }, | |
471 | + { 0x22, 0x430000f0 }, | |
472 | + {} /* terminator */ | |
473 | +}; | |
474 | + | |
437 | 475 | static void cs420x_fixup_gpio_13(struct hda_codec *codec, |
438 | 476 | const struct hda_fixup *fix, int action) |
439 | 477 | { |
440 | 478 | |
441 | 479 | |
442 | 480 | |
... | ... | @@ -556,22 +594,23 @@ |
556 | 594 | |
557 | 595 | /* |
558 | 596 | * CS4208 support: |
559 | - * Its layout is no longer compatible with CS4206/CS4207, and the generic | |
560 | - * parser seems working fairly well, except for trivial fixups. | |
597 | + * Its layout is no longer compatible with CS4206/CS4207 | |
561 | 598 | */ |
562 | 599 | enum { |
600 | + CS4208_MBA6, | |
563 | 601 | CS4208_GPIO0, |
564 | 602 | }; |
565 | 603 | |
566 | 604 | static const struct hda_model_fixup cs4208_models[] = { |
567 | 605 | { .id = CS4208_GPIO0, .name = "gpio0" }, |
606 | + { .id = CS4208_MBA6, .name = "mba6" }, | |
568 | 607 | {} |
569 | 608 | }; |
570 | 609 | |
571 | 610 | static const struct snd_pci_quirk cs4208_fixup_tbl[] = { |
572 | 611 | /* codec SSID */ |
573 | - SND_PCI_QUIRK(0x106b, 0x7100, "MacBookPro 6,1", CS4208_GPIO0), | |
574 | - SND_PCI_QUIRK(0x106b, 0x7200, "MacBookPro 6,2", CS4208_GPIO0), | |
612 | + SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6), | |
613 | + SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6), | |
575 | 614 | {} /* terminator */ |
576 | 615 | }; |
577 | 616 | |
578 | 617 | |
579 | 618 | |
... | ... | @@ -588,18 +627,35 @@ |
588 | 627 | } |
589 | 628 | |
590 | 629 | static const struct hda_fixup cs4208_fixups[] = { |
630 | + [CS4208_MBA6] = { | |
631 | + .type = HDA_FIXUP_PINS, | |
632 | + .v.pins = mba6_pincfgs, | |
633 | + .chained = true, | |
634 | + .chain_id = CS4208_GPIO0, | |
635 | + }, | |
591 | 636 | [CS4208_GPIO0] = { |
592 | 637 | .type = HDA_FIXUP_FUNC, |
593 | 638 | .v.func = cs4208_fixup_gpio0, |
594 | 639 | }, |
595 | 640 | }; |
596 | 641 | |
642 | +/* correct the 0dB offset of input pins */ | |
643 | +static void cs4208_fix_amp_caps(struct hda_codec *codec, hda_nid_t adc) | |
644 | +{ | |
645 | + unsigned int caps; | |
646 | + | |
647 | + caps = query_amp_caps(codec, adc, HDA_INPUT); | |
648 | + caps &= ~(AC_AMPCAP_OFFSET); | |
649 | + caps |= 0x02; | |
650 | + snd_hda_override_amp_caps(codec, adc, HDA_INPUT, caps); | |
651 | +} | |
652 | + | |
597 | 653 | static int patch_cs4208(struct hda_codec *codec) |
598 | 654 | { |
599 | 655 | struct cs_spec *spec; |
600 | 656 | int err; |
601 | 657 | |
602 | - spec = cs_alloc_spec(codec, 0); /* no specific w/a */ | |
658 | + spec = cs_alloc_spec(codec, CS4208_VENDOR_NID); | |
603 | 659 | if (!spec) |
604 | 660 | return -ENOMEM; |
605 | 661 | |
... | ... | @@ -608,6 +664,12 @@ |
608 | 664 | snd_hda_pick_fixup(codec, cs4208_models, cs4208_fixup_tbl, |
609 | 665 | cs4208_fixups); |
610 | 666 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
667 | + | |
668 | + snd_hda_override_wcaps(codec, 0x18, | |
669 | + get_wcaps(codec, 0x18) | AC_WCAP_STEREO); | |
670 | + cs4208_fix_amp_caps(codec, 0x18); | |
671 | + cs4208_fix_amp_caps(codec, 0x1b); | |
672 | + cs4208_fix_amp_caps(codec, 0x1c); | |
611 | 673 | |
612 | 674 | err = cs_parse_auto_config(codec); |
613 | 675 | if (err < 0) |
sound/pci/hda/patch_hdmi.c
... | ... | @@ -1149,32 +1149,43 @@ |
1149 | 1149 | } |
1150 | 1150 | |
1151 | 1151 | static void haswell_config_cvts(struct hda_codec *codec, |
1152 | - int pin_id, int mux_id) | |
1152 | + hda_nid_t pin_nid, int mux_idx) | |
1153 | 1153 | { |
1154 | 1154 | struct hdmi_spec *spec = codec->spec; |
1155 | - struct hdmi_spec_per_pin *per_pin; | |
1156 | - int pin_idx, mux_idx; | |
1157 | - int curr; | |
1158 | - int err; | |
1155 | + hda_nid_t nid, end_nid; | |
1156 | + int cvt_idx, curr; | |
1157 | + struct hdmi_spec_per_cvt *per_cvt; | |
1159 | 1158 | |
1160 | - for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | |
1161 | - per_pin = get_pin(spec, pin_idx); | |
1159 | + /* configure all pins, including "no physical connection" ones */ | |
1160 | + end_nid = codec->start_nid + codec->num_nodes; | |
1161 | + for (nid = codec->start_nid; nid < end_nid; nid++) { | |
1162 | + unsigned int wid_caps = get_wcaps(codec, nid); | |
1163 | + unsigned int wid_type = get_wcaps_type(wid_caps); | |
1162 | 1164 | |
1163 | - if (pin_idx == pin_id) | |
1165 | + if (wid_type != AC_WID_PIN) | |
1164 | 1166 | continue; |
1165 | 1167 | |
1166 | - curr = snd_hda_codec_read(codec, per_pin->pin_nid, 0, | |
1168 | + if (nid == pin_nid) | |
1169 | + continue; | |
1170 | + | |
1171 | + curr = snd_hda_codec_read(codec, nid, 0, | |
1167 | 1172 | AC_VERB_GET_CONNECT_SEL, 0); |
1173 | + if (curr != mux_idx) | |
1174 | + continue; | |
1168 | 1175 | |
1169 | - /* Choose another unused converter */ | |
1170 | - if (curr == mux_id) { | |
1171 | - err = hdmi_choose_cvt(codec, pin_idx, NULL, &mux_idx); | |
1172 | - if (err < 0) | |
1173 | - return; | |
1174 | - snd_printdd("HDMI: choose converter %d for pin %d\n", mux_idx, pin_idx); | |
1175 | - snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0, | |
1176 | + /* choose an unassigned converter. The conveters in the | |
1177 | + * connection list are in the same order as in the codec. | |
1178 | + */ | |
1179 | + for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { | |
1180 | + per_cvt = get_cvt(spec, cvt_idx); | |
1181 | + if (!per_cvt->assigned) { | |
1182 | + snd_printdd("choose cvt %d for pin nid %d\n", | |
1183 | + cvt_idx, nid); | |
1184 | + snd_hda_codec_write_cache(codec, nid, 0, | |
1176 | 1185 | AC_VERB_SET_CONNECT_SEL, |
1177 | - mux_idx); | |
1186 | + cvt_idx); | |
1187 | + break; | |
1188 | + } | |
1178 | 1189 | } |
1179 | 1190 | } |
1180 | 1191 | } |
... | ... | @@ -1216,7 +1227,7 @@ |
1216 | 1227 | |
1217 | 1228 | /* configure unused pins to choose other converters */ |
1218 | 1229 | if (is_haswell(codec)) |
1219 | - haswell_config_cvts(codec, pin_idx, mux_idx); | |
1230 | + haswell_config_cvts(codec, per_pin->pin_nid, mux_idx); | |
1220 | 1231 | |
1221 | 1232 | snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); |
1222 | 1233 |
sound/pci/hda/patch_realtek.c
... | ... | @@ -3439,6 +3439,9 @@ |
3439 | 3439 | /* Set to manual mode */ |
3440 | 3440 | val = alc_read_coef_idx(codec, 0x06); |
3441 | 3441 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
3442 | + /* Enable Line1 input control by verb */ | |
3443 | + val = alc_read_coef_idx(codec, 0x1a); | |
3444 | + alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); | |
3442 | 3445 | break; |
3443 | 3446 | } |
3444 | 3447 | } |
... | ... | @@ -3531,6 +3534,7 @@ |
3531 | 3534 | ALC269VB_FIXUP_ORDISSIMO_EVE2, |
3532 | 3535 | ALC283_FIXUP_CHROME_BOOK, |
3533 | 3536 | ALC282_FIXUP_ASUS_TX300, |
3537 | + ALC283_FIXUP_INT_MIC, | |
3534 | 3538 | }; |
3535 | 3539 | |
3536 | 3540 | static const struct hda_fixup alc269_fixups[] = { |
... | ... | @@ -3790,6 +3794,16 @@ |
3790 | 3794 | .type = HDA_FIXUP_FUNC, |
3791 | 3795 | .v.func = alc282_fixup_asus_tx300, |
3792 | 3796 | }, |
3797 | + [ALC283_FIXUP_INT_MIC] = { | |
3798 | + .type = HDA_FIXUP_VERBS, | |
3799 | + .v.verbs = (const struct hda_verb[]) { | |
3800 | + {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, | |
3801 | + {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, | |
3802 | + { } | |
3803 | + }, | |
3804 | + .chained = true, | |
3805 | + .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST | |
3806 | + }, | |
3793 | 3807 | }; |
3794 | 3808 | |
3795 | 3809 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
... | ... | @@ -3874,7 +3888,7 @@ |
3874 | 3888 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
3875 | 3889 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
3876 | 3890 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
3877 | - SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | |
3891 | + SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), | |
3878 | 3892 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
3879 | 3893 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
3880 | 3894 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), |