All of lore.kernel.org
 help / color / mirror / Atom feed
* wm8904 and output volume control
@ 2022-12-16 23:47 Emanuele Ghidoli
  2022-12-19  9:58 ` Charles Keepax
  0 siblings, 1 reply; 8+ messages in thread
From: Emanuele Ghidoli @ 2022-12-16 23:47 UTC (permalink / raw)
  To: alsa-devel
  Cc: Charles Keepax, Takashi Iwai, Liam Girdwood, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

Hello,
I have found that output volume is set to the default value after a 
limited time (~4 seconds) after play stop.
I have analyzed what is happening:
- at first play the volume is the expected one
- After stopping playing + ~4 seconds wm8904_set_bias_level (..., 
SND_SOC_BIAS_OFF) is called
- Chip is reset and regulator is switched off if "possible" (not in our 
case, it is important to note)
- at second play wm8904_set_bias_level (..., SND_SOC_BIAS_STANDBY) is 
called. wm8904_hw_params is also called just before.

I see that all I2C transactions are good, registers are written as 
expected, especially volume control register (even the silly HPOUT_VU 
bit, to do a volume update is correctly written).
Reading out this register, using i2cget (bypassing regcache), report the 
"expected" value. But the real output volume correspond to the default 
value (hw default, that it is the same value in wm8904_reg_defaults 
structure).

I checked that SYSCLK_ENA is 0 during register writing (needed if 
MCLK/SYSCLK is not present). I do not know if there is some other 
constrain on these registers.

If I rewrite the volume control register, a second time, the volume is 
set (tested with i2cset, from user space. And from kernel space, 
bypassing regcache).

I resolve also by reverting e9149b8c00d2 ("ASoC: wm8904: fix regcache 
handling").
I'm not here to say that the commit is wrong. I analyzed it and seem 
perfect (in few words it align the hw with the regcache avoiding 
potential incoherence).

I'm trying to compare first play and second play register programming 
sequence. They are similar but not the same. But on the first play the 
volume output is good.

Do someone remember something similar fixed on another codec?
Any idea is appreciated.
Thank you.
Best regards,


Emanuele Ghidoli

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: wm8904 and output volume control
  2022-12-16 23:47 wm8904 and output volume control Emanuele Ghidoli
@ 2022-12-19  9:58 ` Charles Keepax
  2022-12-19 15:20   ` Emanuele Ghidoli
  0 siblings, 1 reply; 8+ messages in thread
From: Charles Keepax @ 2022-12-19  9:58 UTC (permalink / raw)
  To: Emanuele Ghidoli
  Cc: alsa-devel, Liam Girdwood, Takashi Iwai, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

On Sat, Dec 17, 2022 at 12:47:14AM +0100, Emanuele Ghidoli wrote:
> Hello,
> I have found that output volume is set to the default value after a
> limited time (~4 seconds) after play stop.
> I have analyzed what is happening:
> - at first play the volume is the expected one
> - After stopping playing + ~4 seconds wm8904_set_bias_level (...,
> SND_SOC_BIAS_OFF) is called
> - Chip is reset and regulator is switched off if "possible" (not in
> our case, it is important to note)
> - at second play wm8904_set_bias_level (..., SND_SOC_BIAS_STANDBY)
> is called. wm8904_hw_params is also called just before.
> 
> I see that all I2C transactions are good, registers are written as
> expected, especially volume control register (even the silly
> HPOUT_VU bit, to do a volume update is correctly written).
> Reading out this register, using i2cget (bypassing regcache), report
> the "expected" value. But the real output volume correspond to the
> default value (hw default, that it is the same value in
> wm8904_reg_defaults structure).
> 
> I checked that SYSCLK_ENA is 0 during register writing (needed if
> MCLK/SYSCLK is not present). I do not know if there is some other
> constrain on these registers.
> 

Yes this might be my guess as well, I wonder if the HPOUT_VU bit
needs SYSCLK to be present to take effect.

> If I rewrite the volume control register, a second time, the volume
> is set (tested with i2cset, from user space. And from kernel space,
> bypassing regcache).
> 

When you write the value the second time is that still before
SYSCLK is present?

Also does just writing one of HPOUT volumes cause the other to
get updated? The HPOUT_VU bit should trigger an update to both.

> I resolve also by reverting e9149b8c00d2 ("ASoC: wm8904: fix
> regcache handling").
> I'm not here to say that the commit is wrong. I analyzed it and seem
> perfect (in few words it align the hw with the regcache avoiding
> potential incoherence).
> 

Yeah I think that commit is fine, I would wager that your system
doesn't turn off the regulators so without that commit the
register retains the old volume across the "power down".

Thanks,
Charles

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: wm8904 and output volume control
  2022-12-19  9:58 ` Charles Keepax
