aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/wm8903.h10
-rw-r--r--sound/soc/codecs/cx20442.c2
-rw-r--r--sound/soc/codecs/wm8903.c2
-rw-r--r--sound/soc/codecs/wm8994.c197
-rw-r--r--sound/soc/soc-dapm.c23
5 files changed, 210 insertions, 24 deletions
diff --git a/include/sound/wm8903.h b/include/sound/wm8903.h
index b4a0db2307ef..1eeebd534f7e 100644
--- a/include/sound/wm8903.h
+++ b/include/sound/wm8903.h
@@ -17,13 +17,9 @@
17/* 17/*
18 * R6 (0x06) - Mic Bias Control 0 18 * R6 (0x06) - Mic Bias Control 0
19 */ 19 */
20#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */ 20#define WM8903_MICDET_THR_MASK 0x0030 /* MICDET_THR - [5:4] */
21#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */ 21#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [5:4] */
22#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */ 22#define WM8903_MICDET_THR_WIDTH 2 /* MICDET_THR - [5:4] */
23#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
24#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
25#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
26#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
27#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */ 23#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
28#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */ 24#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
29#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */ 25#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index bb4bf65b9e7e..0bb424af956f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -367,7 +367,7 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
367 return 0; 367 return 0;
368} 368}
369 369
370static const u8 cx20442_reg = CX20442_TELOUT | CX20442_MIC; 370static const u8 cx20442_reg;
371 371
372static struct snd_soc_codec_driver cx20442_codec_dev = { 372static struct snd_soc_codec_driver cx20442_codec_dev = {
373 .probe = cx20442_codec_probe, 373 .probe = cx20442_codec_probe,
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 987476a5895f..017d99ceb42e 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1482,7 +1482,7 @@ int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
1482 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, 1482 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
1483 irq_mask); 1483 irq_mask);
1484 1484
1485 if (det && shrt) { 1485 if (det || shrt) {
1486 /* Enable mic detection, this may not have been set through 1486 /* Enable mic detection, this may not have been set through
1487 * platform data (eg, if the defaults are OK). */ 1487 * platform data (eg, if the defaults are OK). */
1488 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, 1488 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 37b8aa8a680f..a60b5dbf0154 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -107,6 +107,9 @@ 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;
110}; 113};
111 114
112static int wm8994_readable(unsigned int reg) 115static int wm8994_readable(unsigned int reg)
@@ -1004,6 +1007,93 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
1004 } 1007 }
1005} 1008}
1006 1009
1010static int late_enable_ev(struct snd_soc_dapm_widget *w,
1011 struct snd_kcontrol *kcontrol, int event)
1012{
1013 struct snd_soc_codec *codec = w->codec;
1014 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1015
1016 switch (event) {
1017 case SND_SOC_DAPM_PRE_PMU:
1018 if (wm8994->aif1clk_enable)
1019 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
1020 WM8994_AIF1CLK_ENA_MASK,
1021 WM8994_AIF1CLK_ENA);
1022 if (wm8994->aif2clk_enable)
1023 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
1024 WM8994_AIF2CLK_ENA_MASK,
1025 WM8994_AIF2CLK_ENA);
1026 break;
1027 }
1028
1029 return 0;
1030}
1031
1032static int late_disable_ev(struct snd_soc_dapm_widget *w,
1033 struct snd_kcontrol *kcontrol, int event)
1034{
1035 struct snd_soc_codec *codec = w->codec;
1036 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1037
1038 switch (event) {
1039 case SND_SOC_DAPM_POST_PMD:
1040 if (wm8994->aif1clk_enable) {
1041 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
1042 WM8994_AIF1CLK_ENA_MASK, 0);
1043 wm8994->aif1clk_enable = 0;
1044 }
1045 if (wm8994->aif2clk_enable) {
1046 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
1047 WM8994_AIF2CLK_ENA_MASK, 0);
1048 wm8994->aif2clk_enable = 0;
1049 }
1050 break;
1051 }
1052
1053 return 0;
1054}
1055
1056static int aif1clk_ev(struct snd_soc_dapm_widget *w,
1057 struct snd_kcontrol *kcontrol, int event)
1058{
1059 struct snd_soc_codec *codec = w->codec;
1060 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1061
1062 switch (event) {
1063 case SND_SOC_DAPM_PRE_PMU:
1064 wm8994->aif1clk_enable = 1;
1065 break;
1066 }
1067
1068 return 0;
1069}
1070
1071static int aif2clk_ev(struct snd_soc_dapm_widget *w,
1072 struct snd_kcontrol *kcontrol, int event)
1073{
1074 struct snd_soc_codec *codec = w->codec;
1075 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1076
1077 switch (event) {
1078 case SND_SOC_DAPM_PRE_PMU:
1079 wm8994->aif2clk_enable = 1;
1080 break;
1081 }
1082
1083 return 0;
1084}
1085
1086static int dac_ev(struct snd_soc_dapm_widget *w,
1087 struct snd_kcontrol *kcontrol, int event)
1088{
1089 struct snd_soc_codec *codec = w->codec;
1090 unsigned int mask = 1 << w->shift;
1091
1092 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
1093 mask, mask);
1094 return 0;
1095}
1096
1007static const char *hp_mux_text[] = { 1097static const char *hp_mux_text[] = {
1008 "Mixer", 1098 "Mixer",
1009 "DAC", 1099 "DAC",
@@ -1272,6 +1362,47 @@ static const struct soc_enum aif2dacr_src_enum =
1272static const struct snd_kcontrol_new aif2dacr_src_mux = 1362static const struct snd_kcontrol_new aif2dacr_src_mux =
1273 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); 1363 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
1274 1364
1365static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = {
1366SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev,
1367 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1368SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev,
1369 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1370
1371SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1372 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1373SND_SOC_DAPM_PGA_E("Late DAC1R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1374 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1375SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1376 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1377SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1378 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1379
1380SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
1381};
1382
1383static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
1384SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
1385SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0)
1386};
1387
1388static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = {
1389SND_SOC_DAPM_DAC_E("DAC2L", NULL, SND_SOC_NOPM, 3, 0,
1390 dac_ev, SND_SOC_DAPM_PRE_PMU),
1391SND_SOC_DAPM_DAC_E("DAC2R", NULL, SND_SOC_NOPM, 2, 0,
1392 dac_ev, SND_SOC_DAPM_PRE_PMU),
1393SND_SOC_DAPM_DAC_E("DAC1L", NULL, SND_SOC_NOPM, 1, 0,
1394 dac_ev, SND_SOC_DAPM_PRE_PMU),
1395SND_SOC_DAPM_DAC_E("DAC1R", NULL, SND_SOC_NOPM, 0, 0,
1396 dac_ev, SND_SOC_DAPM_PRE_PMU),
1397};
1398
1399static const struct snd_soc_dapm_widget wm8994_dac_widgets[] = {
1400SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
1401SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
1402SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
1403SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
1404};
1405
1275static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { 1406static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
1276SND_SOC_DAPM_INPUT("DMIC1DAT"), 1407SND_SOC_DAPM_INPUT("DMIC1DAT"),
1277SND_SOC_DAPM_INPUT("DMIC2DAT"), 1408SND_SOC_DAPM_INPUT("DMIC2DAT"),
@@ -1284,9 +1415,6 @@ SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
1284SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), 1415SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
1285SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), 1416SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
1286 1417
1287SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
1288SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
1289
1290SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL, 1418SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL,
1291 0, WM8994_POWER_MANAGEMENT_4, 9, 0), 1419 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
1292SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL, 1420SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL,
@@ -1372,11 +1500,6 @@ SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
1372SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), 1500SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
1373SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), 1501SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
1374 1502
1375SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
1376SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
1377SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
1378SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
1379
1380SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), 1503SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1381SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), 1504SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1382 1505
@@ -1516,14 +1639,12 @@ static const struct snd_soc_dapm_route intercon[] = {
1516 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" }, 1639 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
1517 1640
1518 /* DAC1 inputs */ 1641 /* DAC1 inputs */
1519 { "DAC1L", NULL, "DAC1L Mixer" },
1520 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" }, 1642 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
1521 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, 1643 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
1522 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, 1644 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
1523 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, 1645 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1524 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1646 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1525 1647
1526 { "DAC1R", NULL, "DAC1R Mixer" },
1527 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" }, 1648 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
1528 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, 1649 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
1529 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, 1650 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
@@ -1532,7 +1653,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1532 1653
1533 /* DAC2/AIF2 outputs */ 1654 /* DAC2/AIF2 outputs */
1534 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" }, 1655 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
1535 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
1536 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" }, 1656 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
1537 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, 1657 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
1538 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, 1658 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
@@ -1540,7 +1660,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1540 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1660 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1541 1661
1542 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" }, 1662 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
1543 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
1544 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" }, 1663 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
1545 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, 1664 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
1546 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, 1665 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
@@ -1584,6 +1703,24 @@ static const struct snd_soc_dapm_route intercon[] = {
1584 { "Right Headphone Mux", "DAC", "DAC1R" }, 1703 { "Right Headphone Mux", "DAC", "DAC1R" },
1585}; 1704};
1586 1705
1706static const struct snd_soc_dapm_route wm8994_lateclk_revd_intercon[] = {
1707 { "DAC1L", NULL, "Late DAC1L Enable PGA" },
1708 { "Late DAC1L Enable PGA", NULL, "DAC1L Mixer" },
1709 { "DAC1R", NULL, "Late DAC1R Enable PGA" },
1710 { "Late DAC1R Enable PGA", NULL, "DAC1R Mixer" },
1711 { "DAC2L", NULL, "Late DAC2L Enable PGA" },
1712 { "Late DAC2L Enable PGA", NULL, "AIF2DAC2L Mixer" },
1713 { "DAC2R", NULL, "Late DAC2R Enable PGA" },
1714 { "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" }
1715};
1716
1717static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = {
1718 { "DAC1L", NULL, "DAC1L Mixer" },
1719 { "DAC1R", NULL, "DAC1R Mixer" },
1720 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
1721 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
1722};
1723
1587static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { 1724static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1588 { "AIF1DACDAT", NULL, "AIF2DACDAT" }, 1725 { "AIF1DACDAT", NULL, "AIF2DACDAT" },
1589 { "AIF2DACDAT", NULL, "AIF1DACDAT" }, 1726 { "AIF2DACDAT", NULL, "AIF1DACDAT" },
@@ -2514,6 +2651,22 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2514{ 2651{
2515 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2652 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2516 int i, ret; 2653 int i, ret;
2654 unsigned int val, mask;
2655
2656 if (wm8994->revision < 4) {
2657 /* force a HW read */
2658 val = wm8994_reg_read(codec->control_data,
2659 WM8994_POWER_MANAGEMENT_5);
2660
2661 /* modify the cache only */
2662 codec->cache_only = 1;
2663 mask = WM8994_DAC1R_ENA | WM8994_DAC1L_ENA |
2664 WM8994_DAC2R_ENA | WM8994_DAC2L_ENA;
2665 val &= mask;
2666 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
2667 mask, val);
2668 codec->cache_only = 0;
2669 }
2517 2670
2518 /* Restore the registers */ 2671 /* Restore the registers */
2519 ret = snd_soc_cache_sync(codec); 2672 ret = snd_soc_cache_sync(codec);
@@ -3125,6 +3278,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3125 case WM8994: 3278 case WM8994:
3126 snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, 3279 snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
3127 ARRAY_SIZE(wm8994_specific_dapm_widgets)); 3280 ARRAY_SIZE(wm8994_specific_dapm_widgets));
3281 if (wm8994->revision < 4) {
3282 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
3283 ARRAY_SIZE(wm8994_lateclk_revd_widgets));
3284 snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
3285 ARRAY_SIZE(wm8994_dac_revd_widgets));
3286 } else {
3287 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3288 ARRAY_SIZE(wm8994_lateclk_widgets));
3289 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3290 ARRAY_SIZE(wm8994_dac_widgets));
3291 }
3128 break; 3292 break;
3129 case WM8958: 3293 case WM8958:
3130 snd_soc_add_controls(codec, wm8958_snd_controls, 3294 snd_soc_add_controls(codec, wm8958_snd_controls,
@@ -3143,10 +3307,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3143 snd_soc_dapm_add_routes(dapm, wm8994_intercon, 3307 snd_soc_dapm_add_routes(dapm, wm8994_intercon,
3144 ARRAY_SIZE(wm8994_intercon)); 3308 ARRAY_SIZE(wm8994_intercon));
3145 3309
3146 if (wm8994->revision < 4) 3310 if (wm8994->revision < 4) {
3147 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, 3311 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
3148 ARRAY_SIZE(wm8994_revd_intercon)); 3312 ARRAY_SIZE(wm8994_revd_intercon));
3149 3313 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
3314 ARRAY_SIZE(wm8994_lateclk_revd_intercon));
3315 } else {
3316 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3317 ARRAY_SIZE(wm8994_lateclk_intercon));
3318 }
3150 break; 3319 break;
3151 case WM8958: 3320 case WM8958:
3152 snd_soc_dapm_add_routes(dapm, wm8958_intercon, 3321 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8194f150bab7..25e54230cc6a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -712,7 +712,15 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
712 !path->connected(path->source, path->sink)) 712 !path->connected(path->source, path->sink))
713 continue; 713 continue;
714 714
715 if (path->sink && path->sink->power_check && 715 if (!path->sink)
716 continue;
717
718 if (path->sink->force) {
719 power = 1;
720 break;
721 }
722
723 if (path->sink->power_check &&
716 path->sink->power_check(path->sink)) { 724 path->sink->power_check(path->sink)) {
717 power = 1; 725 power = 1;
718 break; 726 break;
@@ -1627,6 +1635,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
1627int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) 1635int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1628{ 1636{
1629 struct snd_soc_dapm_widget *w; 1637 struct snd_soc_dapm_widget *w;
1638 unsigned int val;
1630 1639
1631 list_for_each_entry(w, &dapm->card->widgets, list) 1640 list_for_each_entry(w, &dapm->card->widgets, list)
1632 { 1641 {
@@ -1675,6 +1684,18 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1675 case snd_soc_dapm_post: 1684 case snd_soc_dapm_post:
1676 break; 1685 break;
1677 } 1686 }
1687
1688 /* Read the initial power state from the device */
1689 if (w->reg >= 0) {
1690 val = snd_soc_read(w->codec, w->reg);
1691 val &= 1 << w->shift;
1692 if (w->invert)
1693 val = !val;
1694
1695 if (val)
1696 w->power = 1;
1697 }
1698
1678 w->new = 1; 1699 w->new = 1;
1679 } 1700 }
1680 1701