aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-22 16:03:50 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-22 16:37:36 -0400
commitd7d5c5476a12333a33b7a14ebb10eccc729c01cb (patch)
tree6b1164624c6598a7c4102baf7c2d18a5cb751af4
parent4dbfe8097157fde1f8054f48f991ea45833852cd (diff)
ASoC: Actively manage the DC servo for WM8903
Save a little extra power by enabling the DC servo offset correction for the output channels only when the relevant channels are enabled. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/wm8903.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index de0a58507202..0bab5c6bd64a 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -392,14 +392,18 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
392 struct snd_soc_codec *codec = w->codec; 392 struct snd_soc_codec *codec = w->codec;
393 u16 val; 393 u16 val;
394 u16 reg; 394 u16 reg;
395 u16 dcs_reg;
396 u16 dcs_bit;
395 int shift; 397 int shift;
396 398
397 switch (w->reg) { 399 switch (w->reg) {
398 case WM8903_POWER_MANAGEMENT_2: 400 case WM8903_POWER_MANAGEMENT_2:
399 reg = WM8903_ANALOGUE_HP_0; 401 reg = WM8903_ANALOGUE_HP_0;
402 dcs_bit = 0 + w->shift;
400 break; 403 break;
401 case WM8903_POWER_MANAGEMENT_3: 404 case WM8903_POWER_MANAGEMENT_3:
402 reg = WM8903_ANALOGUE_LINEOUT_0; 405 reg = WM8903_ANALOGUE_LINEOUT_0;
406 dcs_bit = 2 + w->shift;
403 break; 407 break;
404 default: 408 default:
405 BUG(); 409 BUG();
@@ -439,6 +443,11 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
439 val |= (WM8903_OUTPUT_OUT << shift); 443 val |= (WM8903_OUTPUT_OUT << shift);
440 wm8903_write(codec, reg, val); 444 wm8903_write(codec, reg, val);
441 445
446 /* Enable the DC servo */
447 dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0);
448 dcs_reg |= dcs_bit;
449 wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg);
450
442 /* Remove the short */ 451 /* Remove the short */
443 val |= (WM8903_OUTPUT_SHORT << shift); 452 val |= (WM8903_OUTPUT_SHORT << shift);
444 wm8903_write(codec, reg, val); 453 wm8903_write(codec, reg, val);
@@ -451,6 +460,11 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
451 val &= ~(WM8903_OUTPUT_SHORT << shift); 460 val &= ~(WM8903_OUTPUT_SHORT << shift);
452 wm8903_write(codec, reg, val); 461 wm8903_write(codec, reg, val);
453 462
463 /* Disable the DC servo */
464 dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0);
465 dcs_reg &= ~dcs_bit;
466 wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg);
467
454 /* Then disable the intermediate and output stages */ 468 /* Then disable the intermediate and output stages */
455 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | 469 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
456 WM8903_OUTPUT_IN) << shift); 470 WM8903_OUTPUT_IN) << shift);