aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_cirrus.c105
1 files changed, 70 insertions, 35 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index ea660429713d..036056c42c13 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -138,7 +138,7 @@ enum {
138*/ 138*/
139#define CS4210_DAC_NID 0x02 139#define CS4210_DAC_NID 0x02
140#define CS4210_ADC_NID 0x03 140#define CS4210_ADC_NID 0x03
141#define CS421X_VENDOR_NID 0x0B 141#define CS4210_VENDOR_NID 0x0B
142#define CS421X_DMIC_PIN_NID 0x09 /* Port E */ 142#define CS421X_DMIC_PIN_NID 0x09 /* Port E */
143#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */ 143#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
144 144
@@ -149,6 +149,10 @@ enum {
149 149
150#define SPDIF_EVENT 0x04 150#define SPDIF_EVENT 0x04
151 151
152/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */
153#define CS4213_VENDOR_NID 0x09
154
155
152static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) 156static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
153{ 157{
154 struct cs_spec *spec = codec->spec; 158 struct cs_spec *spec = codec->spec;
@@ -923,8 +927,8 @@ static void cs_automute(struct hda_codec *codec)
923 /* mute speakers if spdif or hp jack is plugged in */ 927 /* mute speakers if spdif or hp jack is plugged in */
924 for (i = 0; i < cfg->speaker_outs; i++) { 928 for (i = 0; i < cfg->speaker_outs; i++) {
925 int pin_ctl = hp_present ? 0 : PIN_OUT; 929 int pin_ctl = hp_present ? 0 : PIN_OUT;
926 /* detect on spdif is specific to CS421x */ 930 /* detect on spdif is specific to CS4210 */
927 if (spdif_present && (spec->vendor_nid == CS421X_VENDOR_NID)) 931 if (spdif_present && (spec->vendor_nid == CS4210_VENDOR_NID))
928 pin_ctl = 0; 932 pin_ctl = 0;
929 933
930 nid = cfg->speaker_pins[i]; 934 nid = cfg->speaker_pins[i];
@@ -938,8 +942,8 @@ static void cs_automute(struct hda_codec *codec)
938 AC_VERB_SET_GPIO_DATA, gpio); 942 AC_VERB_SET_GPIO_DATA, gpio);
939 } 943 }
940 944
941 /* specific to CS421x */ 945 /* specific to CS4210 */
942 if (spec->vendor_nid == CS421X_VENDOR_NID) { 946 if (spec->vendor_nid == CS4210_VENDOR_NID) {
943 /* mute HPs if spdif jack (SENSE_B) is present */ 947 /* mute HPs if spdif jack (SENSE_B) is present */
944 for (i = 0; i < cfg->hp_outs; i++) { 948 for (i = 0; i < cfg->hp_outs; i++) {
945 nid = cfg->hp_pins[i]; 949 nid = cfg->hp_pins[i];
@@ -976,7 +980,12 @@ static void cs_automic(struct hda_codec *codec)
976 present = snd_hda_jack_detect(codec, nid); 980 present = snd_hda_jack_detect(codec, nid);
977 981
978 /* specific to CS421x, single ADC */ 982 /* specific to CS421x, single ADC */
979 if (spec->vendor_nid == CS421X_VENDOR_NID) { 983 if (spec->vendor_nid == CS420X_VENDOR_NID) {
984 if (present)
985 change_cur_input(codec, spec->automic_idx, 0);
986 else
987 change_cur_input(codec, !spec->automic_idx, 0);
988 } else {
980 if (present) { 989 if (present) {
981 spec->last_input = spec->cur_input; 990 spec->last_input = spec->cur_input;
982 spec->cur_input = spec->automic_idx; 991 spec->cur_input = spec->automic_idx;
@@ -984,11 +993,6 @@ static void cs_automic(struct hda_codec *codec)
984 spec->cur_input = spec->last_input; 993 spec->cur_input = spec->last_input;
985 } 994 }
986 cs_update_input_select(codec); 995 cs_update_input_select(codec);
987 } else {
988 if (present)
989 change_cur_input(codec, spec->automic_idx, 0);
990 else
991 change_cur_input(codec, !spec->automic_idx, 0);
992 } 996 }
993} 997}
994 998
@@ -1070,15 +1074,8 @@ static void init_input(struct hda_codec *codec)
1070 if (spec->mic_detect && spec->automic_idx == i) 1074 if (spec->mic_detect && spec->automic_idx == i)
1071 snd_hda_jack_detect_enable(codec, pin, MIC_EVENT); 1075 snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
1072 } 1076 }
1073 /* specific to CS421x */ 1077 /* CS420x has multiple ADC, CS421x has single ADC */
1074 if (spec->vendor_nid == CS421X_VENDOR_NID) { 1078 if (spec->vendor_nid == CS420X_VENDOR_NID) {
1075 if (spec->mic_detect)
1076 cs_automic(codec);
1077 else {
1078 spec->cur_adc = spec->adc_nid[spec->cur_input];
1079 cs_update_input_select(codec);
1080 }
1081 } else {
1082 change_cur_input(codec, spec->cur_input, 1); 1079 change_cur_input(codec, spec->cur_input, 1);
1083 if (spec->mic_detect) 1080 if (spec->mic_detect)
1084 cs_automic(codec); 1081 cs_automic(codec);
@@ -1092,6 +1089,13 @@ static void init_input(struct hda_codec *codec)
1092 * selected in IDX_SPDIF_CTL. 1089 * selected in IDX_SPDIF_CTL.
1093 */ 1090 */
1094 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); 1091 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
1092 } else {
1093 if (spec->mic_detect)
1094 cs_automic(codec);
1095 else {
1096 spec->cur_adc = spec->adc_nid[spec->cur_input];
1097 cs_update_input_select(codec);
1098 }
1095 } 1099 }
1096} 1100}
1097 1101
@@ -1565,7 +1569,7 @@ static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = {
1565 .tlv = { .p = cs421x_speaker_boost_db_scale }, 1569 .tlv = { .p = cs421x_speaker_boost_db_scale },
1566}; 1570};
1567 1571
1568static void cs421x_pinmux_init(struct hda_codec *codec) 1572static void cs4210_pinmux_init(struct hda_codec *codec)
1569{ 1573{
1570 struct cs_spec *spec = codec->spec; 1574 struct cs_spec *spec = codec->spec;
1571 unsigned int def_conf, coef; 1575 unsigned int def_conf, coef;
@@ -1620,10 +1624,11 @@ static int cs421x_init(struct hda_codec *codec)
1620{ 1624{
1621 struct cs_spec *spec = codec->spec; 1625 struct cs_spec *spec = codec->spec;
1622 1626
1623 snd_hda_sequence_write(codec, cs421x_coef_init_verbs); 1627 if (spec->vendor_nid == CS4210_VENDOR_NID) {
1624 snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes); 1628 snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
1625 1629 snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
1626 cs421x_pinmux_init(codec); 1630 cs4210_pinmux_init(codec);
1631 }
1627 1632
1628 if (spec->gpio_mask) { 1633 if (spec->gpio_mask) {
1629 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, 1634 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
@@ -1791,7 +1796,7 @@ static int build_cs421x_output(struct hda_codec *codec)
1791 if (err < 0) 1796 if (err < 0)
1792 return err; 1797 return err;
1793 1798
1794 if (cfg->speaker_outs) { 1799 if (cfg->speaker_outs && (spec->vendor_nid == CS4210_VENDOR_NID)) {
1795 err = snd_hda_ctl_add(codec, 0, 1800 err = snd_hda_ctl_add(codec, 0,
1796 snd_ctl_new1(&cs421x_speaker_bost_ctl, codec)); 1801 snd_ctl_new1(&cs421x_speaker_bost_ctl, codec));
1797 if (err < 0) 1802 if (err < 0)
@@ -1888,6 +1893,7 @@ static int cs421x_parse_auto_config(struct hda_codec *codec)
1888*/ 1893*/
1889static int cs421x_suspend(struct hda_codec *codec, pm_message_t state) 1894static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
1890{ 1895{
1896 struct cs_spec *spec = codec->spec;
1891 unsigned int coef; 1897 unsigned int coef;
1892 1898
1893 snd_hda_shutup_pins(codec); 1899 snd_hda_shutup_pins(codec);
@@ -1897,15 +1903,17 @@ static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
1897 snd_hda_codec_write(codec, CS4210_ADC_NID, 0, 1903 snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
1898 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 1904 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1899 1905
1900 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG); 1906 if (spec->vendor_nid == CS4210_VENDOR_NID) {
1901 coef |= 0x0004; /* PDREF */ 1907 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
1902 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef); 1908 coef |= 0x0004; /* PDREF */
1909 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
1910 }
1903 1911
1904 return 0; 1912 return 0;
1905} 1913}
1906#endif 1914#endif
1907 1915
1908static struct hda_codec_ops cs4210_patch_ops = { 1916static struct hda_codec_ops cs421x_patch_ops = {
1909 .build_controls = cs421x_build_controls, 1917 .build_controls = cs421x_build_controls,
1910 .build_pcms = cs_build_pcms, 1918 .build_pcms = cs_build_pcms,
1911 .init = cs421x_init, 1919 .init = cs421x_init,
@@ -1916,7 +1924,7 @@ static struct hda_codec_ops cs4210_patch_ops = {
1916#endif 1924#endif
1917}; 1925};
1918 1926
1919static int patch_cs421x(struct hda_codec *codec) 1927static int patch_cs4210(struct hda_codec *codec)
1920{ 1928{
1921 struct cs_spec *spec; 1929 struct cs_spec *spec;
1922 int err; 1930 int err;
@@ -1926,7 +1934,7 @@ static int patch_cs421x(struct hda_codec *codec)
1926 return -ENOMEM; 1934 return -ENOMEM;
1927 codec->spec = spec; 1935 codec->spec = spec;
1928 1936
1929 spec->vendor_nid = CS421X_VENDOR_NID; 1937 spec->vendor_nid = CS4210_VENDOR_NID;
1930 1938
1931 spec->board_config = 1939 spec->board_config =
1932 snd_hda_check_board_config(codec, CS421X_MODELS, 1940 snd_hda_check_board_config(codec, CS421X_MODELS,
@@ -1954,14 +1962,39 @@ static int patch_cs421x(struct hda_codec *codec)
1954 is auto-parsed. If GPIO or SENSE_B is forced, DMIC input 1962 is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
1955 is disabled. 1963 is disabled.
1956 */ 1964 */
1957 cs421x_pinmux_init(codec); 1965 cs4210_pinmux_init(codec);
1958 1966
1959 err = cs421x_parse_auto_config(codec); 1967 err = cs421x_parse_auto_config(codec);
1960 if (err < 0) 1968 if (err < 0)
1961 goto error; 1969 goto error;
1962 1970
1963 codec->patch_ops = cs4210_patch_ops; 1971 codec->patch_ops = cs421x_patch_ops;
1972
1973 return 0;
1974
1975 error:
1976 kfree(codec->spec);
1977 codec->spec = NULL;
1978 return err;
1979}
1980
1981static int patch_cs4213(struct hda_codec *codec)
1982{
1983 struct cs_spec *spec;
1984 int err;
1985
1986 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1987 if (!spec)
1988 return -ENOMEM;
1989 codec->spec = spec;
1990
1991 spec->vendor_nid = CS4213_VENDOR_NID;
1992
1993 err = cs421x_parse_auto_config(codec);
1994 if (err < 0)
1995 goto error;
1964 1996
1997 codec->patch_ops = cs421x_patch_ops;
1965 return 0; 1998 return 0;
1966 1999
1967 error: 2000 error:
@@ -1977,13 +2010,15 @@ static int patch_cs421x(struct hda_codec *codec)
1977static const struct hda_codec_preset snd_hda_preset_cirrus[] = { 2010static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
1978 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, 2011 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
1979 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, 2012 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1980 { .id = 0x10134210, .name = "CS4210", .patch = patch_cs421x }, 2013 { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 },
2014 { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 },
1981 {} /* terminator */ 2015 {} /* terminator */
1982}; 2016};
1983 2017
1984MODULE_ALIAS("snd-hda-codec-id:10134206"); 2018MODULE_ALIAS("snd-hda-codec-id:10134206");
1985MODULE_ALIAS("snd-hda-codec-id:10134207"); 2019MODULE_ALIAS("snd-hda-codec-id:10134207");
1986MODULE_ALIAS("snd-hda-codec-id:10134210"); 2020MODULE_ALIAS("snd-hda-codec-id:10134210");
2021MODULE_ALIAS("snd-hda-codec-id:10134213");
1987 2022
1988MODULE_LICENSE("GPL"); 2023MODULE_LICENSE("GPL");
1989MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); 2024MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");