aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorJanusz Krzysztofik <jkrzyszt@tis.icnet.pl>2011-12-29 22:04:54 -0500
committerLiam Girdwood <lrg@ti.com>2012-01-09 06:20:16 -0500
commitf75a8ff67d161b5166a2c2360bb2ffaefd5eb853 (patch)
treedfba447099152b8deae514492e0e1e2a7bcd87cc /sound/soc
parentb425b88418e302caf27e9cf44aa987b83c04cb2d (diff)
ASoC: cx20442: add bias control over a platform provided regulator
Now that a regulator device for controlling the codec chip reset state over a platform agnostic regulator API is available on the only board using this driver so far, extend the driver with a bias control function which will request virtual power to the codec chip from that virtual regulator, and will supersede the present implementation existing at the sound card level. Thanks to the regulator sharing mechanism, both the old (the sound card) and the new (the codec) implementations should coexist smoothly until the sound card file is updated. For this to work as expected, update the sound card .set_bias_level callback to not touch codec->dapm.bias_level. While extending the cx20442 structure, drop unused control_type member. Created against linxu-3.2-rc6, tested on top of patch 1/4 "ARM: OMAP1: ams-delta: set up a regulator over the modem reset GPIO pin". Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@ti.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/cx20442.c48
-rw-r--r--sound/soc/omap/ams-delta.c8
2 files changed, 49 insertions, 7 deletions
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index ae55e31bfc72..d5fd00a64748 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -16,6 +16,7 @@
16#include <linux/tty.h> 16#include <linux/tty.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/regulator/consumer.h>
19 20
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/initval.h> 22#include <sound/initval.h>
@@ -25,8 +26,8 @@
25 26
26 27
27struct cx20442_priv { 28struct cx20442_priv {
28 enum snd_soc_control_type control_type;
29 void *control_data; 29 void *control_data;
30 struct regulator *por;
30}; 31};
31 32
32#define CX20442_PM 0x0 33#define CX20442_PM 0x0
@@ -324,6 +325,38 @@ static struct snd_soc_dai_driver cx20442_dai = {
324 }, 325 },
325}; 326};
326 327
328static int cx20442_set_bias_level(struct snd_soc_codec *codec,
329 enum snd_soc_bias_level level)
330{
331 struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
332 int err = 0;
333
334 switch (level) {
335 case SND_SOC_BIAS_PREPARE:
336 if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY)
337 break;
338 if (IS_ERR(cx20442->por))
339 err = PTR_ERR(cx20442->por);
340 else
341 err = regulator_enable(cx20442->por);
342 break;
343 case SND_SOC_BIAS_STANDBY:
344 if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE)
345 break;
346 if (IS_ERR(cx20442->por))
347 err = PTR_ERR(cx20442->por);
348 else
349 err = regulator_disable(cx20442->por);
350 break;
351 default:
352 break;
353 }
354 if (!err)
355 codec->dapm.bias_level = level;
356
357 return err;
358}
359
327static int cx20442_codec_probe(struct snd_soc_codec *codec) 360static int cx20442_codec_probe(struct snd_soc_codec *codec)
328{ 361{
329 struct cx20442_priv *cx20442; 362 struct cx20442_priv *cx20442;
@@ -331,9 +364,13 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
331 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL); 364 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
332 if (cx20442 == NULL) 365 if (cx20442 == NULL)
333 return -ENOMEM; 366 return -ENOMEM;
334 snd_soc_codec_set_drvdata(codec, cx20442);
335 367
368 cx20442->por = regulator_get(codec->dev, "POR");
369 if (IS_ERR(cx20442->por))
370 dev_warn(codec->dev, "failed to get the regulator");
336 cx20442->control_data = NULL; 371 cx20442->control_data = NULL;
372
373 snd_soc_codec_set_drvdata(codec, cx20442);
337 codec->hw_write = NULL; 374 codec->hw_write = NULL;
338 codec->card->pop_time = 0; 375 codec->card->pop_time = 0;
339 376
@@ -350,6 +387,12 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
350 tty_hangup(tty); 387 tty_hangup(tty);
351 } 388 }
352 389
390 if (!IS_ERR(cx20442->por)) {
391 /* should be already in STANDBY, hence disabled */
392 regulator_put(cx20442->por);
393 }
394
395 snd_soc_codec_set_drvdata(codec, NULL);
353 kfree(cx20442); 396 kfree(cx20442);
354 return 0; 397 return 0;
355} 398}
@@ -359,6 +402,7 @@ static const u8 cx20442_reg;
359static struct snd_soc_codec_driver cx20442_codec_dev = { 402static struct snd_soc_codec_driver cx20442_codec_dev = {
360 .probe = cx20442_codec_probe, 403 .probe = cx20442_codec_probe,
361 .remove = cx20442_codec_remove, 404 .remove = cx20442_codec_remove,
405 .set_bias_level = cx20442_set_bias_level,
362 .reg_cache_default = &cx20442_reg, 406 .reg_cache_default = &cx20442_reg,
363 .reg_cache_size = 1, 407 .reg_cache_size = 1,
364 .reg_word_size = sizeof(u8), 408 .reg_word_size = sizeof(u8),
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 3e523a7a9efb..a67f4370bc9f 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -431,22 +431,20 @@ static int ams_delta_set_bias_level(struct snd_soc_card *card,
431 struct snd_soc_dapm_context *dapm, 431 struct snd_soc_dapm_context *dapm,
432 enum snd_soc_bias_level level) 432 enum snd_soc_bias_level level)
433{ 433{
434 struct snd_soc_codec *codec = card->rtd->codec;
435
436 switch (level) { 434 switch (level) {
437 case SND_SOC_BIAS_ON: 435 case SND_SOC_BIAS_ON:
438 case SND_SOC_BIAS_PREPARE: 436 case SND_SOC_BIAS_PREPARE:
439 case SND_SOC_BIAS_STANDBY: 437 case SND_SOC_BIAS_STANDBY:
440 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) 438 if (card->dapm.bias_level == SND_SOC_BIAS_OFF)
441 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, 439 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
442 AMS_DELTA_LATCH2_MODEM_NRESET); 440 AMS_DELTA_LATCH2_MODEM_NRESET);
443 break; 441 break;
444 case SND_SOC_BIAS_OFF: 442 case SND_SOC_BIAS_OFF:
445 if (codec->dapm.bias_level != SND_SOC_BIAS_OFF) 443 if (card->dapm.bias_level != SND_SOC_BIAS_OFF)
446 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, 444 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
447 0); 445 0);
448 } 446 }
449 codec->dapm.bias_level = level; 447 card->dapm.bias_level = level;
450 448
451 return 0; 449 return 0;
452} 450}