aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-17 07:51:33 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-17 10:09:02 -0400
commitdd76769dd53bdb804a4b02a3eb256f4740f78720 (patch)
tree060763d87cb6acb6e3c9660f6afefaeedabe3441
parenta6c65736bc2e63392334bd800f1b2754ab55db1e (diff)
ASoC: Refresh WM8750 bias management
The WM8750 is using some delayed work to manage the ramping of the bias at startup and resume out of line from the normal flow. This predates the support within ASoC core for moving the resume out of line from the main system resume which provides equivalent functionality with better interaction with applications. Change to doing the ramp in line to make use of the core functionality. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/wm8750.c50
1 files changed, 9 insertions, 41 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index c0c487501248..ee084083a49d 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -611,10 +611,16 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
611 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 611 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
612 break; 612 break;
613 case SND_SOC_BIAS_PREPARE: 613 case SND_SOC_BIAS_PREPARE:
614 /* set vmid to 5k for quick power up */
615 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
616 break; 614 break;
617 case SND_SOC_BIAS_STANDBY: 615 case SND_SOC_BIAS_STANDBY:
616 if (codec->bias_level == SND_SOC_BIAS_OFF) {
617 /* Set VMID to 5k */
618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
619
620 /* ...and ramp */
621 msleep(1000);
622 }
623
618 /* mute dac and set vmid to 500k, enable VREF */ 624 /* mute dac and set vmid to 500k, enable VREF */
619 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 625 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
620 break; 626 break;
@@ -658,13 +664,6 @@ struct snd_soc_dai wm8750_dai = {
658}; 664};
659EXPORT_SYMBOL_GPL(wm8750_dai); 665EXPORT_SYMBOL_GPL(wm8750_dai);
660 666
661static void wm8750_work(struct work_struct *work)
662{
663 struct snd_soc_codec *codec =
664 container_of(work, struct snd_soc_codec, delayed_work.work);
665 wm8750_set_bias_level(codec, codec->bias_level);
666}
667
668static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 667static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
669{ 668{
670 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 669 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -693,14 +692,6 @@ static int wm8750_resume(struct platform_device *pdev)
693 692
694 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 693 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
695 694
696 /* charge wm8750 caps */
697 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
698 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
699 codec->bias_level = SND_SOC_BIAS_ON;
700 schedule_delayed_work(&codec->delayed_work,
701 msecs_to_jiffies(1000));
702 }
703
704 return 0; 695 return 0;
705} 696}
706 697
@@ -744,9 +735,7 @@ static int wm8750_init(struct snd_soc_device *socdev,
744 } 735 }
745 736
746 /* charge output caps */ 737 /* charge output caps */
747 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 738 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
748 codec->bias_level = SND_SOC_BIAS_STANDBY;
749 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
750 739
751 /* set the update bits */ 740 /* set the update bits */
752 reg = snd_soc_read(codec, WM8750_LDAC); 741 reg = snd_soc_read(codec, WM8750_LDAC);
@@ -926,7 +915,6 @@ static int wm8750_probe(struct platform_device *pdev)
926 INIT_LIST_HEAD(&codec->dapm_widgets); 915 INIT_LIST_HEAD(&codec->dapm_widgets);
927 INIT_LIST_HEAD(&codec->dapm_paths); 916 INIT_LIST_HEAD(&codec->dapm_paths);
928 wm8750_socdev = socdev; 917 wm8750_socdev = socdev;
929 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
930 918
931 ret = -ENODEV; 919 ret = -ENODEV;
932 920
@@ -950,25 +938,6 @@ static int wm8750_probe(struct platform_device *pdev)
950 return ret; 938 return ret;
951} 939}
952 940
953/*
954 * This function forces any delayed work to be queued and run.
955 */
956static int run_delayed_work(struct delayed_work *dwork)
957{
958 int ret;
959
960 /* cancel any work waiting to be queued. */
961 ret = cancel_delayed_work(dwork);
962
963 /* if there was any work waiting then we run it now and
964 * wait for it's completion */
965 if (ret) {
966 schedule_delayed_work(dwork, 0);
967 flush_scheduled_work();
968 }
969 return ret;
970}
971
972/* power down chip */ 941/* power down chip */
973static int wm8750_remove(struct platform_device *pdev) 942static int wm8750_remove(struct platform_device *pdev)
974{ 943{
@@ -977,7 +946,6 @@ static int wm8750_remove(struct platform_device *pdev)
977 946
978 if (codec->control_data) 947 if (codec->control_data)
979 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 948 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
980 run_delayed_work(&codec->delayed_work);
981 snd_soc_free_pcms(socdev); 949 snd_soc_free_pcms(socdev);
982 snd_soc_dapm_free(socdev); 950 snd_soc_dapm_free(socdev);
983#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 951#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)