diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-04-22 16:03:50 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-04-22 16:37:36 -0400 |
commit | d7d5c5476a12333a33b7a14ebb10eccc729c01cb (patch) | |
tree | 6b1164624c6598a7c4102baf7c2d18a5cb751af4 | |
parent | 4dbfe8097157fde1f8054f48f991ea45833852cd (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.c | 14 |
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); |