diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-11 23:31:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-11 23:31:28 -0400 |
commit | 2fc07efa2241afe08de136c061b3baa103fb286c (patch) | |
tree | 113b58740841098c3cc363a4069b5ba77549a881 /sound | |
parent | 79360ddd73dfe9a26f49ef4e27b8c26612929b0e (diff) | |
parent | f7f4b2322bf7b8c5929b7eb5a667091f32592580 (diff) |
Merge tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates #2 from Takashi Iwai:
"This update contains a few cleanup works, regression/stable fixes
gathered since the last pull request.
- Clean up with generic hd-audio jack handling code by David
Henningsson
- A few regression fixes for standardized HD-audio auto-parser
- Misc clean-up and small fixes"
* tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: hda - do not detect jack on internal speakers for Realtek
ALSA: hda - Fix missing beep on ASUS X43U notebook
ALSA: hda - Remove AZX_DCAPS_POSFIX_COMBO
ALSA: hda - Warn an allocation for an uninitialized array
ALSA: hda/cirrus - Add missing init/free of hda_gen_spec
ALSA: hda - Fix memory leaks at error path in patch_cirrus.c
ALSA: hda - Add missing hda_gen_spec to struct via_spec
ALSA: hda - remove "Mic Jack Mode" for headset jacks (Latitude Exx30)
ALSA: hda - make Cirrus codec use generic unsol event handler
ALSA: hda - make VIA codec use generic unsol event handler
ALSA: hda - Remove dead GPIO code for VIA codec
ALSA: usb-audio: Add TASCAM US122 MKII playback
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 58 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 27 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 98 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 46 |
7 files changed, 122 insertions, 117 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c0ab72cbeed1..70d4848b5cd0 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -5168,6 +5168,8 @@ EXPORT_SYMBOL_HDA(snd_hda_resume); | |||
5168 | */ | 5168 | */ |
5169 | void *snd_array_new(struct snd_array *array) | 5169 | void *snd_array_new(struct snd_array *array) |
5170 | { | 5170 | { |
5171 | if (snd_BUG_ON(!array->elem_size)) | ||
5172 | return NULL; | ||
5171 | if (array->used >= array->alloced) { | 5173 | if (array->used >= array->alloced) { |
5172 | int num = array->alloced + array->alloc_align; | 5174 | int num = array->alloced + array->alloc_align; |
5173 | int size = (num + 1) * array->elem_size; | 5175 | int size = (num + 1) * array->elem_size; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index f09ff6c14041..6833835a218b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -554,7 +554,6 @@ enum { | |||
554 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | 554 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ |
555 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | 555 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ |
556 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ | 556 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ |
557 | #define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */ | ||
558 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ | 557 | #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ |
559 | 558 | ||
560 | /* quirks for ATI SB / AMD Hudson */ | 559 | /* quirks for ATI SB / AMD Hudson */ |
@@ -2858,10 +2857,6 @@ static int __devinit check_position_fix(struct azx *chip, int fix) | |||
2858 | snd_printd(SFX "Using LPIB position fix\n"); | 2857 | snd_printd(SFX "Using LPIB position fix\n"); |
2859 | return POS_FIX_LPIB; | 2858 | return POS_FIX_LPIB; |
2860 | } | 2859 | } |
2861 | if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) { | ||
2862 | snd_printd(SFX "Using COMBO position fix\n"); | ||
2863 | return POS_FIX_COMBO; | ||
2864 | } | ||
2865 | return POS_FIX_AUTO; | 2860 | return POS_FIX_AUTO; |
2866 | } | 2861 | } |
2867 | 2862 | ||
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index fcfc9f0a056b..61a71131711c 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -897,7 +897,7 @@ static int build_digital_input(struct hda_codec *codec) | |||
897 | * HP/SPK/SPDIF | 897 | * HP/SPK/SPDIF |
898 | */ | 898 | */ |
899 | 899 | ||
900 | static void cs_automute(struct hda_codec *codec) | 900 | static void cs_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl) |
901 | { | 901 | { |
902 | struct cs_spec *spec = codec->spec; | 902 | struct cs_spec *spec = codec->spec; |
903 | struct auto_pin_cfg *cfg = &spec->autocfg; | 903 | struct auto_pin_cfg *cfg = &spec->autocfg; |
@@ -973,7 +973,7 @@ static void cs_automute(struct hda_codec *codec) | |||
973 | * Switch max 3 inputs of a single ADC (nid 3) | 973 | * Switch max 3 inputs of a single ADC (nid 3) |
974 | */ | 974 | */ |
975 | 975 | ||
976 | static void cs_automic(struct hda_codec *codec) | 976 | static void cs_automic(struct hda_codec *codec, struct hda_jack_tbl *tbl) |
977 | { | 977 | { |
978 | struct cs_spec *spec = codec->spec; | 978 | struct cs_spec *spec = codec->spec; |
979 | struct auto_pin_cfg *cfg = &spec->autocfg; | 979 | struct auto_pin_cfg *cfg = &spec->autocfg; |
@@ -1035,7 +1035,7 @@ static void init_output(struct hda_codec *codec) | |||
1035 | if (!cfg->speaker_outs) | 1035 | if (!cfg->speaker_outs) |
1036 | continue; | 1036 | continue; |
1037 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | 1037 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { |
1038 | snd_hda_jack_detect_enable(codec, nid, HP_EVENT); | 1038 | snd_hda_jack_detect_enable_callback(codec, nid, HP_EVENT, cs_automute); |
1039 | spec->hp_detect = 1; | 1039 | spec->hp_detect = 1; |
1040 | } | 1040 | } |
1041 | } | 1041 | } |
@@ -1046,7 +1046,7 @@ static void init_output(struct hda_codec *codec) | |||
1046 | 1046 | ||
1047 | /* SPDIF is enabled on presence detect for CS421x */ | 1047 | /* SPDIF is enabled on presence detect for CS421x */ |
1048 | if (spec->hp_detect || spec->spdif_detect) | 1048 | if (spec->hp_detect || spec->spdif_detect) |
1049 | cs_automute(codec); | 1049 | cs_automute(codec, NULL); |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | static void init_input(struct hda_codec *codec) | 1052 | static void init_input(struct hda_codec *codec) |
@@ -1070,13 +1070,13 @@ static void init_input(struct hda_codec *codec) | |||
1070 | AC_VERB_SET_AMP_GAIN_MUTE, | 1070 | AC_VERB_SET_AMP_GAIN_MUTE, |
1071 | AMP_IN_MUTE(spec->adc_idx[i])); | 1071 | AMP_IN_MUTE(spec->adc_idx[i])); |
1072 | if (spec->mic_detect && spec->automic_idx == i) | 1072 | if (spec->mic_detect && spec->automic_idx == i) |
1073 | snd_hda_jack_detect_enable(codec, pin, MIC_EVENT); | 1073 | snd_hda_jack_detect_enable_callback(codec, pin, MIC_EVENT, cs_automic); |
1074 | } | 1074 | } |
1075 | /* CS420x has multiple ADC, CS421x has single ADC */ | 1075 | /* CS420x has multiple ADC, CS421x has single ADC */ |
1076 | if (spec->vendor_nid == CS420X_VENDOR_NID) { | 1076 | if (spec->vendor_nid == CS420X_VENDOR_NID) { |
1077 | change_cur_input(codec, spec->cur_input, 1); | 1077 | change_cur_input(codec, spec->cur_input, 1); |
1078 | if (spec->mic_detect) | 1078 | if (spec->mic_detect) |
1079 | cs_automic(codec); | 1079 | cs_automic(codec, NULL); |
1080 | 1080 | ||
1081 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ | 1081 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ |
1082 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) | 1082 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) |
@@ -1089,7 +1089,7 @@ static void init_input(struct hda_codec *codec) | |||
1089 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | 1089 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); |
1090 | } else { | 1090 | } else { |
1091 | if (spec->mic_detect) | 1091 | if (spec->mic_detect) |
1092 | cs_automic(codec); | 1092 | cs_automic(codec, NULL); |
1093 | else { | 1093 | else { |
1094 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | 1094 | spec->cur_adc = spec->adc_nid[spec->cur_input]; |
1095 | cs_update_input_select(codec); | 1095 | cs_update_input_select(codec); |
@@ -1243,28 +1243,16 @@ static void cs_free(struct hda_codec *codec) | |||
1243 | struct cs_spec *spec = codec->spec; | 1243 | struct cs_spec *spec = codec->spec; |
1244 | kfree(spec->capture_bind[0]); | 1244 | kfree(spec->capture_bind[0]); |
1245 | kfree(spec->capture_bind[1]); | 1245 | kfree(spec->capture_bind[1]); |
1246 | snd_hda_gen_free(&spec->gen); | ||
1246 | kfree(codec->spec); | 1247 | kfree(codec->spec); |
1247 | } | 1248 | } |
1248 | 1249 | ||
1249 | static void cs_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1250 | { | ||
1251 | switch (snd_hda_jack_get_action(codec, res >> 26)) { | ||
1252 | case HP_EVENT: | ||
1253 | cs_automute(codec); | ||
1254 | break; | ||
1255 | case MIC_EVENT: | ||
1256 | cs_automic(codec); | ||
1257 | break; | ||
1258 | } | ||
1259 | snd_hda_jack_report_sync(codec); | ||
1260 | } | ||
1261 | |||
1262 | static const struct hda_codec_ops cs_patch_ops = { | 1250 | static const struct hda_codec_ops cs_patch_ops = { |
1263 | .build_controls = cs_build_controls, | 1251 | .build_controls = cs_build_controls, |
1264 | .build_pcms = cs_build_pcms, | 1252 | .build_pcms = cs_build_pcms, |
1265 | .init = cs_init, | 1253 | .init = cs_init, |
1266 | .free = cs_free, | 1254 | .free = cs_free, |
1267 | .unsol_event = cs_unsol_event, | 1255 | .unsol_event = snd_hda_jack_unsol_event, |
1268 | }; | 1256 | }; |
1269 | 1257 | ||
1270 | static int cs_parse_auto_config(struct hda_codec *codec) | 1258 | static int cs_parse_auto_config(struct hda_codec *codec) |
@@ -1439,6 +1427,7 @@ static int patch_cs420x(struct hda_codec *codec) | |||
1439 | if (!spec) | 1427 | if (!spec) |
1440 | return -ENOMEM; | 1428 | return -ENOMEM; |
1441 | codec->spec = spec; | 1429 | codec->spec = spec; |
1430 | snd_hda_gen_init(&spec->gen); | ||
1442 | 1431 | ||
1443 | spec->vendor_nid = CS420X_VENDOR_NID; | 1432 | spec->vendor_nid = CS420X_VENDOR_NID; |
1444 | 1433 | ||
@@ -1457,7 +1446,7 @@ static int patch_cs420x(struct hda_codec *codec) | |||
1457 | return 0; | 1446 | return 0; |
1458 | 1447 | ||
1459 | error: | 1448 | error: |
1460 | kfree(codec->spec); | 1449 | cs_free(codec); |
1461 | codec->spec = NULL; | 1450 | codec->spec = NULL; |
1462 | return err; | 1451 | return err; |
1463 | } | 1452 | } |
@@ -1674,7 +1663,7 @@ static void init_cs421x_digital(struct hda_codec *codec) | |||
1674 | if (!cfg->speaker_outs) | 1663 | if (!cfg->speaker_outs) |
1675 | continue; | 1664 | continue; |
1676 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | 1665 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { |
1677 | snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT); | 1666 | snd_hda_jack_detect_enable_callback(codec, nid, SPDIF_EVENT, cs_automute); |
1678 | spec->spdif_detect = 1; | 1667 | spec->spdif_detect = 1; |
1679 | } | 1668 | } |
1680 | } | 1669 | } |
@@ -1889,21 +1878,6 @@ static int cs421x_build_controls(struct hda_codec *codec) | |||
1889 | return 0; | 1878 | return 0; |
1890 | } | 1879 | } |
1891 | 1880 | ||
1892 | static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1893 | { | ||
1894 | switch (snd_hda_jack_get_action(codec, res >> 26)) { | ||
1895 | case HP_EVENT: | ||
1896 | case SPDIF_EVENT: | ||
1897 | cs_automute(codec); | ||
1898 | break; | ||
1899 | |||
1900 | case MIC_EVENT: | ||
1901 | cs_automic(codec); | ||
1902 | break; | ||
1903 | } | ||
1904 | snd_hda_jack_report_sync(codec); | ||
1905 | } | ||
1906 | |||
1907 | static int parse_cs421x_input(struct hda_codec *codec) | 1881 | static int parse_cs421x_input(struct hda_codec *codec) |
1908 | { | 1882 | { |
1909 | struct cs_spec *spec = codec->spec; | 1883 | struct cs_spec *spec = codec->spec; |
@@ -1977,7 +1951,7 @@ static struct hda_codec_ops cs421x_patch_ops = { | |||
1977 | .build_pcms = cs_build_pcms, | 1951 | .build_pcms = cs_build_pcms, |
1978 | .init = cs421x_init, | 1952 | .init = cs421x_init, |
1979 | .free = cs_free, | 1953 | .free = cs_free, |
1980 | .unsol_event = cs421x_unsol_event, | 1954 | .unsol_event = snd_hda_jack_unsol_event, |
1981 | #ifdef CONFIG_PM | 1955 | #ifdef CONFIG_PM |
1982 | .suspend = cs421x_suspend, | 1956 | .suspend = cs421x_suspend, |
1983 | #endif | 1957 | #endif |
@@ -1992,6 +1966,7 @@ static int patch_cs4210(struct hda_codec *codec) | |||
1992 | if (!spec) | 1966 | if (!spec) |
1993 | return -ENOMEM; | 1967 | return -ENOMEM; |
1994 | codec->spec = spec; | 1968 | codec->spec = spec; |
1969 | snd_hda_gen_init(&spec->gen); | ||
1995 | 1970 | ||
1996 | spec->vendor_nid = CS4210_VENDOR_NID; | 1971 | spec->vendor_nid = CS4210_VENDOR_NID; |
1997 | 1972 | ||
@@ -2017,7 +1992,7 @@ static int patch_cs4210(struct hda_codec *codec) | |||
2017 | return 0; | 1992 | return 0; |
2018 | 1993 | ||
2019 | error: | 1994 | error: |
2020 | kfree(codec->spec); | 1995 | cs_free(codec); |
2021 | codec->spec = NULL; | 1996 | codec->spec = NULL; |
2022 | return err; | 1997 | return err; |
2023 | } | 1998 | } |
@@ -2031,6 +2006,7 @@ static int patch_cs4213(struct hda_codec *codec) | |||
2031 | if (!spec) | 2006 | if (!spec) |
2032 | return -ENOMEM; | 2007 | return -ENOMEM; |
2033 | codec->spec = spec; | 2008 | codec->spec = spec; |
2009 | snd_hda_gen_init(&spec->gen); | ||
2034 | 2010 | ||
2035 | spec->vendor_nid = CS4213_VENDOR_NID; | 2011 | spec->vendor_nid = CS4213_VENDOR_NID; |
2036 | 2012 | ||
@@ -2042,7 +2018,7 @@ static int patch_cs4213(struct hda_codec *codec) | |||
2042 | return 0; | 2018 | return 0; |
2043 | 2019 | ||
2044 | error: | 2020 | error: |
2045 | kfree(codec->spec); | 2021 | cs_free(codec); |
2046 | codec->spec = NULL; | 2022 | codec->spec = NULL; |
2047 | return err; | 2023 | return err; |
2048 | } | 2024 | } |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8568aee56e2d..8253b4eeb6a1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -611,6 +611,8 @@ static void alc_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack | |||
611 | { | 611 | { |
612 | struct alc_spec *spec = codec->spec; | 612 | struct alc_spec *spec = codec->spec; |
613 | 613 | ||
614 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
615 | return; | ||
614 | /* check LO jack only when it's different from HP */ | 616 | /* check LO jack only when it's different from HP */ |
615 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0]) | 617 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0]) |
616 | return; | 618 | return; |
@@ -4245,6 +4247,7 @@ static void alc_auto_init_std(struct hda_codec *codec) | |||
4245 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 4247 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
4246 | 4248 | ||
4247 | static const struct snd_pci_quirk beep_white_list[] = { | 4249 | static const struct snd_pci_quirk beep_white_list[] = { |
4250 | SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), | ||
4248 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 4251 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
4249 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), | 4252 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), |
4250 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), | 4253 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fe163547f906..770013ff556f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -104,6 +104,7 @@ enum { | |||
104 | STAC_92HD83XXX_HP_LED, | 104 | STAC_92HD83XXX_HP_LED, |
105 | STAC_92HD83XXX_HP_INV_LED, | 105 | STAC_92HD83XXX_HP_INV_LED, |
106 | STAC_92HD83XXX_HP_MIC_LED, | 106 | STAC_92HD83XXX_HP_MIC_LED, |
107 | STAC_92HD83XXX_HEADSET_JACK, | ||
107 | STAC_92HD83XXX_MODELS | 108 | STAC_92HD83XXX_MODELS |
108 | }; | 109 | }; |
109 | 110 | ||
@@ -204,6 +205,7 @@ struct sigmatel_spec { | |||
204 | unsigned int check_volume_offset:1; | 205 | unsigned int check_volume_offset:1; |
205 | unsigned int auto_mic:1; | 206 | unsigned int auto_mic:1; |
206 | unsigned int linear_tone_beep:1; | 207 | unsigned int linear_tone_beep:1; |
208 | unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */ | ||
207 | 209 | ||
208 | /* gpio lines */ | 210 | /* gpio lines */ |
209 | unsigned int eapd_mask; | 211 | unsigned int eapd_mask; |
@@ -1684,6 +1686,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |||
1684 | [STAC_92HD83XXX_HP_LED] = "hp-led", | 1686 | [STAC_92HD83XXX_HP_LED] = "hp-led", |
1685 | [STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led", | 1687 | [STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led", |
1686 | [STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led", | 1688 | [STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led", |
1689 | [STAC_92HD83XXX_HEADSET_JACK] = "headset-jack", | ||
1687 | }; | 1690 | }; |
1688 | 1691 | ||
1689 | static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | 1692 | static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { |
@@ -1694,6 +1697,24 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1694 | "DFI LanParty", STAC_92HD83XXX_REF), | 1697 | "DFI LanParty", STAC_92HD83XXX_REF), |
1695 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, | 1698 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, |
1696 | "unknown Dell", STAC_DELL_S14), | 1699 | "unknown Dell", STAC_DELL_S14), |
1700 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532, | ||
1701 | "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK), | ||
1702 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533, | ||
1703 | "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK), | ||
1704 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534, | ||
1705 | "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK), | ||
1706 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535, | ||
1707 | "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK), | ||
1708 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c, | ||
1709 | "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK), | ||
1710 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d, | ||
1711 | "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK), | ||
1712 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549, | ||
1713 | "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK), | ||
1714 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d, | ||
1715 | "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK), | ||
1716 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584, | ||
1717 | "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK), | ||
1697 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, | 1718 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, |
1698 | "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), | 1719 | "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), |
1699 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, | 1720 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, |
@@ -2855,6 +2876,9 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec, | |||
2855 | char name[22]; | 2876 | char name[22]; |
2856 | 2877 | ||
2857 | if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) { | 2878 | if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) { |
2879 | if (spec->headset_jack && snd_hda_get_input_pin_attr(def_conf) | ||
2880 | != INPUT_PIN_ATTR_DOCK) | ||
2881 | return 0; | ||
2858 | if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD | 2882 | if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD |
2859 | && nid == spec->line_switch) | 2883 | && nid == spec->line_switch) |
2860 | control = STAC_CTL_WIDGET_IO_SWITCH; | 2884 | control = STAC_CTL_WIDGET_IO_SWITCH; |
@@ -5626,6 +5650,9 @@ again: | |||
5626 | case STAC_92HD83XXX_HP_MIC_LED: | 5650 | case STAC_92HD83XXX_HP_MIC_LED: |
5627 | spec->mic_mute_led_gpio = 0x08; /* GPIO3 */ | 5651 | spec->mic_mute_led_gpio = 0x08; /* GPIO3 */ |
5628 | break; | 5652 | break; |
5653 | case STAC_92HD83XXX_HEADSET_JACK: | ||
5654 | spec->headset_jack = 1; | ||
5655 | break; | ||
5629 | } | 5656 | } |
5630 | 5657 | ||
5631 | if (find_mute_led_cfg(codec, default_polarity)) | 5658 | if (find_mute_led_cfg(codec, default_polarity)) |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 5a45a912aedc..72a2f60b087c 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -118,6 +118,8 @@ enum { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | struct via_spec { | 120 | struct via_spec { |
121 | struct hda_gen_spec gen; | ||
122 | |||
121 | /* codec parameterization */ | 123 | /* codec parameterization */ |
122 | const struct snd_kcontrol_new *mixers[6]; | 124 | const struct snd_kcontrol_new *mixers[6]; |
123 | unsigned int num_mixers; | 125 | unsigned int num_mixers; |
@@ -246,6 +248,7 @@ static struct via_spec * via_new_spec(struct hda_codec *codec) | |||
246 | /* VT1708BCE & VT1708S are almost same */ | 248 | /* VT1708BCE & VT1708S are almost same */ |
247 | if (spec->codec_type == VT1708BCE) | 249 | if (spec->codec_type == VT1708BCE) |
248 | spec->codec_type = VT1708S; | 250 | spec->codec_type = VT1708S; |
251 | snd_hda_gen_init(&spec->gen); | ||
249 | return spec; | 252 | return spec; |
250 | } | 253 | } |
251 | 254 | ||
@@ -299,7 +302,6 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) | |||
299 | 302 | ||
300 | #define VIA_JACK_EVENT 0x20 | 303 | #define VIA_JACK_EVENT 0x20 |
301 | #define VIA_HP_EVENT 0x01 | 304 | #define VIA_HP_EVENT 0x01 |
302 | #define VIA_GPIO_EVENT 0x02 | ||
303 | #define VIA_LINE_EVENT 0x03 | 305 | #define VIA_LINE_EVENT 0x03 |
304 | 306 | ||
305 | enum { | 307 | enum { |
@@ -1628,6 +1630,7 @@ static void via_free(struct hda_codec *codec) | |||
1628 | vt1708_stop_hp_work(spec); | 1630 | vt1708_stop_hp_work(spec); |
1629 | kfree(spec->bind_cap_vol); | 1631 | kfree(spec->bind_cap_vol); |
1630 | kfree(spec->bind_cap_sw); | 1632 | kfree(spec->bind_cap_sw); |
1633 | snd_hda_gen_free(&spec->gen); | ||
1631 | kfree(spec); | 1634 | kfree(spec); |
1632 | } | 1635 | } |
1633 | 1636 | ||
@@ -1685,69 +1688,6 @@ static void via_hp_automute(struct hda_codec *codec) | |||
1685 | via_line_automute(codec, present); | 1688 | via_line_automute(codec, present); |
1686 | } | 1689 | } |
1687 | 1690 | ||
1688 | static void via_gpio_control(struct hda_codec *codec) | ||
1689 | { | ||
1690 | unsigned int gpio_data; | ||
1691 | unsigned int vol_counter; | ||
1692 | unsigned int vol; | ||
1693 | unsigned int master_vol; | ||
1694 | |||
1695 | struct via_spec *spec = codec->spec; | ||
1696 | |||
1697 | gpio_data = snd_hda_codec_read(codec, codec->afg, 0, | ||
1698 | AC_VERB_GET_GPIO_DATA, 0) & 0x03; | ||
1699 | |||
1700 | vol_counter = (snd_hda_codec_read(codec, codec->afg, 0, | ||
1701 | 0xF84, 0) & 0x3F0000) >> 16; | ||
1702 | |||
1703 | vol = vol_counter & 0x1F; | ||
1704 | master_vol = snd_hda_codec_read(codec, 0x1A, 0, | ||
1705 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
1706 | AC_AMP_GET_INPUT); | ||
1707 | |||
1708 | if (gpio_data == 0x02) { | ||
1709 | /* unmute line out */ | ||
1710 | snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0], | ||
1711 | PIN_OUT); | ||
1712 | if (vol_counter & 0x20) { | ||
1713 | /* decrease volume */ | ||
1714 | if (vol > master_vol) | ||
1715 | vol = master_vol; | ||
1716 | snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, | ||
1717 | 0, HDA_AMP_VOLMASK, | ||
1718 | master_vol-vol); | ||
1719 | } else { | ||
1720 | /* increase volume */ | ||
1721 | snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0, | ||
1722 | HDA_AMP_VOLMASK, | ||
1723 | ((master_vol+vol) > 0x2A) ? 0x2A : | ||
1724 | (master_vol+vol)); | ||
1725 | } | ||
1726 | } else if (!(gpio_data & 0x02)) { | ||
1727 | /* mute line out */ | ||
1728 | snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0], 0); | ||
1729 | } | ||
1730 | } | ||
1731 | |||
1732 | /* unsolicited event for jack sensing */ | ||
1733 | static void via_unsol_event(struct hda_codec *codec, | ||
1734 | unsigned int res) | ||
1735 | { | ||
1736 | res >>= 26; | ||
1737 | res = snd_hda_jack_get_action(codec, res); | ||
1738 | |||
1739 | if (res & VIA_JACK_EVENT) | ||
1740 | set_widgets_power_state(codec); | ||
1741 | |||
1742 | res &= ~VIA_JACK_EVENT; | ||
1743 | |||
1744 | if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT) | ||
1745 | via_hp_automute(codec); | ||
1746 | else if (res == VIA_GPIO_EVENT) | ||
1747 | via_gpio_control(codec); | ||
1748 | snd_hda_jack_report_sync(codec); | ||
1749 | } | ||
1750 | |||
1751 | #ifdef CONFIG_PM | 1691 | #ifdef CONFIG_PM |
1752 | static int via_suspend(struct hda_codec *codec) | 1692 | static int via_suspend(struct hda_codec *codec) |
1753 | { | 1693 | { |
@@ -1783,7 +1723,7 @@ static const struct hda_codec_ops via_patch_ops = { | |||
1783 | .build_pcms = via_build_pcms, | 1723 | .build_pcms = via_build_pcms, |
1784 | .init = via_init, | 1724 | .init = via_init, |
1785 | .free = via_free, | 1725 | .free = via_free, |
1786 | .unsol_event = via_unsol_event, | 1726 | .unsol_event = snd_hda_jack_unsol_event, |
1787 | #ifdef CONFIG_PM | 1727 | #ifdef CONFIG_PM |
1788 | .suspend = via_suspend, | 1728 | .suspend = via_suspend, |
1789 | .check_power_status = via_check_power_status, | 1729 | .check_power_status = via_check_power_status, |
@@ -2761,6 +2701,17 @@ static void via_auto_init_dig_in(struct hda_codec *codec) | |||
2761 | snd_hda_set_pin_ctl(codec, spec->autocfg.dig_in_pin, PIN_IN); | 2701 | snd_hda_set_pin_ctl(codec, spec->autocfg.dig_in_pin, PIN_IN); |
2762 | } | 2702 | } |
2763 | 2703 | ||
2704 | static void via_jack_output_event(struct hda_codec *codec, struct hda_jack_tbl *tbl) | ||
2705 | { | ||
2706 | set_widgets_power_state(codec); | ||
2707 | via_hp_automute(codec); | ||
2708 | } | ||
2709 | |||
2710 | static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl) | ||
2711 | { | ||
2712 | set_widgets_power_state(codec); | ||
2713 | } | ||
2714 | |||
2764 | /* initialize the unsolicited events */ | 2715 | /* initialize the unsolicited events */ |
2765 | static void via_auto_init_unsol_event(struct hda_codec *codec) | 2716 | static void via_auto_init_unsol_event(struct hda_codec *codec) |
2766 | { | 2717 | { |
@@ -2768,26 +2719,31 @@ static void via_auto_init_unsol_event(struct hda_codec *codec) | |||
2768 | struct auto_pin_cfg *cfg = &spec->autocfg; | 2719 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2769 | unsigned int ev; | 2720 | unsigned int ev; |
2770 | int i; | 2721 | int i; |
2722 | hda_jack_callback cb; | ||
2771 | 2723 | ||
2772 | if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0])) | 2724 | if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0])) |
2773 | snd_hda_jack_detect_enable(codec, cfg->hp_pins[0], | 2725 | snd_hda_jack_detect_enable_callback(codec, cfg->hp_pins[0], |
2774 | VIA_HP_EVENT | VIA_JACK_EVENT); | 2726 | VIA_HP_EVENT | VIA_JACK_EVENT, |
2727 | via_jack_output_event); | ||
2775 | 2728 | ||
2776 | if (cfg->speaker_pins[0]) | 2729 | if (cfg->speaker_pins[0]) |
2777 | ev = VIA_LINE_EVENT; | 2730 | ev = VIA_LINE_EVENT; |
2778 | else | 2731 | else |
2779 | ev = 0; | 2732 | ev = 0; |
2733 | cb = ev ? via_jack_output_event : via_jack_powerstate_event; | ||
2734 | |||
2780 | for (i = 0; i < cfg->line_outs; i++) { | 2735 | for (i = 0; i < cfg->line_outs; i++) { |
2781 | if (cfg->line_out_pins[i] && | 2736 | if (cfg->line_out_pins[i] && |
2782 | is_jack_detectable(codec, cfg->line_out_pins[i])) | 2737 | is_jack_detectable(codec, cfg->line_out_pins[i])) |
2783 | snd_hda_jack_detect_enable(codec, cfg->line_out_pins[i], | 2738 | snd_hda_jack_detect_enable_callback(codec, cfg->line_out_pins[i], |
2784 | ev | VIA_JACK_EVENT); | 2739 | ev | VIA_JACK_EVENT, cb); |
2785 | } | 2740 | } |
2786 | 2741 | ||
2787 | for (i = 0; i < cfg->num_inputs; i++) { | 2742 | for (i = 0; i < cfg->num_inputs; i++) { |
2788 | if (is_jack_detectable(codec, cfg->inputs[i].pin)) | 2743 | if (is_jack_detectable(codec, cfg->inputs[i].pin)) |
2789 | snd_hda_jack_detect_enable(codec, cfg->inputs[i].pin, | 2744 | snd_hda_jack_detect_enable_callback(codec, cfg->inputs[i].pin, |
2790 | VIA_JACK_EVENT); | 2745 | VIA_JACK_EVENT, |
2746 | via_jack_powerstate_event); | ||
2791 | } | 2747 | } |
2792 | } | 2748 | } |
2793 | 2749 | ||
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index d73ac9bc4272..88d8cebbb244 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -2780,6 +2780,52 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2780 | 2780 | ||
2781 | } | 2781 | } |
2782 | }, | 2782 | }, |
2783 | { | ||
2784 | /* Tascam US122 MKII - playback-only support */ | ||
2785 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
2786 | .idVendor = 0x0644, | ||
2787 | .idProduct = 0x8021, | ||
2788 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
2789 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
2790 | .vendor_name = "TASCAM", | ||
2791 | .product_name = "US122 MKII", | ||
2792 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2793 | .type = QUIRK_COMPOSITE, | ||
2794 | .data = (const struct snd_usb_audio_quirk[]) { | ||
2795 | { | ||
2796 | .ifnum = 0, | ||
2797 | .type = QUIRK_IGNORE_INTERFACE | ||
2798 | }, | ||
2799 | { | ||
2800 | .ifnum = 1, | ||
2801 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2802 | .data = &(const struct audioformat) { | ||
2803 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
2804 | .channels = 2, | ||
2805 | .iface = 1, | ||
2806 | .altsetting = 1, | ||
2807 | .altset_idx = 1, | ||
2808 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
2809 | .endpoint = 0x02, | ||
2810 | .ep_attr = USB_ENDPOINT_XFER_ISOC, | ||
2811 | .rates = SNDRV_PCM_RATE_44100 | | ||
2812 | SNDRV_PCM_RATE_48000 | | ||
2813 | SNDRV_PCM_RATE_88200 | | ||
2814 | SNDRV_PCM_RATE_96000, | ||
2815 | .rate_min = 44100, | ||
2816 | .rate_max = 96000, | ||
2817 | .nr_rates = 4, | ||
2818 | .rate_table = (unsigned int[]) { | ||
2819 | 44100, 48000, 88200, 96000 | ||
2820 | } | ||
2821 | } | ||
2822 | }, | ||
2823 | { | ||
2824 | .ifnum = -1 | ||
2825 | } | ||
2826 | } | ||
2827 | } | ||
2828 | }, | ||
2783 | 2829 | ||
2784 | /* Microsoft XboxLive Headset/Xbox Communicator */ | 2830 | /* Microsoft XboxLive Headset/Xbox Communicator */ |
2785 | { | 2831 | { |