aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dapm.h2
-rw-r--r--include/sound/soc-dpcm.h2
-rw-r--r--sound/soc/codecs/wm8350.c25
-rw-r--r--sound/soc/codecs/wm8753.c73
-rw-r--r--sound/soc/codecs/wm8971.c99
-rw-r--r--sound/soc/soc-core.c104
-rw-r--r--sound/soc/soc-dapm.c3
-rw-r--r--sound/soc/soc-pcm.c16
8 files changed, 135 insertions, 189 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 8d7416e46861..485fc9d1a7bc 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -586,8 +586,6 @@ struct snd_soc_dapm_update {
586/* DAPM context */ 586/* DAPM context */
587struct snd_soc_dapm_context { 587struct snd_soc_dapm_context {
588 enum snd_soc_bias_level bias_level; 588 enum snd_soc_bias_level bias_level;
589 enum snd_soc_bias_level suspend_bias_level;
590 struct delayed_work delayed_work;
591 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ 589 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
592 /* Go to BIAS_OFF in suspend if the DAPM context is idle */ 590 /* Go to BIAS_OFF in suspend if the DAPM context is idle */
593 unsigned int suspend_bias_off:1; 591 unsigned int suspend_bias_off:1;
diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h
index 98f2ade0266e..806059052bfc 100644
--- a/include/sound/soc-dpcm.h
+++ b/include/sound/soc-dpcm.h
@@ -135,7 +135,7 @@ void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream,
135 135
136/* internal use only */ 136/* internal use only */
137int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); 137int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute);
138int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd); 138void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
139int soc_dpcm_runtime_update(struct snd_soc_card *); 139int soc_dpcm_runtime_update(struct snd_soc_card *);
140 140
141int dpcm_path_get(struct snd_soc_pcm_runtime *fe, 141int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index c81a9eab3e3e..c65e5a75fc1a 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -69,14 +69,14 @@ struct wm8350_data {
69 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 69 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
70 int fll_freq_out; 70 int fll_freq_out;
71 int fll_freq_in; 71 int fll_freq_in;
72 struct delayed_work pga_work;
72}; 73};
73 74
74/* 75/*
75 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. 76 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
76 */ 77 */
77static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) 78static inline int wm8350_out1_ramp_step(struct wm8350_data *wm8350_data)
78{ 79{
79 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
80 struct wm8350_output *out1 = &wm8350_data->out1; 80 struct wm8350_output *out1 = &wm8350_data->out1;
81 struct wm8350 *wm8350 = wm8350_data->wm8350; 81 struct wm8350 *wm8350 = wm8350_data->wm8350;
82 int left_complete = 0, right_complete = 0; 82 int left_complete = 0, right_complete = 0;
@@ -140,9 +140,8 @@ static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
140/* 140/*
141 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown. 141 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
142 */ 142 */
143static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) 143static inline int wm8350_out2_ramp_step(struct wm8350_data *wm8350_data)
144{ 144{
145 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
146 struct wm8350_output *out2 = &wm8350_data->out2; 145 struct wm8350_output *out2 = &wm8350_data->out2;
147 struct wm8350 *wm8350 = wm8350_data->wm8350; 146 struct wm8350 *wm8350 = wm8350_data->wm8350;
148 int left_complete = 0, right_complete = 0; 147 int left_complete = 0, right_complete = 0;
@@ -210,10 +209,8 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
210 */ 209 */
211static void wm8350_pga_work(struct work_struct *work) 210static void wm8350_pga_work(struct work_struct *work)
212{ 211{
213 struct snd_soc_dapm_context *dapm = 212 struct wm8350_data *wm8350_data =
214 container_of(work, struct snd_soc_dapm_context, delayed_work.work); 213 container_of(work, struct wm8350_data, pga_work.work);
215 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
216 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
217 struct wm8350_output *out1 = &wm8350_data->out1, 214 struct wm8350_output *out1 = &wm8350_data->out1,
218 *out2 = &wm8350_data->out2; 215 *out2 = &wm8350_data->out2;
219 int i, out1_complete, out2_complete; 216 int i, out1_complete, out2_complete;
@@ -226,9 +223,9 @@ static void wm8350_pga_work(struct work_struct *work)
226 for (i = 0; i <= 63; i++) { 223 for (i = 0; i <= 63; i++) {
227 out1_complete = 1, out2_complete = 1; 224 out1_complete = 1, out2_complete = 1;
228 if (out1->ramp != WM8350_RAMP_NONE) 225 if (out1->ramp != WM8350_RAMP_NONE)
229 out1_complete = wm8350_out1_ramp_step(codec); 226 out1_complete = wm8350_out1_ramp_step(wm8350_data);
230 if (out2->ramp != WM8350_RAMP_NONE) 227 if (out2->ramp != WM8350_RAMP_NONE)
231 out2_complete = wm8350_out2_ramp_step(codec); 228 out2_complete = wm8350_out2_ramp_step(wm8350_data);
232 229
233 /* ramp finished ? */ 230 /* ramp finished ? */
234 if (out1_complete && out2_complete) 231 if (out1_complete && out2_complete)
@@ -283,7 +280,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
283 out->ramp = WM8350_RAMP_UP; 280 out->ramp = WM8350_RAMP_UP;
284 out->active = 1; 281 out->active = 1;
285 282
286 schedule_delayed_work(&codec->dapm.delayed_work, 283 schedule_delayed_work(&wm8350_data->pga_work,
287 msecs_to_jiffies(1)); 284 msecs_to_jiffies(1));
288 break; 285 break;
289 286
@@ -291,7 +288,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
291 out->ramp = WM8350_RAMP_DOWN; 288 out->ramp = WM8350_RAMP_DOWN;
292 out->active = 0; 289 out->active = 0;
293 290
294 schedule_delayed_work(&codec->dapm.delayed_work, 291 schedule_delayed_work(&wm8350_data->pga_work,
295 msecs_to_jiffies(1)); 292 msecs_to_jiffies(1));
296 break; 293 break;
297 } 294 }
@@ -1492,7 +1489,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1492 /* Put the codec into reset if it wasn't already */ 1489 /* Put the codec into reset if it wasn't already */
1493 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1490 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1494 1491
1495 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work); 1492 INIT_DELAYED_WORK(&priv->pga_work, wm8350_pga_work);
1496 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work); 1493 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
1497 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work); 1494 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
1498 1495
@@ -1578,7 +1575,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1578 1575
1579 /* if there was any work waiting then we run it now and 1576 /* if there was any work waiting then we run it now and
1580 * wait for its completion */ 1577 * wait for its completion */
1581 flush_delayed_work(&codec->dapm.delayed_work); 1578 flush_delayed_work(&priv->pga_work);
1582 1579
1583 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1580 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1584 1581
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 21ca3a94fc96..c50a5959345f 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -153,6 +153,7 @@ struct wm8753_priv {
153 unsigned int hifi_fmt; 153 unsigned int hifi_fmt;
154 154
155 int dai_func; 155 int dai_func;
156 struct delayed_work charge_work;
156}; 157};
157 158
158#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0) 159#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
@@ -1326,9 +1327,19 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1326 return 0; 1327 return 0;
1327} 1328}
1328 1329
1330static void wm8753_charge_work(struct work_struct *work)
1331{
1332 struct wm8753_priv *wm8753 =
1333 container_of(work, struct wm8753_priv, charge_work.work);
1334
1335 /* Set to 500k */
1336 regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100);
1337}
1338
1329static int wm8753_set_bias_level(struct snd_soc_codec *codec, 1339static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1330 enum snd_soc_bias_level level) 1340 enum snd_soc_bias_level level)
1331{ 1341{
1342 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1332 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e; 1343 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
1333 1344
1334 switch (level) { 1345 switch (level) {
@@ -1337,14 +1348,22 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1337 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); 1348 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
1338 break; 1349 break;
1339 case SND_SOC_BIAS_PREPARE: 1350 case SND_SOC_BIAS_PREPARE:
1340 /* set vmid to 5k for quick power up */ 1351 /* Wait until fully charged */
1341 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); 1352 flush_delayed_work(&wm8753->charge_work);
1342 break; 1353 break;
1343 case SND_SOC_BIAS_STANDBY: 1354 case SND_SOC_BIAS_STANDBY:
1344 /* mute dac and set vmid to 500k, enable VREF */ 1355 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1345 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141); 1356 /* set vmid to 5k for quick power up */
1357 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
1358 schedule_delayed_work(&wm8753->charge_work,
1359 msecs_to_jiffies(caps_charge));
1360 } else {
1361 /* mute dac and set vmid to 500k, enable VREF */
1362 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
1363 }
1346 break; 1364 break;
1347 case SND_SOC_BIAS_OFF: 1365 case SND_SOC_BIAS_OFF:
1366 cancel_delayed_work_sync(&wm8753->charge_work);
1348 snd_soc_write(codec, WM8753_PWR1, 0x0001); 1367 snd_soc_write(codec, WM8753_PWR1, 0x0001);
1349 break; 1368 break;
1350 } 1369 }
@@ -1428,38 +1447,12 @@ static struct snd_soc_dai_driver wm8753_dai[] = {
1428}, 1447},
1429}; 1448};
1430 1449
1431static void wm8753_work(struct work_struct *work)
1432{
1433 struct snd_soc_dapm_context *dapm =
1434 container_of(work, struct snd_soc_dapm_context,
1435 delayed_work.work);
1436 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
1437 wm8753_set_bias_level(codec, dapm->bias_level);
1438}
1439
1440static int wm8753_suspend(struct snd_soc_codec *codec)
1441{
1442 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1443 return 0;
1444}
1445
1446static int wm8753_resume(struct snd_soc_codec *codec) 1450static int wm8753_resume(struct snd_soc_codec *codec)
1447{ 1451{
1448 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1452 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1449 1453
1450 regcache_sync(wm8753->regmap); 1454 regcache_sync(wm8753->regmap);
1451 1455
1452 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1453
1454 /* charge wm8753 caps */
1455 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
1456 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1457 codec->dapm.bias_level = SND_SOC_BIAS_ON;
1458 queue_delayed_work(system_power_efficient_wq,
1459 &codec->dapm.delayed_work,
1460 msecs_to_jiffies(caps_charge));
1461 }
1462
1463 return 0; 1456 return 0;
1464} 1457}
1465 1458
@@ -1468,7 +1461,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1468 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1461 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1469 int ret; 1462 int ret;
1470 1463
1471 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); 1464 INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work);
1472 1465
1473 ret = wm8753_reset(codec); 1466 ret = wm8753_reset(codec);
1474 if (ret < 0) { 1467 if (ret < 0) {
@@ -1476,14 +1469,8 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1476 return ret; 1469 return ret;
1477 } 1470 }
1478 1471
1479 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1480 wm8753->dai_func = 0; 1472 wm8753->dai_func = 0;
1481 1473
1482 /* charge output caps */
1483 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1484 schedule_delayed_work(&codec->dapm.delayed_work,
1485 msecs_to_jiffies(caps_charge));
1486
1487 /* set the update bits */ 1474 /* set the update bits */
1488 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100); 1475 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1489 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100); 1476 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
@@ -1499,21 +1486,11 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1499 return 0; 1486 return 0;
1500} 1487}
1501 1488
1502/* power down chip */
1503static int wm8753_remove(struct snd_soc_codec *codec)
1504{
1505 flush_delayed_work(&codec->dapm.delayed_work);
1506 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1507
1508 return 0;
1509}
1510
1511static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { 1489static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1512 .probe = wm8753_probe, 1490 .probe = wm8753_probe,
1513 .remove = wm8753_remove,
1514 .suspend = wm8753_suspend,
1515 .resume = wm8753_resume, 1491 .resume = wm8753_resume,
1516 .set_bias_level = wm8753_set_bias_level, 1492 .set_bias_level = wm8753_set_bias_level,
1493 .suspend_bias_off = true,
1517 1494
1518 .controls = wm8753_snd_controls, 1495 .controls = wm8753_snd_controls,
1519 .num_controls = ARRAY_SIZE(wm8753_snd_controls), 1496 .num_controls = ARRAY_SIZE(wm8753_snd_controls),
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 39ddb9b8834c..f9cbabdc6238 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -31,11 +31,11 @@
31 31
32#define WM8971_REG_COUNT 43 32#define WM8971_REG_COUNT 43
33 33
34static struct workqueue_struct *wm8971_workq = NULL;
35
36/* codec private data */ 34/* codec private data */
37struct wm8971_priv { 35struct wm8971_priv {
38 unsigned int sysclk; 36 unsigned int sysclk;
37 struct delayed_work charge_work;
38 struct regmap *regmap;
39}; 39};
40 40
41/* 41/*
@@ -552,9 +552,19 @@ static int wm8971_mute(struct snd_soc_dai *dai, int mute)
552 return 0; 552 return 0;
553} 553}
554 554
555static void wm8971_charge_work(struct work_struct *work)
556{
557 struct wm8971_priv *wm8971 =
558 container_of(work, struct wm8971_priv, charge_work.work);
559
560 /* Set to 500k */
561 regmap_update_bits(wm8971->regmap, WM8971_PWR1, 0x0180, 0x0100);
562}
563
555static int wm8971_set_bias_level(struct snd_soc_codec *codec, 564static int wm8971_set_bias_level(struct snd_soc_codec *codec,
556 enum snd_soc_bias_level level) 565 enum snd_soc_bias_level level)
557{ 566{
567 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
558 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 568 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
559 569
560 switch (level) { 570 switch (level) {
@@ -563,15 +573,24 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
563 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1); 573 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
564 break; 574 break;
565 case SND_SOC_BIAS_PREPARE: 575 case SND_SOC_BIAS_PREPARE:
576 /* Wait until fully charged */
577 flush_delayed_work(&wm8971->charge_work);
566 break; 578 break;
567 case SND_SOC_BIAS_STANDBY: 579 case SND_SOC_BIAS_STANDBY:
568 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) 580 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
569 snd_soc_cache_sync(codec); 581 snd_soc_cache_sync(codec);
582 /* charge output caps - set vmid to 5k for quick power up */
583 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x01c0);
584 queue_delayed_work(system_power_efficient_wq,
585 &wm8971->charge_work, msecs_to_jiffies(1000));
586 } else {
587 /* mute dac and set vmid to 500k, enable VREF */
588 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
589 }
570 590
571 /* mute dac and set vmid to 500k, enable VREF */
572 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
573 break; 591 break;
574 case SND_SOC_BIAS_OFF: 592 case SND_SOC_BIAS_OFF:
593 cancel_delayed_work_sync(&wm8971->charge_work);
575 snd_soc_write(codec, WM8971_PWR1, 0x0001); 594 snd_soc_write(codec, WM8971_PWR1, 0x0001);
576 break; 595 break;
577 } 596 }
@@ -610,58 +629,14 @@ static struct snd_soc_dai_driver wm8971_dai = {
610 .ops = &wm8971_dai_ops, 629 .ops = &wm8971_dai_ops,
611}; 630};
612 631
613static void wm8971_work(struct work_struct *work)
614{
615 struct snd_soc_dapm_context *dapm =
616 container_of(work, struct snd_soc_dapm_context,
617 delayed_work.work);
618 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
619 wm8971_set_bias_level(codec, codec->dapm.bias_level);
620}
621
622static int wm8971_suspend(struct snd_soc_codec *codec)
623{
624 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
625 return 0;
626}
627
628static int wm8971_resume(struct snd_soc_codec *codec)
629{
630 u16 reg;
631
632 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
633
634 /* charge wm8971 caps */
635 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
636 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
637 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
638 codec->dapm.bias_level = SND_SOC_BIAS_ON;
639 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
640 msecs_to_jiffies(1000));
641 }
642
643 return 0;
644}
645
646static int wm8971_probe(struct snd_soc_codec *codec) 632static int wm8971_probe(struct snd_soc_codec *codec)
647{ 633{
648 int ret = 0; 634 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
649 u16 reg;
650 635
651 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work); 636 INIT_DELAYED_WORK(&wm8971->charge_work, wm8971_charge_work);
652 wm8971_workq = create_workqueue("wm8971");
653 if (wm8971_workq == NULL)
654 return -ENOMEM;
655 637
656 wm8971_reset(codec); 638 wm8971_reset(codec);
657 639
658 /* charge output caps - set vmid to 5k for quick power up */
659 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
660 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
661 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
662 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
663 msecs_to_jiffies(1000));
664
665 /* set the update bits */ 640 /* set the update bits */
666 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100); 641 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100);
667 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100); 642 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100);
@@ -672,26 +647,13 @@ static int wm8971_probe(struct snd_soc_codec *codec)
672 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); 647 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
673 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); 648 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
674 649
675 return ret;
676}
677
678
679/* power down chip */
680static int wm8971_remove(struct snd_soc_codec *codec)
681{
682 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
683
684 if (wm8971_workq)
685 destroy_workqueue(wm8971_workq);
686 return 0; 650 return 0;
687} 651}
688 652
689static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { 653static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
690 .probe = wm8971_probe, 654 .probe = wm8971_probe,
691 .remove = wm8971_remove,
692 .suspend = wm8971_suspend,
693 .resume = wm8971_resume,
694 .set_bias_level = wm8971_set_bias_level, 655 .set_bias_level = wm8971_set_bias_level,
656 .suspend_bias_off = true,
695 657
696 .controls = wm8971_snd_controls, 658 .controls = wm8971_snd_controls,
697 .num_controls = ARRAY_SIZE(wm8971_snd_controls), 659 .num_controls = ARRAY_SIZE(wm8971_snd_controls),
@@ -715,7 +677,6 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
715 const struct i2c_device_id *id) 677 const struct i2c_device_id *id)
716{ 678{
717 struct wm8971_priv *wm8971; 679 struct wm8971_priv *wm8971;
718 struct regmap *regmap;
719 int ret; 680 int ret;
720 681
721 wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), 682 wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv),
@@ -723,9 +684,9 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
723 if (wm8971 == NULL) 684 if (wm8971 == NULL)
724 return -ENOMEM; 685 return -ENOMEM;
725 686
726 regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap); 687 wm8971->regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap);
727 if (IS_ERR(regmap)) 688 if (IS_ERR(wm8971->regmap))
728 return PTR_ERR(regmap); 689 return PTR_ERR(wm8971->regmap);
729 690
730 i2c_set_clientdata(i2c, wm8971); 691 i2c_set_clientdata(i2c, wm8971);
731 692
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 07aa54385ae0..2fb3bf738b5b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -292,6 +292,9 @@ static const struct file_operations codec_reg_fops = {
292 292
293static void soc_init_component_debugfs(struct snd_soc_component *component) 293static void soc_init_component_debugfs(struct snd_soc_component *component)
294{ 294{
295 if (!component->card->debugfs_card_root)
296 return;
297
295 if (component->debugfs_prefix) { 298 if (component->debugfs_prefix) {
296 char *name; 299 char *name;
297 300
@@ -455,6 +458,9 @@ static const struct file_operations platform_list_fops = {
455 458
456static void soc_init_card_debugfs(struct snd_soc_card *card) 459static void soc_init_card_debugfs(struct snd_soc_card *card)
457{ 460{
461 if (!snd_soc_debugfs_root)
462 return;
463
458 card->debugfs_card_root = debugfs_create_dir(card->name, 464 card->debugfs_card_root = debugfs_create_dir(card->name,
459 snd_soc_debugfs_root); 465 snd_soc_debugfs_root);
460 if (!card->debugfs_card_root) { 466 if (!card->debugfs_card_root) {
@@ -476,6 +482,34 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
476 debugfs_remove_recursive(card->debugfs_card_root); 482 debugfs_remove_recursive(card->debugfs_card_root);
477} 483}
478 484
485
486static void snd_soc_debugfs_init(void)
487{
488 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
489 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
490 pr_warn("ASoC: Failed to create debugfs directory\n");
491 snd_soc_debugfs_root = NULL;
492 return;
493 }
494
495 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
496 &codec_list_fops))
497 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
498
499 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
500 &dai_list_fops))
501 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
502
503 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
504 &platform_list_fops))
505 pr_warn("ASoC: Failed to create platform list debugfs file\n");
506}
507
508static void snd_soc_debugfs_exit(void)
509{
510 debugfs_remove_recursive(snd_soc_debugfs_root);
511}
512
479#else 513#else
480 514
481#define soc_init_codec_debugfs NULL 515#define soc_init_codec_debugfs NULL
@@ -497,6 +531,15 @@ static inline void soc_init_card_debugfs(struct snd_soc_card *card)
497static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card) 531static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
498{ 532{
499} 533}
534
535static inline void snd_soc_debugfs_init(void)
536{
537}
538
539static inline void snd_soc_debugfs_exit(void)
540{
541}
542
500#endif 543#endif
501 544
502struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, 545struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
@@ -595,15 +638,9 @@ int snd_soc_suspend(struct device *dev)
595 cpu_dai->driver->suspend(cpu_dai); 638 cpu_dai->driver->suspend(cpu_dai);
596 } 639 }
597 640
598 /* close any waiting streams and save state */ 641 /* close any waiting streams */
599 for (i = 0; i < card->num_rtd; i++) { 642 for (i = 0; i < card->num_rtd; i++)
600 struct snd_soc_dai **codec_dais = card->rtd[i].codec_dais;
601 flush_delayed_work(&card->rtd[i].delayed_work); 643 flush_delayed_work(&card->rtd[i].delayed_work);
602 for (j = 0; j < card->rtd[i].num_codecs; j++) {
603 codec_dais[j]->codec->dapm.suspend_bias_level =
604 codec_dais[j]->codec->dapm.bias_level;
605 }
606 }
607 644
608 for (i = 0; i < card->num_rtd; i++) { 645 for (i = 0; i < card->num_rtd; i++) {
609 646
@@ -1322,21 +1359,17 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1322 } 1359 }
1323 } 1360 }
1324 1361
1362 if (dai_link->dai_fmt)
1363 snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
1364
1325 ret = soc_post_component_init(rtd, dai_link->name); 1365 ret = soc_post_component_init(rtd, dai_link->name);
1326 if (ret) 1366 if (ret)
1327 return ret; 1367 return ret;
1328 1368
1329#ifdef CONFIG_DEBUG_FS 1369#ifdef CONFIG_DEBUG_FS
1330 /* add DPCM sysfs entries */ 1370 /* add DPCM sysfs entries */
1331 if (dai_link->dynamic) { 1371 if (dai_link->dynamic)
1332 ret = soc_dpcm_debugfs_add(rtd); 1372 soc_dpcm_debugfs_add(rtd);
1333 if (ret < 0) {
1334 dev_err(rtd->dev,
1335 "ASoC: failed to add dpcm sysfs entries: %d\n",
1336 ret);
1337 return ret;
1338 }
1339 }
1340#endif 1373#endif
1341 1374
1342 if (cpu_dai->driver->compress_dai) { 1375 if (cpu_dai->driver->compress_dai) {
@@ -1426,7 +1459,6 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1426 1459
1427 /* unregister the rtd device */ 1460 /* unregister the rtd device */
1428 if (rtd->dev_registered) { 1461 if (rtd->dev_registered) {
1429 device_remove_file(rtd->dev, &dev_attr_codec_reg);
1430 device_unregister(rtd->dev); 1462 device_unregister(rtd->dev);
1431 rtd->dev_registered = 0; 1463 rtd->dev_registered = 0;
1432 } 1464 }
@@ -1560,6 +1592,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1560 goto base_error; 1592 goto base_error;
1561 } 1593 }
1562 1594
1595 soc_init_card_debugfs(card);
1596
1563 card->dapm.bias_level = SND_SOC_BIAS_OFF; 1597 card->dapm.bias_level = SND_SOC_BIAS_OFF;
1564 card->dapm.dev = card->dev; 1598 card->dapm.dev = card->dev;
1565 card->dapm.card = card; 1599 card->dapm.card = card;
@@ -1641,12 +1675,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1641 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, 1675 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
1642 card->num_of_dapm_routes); 1676 card->num_of_dapm_routes);
1643 1677
1644 for (i = 0; i < card->num_links; i++) {
1645 if (card->dai_link[i].dai_fmt)
1646 snd_soc_runtime_set_dai_fmt(&card->rtd[i],
1647 card->dai_link[i].dai_fmt);
1648 }
1649
1650 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1678 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1651 "%s", card->name); 1679 "%s", card->name);
1652 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1680 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -1702,6 +1730,7 @@ card_probe_error:
1702 if (card->remove) 1730 if (card->remove)
1703 card->remove(card); 1731 card->remove(card);
1704 1732
1733 soc_cleanup_card_debugfs(card);
1705 snd_card_free(card->snd_card); 1734 snd_card_free(card->snd_card);
1706 1735
1707base_error: 1736base_error:
@@ -2380,8 +2409,6 @@ int snd_soc_register_card(struct snd_soc_card *card)
2380 2409
2381 snd_soc_initialize_card_lists(card); 2410 snd_soc_initialize_card_lists(card);
2382 2411
2383 soc_init_card_debugfs(card);
2384
2385 card->rtd = devm_kzalloc(card->dev, 2412 card->rtd = devm_kzalloc(card->dev,
2386 sizeof(struct snd_soc_pcm_runtime) * 2413 sizeof(struct snd_soc_pcm_runtime) *
2387 (card->num_links + card->num_aux_devs), 2414 (card->num_links + card->num_aux_devs),
@@ -2412,7 +2439,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2412 2439
2413 ret = snd_soc_instantiate_card(card); 2440 ret = snd_soc_instantiate_card(card);
2414 if (ret != 0) 2441 if (ret != 0)
2415 soc_cleanup_card_debugfs(card); 2442 return ret;
2416 2443
2417 /* deactivate pins to sleep state */ 2444 /* deactivate pins to sleep state */
2418 for (i = 0; i < card->num_rtd; i++) { 2445 for (i = 0; i < card->num_rtd; i++) {
@@ -3595,26 +3622,7 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs);
3595 3622
3596static int __init snd_soc_init(void) 3623static int __init snd_soc_init(void)
3597{ 3624{
3598#ifdef CONFIG_DEBUG_FS 3625 snd_soc_debugfs_init();
3599 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
3600 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
3601 pr_warn("ASoC: Failed to create debugfs directory\n");
3602 snd_soc_debugfs_root = NULL;
3603 }
3604
3605 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
3606 &codec_list_fops))
3607 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
3608
3609 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
3610 &dai_list_fops))
3611 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
3612
3613 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
3614 &platform_list_fops))
3615 pr_warn("ASoC: Failed to create platform list debugfs file\n");
3616#endif
3617
3618 snd_soc_util_init(); 3626 snd_soc_util_init();
3619 3627
3620 return platform_driver_register(&soc_driver); 3628 return platform_driver_register(&soc_driver);
@@ -3624,9 +3632,9 @@ module_init(snd_soc_init);
3624static void __exit snd_soc_exit(void) 3632static void __exit snd_soc_exit(void)
3625{ 3633{
3626 snd_soc_util_exit(); 3634 snd_soc_util_exit();
3635 snd_soc_debugfs_exit();
3627 3636
3628#ifdef CONFIG_DEBUG_FS 3637#ifdef CONFIG_DEBUG_FS
3629 debugfs_remove_recursive(snd_soc_debugfs_root);
3630#endif 3638#endif
3631 platform_driver_unregister(&soc_driver); 3639 platform_driver_unregister(&soc_driver);
3632} 3640}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b6f88202b8c9..1fd2d458824e 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1898,6 +1898,9 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1898{ 1898{
1899 struct dentry *d; 1899 struct dentry *d;
1900 1900
1901 if (!parent)
1902 return;
1903
1901 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); 1904 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1902 1905
1903 if (!dapm->debugfs_dapm) { 1906 if (!dapm->debugfs_dapm) {
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 6e3781e88f9a..35fe58f4fa86 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1097,8 +1097,9 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
1097 stream ? "<-" : "->", be->dai_link->name); 1097 stream ? "<-" : "->", be->dai_link->name);
1098 1098
1099#ifdef CONFIG_DEBUG_FS 1099#ifdef CONFIG_DEBUG_FS
1100 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644, 1100 if (fe->debugfs_dpcm_root)
1101 fe->debugfs_dpcm_root, &dpcm->state); 1101 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644,
1102 fe->debugfs_dpcm_root, &dpcm->state);
1102#endif 1103#endif
1103 return 1; 1104 return 1;
1104} 1105}
@@ -2803,10 +2804,13 @@ static const struct file_operations dpcm_state_fops = {
2803 .llseek = default_llseek, 2804 .llseek = default_llseek,
2804}; 2805};
2805 2806
2806int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) 2807void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
2807{ 2808{
2808 if (!rtd->dai_link) 2809 if (!rtd->dai_link)
2809 return 0; 2810 return;
2811
2812 if (!rtd->card->debugfs_card_root)
2813 return;
2810 2814
2811 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, 2815 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
2812 rtd->card->debugfs_card_root); 2816 rtd->card->debugfs_card_root);
@@ -2814,13 +2818,11 @@ int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
2814 dev_dbg(rtd->dev, 2818 dev_dbg(rtd->dev,
2815 "ASoC: Failed to create dpcm debugfs directory %s\n", 2819 "ASoC: Failed to create dpcm debugfs directory %s\n",
2816 rtd->dai_link->name); 2820 rtd->dai_link->name);
2817 return -EINVAL; 2821 return;
2818 } 2822 }
2819 2823
2820 rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444, 2824 rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444,
2821 rtd->debugfs_dpcm_root, 2825 rtd->debugfs_dpcm_root,
2822 rtd, &dpcm_state_fops); 2826 rtd, &dpcm_state_fops);
2823
2824 return 0;
2825} 2827}
2826#endif 2828#endif