diff options
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 265 |
1 files changed, 242 insertions, 23 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 247a6a99feb8..4afbe3b2e443 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -107,6 +107,12 @@ struct wm8994_priv { | |||
107 | 107 | ||
108 | int revision; | 108 | int revision; |
109 | struct wm8994_pdata *pdata; | 109 | struct wm8994_pdata *pdata; |
110 | |||
111 | unsigned int aif1clk_enable:1; | ||
112 | unsigned int aif2clk_enable:1; | ||
113 | |||
114 | unsigned int aif1clk_disable:1; | ||
115 | unsigned int aif2clk_disable:1; | ||
110 | }; | 116 | }; |
111 | 117 | ||
112 | static int wm8994_readable(unsigned int reg) | 118 | static int wm8994_readable(unsigned int reg) |
@@ -1004,6 +1010,110 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) | |||
1004 | } | 1010 | } |
1005 | } | 1011 | } |
1006 | 1012 | ||
1013 | static int late_enable_ev(struct snd_soc_dapm_widget *w, | ||
1014 | struct snd_kcontrol *kcontrol, int event) | ||
1015 | { | ||
1016 | struct snd_soc_codec *codec = w->codec; | ||
1017 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
1018 | |||
1019 | switch (event) { | ||
1020 | case SND_SOC_DAPM_PRE_PMU: | ||
1021 | if (wm8994->aif1clk_enable) { | ||
1022 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, | ||
1023 | WM8994_AIF1CLK_ENA_MASK, | ||
1024 | WM8994_AIF1CLK_ENA); | ||
1025 | wm8994->aif1clk_enable = 0; | ||
1026 | } | ||
1027 | if (wm8994->aif2clk_enable) { | ||
1028 | snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, | ||
1029 | WM8994_AIF2CLK_ENA_MASK, | ||
1030 | WM8994_AIF2CLK_ENA); | ||
1031 | wm8994->aif2clk_enable = 0; | ||
1032 | } | ||
1033 | break; | ||
1034 | } | ||
1035 | |||
1036 | return 0; | ||
1037 | } | ||
1038 | |||
1039 | static int late_disable_ev(struct snd_soc_dapm_widget *w, | ||
1040 | struct snd_kcontrol *kcontrol, int event) | ||
1041 | { | ||
1042 | struct snd_soc_codec *codec = w->codec; | ||
1043 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
1044 | |||
1045 | switch (event) { | ||
1046 | case SND_SOC_DAPM_POST_PMD: | ||
1047 | if (wm8994->aif1clk_disable) { | ||
1048 | snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, | ||
1049 | WM8994_AIF1CLK_ENA_MASK, 0); | ||
1050 | wm8994->aif1clk_disable = 0; | ||
1051 | } | ||
1052 | if (wm8994->aif2clk_disable) { | ||
1053 | snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, | ||
1054 | WM8994_AIF2CLK_ENA_MASK, 0); | ||
1055 | wm8994->aif2clk_disable = 0; | ||
1056 | } | ||
1057 | break; | ||
1058 | } | ||
1059 | |||
1060 | return 0; | ||
1061 | } | ||
1062 | |||
1063 | static int aif1clk_ev(struct snd_soc_dapm_widget *w, | ||
1064 | struct snd_kcontrol *kcontrol, int event) | ||
1065 | { | ||
1066 | struct snd_soc_codec *codec = w->codec; | ||
1067 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
1068 | |||
1069 | switch (event) { | ||
1070 | case SND_SOC_DAPM_PRE_PMU: | ||
1071 | wm8994->aif1clk_enable = 1; | ||
1072 | break; | ||
1073 | case SND_SOC_DAPM_POST_PMD: | ||
1074 | wm8994->aif1clk_disable = 1; | ||
1075 | break; | ||
1076 | } | ||
1077 | |||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | static int aif2clk_ev(struct snd_soc_dapm_widget *w, | ||
1082 | struct snd_kcontrol *kcontrol, int event) | ||
1083 | { | ||
1084 | struct snd_soc_codec *codec = w->codec; | ||
1085 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
1086 | |||
1087 | switch (event) { | ||
1088 | case SND_SOC_DAPM_PRE_PMU: | ||
1089 | wm8994->aif2clk_enable = 1; | ||
1090 | break; | ||
1091 | case SND_SOC_DAPM_POST_PMD: | ||
1092 | wm8994->aif2clk_disable = 1; | ||
1093 | break; | ||
1094 | } | ||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | static int adc_mux_ev(struct snd_soc_dapm_widget *w, | ||
1100 | struct snd_kcontrol *kcontrol, int event) | ||
1101 | { | ||
1102 | late_enable_ev(w, kcontrol, event); | ||
1103 | return 0; | ||
1104 | } | ||
1105 | |||
1106 | static int dac_ev(struct snd_soc_dapm_widget *w, | ||
1107 | struct snd_kcontrol *kcontrol, int event) | ||
1108 | { | ||
1109 | struct snd_soc_codec *codec = w->codec; | ||
1110 | unsigned int mask = 1 << w->shift; | ||
1111 | |||
1112 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, | ||
1113 | mask, mask); | ||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1007 | static const char *hp_mux_text[] = { | 1117 | static const char *hp_mux_text[] = { |
1008 | "Mixer", | 1118 | "Mixer", |
1009 | "DAC", | 1119 | "DAC", |
@@ -1272,6 +1382,59 @@ static const struct soc_enum aif2dacr_src_enum = | |||
1272 | static const struct snd_kcontrol_new aif2dacr_src_mux = | 1382 | static const struct snd_kcontrol_new aif2dacr_src_mux = |
1273 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); | 1383 | SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); |
1274 | 1384 | ||
1385 | static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = { | ||
1386 | SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev, | ||
1387 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
1388 | SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev, | ||
1389 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
1390 | |||
1391 | SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
1392 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), | ||
1393 | SND_SOC_DAPM_PGA_E("Late DAC1R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
1394 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), | ||
1395 | SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
1396 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), | ||
1397 | SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, | ||
1398 | late_enable_ev, SND_SOC_DAPM_PRE_PMU), | ||
1399 | |||
1400 | SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) | ||
1401 | }; | ||
1402 | |||
1403 | static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { | ||
1404 | SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), | ||
1405 | SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0) | ||
1406 | }; | ||
1407 | |||
1408 | static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = { | ||
1409 | SND_SOC_DAPM_DAC_E("DAC2L", NULL, SND_SOC_NOPM, 3, 0, | ||
1410 | dac_ev, SND_SOC_DAPM_PRE_PMU), | ||
1411 | SND_SOC_DAPM_DAC_E("DAC2R", NULL, SND_SOC_NOPM, 2, 0, | ||
1412 | dac_ev, SND_SOC_DAPM_PRE_PMU), | ||
1413 | SND_SOC_DAPM_DAC_E("DAC1L", NULL, SND_SOC_NOPM, 1, 0, | ||
1414 | dac_ev, SND_SOC_DAPM_PRE_PMU), | ||
1415 | SND_SOC_DAPM_DAC_E("DAC1R", NULL, SND_SOC_NOPM, 0, 0, | ||
1416 | dac_ev, SND_SOC_DAPM_PRE_PMU), | ||
1417 | }; | ||
1418 | |||
1419 | static const struct snd_soc_dapm_widget wm8994_dac_widgets[] = { | ||
1420 | SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0), | ||
1421 | SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0), | ||
1422 | SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0), | ||
1423 | SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), | ||
1424 | }; | ||
1425 | |||
1426 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { | ||
1427 | SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, | ||
1428 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | ||
1429 | SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, | ||
1430 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | ||
1431 | }; | ||
1432 | |||
1433 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { | ||
1434 | SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), | ||
1435 | SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), | ||
1436 | }; | ||
1437 | |||
1275 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { | 1438 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { |
1276 | SND_SOC_DAPM_INPUT("DMIC1DAT"), | 1439 | SND_SOC_DAPM_INPUT("DMIC1DAT"), |
1277 | SND_SOC_DAPM_INPUT("DMIC2DAT"), | 1440 | SND_SOC_DAPM_INPUT("DMIC2DAT"), |
@@ -1284,12 +1447,9 @@ SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0), | |||
1284 | SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), | 1447 | SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), |
1285 | SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), | 1448 | SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), |
1286 | 1449 | ||
1287 | SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), | 1450 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL, |
1288 | SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), | ||
1289 | |||
1290 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", | ||
1291 | 0, WM8994_POWER_MANAGEMENT_4, 9, 0), | 1451 | 0, WM8994_POWER_MANAGEMENT_4, 9, 0), |
1292 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", | 1452 | SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL, |
1293 | 0, WM8994_POWER_MANAGEMENT_4, 8, 0), | 1453 | 0, WM8994_POWER_MANAGEMENT_4, 8, 0), |
1294 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, | 1454 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, |
1295 | WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, | 1455 | WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, |
@@ -1298,9 +1458,9 @@ SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0, | |||
1298 | WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, | 1458 | WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, |
1299 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | 1459 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), |
1300 | 1460 | ||
1301 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", | 1461 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL, |
1302 | 0, WM8994_POWER_MANAGEMENT_4, 11, 0), | 1462 | 0, WM8994_POWER_MANAGEMENT_4, 11, 0), |
1303 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", | 1463 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL, |
1304 | 0, WM8994_POWER_MANAGEMENT_4, 10, 0), | 1464 | 0, WM8994_POWER_MANAGEMENT_4, 10, 0), |
1305 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, | 1465 | SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, |
1306 | WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, | 1466 | WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, |
@@ -1345,6 +1505,7 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, | |||
1345 | 1505 | ||
1346 | SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | 1506 | SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), |
1347 | SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | 1507 | SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), |
1508 | SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1348 | SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | 1509 | SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), |
1349 | 1510 | ||
1350 | SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), | 1511 | SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), |
@@ -1368,14 +1529,6 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0), | |||
1368 | SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), | 1529 | SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), |
1369 | SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), | 1530 | SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), |
1370 | 1531 | ||
1371 | SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), | ||
1372 | SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), | ||
1373 | |||
1374 | SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0), | ||
1375 | SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0), | ||
1376 | SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0), | ||
1377 | SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), | ||
1378 | |||
1379 | SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), | 1532 | SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), |
1380 | SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), | 1533 | SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), |
1381 | 1534 | ||
@@ -1515,14 +1668,12 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1515 | { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" }, | 1668 | { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" }, |
1516 | 1669 | ||
1517 | /* DAC1 inputs */ | 1670 | /* DAC1 inputs */ |
1518 | { "DAC1L", NULL, "DAC1L Mixer" }, | ||
1519 | { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" }, | 1671 | { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" }, |
1520 | { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, | 1672 | { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, |
1521 | { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, | 1673 | { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, |
1522 | { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, | 1674 | { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, |
1523 | { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, | 1675 | { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, |
1524 | 1676 | ||
1525 | { "DAC1R", NULL, "DAC1R Mixer" }, | ||
1526 | { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" }, | 1677 | { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" }, |
1527 | { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, | 1678 | { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, |
1528 | { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, | 1679 | { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, |
@@ -1531,7 +1682,6 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1531 | 1682 | ||
1532 | /* DAC2/AIF2 outputs */ | 1683 | /* DAC2/AIF2 outputs */ |
1533 | { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" }, | 1684 | { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" }, |
1534 | { "DAC2L", NULL, "AIF2DAC2L Mixer" }, | ||
1535 | { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" }, | 1685 | { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" }, |
1536 | { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, | 1686 | { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, |
1537 | { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, | 1687 | { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, |
@@ -1539,13 +1689,17 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1539 | { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, | 1689 | { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, |
1540 | 1690 | ||
1541 | { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" }, | 1691 | { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" }, |
1542 | { "DAC2R", NULL, "AIF2DAC2R Mixer" }, | ||
1543 | { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" }, | 1692 | { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" }, |
1544 | { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, | 1693 | { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, |
1545 | { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, | 1694 | { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, |
1546 | { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, | 1695 | { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, |
1547 | { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, | 1696 | { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, |
1548 | 1697 | ||
1698 | { "AIF1ADCDAT", NULL, "AIF1ADC1L" }, | ||
1699 | { "AIF1ADCDAT", NULL, "AIF1ADC1R" }, | ||
1700 | { "AIF1ADCDAT", NULL, "AIF1ADC2L" }, | ||
1701 | { "AIF1ADCDAT", NULL, "AIF1ADC2R" }, | ||
1702 | |||
1549 | { "AIF2ADCDAT", NULL, "AIF2ADC Mux" }, | 1703 | { "AIF2ADCDAT", NULL, "AIF2ADC Mux" }, |
1550 | 1704 | ||
1551 | /* AIF3 output */ | 1705 | /* AIF3 output */ |
@@ -1578,6 +1732,31 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1578 | { "Right Headphone Mux", "DAC", "DAC1R" }, | 1732 | { "Right Headphone Mux", "DAC", "DAC1R" }, |
1579 | }; | 1733 | }; |
1580 | 1734 | ||
1735 | static const struct snd_soc_dapm_route wm8994_lateclk_revd_intercon[] = { | ||
1736 | { "DAC1L", NULL, "Late DAC1L Enable PGA" }, | ||
1737 | { "Late DAC1L Enable PGA", NULL, "DAC1L Mixer" }, | ||
1738 | { "DAC1R", NULL, "Late DAC1R Enable PGA" }, | ||
1739 | { "Late DAC1R Enable PGA", NULL, "DAC1R Mixer" }, | ||
1740 | { "DAC2L", NULL, "Late DAC2L Enable PGA" }, | ||
1741 | { "Late DAC2L Enable PGA", NULL, "AIF2DAC2L Mixer" }, | ||
1742 | { "DAC2R", NULL, "Late DAC2R Enable PGA" }, | ||
1743 | { "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" } | ||
1744 | }; | ||
1745 | |||
1746 | static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = { | ||
1747 | { "DAC1L", NULL, "DAC1L Mixer" }, | ||
1748 | { "DAC1R", NULL, "DAC1R Mixer" }, | ||
1749 | { "DAC2L", NULL, "AIF2DAC2L Mixer" }, | ||
1750 | { "DAC2R", NULL, "AIF2DAC2R Mixer" }, | ||
1751 | }; | ||
1752 | |||
1753 | static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { | ||
1754 | { "AIF1DACDAT", NULL, "AIF2DACDAT" }, | ||
1755 | { "AIF2DACDAT", NULL, "AIF1DACDAT" }, | ||
1756 | { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, | ||
1757 | { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, | ||
1758 | }; | ||
1759 | |||
1581 | static const struct snd_soc_dapm_route wm8994_intercon[] = { | 1760 | static const struct snd_soc_dapm_route wm8994_intercon[] = { |
1582 | { "AIF2DACL", NULL, "AIF2DAC Mux" }, | 1761 | { "AIF2DACL", NULL, "AIF2DAC Mux" }, |
1583 | { "AIF2DACR", NULL, "AIF2DAC Mux" }, | 1762 | { "AIF2DACR", NULL, "AIF2DAC Mux" }, |
@@ -2386,7 +2565,7 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate) | |||
2386 | else | 2565 | else |
2387 | val = 0; | 2566 | val = 0; |
2388 | 2567 | ||
2389 | return snd_soc_update_bits(codec, reg, mask, reg); | 2568 | return snd_soc_update_bits(codec, reg, mask, val); |
2390 | } | 2569 | } |
2391 | 2570 | ||
2392 | #define WM8994_RATES SNDRV_PCM_RATE_8000_96000 | 2571 | #define WM8994_RATES SNDRV_PCM_RATE_8000_96000 |
@@ -2501,6 +2680,22 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
2501 | { | 2680 | { |
2502 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2681 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2503 | int i, ret; | 2682 | int i, ret; |
2683 | unsigned int val, mask; | ||
2684 | |||
2685 | if (wm8994->revision < 4) { | ||
2686 | /* force a HW read */ | ||
2687 | val = wm8994_reg_read(codec->control_data, | ||
2688 | WM8994_POWER_MANAGEMENT_5); | ||
2689 | |||
2690 | /* modify the cache only */ | ||
2691 | codec->cache_only = 1; | ||
2692 | mask = WM8994_DAC1R_ENA | WM8994_DAC1L_ENA | | ||
2693 | WM8994_DAC2R_ENA | WM8994_DAC2L_ENA; | ||
2694 | val &= mask; | ||
2695 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, | ||
2696 | mask, val); | ||
2697 | codec->cache_only = 0; | ||
2698 | } | ||
2504 | 2699 | ||
2505 | /* Restore the registers */ | 2700 | /* Restore the registers */ |
2506 | ret = snd_soc_cache_sync(codec); | 2701 | ret = snd_soc_cache_sync(codec); |
@@ -2834,11 +3029,10 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
2834 | report |= SND_JACK_BTN_5; | 3029 | report |= SND_JACK_BTN_5; |
2835 | 3030 | ||
2836 | done: | 3031 | done: |
2837 | snd_soc_jack_report(wm8994->micdet[0].jack, | 3032 | snd_soc_jack_report(wm8994->micdet[0].jack, report, |
2838 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | | 3033 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | |
2839 | SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 | | 3034 | SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 | |
2840 | SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT, | 3035 | SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT); |
2841 | report); | ||
2842 | } | 3036 | } |
2843 | 3037 | ||
2844 | /** | 3038 | /** |
@@ -3112,6 +3306,21 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3112 | case WM8994: | 3306 | case WM8994: |
3113 | snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, | 3307 | snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, |
3114 | ARRAY_SIZE(wm8994_specific_dapm_widgets)); | 3308 | ARRAY_SIZE(wm8994_specific_dapm_widgets)); |
3309 | if (wm8994->revision < 4) { | ||
3310 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, | ||
3311 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); | ||
3312 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, | ||
3313 | ARRAY_SIZE(wm8994_adc_revd_widgets)); | ||
3314 | snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets, | ||
3315 | ARRAY_SIZE(wm8994_dac_revd_widgets)); | ||
3316 | } else { | ||
3317 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets, | ||
3318 | ARRAY_SIZE(wm8994_lateclk_widgets)); | ||
3319 | snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets, | ||
3320 | ARRAY_SIZE(wm8994_adc_widgets)); | ||
3321 | snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets, | ||
3322 | ARRAY_SIZE(wm8994_dac_widgets)); | ||
3323 | } | ||
3115 | break; | 3324 | break; |
3116 | case WM8958: | 3325 | case WM8958: |
3117 | snd_soc_add_controls(codec, wm8958_snd_controls, | 3326 | snd_soc_add_controls(codec, wm8958_snd_controls, |
@@ -3129,6 +3338,16 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3129 | case WM8994: | 3338 | case WM8994: |
3130 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | 3339 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, |
3131 | ARRAY_SIZE(wm8994_intercon)); | 3340 | ARRAY_SIZE(wm8994_intercon)); |
3341 | |||
3342 | if (wm8994->revision < 4) { | ||
3343 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | ||
3344 | ARRAY_SIZE(wm8994_revd_intercon)); | ||
3345 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, | ||
3346 | ARRAY_SIZE(wm8994_lateclk_revd_intercon)); | ||
3347 | } else { | ||
3348 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, | ||
3349 | ARRAY_SIZE(wm8994_lateclk_intercon)); | ||
3350 | } | ||
3132 | break; | 3351 | break; |
3133 | case WM8958: | 3352 | case WM8958: |
3134 | snd_soc_dapm_add_routes(dapm, wm8958_intercon, | 3353 | snd_soc_dapm_add_routes(dapm, wm8958_intercon, |