@ 2022-12-19 15:20   ` Emanuele Ghidoli
  2022-12-20 10:00     ` Charles Keepax
  0 siblings, 1 reply; 8+ messages in thread
From: Emanuele Ghidoli @ 2022-12-19 15:20 UTC (permalink / raw)
  To: Charles Keepax, Emanuele Ghidoli
  Cc: alsa-devel, Liam Girdwood, Takashi Iwai, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

On 19/12/2022 10:58, Charles Keepax wrote:
> On Sat, Dec 17, 2022 at 12:47:14AM +0100, Emanuele Ghidoli wrote:
>> Hello,
>> I have found that output volume is set to the default value after a
>> limited time (~4 seconds) after play stop.
>> I have analyzed what is happening:
>> - at first play the volume is the expected one
>> - After stopping playing + ~4 seconds wm8904_set_bias_level (...,
>> SND_SOC_BIAS_OFF) is called
>> - Chip is reset and regulator is switched off if "possible" (not in
>> our case, it is important to note)
>> - at second play wm8904_set_bias_level (..., SND_SOC_BIAS_STANDBY)
>> is called. wm8904_hw_params is also called just before.
>>
>> I see that all I2C transactions are good, registers are written as
>> expected, especially volume control register (even the silly
>> HPOUT_VU bit, to do a volume update is correctly written).
>> Reading out this register, using i2cget (bypassing regcache), report
>> the "expected" value. But the real output volume correspond to the
>> default value (hw default, that it is the same value in
>> wm8904_reg_defaults structure).
>>
>> I checked that SYSCLK_ENA is 0 during register writing (needed if
>> MCLK/SYSCLK is not present). I do not know if there is some other
>> constrain on these registers.
>>
> 
> Yes this might be my guess as well, I wonder if the HPOUT_VU bit
> needs SYSCLK to be present to take effect.
> 
>> If I rewrite the volume control register, a second time, the volume
>> is set (tested with i2cset, from user space. And from kernel space,
>> bypassing regcache).
>>
> 
> When you write the value the second time is that still before
> SYSCLK is present?
> 
> Also does just writing one of HPOUT volumes cause the other to
> get updated? The HPOUT_VU bit should trigger an update to both.
> 
>> I resolve also by reverting e9149b8c00d2 ("ASoC: wm8904: fix
>> regcache handling").
>> I'm not here to say that the commit is wrong. I analyzed it and seem
>> perfect (in few words it align the hw with the regcache avoiding
>> potential incoherence).
>>
> 
> Yeah I think that commit is fine, I would wager that your system
> doesn't turn off the regulators so without that commit the
> register retains the old volume across the "power down".
> 
> Thanks,
> Charles

Hello Charles,
thank you.

With this patch (draft) seem the "bug" is fixed: (bug that is present, 
for sure, also with an effective regulator)

diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index ca6a01a230af..33452daf1ae8 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1903,6 +1903,7 @@ static int wm8904_set_bias_level(struct 
snd_soc_component *component,
                         }

                         regcache_cache_only(wm8904->regmap, false);
+                       regcache_sync_region(wm8904->regmap, 
WM8904_CLASS_W_0, WM8904_CLASS_W_0);
                         regcache_sync(wm8904->regmap);

                         /* Enable bias */

I infer, from datasheet, that volume update is applied in different way 
based on charge pump dynamic vs register control (CP_DYN_PWR bit in 
CLASS_W register):
"Under Register control, the HPOUTL_VOL, HPOUTR_VOL, LINEOUTL_VOL and 
LINEOUTR_VOL register settings are used to control the charge pump mode 
of operation.
Under Dynamic control, the audio signal level in the DAC is used to 
control the charge pump mode of operation."

The second sentence do not explain that volume register is still 
considered by the component but likely in a different way.

It is important to note that I trace I2C transactions and, without the 
patch, the CLASS_W register is written JUST after volume update 
registers (with the patch is written before and after).

At this point I have no doubt that we have to update that register 
before writing volume.

I guess: is there another way to do same/similar thing (in a better way, 
like just force write to that register a little bit before of volume 
update. I walk around regmap/regcache but I do not find a different 
solution)?

We must pay attention that cached value of this register can be changed 
by widget "Class G" (my patch should work also if you toggle this widget).

Thank you,
best regards.

Emanuele Ghidoli







^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: wm8904 and output volume control
  2022-12-19 15:20   ` Emanuele Ghidoli
@ 2022-12-20 10:00     ` Charles Keepax
  2022-12-20 19:12       ` Emanuele Ghidoli
  0 siblings, 1 reply; 8+ messages in thread
From: Charles Keepax @ 2022-12-20 10:00 UTC (permalink / raw)
  To: Emanuele Ghidoli
  Cc: alsa-devel, Liam Girdwood, Takashi Iwai, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

On Mon, Dec 19, 2022 at 04:20:10PM +0100, Emanuele Ghidoli wrote:
> On 19/12/2022 10:58, Charles Keepax wrote:
> >On Sat, Dec 17, 2022 at 12:47:14AM +0100, Emanuele Ghidoli wrote:
> With this patch (draft) seem the "bug" is fixed: (bug that is
> present, for sure, also with an effective regulator)
> 
> diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
> index ca6a01a230af..33452daf1ae8 100644
> --- a/sound/soc/codecs/wm8904.c
> +++ b/sound/soc/codecs/wm8904.c
> @@ -1903,6 +1903,7 @@ static int wm8904_set_bias_level(struct
> snd_soc_component *component,
>                         }
> 
>                         regcache_cache_only(wm8904->regmap, false);
> +                       regcache_sync_region(wm8904->regmap,
> WM8904_CLASS_W_0, WM8904_CLASS_W_0);
>                         regcache_sync(wm8904->regmap);
> 
>                         /* Enable bias */
> 

That is some good detective work.

> I infer, from datasheet, that volume update is applied in different
> way based on charge pump dynamic vs register control (CP_DYN_PWR bit
> in CLASS_W register):
> "Under Register control, the HPOUTL_VOL, HPOUTR_VOL, LINEOUTL_VOL
> and LINEOUTR_VOL register settings are used to control the charge
> pump mode of operation.
> Under Dynamic control, the audio signal level in the DAC is used to
> control the charge pump mode of operation."
> 
> The second sentence do not explain that volume register is still
> considered by the component but likely in a different way.
> 
> It is important to note that I trace I2C transactions and, without
> the patch, the CLASS_W register is written JUST after volume update
> registers (with the patch is written before and after).
> 
> At this point I have no doubt that we have to update that register
> before writing volume.
> 

Hmm... I think my only concern here is this feels a bit counter
intuitive, the default value is described as "controlled by
volume register settings" and we are saying in that situation the
volume registers don't seem to update properly. That is far from
impossible but I think we should perhaps poke a little more to
make sure we understand the bounds here.

I see that that CP_DYN_PWR bit is disabled when audio is going
through one of the bypass paths. Would you be able to enable one
of the bypass paths and see if you can manually adjust the volume
on the headphone output, with a bypass path active?

Would also perhaps be interesting as a test to completely remove
the write to CP_DYN_PWR from probe and leave things set to manual
and see how the volume behaves then?

I guess the interests here are to find out if the SYSCLK is
involved at all. And if the issue is changing CP_DYN_PWR after a
volume update is what causes the problem. I could perhaps see a
situation where the volume update data is sent to a different
place depending on the value of CP_DYN_PWR, meaning that changing
that bit after doing a volume update causes the volume data to be
lost, but that implies we might need a fix for the Class G widget
as well.

> I guess: is there another way to do same/similar thing (in a better
> way, like just force write to that register a little bit before of
> volume update. I walk around regmap/regcache but I do not find a
> different solution)?
> 
> We must pay attention that cached value of this register can be
> changed by widget "Class G" (my patch should work also if you toggle
> this widget).

I think assuming we get a point that the requirement is
simply that CLASS_W needs written before the volume, the change
as you propose it looks good. But I suspect there is a little
more going on here.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: wm8904 and output volume control
  2022-12-20 10:00     ` Charles Keepax
@ 2022-12-20 19:12       ` Emanuele Ghidoli
  2022-12-21 16:56         ` Charles Keepax
  0 siblings, 1 reply; 8+ messages in thread
From: Emanuele Ghidoli @ 2022-12-20 19:12 UTC (permalink / raw)
  To: Charles Keepax, Emanuele Ghidoli
  Cc: alsa-devel, Liam Girdwood, Takashi Iwai, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

On 20/12/2022 11:00, Charles Keepax wrote:
> On Mon, Dec 19, 2022 at 04:20:10PM +0100, Emanuele Ghidoli wrote:
>> On 19/12/2022 10:58, Charles Keepax wrote:
>>> On Sat, Dec 17, 2022 at 12:47:14AM +0100, Emanuele Ghidoli wrote:
>> I infer, from datasheet, that volume update is applied in different
>> way based on charge pump dynamic vs register control (CP_DYN_PWR bit
>> in CLASS_W register):
>> "Under Register control, the HPOUTL_VOL, HPOUTR_VOL, LINEOUTL_VOL
>> and LINEOUTR_VOL register settings are used to control the charge
>> pump mode of operation.
>> Under Dynamic control, the audio signal level in the DAC is used to
>> control the charge pump mode of operation."
>>
>> The second sentence do not explain that volume register is still
>> considered by the component but likely in a different way.
>>
>> It is important to note that I trace I2C transactions and, without
>> the patch, the CLASS_W register is written JUST after volume update
>> registers (with the patch is written before and after).
>>
>> At this point I have no doubt that we have to update that register
>> before writing volume.
>>
> 
> Hmm... I think my only concern here is this feels a bit counter
> intuitive, the default value is described as "controlled by
> volume register settings" and we are saying in that situation the
> volume registers don't seem to update properly. That is far from
> impossible but I think we should perhaps poke a little more to
> make sure we understand the bounds here.
I did some more test and I'm not 100% sure of what is going on anymore.


> I see that that CP_DYN_PWR bit is disabled when audio is going
> through one of the bypass paths. Would you be able to enable one
> of the bypass paths and see if you can manually adjust the volume
> on the headphone output, with a bypass path active?
With the previous change, I tested all the possible combination with one 
channel from the DAC and the other toggling from DAC to Bypass changing 
the volume and it's always correct.


> Would also perhaps be interesting as a test to completely remove
> the write to CP_DYN_PWR from probe and leave things set to manual
> and see how the volume behaves then?
When I tried to remove any write to this register my modification 
stopped working.


> I guess the interests here are to find out if the SYSCLK is
> involved at all.
I tested keep the clock always enabled, removing clk_disable_unprepare 
when going into SND_SOC_BIAS_OFF and it has zero effects.
Or did you mean something else?

Said all of that, I did one last test, forcing a volume update on
the charge pump enable callback, cp_event(), with this and only this
modification in everything is working fine.

Could it just be as easy as that the volume is applied only when the 
charge pump is already active?

 From the datasheet this seems a good explanation:

  The Charge Pump is enabled by setting the CP_ENA bit. When enabled, the
  charge pump adjusts the output voltages (CPVOUTP and CPVOUTN).

What do you think?

Emanuele


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: wm8904 and output volume control
  2022-12-20 19:12       ` Emanuele Ghidoli
@ 2022-12-21 16:56         ` Charles Keepax
  2022-12-21 17:38           ` Emanuele Ghidoli
  0 siblings, 1 reply; 8+ messages in thread
From: Charles Keepax @ 2022-12-21 16:56 UTC (permalink / raw)
  To: Emanuele Ghidoli
  Cc: alsa-devel, Liam Girdwood, Takashi Iwai, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

On Tue, Dec 20, 2022 at 08:12:23PM +0100, Emanuele Ghidoli wrote:
> On 20/12/2022 11:00, Charles Keepax wrote:
> >On Mon, Dec 19, 2022 at 04:20:10PM +0100, Emanuele Ghidoli wrote:
> >>On 19/12/2022 10:58, Charles Keepax wrote:
> >>>On Sat, Dec 17, 2022 at 12:47:14AM +0100, Emanuele Ghidoli wrote:
> >I see that that CP_DYN_PWR bit is disabled when audio is going
> >through one of the bypass paths. Would you be able to enable one
> >of the bypass paths and see if you can manually adjust the volume
> >on the headphone output, with a bypass path active?
> With the previous change, I tested all the possible combination with
> one channel from the DAC and the other toggling from DAC to Bypass
> changing the volume and it's always correct.
> 
> >Would also perhaps be interesting as a test to completely remove
> >the write to CP_DYN_PWR from probe and leave things set to manual
> >and see how the volume behaves then?
> When I tried to remove any write to this register my modification
> stopped working.
> 

Apologies just to be totally clear here, you are saying that
whilst a bypass path is active (ie. the class G widget has
cleared CP_DYN_PWR), you can still control the volume? But if you
remove the set of CP_DYN_PWR from probe, the volume doesn't
update at all, audio playing or not?

> >I guess the interests here are to find out if the SYSCLK is
> >involved at all.
> I tested keep the clock always enabled, removing
> clk_disable_unprepare when going into SND_SOC_BIAS_OFF and it has
> zero effects.
> Or did you mean something else?
> 

Yeah that is not quite what I was getting at. I am wondering if
volume updates work whilst CP_DYN_PWR==0 and CLK_SYS_ENA==1.

> Said all of that, I did one last test, forcing a volume update on
> the charge pump enable callback, cp_event(), with this and only this
> modification in everything is working fine.
> 
> Could it just be as easy as that the volume is applied only when the
> charge pump is already active?
> 
> From the datasheet this seems a good explanation:
> 
>  The Charge Pump is enabled by setting the CP_ENA bit. When enabled, the
>  charge pump adjusts the output voltages (CPVOUTP and CPVOUTN).
> 
> What do you think?

I think we are getting pretty close, but we need to try and
narrow down what the requirement is here, is it the charge pump,
or the sysclk? That needs to be on for the volume update to work.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: wm8904 and output volume control
  2022-12-21 16:56         ` Charles Keepax
@ 2022-12-21 17:38           ` Emanuele Ghidoli
  2022-12-28 10:04             ` Charles Keepax
  0 siblings, 1 reply; 8+ messages in thread
From: Emanuele Ghidoli @ 2022-12-21 17:38 UTC (permalink / raw)
  To: Charles Keepax, Emanuele Ghidoli
  Cc: alsa-devel, Liam Girdwood, Takashi Iwai, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

On 21/12/2022 17:56, Charles Keepax wrote:
> On Tue, Dec 20, 2022 at 08:12:23PM +0100, Emanuele Ghidoli wrote:
>> On 20/12/2022 11:00, Charles Keepax wrote:
>>> On Mon, Dec 19, 2022 at 04:20:10PM +0100, Emanuele Ghidoli wrote:
>>>> On 19/12/2022 10:58, Charles Keepax wrote:
>>>>> On Sat, Dec 17, 2022 at 12:47:14AM +0100, Emanuele Ghidoli wrote:
>>> I see that that CP_DYN_PWR bit is disabled when audio is going
>>> through one of the bypass paths. Would you be able to enable one
>>> of the bypass paths and see if you can manually adjust the volume
>>> on the headphone output, with a bypass path active?
>> With the previous change, I tested all the possible combination with
>> one channel from the DAC and the other toggling from DAC to Bypass
>> changing the volume and it's always correct.
>>
>>> Would also perhaps be interesting as a test to completely remove
>>> the write to CP_DYN_PWR from probe and leave things set to manual
>>> and see how the volume behaves then?
>> When I tried to remove any write to this register my modification
>> stopped working.
>>
> 
> Apologies just to be totally clear here, you are saying that
> whilst a bypass path is active (ie. the class G widget has
> cleared CP_DYN_PWR), you can still control the volume? But if you
> remove the set of CP_DYN_PWR from probe, the volume doesn't
> update at all, audio playing or not?
Yes, exactly. But I have also commented:
SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0)

