ASoC: wm9081: Use snd_soc_update_bits for read-modify-write
Subsystems (3)
PATCH RESEND v2 1/1 ASoC: wm9081: Use snd_soc_update_bits for read-modify-write
Use snd_soc_update_bits for read-modify-write register access instead of open-coding it using snd_soc_read and snd_soc_write
---
RESEND:
I just found I doesn't set my mail client properly to show correct sender, so here is a resend.
v2:
For Initial cold start ( change bias level from SND_SOC_BIAS_OFF to SND_SOC_BIAS_STANDBY ), the v1 does not set VMID_SEL[1:0] bits correctly for Normal bias enable & soft start off.
In v2 we also clear VMID_SEL[1:0] bits for Normal bias enable & soft start off. We did clear VMID_SEL[1:0] bits in SND_SOC_BIAS_OFF,
thus we know the VMID_SEL[1:0] bits status is 0b00 in this case.
sound/soc/codecs/wm9081.c | 82 +++++++++++++++++++------------------------- 1 files changed, 35 insertions(+), 47 deletions(-)
sound/soc/codecs/wm9081.c +35 -47
@@ -766,84 +766,73 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = {static int wm9081_set_bias_level (struct snd_soc_codec *codec,enum snd_soc_bias_level level) { -u16 reg; -switch (level) {case SND_SOC_BIAS_ON :break ;case SND_SOC_BIAS_PREPARE :/* VMID=2*40k */ - reg =snd_soc_read (codec,WM9081_VMID_CONTROL ); - reg &= ~WM9081_VMID_SEL_MASK ; - reg |=0x2 ; -snd_soc_write (codec,WM9081_VMID_CONTROL , reg); +snd_soc_update_bits (codec,WM9081_VMID_CONTROL , +WM9081_VMID_SEL_MASK ,0x2 );/* Normal bias current */ - reg =snd_soc_read (codec,WM9081_BIAS_CONTROL_1 ); - reg &= ~WM9081_STBY_BIAS_ENA ; -snd_soc_write (codec,WM9081_BIAS_CONTROL_1 , reg); +snd_soc_update_bits (codec,WM9081_BIAS_CONTROL_1 , +WM9081_STBY_BIAS_ENA ,0 );break ;case SND_SOC_BIAS_STANDBY :/* Initial cold start */ if (codec->dapm.bias_level ==SND_SOC_BIAS_OFF ) {/* Disable LINEOUT discharge */ - reg =snd_soc_read (codec,WM9081_ANTI_POP_CONTROL ); - reg &= ~WM9081_LINEOUT_DISCH ; -snd_soc_write (codec,WM9081_ANTI_POP_CONTROL , reg); +snd_soc_update_bits (codec,WM9081_ANTI_POP_CONTROL , +WM9081_LINEOUT_DISCH ,0 );/* Select startup bias source */ - reg =snd_soc_read (codec,WM9081_BIAS_CONTROL_1 ); - reg |=WM9081_BIAS_SRC |WM9081_BIAS_ENA ; -snd_soc_write (codec,WM9081_BIAS_CONTROL_1 , reg); +snd_soc_update_bits (codec,WM9081_BIAS_CONTROL_1 , +WM9081_BIAS_SRC |WM9081_BIAS_ENA , +WM9081_BIAS_SRC |WM9081_BIAS_ENA );/* VMID 2*4k; Soft VMID ramp enable */ - reg =snd_soc_read (codec,WM9081_VMID_CONTROL ); - reg |=WM9081_VMID_RAMP |0x6 ; -snd_soc_write (codec,WM9081_VMID_CONTROL , reg); - +snd_soc_update_bits (codec,WM9081_VMID_CONTROL , +WM9081_VMID_RAMP |0x6 , +WM9081_VMID_RAMP |0x6 );mdelay (100 );/* Normal bias enable & soft start off */ - reg |=WM9081_BIAS_ENA ; - reg &= ~WM9081_VMID_RAMP ; -snd_soc_write (codec,WM9081_VMID_CONTROL , reg); +snd_soc_update_bits (codec,WM9081_VMID_CONTROL , +WM9081_VMID_RAMP |WM9081_BIAS_ENA | +WM9081_VMID_SEL_MASK , +WM9081_BIAS_ENA );/* Standard bias source */ - reg =snd_soc_read (codec,WM9081_BIAS_CONTROL_1 ); - reg &= ~WM9081_BIAS_SRC ; -snd_soc_write (codec,WM9081_BIAS_CONTROL_1 , reg); +snd_soc_update_bits (codec,WM9081_BIAS_CONTROL_1 , +WM9081_BIAS_SRC ,0 ); }/* VMID 2*240k */ - reg =snd_soc_read (codec,WM9081_BIAS_CONTROL_1 ); - reg &= ~WM9081_VMID_SEL_MASK ; - reg |=0x04 ; -snd_soc_write (codec,WM9081_VMID_CONTROL , reg); +snd_soc_update_bits (codec,WM9081_BIAS_CONTROL_1 , +WM9081_VMID_SEL_MASK ,0x04 );/* Standby bias current on */ - reg =snd_soc_read (codec,WM9081_BIAS_CONTROL_1 ); - reg |=WM9081_STBY_BIAS_ENA ; -snd_soc_write (codec,WM9081_BIAS_CONTROL_1 , reg); +snd_soc_update_bits (codec,WM9081_BIAS_CONTROL_1 , +WM9081_STBY_BIAS_ENA , +WM9081_STBY_BIAS_ENA );break ;case SND_SOC_BIAS_OFF :/* Startup bias source */ - reg =snd_soc_read (codec,WM9081_BIAS_CONTROL_1 ); - reg |=WM9081_BIAS_SRC ; -snd_soc_write (codec,WM9081_BIAS_CONTROL_1 , reg); +snd_soc_update_bits (codec,WM9081_BIAS_CONTROL_1 , +WM9081_BIAS_SRC ,WM9081_BIAS_SRC );/* Disable VMID and biases with soft ramping */ - reg =snd_soc_read (codec,WM9081_VMID_CONTROL ); - reg &= ~(WM9081_VMID_SEL_MASK |WM9081_BIAS_ENA ); - reg |=WM9081_VMID_RAMP ; -snd_soc_write (codec,WM9081_VMID_CONTROL , reg); +snd_soc_update_bits (codec,WM9081_VMID_CONTROL , +WM9081_VMID_RAMP |WM9081_VMID_SEL_MASK | +WM9081_BIAS_ENA ,WM9081_VMID_RAMP );/* Actively discharge LINEOUT */ - reg =snd_soc_read (codec,WM9081_ANTI_POP_CONTROL ); - reg |=WM9081_LINEOUT_DISCH ; -snd_soc_write (codec,WM9081_ANTI_POP_CONTROL , reg); +snd_soc_update_bits (codec,WM9081_ANTI_POP_CONTROL , +WM9081_LINEOUT_DISCH , +WM9081_LINEOUT_DISCH );break ; }
@@ -1242,11 +1231,10 @@ static int wm9081_probe(struct snd_soc_codec *codec)wm9081_set_bias_level (codec,SND_SOC_BIAS_STANDBY );/* Enable zero cross by default */ - reg =snd_soc_read (codec,WM9081_ANALOGUE_LINEOUT ); -snd_soc_write (codec,WM9081_ANALOGUE_LINEOUT , reg |WM9081_LINEOUTZC ); - reg =snd_soc_read (codec,WM9081_ANALOGUE_SPEAKER_PGA ); -snd_soc_write (codec,WM9081_ANALOGUE_SPEAKER_PGA , - reg |WM9081_SPKPGAZC ); +snd_soc_update_bits (codec,WM9081_ANALOGUE_LINEOUT , +WM9081_LINEOUTZC ,WM9081_LINEOUTZC ); +snd_soc_update_bits (codec,WM9081_ANALOGUE_SPEAKER_PGA , +WM9081_SPKPGAZC ,WM9081_SPKPGAZC );snd_soc_add_controls (codec, wm9081_snd_controls,ARRAY_SIZE (wm9081_snd_controls));
Signature · 1 line
1.7.5.4
Quoted 9 lines · Axel Lin
Use
snd_soc_update_bitsfor read-modify-write register access instead of open-coding it usingsnd_soc_readandsnd_soc_writeSigned-off-by Axel Lin <[email protected]>---
RESEND:
I just found I doesn't set my mail client properly to show correct sender, so here is a resend.
Quoted 8 lines
v2:
For Initial cold start ( change bias level fromSND_SOC_BIAS_OFFtoSND_SOC_BIAS_STANDBY), the v1 does not set VMID_SEL[1:0] bits correctly for Normal bias enable & soft start off.
In v2 we also clear VMID_SEL[1:0] bits for Normal bias enable & soft start off. We did clear VMID_SEL[1:0] bits inSND_SOC_BIAS_OFF,
thus we know the VMID_SEL[1:0] bits status is 0b00 in this case.
The mechanics look OK, but best for Mark to check with the hardware.
Quoted 145 lines
sound/soc/codecs/wm9081.c | 82 +++++++++++++++++++-------------------------
1 files changed, 35 insertions(+), 47 deletions(-)sound/soc/codecs/wm9081.c +0
-2@@ -766,84 +766,73 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { static int wm9081_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg; - switch (level) {case
SND_SOC_BIAS_ON:
break;case
SND_SOC_BIAS_PREPARE:
/* VMID=2*40k */
- reg =snd_soc_read(codec, WM9081_VMID_CONTROL);
- reg &= ~WM9081_VMID_SEL_MASK;
- reg |=0x2;
-snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec,WM9081_VMID_CONTROL,
+WM9081_VMID_SEL_MASK,0x2);/* Normal bias current */
- reg =snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg &= ~WM9081_STBY_BIAS_ENA;
-snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec,WM9081_BIAS_CONTROL_1,
+WM9081_STBY_BIAS_ENA, 0); break;case
SND_SOC_BIAS_STANDBY:
/* Initial cold start */
if (codec->dapm.bias_level==SND_SOC_BIAS_OFF) { /* Disable LINEOUT discharge */
- reg =snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
- reg &= ~WM9081_LINEOUT_DISCH;
-snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
+ snd_soc_update_bits(codec,WM9081_ANTI_POP_CONTROL,
+WM9081_LINEOUT_DISCH, 0);/* Select startup bias source */
- reg =snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg |=WM9081_BIAS_SRC|WM9081_BIAS_ENA;
-snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec,WM9081_BIAS_CONTROL_1,
+WM9081_BIAS_SRC|WM9081_BIAS_ENA,
+WM9081_BIAS_SRC|WM9081_BIAS_ENA);/* VMID 2*4k; Soft VMID ramp enable */
- reg =snd_soc_read(codec, WM9081_VMID_CONTROL);
- reg |=WM9081_VMID_RAMP|0x6;
-snd_soc_write(codec, WM9081_VMID_CONTROL, reg); -
+ snd_soc_update_bits(codec,WM9081_VMID_CONTROL,
+WM9081_VMID_RAMP|0x6,
+WM9081_VMID_RAMP|0x6); mdelay(100);/* Normal bias enable & soft start off */
- reg |=WM9081_BIAS_ENA;
- reg &= ~WM9081_VMID_RAMP;
-snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec,WM9081_VMID_CONTROL,
+WM9081_VMID_RAMP|WM9081_BIAS_ENA|
+WM9081_VMID_SEL_MASK,
+WM9081_BIAS_ENA);/* Standard bias source */
- reg =snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg &= ~WM9081_BIAS_SRC;
-snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec,WM9081_BIAS_CONTROL_1,
+WM9081_BIAS_SRC, 0); }/* VMID 2*240k */
- reg =snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg &= ~WM9081_VMID_SEL_MASK;
- reg |=0x04;
-snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec,WM9081_BIAS_CONTROL_1,
+WM9081_VMID_SEL_MASK,0x04);/* Standby bias current on */
- reg =snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg |=WM9081_STBY_BIAS_ENA;
-snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec,WM9081_BIAS_CONTROL_1,
+WM9081_STBY_BIAS_ENA,
+WM9081_STBY_BIAS_ENA); break;case
SND_SOC_BIAS_OFF:
/* Startup bias source */
- reg =snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
- reg |=WM9081_BIAS_SRC;
-snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+ snd_soc_update_bits(codec,WM9081_BIAS_CONTROL_1,
+WM9081_BIAS_SRC,WM9081_BIAS_SRC);/* Disable VMID and biases with soft ramping */
- reg =snd_soc_read(codec, WM9081_VMID_CONTROL);
- reg &= ~(WM9081_VMID_SEL_MASK |WM9081_BIAS_ENA);
- reg |=WM9081_VMID_RAMP;
-snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec,WM9081_VMID_CONTROL,
+WM9081_VMID_RAMP|WM9081_VMID_SEL_MASK|
+WM9081_BIAS_ENA,WM9081_VMID_RAMP);/* Actively discharge LINEOUT */
- reg =snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
- reg |=WM9081_LINEOUT_DISCH;
-snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
+ snd_soc_update_bits(codec,WM9081_ANTI_POP_CONTROL,
+WM9081_LINEOUT_DISCH,
+WM9081_LINEOUT_DISCH); break;
}sound/soc/codecs/wm9081.c +4
-6@@ -1242,11 +1231,10 @@ static int wm9081_probe(struct snd_soc_codec *codec) wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* Enable zero cross by default */ - reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT); - snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC); - reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA); - snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, - reg | WM9081_SPKPGAZC); + snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, + WM9081_LINEOUTZC, WM9081_LINEOUTZC); + snd_soc_update_bits(codec, WM9081_ANALOGUE_SPEAKER_PGA, + WM9081_SPKPGAZC, WM9081_SPKPGAZC); snd_soc_add_controls(codec, wm9081_snd_controls, ARRAY_SIZE(wm9081_snd_controls)); --1.7.5.4
sound/soc/codecs/wm9081.c static const struct snd_soc_dapm_route wm9081_audio_paths[] = { · line 805
Quoted 8 lines · Axel Lin
sound/soc/codecs/wm9081.c +4
-3/* Normal bias enable & soft start off */ - reg |=WM9081_BIAS_ENA ; - reg &= ~WM9081_VMID_RAMP ; -snd_soc_write (codec,WM9081_VMID_CONTROL , reg); +snd_soc_update_bits (codec,WM9081_VMID_CONTROL , +WM9081_VMID_RAMP |WM9081_BIAS_ENA | +WM9081_VMID_SEL_MASK , +WM9081_BIAS_ENA );
This looks (and sounds) wrong - the original code didn't touch VMID_SEL_MASK for this update but the new version will clear VMID_SEL_MASK. Even with that fixed there still seems to be some issue here, though.
2011/11/5 Mark Brown <[email protected]>:
Quoted 11 lines · Axel Lin
Quoted 9 lines
/* Normal bias enable & soft start off */
- reg |=WM9081_BIAS_ENA;
- reg &= ~WM9081_VMID_RAMP;
-snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+ snd_soc_update_bits(codec,WM9081_VMID_CONTROL,
+WM9081_VMID_RAMP|WM9081_BIAS_ENA|
+WM9081_VMID_SEL_MASK,
+WM9081_BIAS_ENA);
Quoted 5 lines
This looks (and sounds) wrong - the original code didn't touch
VMID_SEL_MASKfor this update but the new version will clearVMID_SEL_MASK. Even with that fixed there still seems to be some issue here, though.
Hi Mark,
I just re-check current code, and I think current code (before converting to snd_soc_update_bits) is broken.
See below 2 patches: ( I'm sending the patch now)
ASoC: wm9081: Fix reading wrong register for setting VMID 2*240k
ASoC: wm9081: Don't write WM9081_BIAS_ENA bit to WM9081_VMID_CONTROL register
Would you mind to test if above 2 patches works.
If it works, I'll send a new patch to use snd_soc_update_bits for read-modify-write.
Thanks,
Axel