aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-07-30 06:18:52 -0400
committerMark Brown <broonie@linaro.org>2013-07-30 07:04:02 -0400
commit113591e477acb6b6dbc186ad2ee29a2502e68c33 (patch)
tree7c116f8ec3d3e8d82abd8181a8fb021b7eb82d57
parent5ae90d8e467e625e447000cb4335c4db973b1095 (diff)
ASoC: uda134x: fix codec driver by converting to DAPM
For some reason, the DAC/ADCs are not being powered up when I try and use the UDA1341 driver; this used to work. Looking back in the git history, I don't see anything obvious which would cause this regression. However, from dumping the register writes, it seems that the codec is powered down, and nothing calls set_bias_level to wake the codec up. Moreover, this driver hasn't had DAPM support added to it, which prevents platform drivers from taking advantage of DAPMs facilities. So, let's add DAPM support to the driver. As we move the power control for the DAC/ADC into DAPM, we no longer need it in set_bias_level() - this function just becomes a way to manipulate the power control and sync the register cache with the hardware at the appropriate point. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/codecs/uda134x.c88
1 files changed, 53 insertions, 35 deletions
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 6d0aa44c3757..c94d4c1e3dac 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -325,7 +325,6 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
325static int uda134x_set_bias_level(struct snd_soc_codec *codec, 325static int uda134x_set_bias_level(struct snd_soc_codec *codec,
326 enum snd_soc_bias_level level) 326 enum snd_soc_bias_level level)
327{ 327{
328 u8 reg;
329 struct uda134x_platform_data *pd = codec->control_data; 328 struct uda134x_platform_data *pd = codec->control_data;
330 int i; 329 int i;
331 u8 *cache = codec->reg_cache; 330 u8 *cache = codec->reg_cache;
@@ -334,23 +333,6 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
334 333
335 switch (level) { 334 switch (level) {
336 case SND_SOC_BIAS_ON: 335 case SND_SOC_BIAS_ON:
337 /* ADC, DAC on */
338 switch (pd->model) {
339 case UDA134X_UDA1340:
340 case UDA134X_UDA1344:
341 case UDA134X_UDA1345:
342 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
343 uda134x_write(codec, UDA134X_DATA011, reg | 0x03);
344 break;
345 case UDA134X_UDA1341:
346 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
347 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
348 break;
349 default:
350 printk(KERN_ERR "UDA134X SoC codec: "
351 "unsupported model %d\n", pd->model);
352 return -EINVAL;
353 }
354 break; 336 break;
355 case SND_SOC_BIAS_PREPARE: 337 case SND_SOC_BIAS_PREPARE:
356 /* power on */ 338 /* power on */
@@ -362,23 +344,6 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
362 } 344 }
363 break; 345 break;
364 case SND_SOC_BIAS_STANDBY: 346 case SND_SOC_BIAS_STANDBY:
365 /* ADC, DAC power off */
366 switch (pd->model) {
367 case UDA134X_UDA1340:
368 case UDA134X_UDA1344:
369 case UDA134X_UDA1345:
370 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
371 uda134x_write(codec, UDA134X_DATA011, reg & ~(0x03));
372 break;
373 case UDA134X_UDA1341:
374 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
375 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
376 break;
377 default:
378 printk(KERN_ERR "UDA134X SoC codec: "
379 "unsupported model %d\n", pd->model);
380 return -EINVAL;
381 }
382 break; 347 break;
383 case SND_SOC_BIAS_OFF: 348 case SND_SOC_BIAS_OFF:
384 /* power off */ 349 /* power off */
@@ -450,6 +415,37 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
450SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 415SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
451}; 416};
452 417
418/* UDA1341 has the DAC/ADC power down in STATUS1 */
419static const struct snd_soc_dapm_widget uda1341_dapm_widgets[] = {
420 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_STATUS1, 0, 0),
421 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_STATUS1, 1, 0),
422};
423
424/* UDA1340/4/5 has the DAC/ADC pwoer down in DATA0 11 */
425static const struct snd_soc_dapm_widget uda1340_dapm_widgets[] = {
426 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_DATA011, 0, 0),
427 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_DATA011, 1, 0),
428};
429
430/* Common DAPM widgets */
431static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = {
432 SND_SOC_DAPM_INPUT("VINL1"),
433 SND_SOC_DAPM_INPUT("VINR1"),
434 SND_SOC_DAPM_INPUT("VINL2"),
435 SND_SOC_DAPM_INPUT("VINR2"),
436 SND_SOC_DAPM_OUTPUT("VOUTL"),
437 SND_SOC_DAPM_OUTPUT("VOUTR"),
438};
439
440static const struct snd_soc_dapm_route uda134x_dapm_routes[] = {
441 { "ADC", NULL, "VINL1" },
442 { "ADC", NULL, "VINR1" },
443 { "ADC", NULL, "VINL2" },
444 { "ADC", NULL, "VINR2" },
445 { "VOUTL", NULL, "DAC" },
446 { "VOUTR", NULL, "DAC" },
447};
448
453static const struct snd_soc_dai_ops uda134x_dai_ops = { 449static const struct snd_soc_dai_ops uda134x_dai_ops = {
454 .startup = uda134x_startup, 450 .startup = uda134x_startup,
455 .shutdown = uda134x_shutdown, 451 .shutdown = uda134x_shutdown,
@@ -485,6 +481,8 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
485{ 481{
486 struct uda134x_priv *uda134x; 482 struct uda134x_priv *uda134x;
487 struct uda134x_platform_data *pd = codec->card->dev->platform_data; 483 struct uda134x_platform_data *pd = codec->card->dev->platform_data;
484 const struct snd_soc_dapm_widget *widgets;
485 unsigned num_widgets;
488 486
489 int ret; 487 int ret;
490 488
@@ -526,6 +524,22 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
526 else 524 else
527 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 525 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
528 526
527 if (pd->model == UDA134X_UDA1341) {
528 widgets = uda1341_dapm_widgets;
529 num_widgets = ARRAY_SIZE(uda1341_dapm_widgets);
530 } else {
531 widgets = uda1340_dapm_widgets;
532 num_widgets = ARRAY_SIZE(uda1340_dapm_widgets);
533 }
534
535 ret = snd_soc_dapm_new_controls(&codec->dapm, widgets, num_widgets);
536 if (ret) {
537 printk(KERN_ERR "%s failed to register dapm controls: %d",
538 __func__, ret);
539 kfree(uda134x);
540 return ret;
541 }
542
529 switch (pd->model) { 543 switch (pd->model) {
530 case UDA134X_UDA1340: 544 case UDA134X_UDA1340:
531 case UDA134X_UDA1344: 545 case UDA134X_UDA1344:
@@ -599,6 +613,10 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
599 .read = uda134x_read_reg_cache, 613 .read = uda134x_read_reg_cache,
600 .write = uda134x_write, 614 .write = uda134x_write,
601 .set_bias_level = uda134x_set_bias_level, 615 .set_bias_level = uda134x_set_bias_level,
616 .dapm_widgets = uda134x_dapm_widgets,
617 .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets),
618 .dapm_routes = uda134x_dapm_routes,
619 .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes),
602}; 620};
603 621
604static int uda134x_codec_probe(struct platform_device *pdev) 622static int uda134x_codec_probe(struct platform_device *pdev)