In every case the volume updates, while playing, when you write the relevant register
(raw i2cset or changing volume using amixer).

To be clear:
The volume is not updated, after BIAS off, if we are in CLASS G WITH
bypass DISABLED (that, without these modification, it is a condition we
cannot trigger. Normally: Bypass ON->class G, bypass OFF->class W).

Effectively, maybe, the test with bypass enabled is affected by the fact
codec is not switched off (bias is kept on... otherwise as soon I stop
playing something from my linux device bypass will stop working due to
codec reset/power off).
In other words the Dynamic Audio Power Managent (DAPM),
which I "understand" only now, is doing its work.

> 
>>> I guess the interests here are to find out if the SYSCLK is
>>> involved at all.
>> I tested keep the clock always enabled, removing
>> clk_disable_unprepare when going into SND_SOC_BIAS_OFF and it has
>> zero effects.
>> Or did you mean something else?
>>
> 
> Yeah that is not quite what I was getting at. I am wondering if
> volume updates work whilst CP_DYN_PWR==0 and CLK_SYS_ENA==1.
Why are you wondering? It should be a standard working case (obviously
with MCLK running). I know, from datasheet, that:
"CLK_SYS_ENA = 1 and MCLK is not present, then register access will be
unsuccessful". But it is not our case.
> 
>> Said all of that, I did one last test, forcing a volume update on
>> the charge pump enable callback, cp_event(), with this and only this
>> modification in everything is working fine.
>>
>> Could it just be as easy as that the volume is applied only when the
>> charge pump is already active?
>>
>>  From the datasheet this seems a good explanation:
>>
>>   The Charge Pump is enabled by setting the CP_ENA bit. When enabled, the
>>   charge pump adjusts the output voltages (CPVOUTP and CPVOUTN).
>>
>> What do you think?
> 
> I think we are getting pretty close, but we need to try and
> narrow down what the requirement is here, is it the charge pump,
> or the sysclk? That needs to be on for the volume update to work.
Watching another codec driver (wm8964: see out_pga_event comment) and
the Startup-sequence (of WM8904) in datasheet we figure out that volume
update must be done after PGA enable.
I tested another patch, I'm pretty convinced that it is the right way to
do it. Now it is working in all conditions (even Class G with disabled bypass).
Maybe some hw guy in Cirrus Logic can dig around?
Anyway, this is the tested patch, that, to me, sound good:

diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index ca6a01a230af..791d8738d1c0 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -697,6 +697,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
         int dcs_mask;
         int dcs_l, dcs_r;
         int dcs_l_reg, dcs_r_reg;
+       int an_out_reg;
         int timeout;
         int pwr_reg;
  
@@ -712,6 +713,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
                 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
                 dcs_r_reg = WM8904_DC_SERVO_8;
                 dcs_l_reg = WM8904_DC_SERVO_9;
+               an_out_reg = WM8904_ANALOGUE_OUT1_LEFT;
                 dcs_l = 0;
                 dcs_r = 1;
                 break;
@@ -720,6 +722,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
                 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
                 dcs_r_reg = WM8904_DC_SERVO_6;
                 dcs_l_reg = WM8904_DC_SERVO_7;
+               an_out_reg = WM8904_ANALOGUE_OUT2_LEFT;
                 dcs_l = 2;
                 dcs_r = 3;
                 break;
@@ -792,6 +795,10 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
                 snd_soc_component_update_bits(component, reg,
                                     WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
                                     WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
+
+               /* Update volume, requires PGA to be powered */
+               val = snd_soc_component_read(component, an_out_reg);
+               snd_soc_component_write(component, an_out_reg, val);
                 break;
  
         case SND_SOC_DAPM_POST_PMU:


> 
> Thanks,
> Charles

Thank you.
Best regards,

Emanuele


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: wm8904 and output volume control
  2022-12-21 17:38           ` Emanuele Ghidoli
@ 2022-12-28 10:04             ` Charles Keepax
  0 siblings, 0 replies; 8+ messages in thread
From: Charles Keepax @ 2022-12-28 10:04 UTC (permalink / raw)
  To: Emanuele Ghidoli
  Cc: alsa-devel, Liam Girdwood, Takashi Iwai, Michael Walle,
	Mark Brown, Francesco Dolcini, emanuele.ghidoli

On Wed, Dec 21, 2022 at 06:38:16PM +0100, Emanuele Ghidoli wrote:
> On 21/12/2022 17:56, Charles Keepax wrote:
> >On Tue, Dec 20, 2022 at 08:12:23PM +0100, Emanuele Ghidoli wrote:
> >>On 20/12/2022 11:00, Charles Keepax wrote:
> >>>On Mon, Dec 19, 2022 at 04:20:10PM +0100, Emanuele Ghidoli wrote:
> >>>>On 19/12/2022 10:58, Charles Keepax wrote:
> >>>>>On Sat, Dec 17, 2022 at 12:47:14AM +0100, Emanuele Ghidoli wrote:
> In every case the volume updates, while playing, when you write the relevant register
> (raw i2cset or changing volume using amixer).
> >Yeah that is not quite what I was getting at. I am wondering if
> >volume updates work whilst CP_DYN_PWR==0 and CLK_SYS_ENA==1.
> Why are you wondering? It should be a standard working case (obviously
> with MCLK running). I know, from datasheet, that:
> "CLK_SYS_ENA = 1 and MCLK is not present, then register access will be
> unsuccessful". But it is not our case.

Apologies yes I was intending for MCLK to be on as well, but I
think we have covered this test condition with your "In every
case the volume updates, while playing" comment above.

> Watching another codec driver (wm8964: see out_pga_event comment) and
> the Startup-sequence (of WM8904) in datasheet we figure out that volume
> update must be done after PGA enable.
> I tested another patch, I'm pretty convinced that it is the right way to
> do it. Now it is working in all conditions (even Class G with disabled bypass).
> Maybe some hw guy in Cirrus Logic can dig around?
> Anyway, this is the tested patch, that, to me, sound good:
> 

Yeah this patch looks better, as you say tracks with the
datasheet and other CODECs of the same era have a similar
requirement. I think if send this one as a separate patch we can
go with that and feel free to add my ack:

Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>

Thanks,
Charles

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-12-28 10:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-16 23:47 wm8904 and output volume control Emanuele Ghidoli
2022-12-19  9:58 ` Charles Keepax
2022-12-19 15:20   ` Emanuele Ghidoli
2022-12-20 10:00     ` Charles Keepax
2022-12-20 19:12       ` Emanuele Ghidoli
2022-12-21 16:56         ` Charles Keepax
2022-12-21 17:38           ` Emanuele Ghidoli
2022-12-28 10:04             ` Charles Keepax

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.