diff options
| -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 | { |
