23 #include <linux/slab.h>
24 #include <linux/pci.h>
25 #include <linux/module.h>
101 #define CS420X_VENDOR_NID 0x11
102 #define CS_DIG_OUT1_PIN_NID 0x10
103 #define CS_DIG_OUT2_PIN_NID 0x15
104 #define CS_DMIC1_PIN_NID 0x0e
105 #define CS_DMIC2_PIN_NID 0x12
108 #define IDX_SPDIF_STAT 0x0000
109 #define IDX_SPDIF_CTL 0x0001
110 #define IDX_ADC_CFG 0x0002
117 #define CS_COEF_ADC_SZC_MASK (3 << 0)
118 #define CS_COEF_ADC_MIC_SZC_MODE (3 << 0)
119 #define CS_COEF_ADC_LI_SZC_MODE (3 << 0)
121 #define CS_COEF_ADC_MIC_PGA_MODE (1 << 5)
122 #define CS_COEF_ADC_LI_PGA_MODE (1 << 6)
123 #define IDX_DAC_CFG 0x0003
130 #define CS_COEF_DAC_HP_SZC_MODE (3 << 0)
131 #define CS_COEF_DAC_LO_SZC_MODE (3 << 2)
132 #define CS_COEF_DAC_SPK_SZC_MODE (3 << 4)
134 #define IDX_BEEP_CFG 0x0004
146 #define CS4210_DAC_NID 0x02
147 #define CS4210_ADC_NID 0x03
148 #define CS4210_VENDOR_NID 0x0B
149 #define CS421X_DMIC_PIN_NID 0x09
150 #define CS421X_SPDIF_PIN_NID 0x0A
152 #define CS421X_IDX_DEV_CFG 0x01
153 #define CS421X_IDX_ADC_CFG 0x02
154 #define CS421X_IDX_DAC_CFG 0x03
155 #define CS421X_IDX_SPK_CTL 0x04
157 #define SPDIF_EVENT 0x04
160 #define CS4213_VENDOR_NID 0x09
200 unsigned int stream_tag,
206 stream_tag, format, substream);
228 static int cs_dig_playback_pcm_close(
struct hda_pcm_stream *hinfo,
236 static int cs_dig_playback_pcm_prepare(
struct hda_pcm_stream *hinfo,
238 unsigned int stream_tag,
247 static int cs_dig_playback_pcm_cleanup(
struct hda_pcm_stream *hinfo,
269 unsigned int stream_tag,
277 cs_update_input_select(codec);
299 .open = cs_playback_pcm_open,
300 .prepare = cs_playback_pcm_prepare,
301 .cleanup = cs_playback_pcm_cleanup
310 .prepare = cs_capture_pcm_prepare,
311 .cleanup = cs_capture_pcm_cleanup
320 .open = cs_dig_playback_pcm_open,
321 .close = cs_dig_playback_pcm_close,
322 .prepare = cs_dig_playback_pcm_prepare,
323 .cleanup = cs_dig_playback_pcm_cleanup
333 static int cs_build_pcms(
struct hda_codec *codec)
341 info->
name =
"Cirrus Analog";
355 info->
name =
"Cirrus Digital";
361 cs_pcm_digital_playback;
367 cs_pcm_digital_capture;
389 static int is_ext_mic(
struct hda_codec *codec,
unsigned int idx)
408 for (i = 0; i < codec->
num_nodes; i++, nid++) {
410 type = get_wcaps_type(get_wcaps(codec, nid));
429 static int parse_output(
struct hda_codec *codec)
444 spec->
multiout.max_channels = i * 2;
448 for (i = 0; i < cfg->
hp_outs; i++) {
455 spec->
multiout.extra_out_nid[extra_nids++] = dac;
461 spec->
multiout.extra_out_nid[extra_nids++] = dac;
475 static int parse_input(
struct hda_codec *codec)
495 if (is_ext_mic(codec, cfg->
inputs[0].pin)) {
496 if (!is_ext_mic(codec, cfg->
inputs[1].pin)) {
501 if (is_ext_mic(codec, cfg->
inputs[1].pin)) {
511 static int parse_digital_output(
struct hda_codec *codec)
531 static int parse_digital_input(
struct hda_codec *codec)
546 static const char *
const dir_sfx[2] = {
"Playback",
"Capture" };
549 unsigned int pval,
int dir,
struct snd_kcontrol **kctlp)
555 snprintf(tmp,
sizeof(tmp),
"%s %s Switch", name, dir_sfx[dir]);
561 static int add_volume(
struct hda_codec *codec,
const char *name,
562 int index,
unsigned int pval,
int dir,
569 snprintf(tmp,
sizeof(tmp),
"%s %s Volume", name, dir_sfx[dir]);
609 int num_ctls,
int type)
615 static const char *
const speakers[] = {
616 "Front Speaker",
"Surround Speaker",
"Bass Speaker"
618 static const char *
const line_outs[] = {
619 "Front Line Out",
"Surround Line Out",
"Bass Line Out"
622 fix_volume_caps(codec, dac);
624 err = add_vmaster(codec, dac);
637 name = speakers[
idx];
643 name = line_outs[
idx];
649 err = add_mute(codec, name, index,
653 err = snd_ctl_add_slave(spec->
vmaster_sw, kctl);
657 err = add_volume(codec, name, index,
668 static int build_output(
struct hda_codec *codec)
680 for (i = 0; i < cfg->
hp_outs; i++) {
703 static int change_cur_input(
struct hda_codec *codec,
unsigned int idx,
719 cs_update_input_select(codec);
723 static int cs_capture_source_info(
struct snd_kcontrol *kcontrol,
743 static int cs_capture_source_get(
struct snd_kcontrol *kcontrol,
752 static int cs_capture_source_put(
struct snd_kcontrol *kcontrol,
757 unsigned int idx = ucontrol->
value.enumerated.item[0];
762 return change_cur_input(codec, idx, 0);
767 .name =
"Capture Source",
769 .info = cs_capture_source_info,
770 .get = cs_capture_source_get,
771 .put = cs_capture_source_put,
781 bind = kzalloc(
sizeof(*bind) +
sizeof(
long) * (spec->
num_inputs + 1),
798 static int add_input_volume_control(
struct hda_codec *codec,
814 return add_volume(codec, label, 0,
818 static int build_input(
struct hda_codec *codec)
829 for (i = 0; i < 2; i++) {
858 err = add_input_volume_control(codec, &spec->
autocfg, i);
869 static int build_digital_output(
struct hda_codec *codec)
887 static int build_digital_input(
struct hda_codec *codec)
905 unsigned int hp_present;
906 unsigned int spdif_present;
926 for (i = 0; i < cfg->
hp_outs; i++) {
937 int pin_ctl = hp_present ? 0 :
PIN_OUT;
943 snd_hda_set_pin_ctl(codec, nid, pin_ctl);
946 unsigned int gpio = hp_present ?
955 for (i = 0; i < cfg->
hp_outs; i++) {
957 snd_hda_set_pin_ctl(codec, nid,
964 snd_hda_set_pin_ctl(codec, nid,
982 unsigned int present;
1002 cs_update_input_select(codec);
1009 static void init_output(
struct hda_codec *codec)
1016 for (i = 0; i < spec->
multiout.num_dacs; i++)
1023 if (!spec->
multiout.extra_out_nid[i])
1033 for (i = 0; i < cfg->
hp_outs; i++) {
1035 snd_hda_set_pin_ctl(codec, nid,
PIN_HP);
1050 cs_automute(codec,
NULL);
1053 static void init_input(
struct hda_codec *codec)
1069 snd_hda_set_pin_ctl(codec, pin, ctl);
1078 change_cur_input(codec, spec->
cur_input, 1);
1080 cs_automic(codec,
NULL);
1097 cs_automic(codec,
NULL);
1100 cs_update_input_select(codec);
1105 static const struct hda_verb cs_coef_init_verbs[] = {
1139 static const struct hda_verb cs_errata_init_verbs[] = {
1170 static const struct hda_verb mbp101_init_verbs[] = {
1179 static void init_digital(
struct hda_codec *codec)
1193 static int cs_init(
struct hda_codec *codec)
1213 init_digital(codec);
1218 static int cs_build_controls(
struct hda_codec *codec)
1223 err = build_output(codec);
1226 err = build_input(codec);
1229 err = build_digital_output(codec);
1232 err = build_digital_input(codec);
1235 err = cs_init(codec);
1246 static void cs_free(
struct hda_codec *codec)
1251 snd_hda_gen_free(&spec->
gen);
1256 .build_controls = cs_build_controls,
1257 .build_pcms = cs_build_pcms,
1263 static int cs_parse_auto_config(
struct hda_codec *codec)
1272 err = parse_output(codec);
1275 err = parse_input(codec);
1278 err = parse_digital_output(codec);
1281 err = parse_digital_input(codec);
1297 static const struct snd_pci_quirk cs420x_fixup_tbl[] = {
1298 SND_PCI_QUIRK(0x10de, 0x0ac0,
"MacBookPro 5,3",
CS420X_MBP53),
1299 SND_PCI_QUIRK(0x10de, 0x0d94,
"MacBookAir 3,1(2)",
CS420X_MBP55),
1300 SND_PCI_QUIRK(0x10de, 0xcb79,
"MacBookPro 5,5",
CS420X_MBP55),
1301 SND_PCI_QUIRK(0x10de, 0xcb89,
"MacBookPro 7,1",
CS420X_MBP55),
1307 SND_PCI_QUIRK(0x106b, 0x2800,
"MacBookPro 10,1",
CS420X_MBP101),
1312 static const struct hda_pintbl mbp53_pincfgs[] = {
1313 { 0x09, 0x012b4050 },
1314 { 0x0a, 0x90100141 },
1315 { 0x0b, 0x90100140 },
1316 { 0x0c, 0x018b3020 },
1317 { 0x0d, 0x90a00110 },
1318 { 0x0e, 0x400000f0 },
1319 { 0x0f, 0x01cbe030 },
1320 { 0x10, 0x014be060 },
1321 { 0x12, 0x400000f0 },
1322 { 0x15, 0x400000f0 },
1326 static const struct hda_pintbl mbp55_pincfgs[] = {
1327 { 0x09, 0x012b4030 },
1328 { 0x0a, 0x90100121 },
1329 { 0x0b, 0x90100120 },
1330 { 0x0c, 0x400000f0 },
1331 { 0x0d, 0x90a00110 },
1332 { 0x0e, 0x400000f0 },
1333 { 0x0f, 0x400000f0 },
1334 { 0x10, 0x014be040 },
1335 { 0x12, 0x400000f0 },
1336 { 0x15, 0x400000f0 },
1340 static const struct hda_pintbl imac27_pincfgs[] = {
1341 { 0x09, 0x012b4050 },
1342 { 0x0a, 0x90100140 },
1343 { 0x0b, 0x90100142 },
1344 { 0x0c, 0x018b3020 },
1345 { 0x0d, 0x90a00110 },
1346 { 0x0e, 0x400000f0 },
1347 { 0x0f, 0x01cbe030 },
1348 { 0x10, 0x014be060 },
1349 { 0x12, 0x01ab9070 },
1350 { 0x15, 0x400000f0 },
1354 static const struct hda_pintbl mbp101_pincfgs[] = {
1355 { 0x0d, 0x40ab90f0 },
1356 { 0x0e, 0x90a600f0 },
1357 { 0x12, 0x50a600f0 },
1361 static void cs420x_fixup_gpio_13(
struct hda_codec *codec,
1373 static void cs420x_fixup_gpio_23(
struct hda_codec *codec,
1374 const struct hda_fixup *fix,
int action)
1385 static const struct hda_fixup cs420x_fixups[] = {
1388 .v.pins = mbp53_pincfgs,
1394 .v.pins = mbp55_pincfgs,
1400 .v.pins = imac27_pincfgs,
1406 .v.func = cs420x_fixup_gpio_13,
1410 .v.func = cs420x_fixup_gpio_23,
1414 .v.pins = mbp101_pincfgs,
1420 .v.verbs = mbp101_init_verbs,
1426 static int patch_cs420x(
struct hda_codec *codec)
1435 snd_hda_gen_init(&spec->
gen);
1443 err = cs_parse_auto_config(codec);
1473 static const struct snd_pci_quirk cs421x_fixup_tbl[] = {
1481 static const struct hda_pintbl cdb4210_pincfgs[] = {
1482 { 0x05, 0x0321401f },
1483 { 0x06, 0x90170010 },
1484 { 0x07, 0x03813031 },
1485 { 0x08, 0xb7a70037 },
1486 { 0x09, 0xb7a6003e },
1487 { 0x0a, 0x034510f0 },
1492 static void cs421x_fixup_sense_b(
struct hda_codec *codec,
1493 const struct hda_fixup *fix,
int action)
1500 static const struct hda_fixup cs421x_fixups[] = {
1503 .v.pins = cdb4210_pincfgs,
1509 .v.func = cs421x_fixup_sense_b,
1513 static const struct hda_verb cs421x_coef_init_verbs[] = {
1550 static const struct hda_verb cs421x_coef_init_verbs_A1_silicon_fixes[] = {
1574 static int cs421x_boost_vol_info(
struct snd_kcontrol *kcontrol,
1584 static int cs421x_boost_vol_get(
struct snd_kcontrol *kcontrol,
1589 ucontrol->
value.integer.value[0] =
1594 static int cs421x_boost_vol_put(
struct snd_kcontrol *kcontrol,
1599 unsigned int vol = ucontrol->
value.integer.value[0];
1602 unsigned int original_coef = coef;
1605 coef |= (vol & 0x0003);
1606 if (original_coef == coef)
1619 .name =
"Speaker Boost Playback Volume",
1620 .info = cs421x_boost_vol_info,
1621 .
get = cs421x_boost_vol_get,
1622 .
put = cs421x_boost_vol_put,
1623 .tlv = { .p = cs421x_speaker_boost_db_scale },
1626 static void cs4210_pinmux_init(
struct hda_codec *codec)
1629 unsigned int def_conf, coef;
1659 static void init_cs421x_digital(
struct hda_codec *codec)
1666 for (i = 0; i < cfg->
dig_outs; i++) {
1677 static int cs421x_init(
struct hda_codec *codec)
1684 cs4210_pinmux_init(codec);
1698 init_cs421x_digital(codec);
1706 static int cs421x_mux_enum_info(
struct snd_kcontrol *kcontrol,
1715 static int cs421x_mux_enum_get(
struct snd_kcontrol *kcontrol,
1725 static int cs421x_mux_enum_put(
struct snd_kcontrol *kcontrol,
1738 .name =
"Capture Source",
1740 .info = cs421x_mux_enum_info,
1741 .get = cs421x_mux_enum_get,
1742 .put = cs421x_mux_enum_put,
1745 static int cs421x_add_input_volume_control(
struct hda_codec *codec,
int item)
1754 if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
1762 return add_volume(codec, imux->
items[item].label, 0,
1767 static int build_cs421x_input(
struct hda_codec *codec)
1772 int i,
err, type_idx;
1781 for (i = 0; i < 2; i++) {
1807 err = cs421x_add_input_volume_control(codec, i);
1830 static int build_cs421x_output(
struct hda_codec *codec)
1837 char *name =
"Master";
1839 fix_volume_caps(codec, dac);
1841 err = add_mute(codec, name, 0,
1846 err = add_volume(codec, name, 0,
1860 static int cs421x_build_controls(
struct hda_codec *codec)
1865 err = build_cs421x_output(codec);
1868 err = build_cs421x_input(codec);
1871 err = build_digital_output(codec);
1874 err = cs421x_init(codec);
1885 static int parse_cs421x_input(
struct hda_codec *codec)
1898 if (is_ext_mic(codec, i) && cfg->
num_inputs >= 2) {
1906 static int cs421x_parse_auto_config(
struct hda_codec *codec)
1914 err = parse_output(codec);
1917 err = parse_cs421x_input(codec);
1920 err = parse_digital_output(codec);
1931 static int cs421x_suspend(
struct hda_codec *codec)
1954 .build_controls = cs421x_build_controls,
1955 .build_pcms = cs_build_pcms,
1956 .init = cs421x_init,
1960 .suspend = cs421x_suspend,
1964 static int patch_cs4210(
struct hda_codec *codec)
1973 snd_hda_gen_init(&spec->
gen);
1986 cs4210_pinmux_init(codec);
1988 err = cs421x_parse_auto_config(codec);
2004 static int patch_cs4213(
struct hda_codec *codec)
2013 snd_hda_gen_init(&spec->
gen);
2017 err = cs421x_parse_auto_config(codec);
2035 { .id = 0x10134206, .name =
"CS4206", .patch = patch_cs420x },
2036 { .id = 0x10134207, .name =
"CS4207", .patch = patch_cs420x },
2037 { .id = 0x10134210, .name =
"CS4210", .patch = patch_cs4210 },
2038 { .id = 0x10134213, .name =
"CS4213", .patch = patch_cs4213 },
2051 .preset = snd_hda_preset_cirrus,
2055 static int __init patch_cirrus_init(
void)
2060 static void __exit patch_cirrus_exit(
void)