diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-02-09 12:42:55 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-02-09 17:49:52 -0500 |
commit | 13a9983eb197254dffd9ea63a2d5f12c54eb651c (patch) | |
tree | 7a3461070e40c1bff37cfe798eccc27a121f54b3 /sound | |
parent | 1e113bf9e088f1a6f4a1cdadce598ccc340f8fc1 (diff) |
ASoC: Convert WM8903 to use PGA_S for output stage enables
This simplfies the code and slightly reduces the startup time.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/wm8903.c | 180 |
1 files changed, 60 insertions, 120 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 0190c5aa44f8..9793775d5798 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -246,6 +246,8 @@ static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int re | |||
246 | case WM8903_REVISION_NUMBER: | 246 | case WM8903_REVISION_NUMBER: |
247 | case WM8903_INTERRUPT_STATUS_1: | 247 | case WM8903_INTERRUPT_STATUS_1: |
248 | case WM8903_WRITE_SEQUENCER_4: | 248 | case WM8903_WRITE_SEQUENCER_4: |
249 | case WM8903_POWER_MANAGEMENT_3: | ||
250 | case WM8903_POWER_MANAGEMENT_2: | ||
249 | return 1; | 251 | return 1; |
250 | 252 | ||
251 | default: | 253 | default: |
@@ -304,11 +306,6 @@ static void wm8903_reset(struct snd_soc_codec *codec) | |||
304 | sizeof(wm8903_reg_defaults)); | 306 | sizeof(wm8903_reg_defaults)); |
305 | } | 307 | } |
306 | 308 | ||
307 | #define WM8903_OUTPUT_SHORT 0x8 | ||
308 | #define WM8903_OUTPUT_OUT 0x4 | ||
309 | #define WM8903_OUTPUT_INT 0x2 | ||
310 | #define WM8903_OUTPUT_IN 0x1 | ||
311 | |||
312 | static int wm8903_cp_event(struct snd_soc_dapm_widget *w, | 309 | static int wm8903_cp_event(struct snd_soc_dapm_widget *w, |
313 | struct snd_kcontrol *kcontrol, int event) | 310 | struct snd_kcontrol *kcontrol, int event) |
314 | { | 311 | { |
@@ -319,99 +316,6 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w, | |||
319 | } | 316 | } |
320 | 317 | ||
321 | /* | 318 | /* |
322 | * Event for headphone and line out amplifier power changes. Special | ||
323 | * power up/down sequences are required in order to maximise pop/click | ||
324 | * performance. | ||
325 | */ | ||
326 | static int wm8903_output_event(struct snd_soc_dapm_widget *w, | ||
327 | struct snd_kcontrol *kcontrol, int event) | ||
328 | { | ||
329 | struct snd_soc_codec *codec = w->codec; | ||
330 | u16 val; | ||
331 | u16 reg; | ||
332 | u16 dcs_reg; | ||
333 | u16 dcs_bit; | ||
334 | int shift; | ||
335 | |||
336 | switch (w->reg) { | ||
337 | case WM8903_POWER_MANAGEMENT_2: | ||
338 | reg = WM8903_ANALOGUE_HP_0; | ||
339 | dcs_bit = 0 + w->shift; | ||
340 | break; | ||
341 | case WM8903_POWER_MANAGEMENT_3: | ||
342 | reg = WM8903_ANALOGUE_LINEOUT_0; | ||
343 | dcs_bit = 2 + w->shift; | ||
344 | break; | ||
345 | default: | ||
346 | BUG(); | ||
347 | return -EINVAL; /* Spurious warning from some compilers */ | ||
348 | } | ||
349 | |||
350 | switch (w->shift) { | ||
351 | case 0: | ||
352 | shift = 0; | ||
353 | break; | ||
354 | case 1: | ||
355 | shift = 4; | ||
356 | break; | ||
357 | default: | ||
358 | BUG(); | ||
359 | return -EINVAL; /* Spurious warning from some compilers */ | ||
360 | } | ||
361 | |||
362 | if (event & SND_SOC_DAPM_PRE_PMU) { | ||
363 | val = snd_soc_read(codec, reg); | ||
364 | |||
365 | /* Short the output */ | ||
366 | val &= ~(WM8903_OUTPUT_SHORT << shift); | ||
367 | snd_soc_write(codec, reg, val); | ||
368 | } | ||
369 | |||
370 | if (event & SND_SOC_DAPM_POST_PMU) { | ||
371 | val = snd_soc_read(codec, reg); | ||
372 | |||
373 | val |= (WM8903_OUTPUT_IN << shift); | ||
374 | snd_soc_write(codec, reg, val); | ||
375 | |||
376 | val |= (WM8903_OUTPUT_INT << shift); | ||
377 | snd_soc_write(codec, reg, val); | ||
378 | |||
379 | /* Turn on the output ENA_OUTP */ | ||
380 | val |= (WM8903_OUTPUT_OUT << shift); | ||
381 | snd_soc_write(codec, reg, val); | ||
382 | |||
383 | /* Enable the DC servo */ | ||
384 | dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); | ||
385 | dcs_reg |= dcs_bit; | ||
386 | snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg); | ||
387 | |||
388 | /* Remove the short */ | ||
389 | val |= (WM8903_OUTPUT_SHORT << shift); | ||
390 | snd_soc_write(codec, reg, val); | ||
391 | } | ||
392 | |||
393 | if (event & SND_SOC_DAPM_PRE_PMD) { | ||
394 | val = snd_soc_read(codec, reg); | ||
395 | |||
396 | /* Short the output */ | ||
397 | val &= ~(WM8903_OUTPUT_SHORT << shift); | ||
398 | snd_soc_write(codec, reg, val); | ||
399 | |||
400 | /* Disable the DC servo */ | ||
401 | dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); | ||
402 | dcs_reg &= ~dcs_bit; | ||
403 | snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg); | ||
404 | |||
405 | /* Then disable the intermediate and output stages */ | ||
406 | val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | | ||
407 | WM8903_OUTPUT_IN) << shift); | ||
408 | snd_soc_write(codec, reg, val); | ||
409 | } | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * When used with DAC outputs only the WM8903 charge pump supports | 319 | * When used with DAC outputs only the WM8903 charge pump supports |
416 | * operation in class W mode, providing very low power consumption | 320 | * operation in class W mode, providing very low power consumption |
417 | * when used with digital sources. Enable and disable this mode | 321 | * when used with digital sources. Enable and disable this mode |
@@ -913,23 +817,40 @@ SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0, | |||
913 | SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, | 817 | SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, |
914 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), | 818 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), |
915 | 819 | ||
916 | SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, | 820 | SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0, |
917 | 1, 0, NULL, 0, wm8903_output_event, | 821 | 4, 0, NULL, 0), |
918 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 822 | SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0, |
919 | SND_SOC_DAPM_PRE_PMD), | 823 | 0, 0, NULL, 0), |
920 | SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, | 824 | |
921 | 0, 0, NULL, 0, wm8903_output_event, | 825 | SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 4, 0, |
922 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 826 | NULL, 0), |
923 | SND_SOC_DAPM_PRE_PMD), | 827 | SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 0, 0, |
924 | 828 | NULL, 0), | |
925 | SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, | 829 | |
926 | NULL, 0, wm8903_output_event, | 830 | SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0), |
927 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 831 | SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0), |
928 | SND_SOC_DAPM_PRE_PMD), | 832 | SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0), |
929 | SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, | 833 | SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0), |
930 | NULL, 0, wm8903_output_event, | 834 | SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0), |
931 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 835 | SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0), |
932 | SND_SOC_DAPM_PRE_PMD), | 836 | |
837 | SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0, | ||
838 | NULL, 0), | ||
839 | SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0, | ||
840 | NULL, 0), | ||
841 | SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 5, 0, | ||
842 | NULL, 0), | ||
843 | SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0, | ||
844 | NULL, 0), | ||
845 | SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0, | ||
846 | NULL, 0), | ||
847 | SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 1, 0, | ||
848 | NULL, 0), | ||
849 | |||
850 | SND_SOC_DAPM_PGA_S("HPL_DCS", 3, WM8903_DC_SERVO_0, 3, 0, NULL, 0), | ||
851 | SND_SOC_DAPM_PGA_S("HPR_DCS", 3, WM8903_DC_SERVO_0, 2, 0, NULL, 0), | ||
852 | SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, WM8903_DC_SERVO_0, 1, 0, NULL, 0), | ||
853 | SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, WM8903_DC_SERVO_0, 0, 0, NULL, 0), | ||
933 | 854 | ||
934 | SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, | 855 | SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, |
935 | NULL, 0), | 856 | NULL, 0), |
@@ -1045,11 +966,30 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1045 | { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, | 966 | { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, |
1046 | { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, | 967 | { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, |
1047 | 968 | ||
1048 | { "HPOUTL", NULL, "Left Headphone Output PGA" }, | 969 | { "HPL_ENA_DLY", NULL, "Left Headphone Output PGA" }, |
1049 | { "HPOUTR", NULL, "Right Headphone Output PGA" }, | 970 | { "HPR_ENA_DLY", NULL, "Right Headphone Output PGA" }, |
1050 | 971 | { "LINEOUTL_ENA_DLY", NULL, "Left Line Output PGA" }, | |
1051 | { "LINEOUTL", NULL, "Left Line Output PGA" }, | 972 | { "LINEOUTR_ENA_DLY", NULL, "Right Line Output PGA" }, |
1052 | { "LINEOUTR", NULL, "Right Line Output PGA" }, | 973 | |
974 | { "HPL_DCS", NULL, "HPL_ENA_DLY" }, | ||
975 | { "HPR_DCS", NULL, "HPR_ENA_DLY" }, | ||
976 | { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" }, | ||
977 | { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" }, | ||
978 | |||
979 | { "HPL_ENA_OUTP", NULL, "HPL_DCS" }, | ||
980 | { "HPR_ENA_OUTP", NULL, "HPR_DCS" }, | ||
981 | { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" }, | ||
982 | { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" }, | ||
983 | |||
984 | { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" }, | ||
985 | { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" }, | ||
986 | { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" }, | ||
987 | { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" }, | ||
988 | |||
989 | { "HPOUTL", NULL, "HPL_RMV_SHORT" }, | ||
990 | { "HPOUTR", NULL, "HPR_RMV_SHORT" }, | ||
991 | { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" }, | ||
992 | { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" }, | ||
1053 | 993 | ||
1054 | { "LOP", NULL, "Left Speaker PGA" }, | 994 | { "LOP", NULL, "Left Speaker PGA" }, |
1055 | { "LON", NULL, "Left Speaker PGA" }, | 995 | { "LON", NULL, "Left Speaker PGA" }, |