* [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it
@ 2014-07-16 12:10 Richard Fitzgerald
2014-07-17 19:42 ` Mark Brown
2014-07-22 10:42 ` [PATCH v2] " Richard Fitzgerald
0 siblings, 2 replies; 8+ messages in thread
From: Richard Fitzgerald @ 2014-07-16 12:10 UTC (permalink / raw)
To: perex, tiwai, lgirdwood, broonie; +Cc: patches, alsa-devel, linux-kernel
If we don't disable the AIF TX/RX then we may fall into a
situation where the new AIF settings are ignored by the device.
For example, this problem manifests when switching between
different sample rates.
Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
sound/soc/codecs/arizona.c | 20 ++++++++++++++++++--
1 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index fb30c82..270e7ad 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1249,6 +1249,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
int tdm_width = arizona->tdm_width[dai->id - 1];
int tdm_slots = arizona->tdm_slots[dai->id - 1];
int bclk, lrclk, wl, frame, bclk_target;
+ unsigned int aif_tx_state, aif_rx_state;
if (params_rate(params) % 8000)
rates = &arizona_44k1_bclk_rates[0];
@@ -1299,9 +1300,18 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
wl = snd_pcm_format_width(params_format(params));
frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
+ /* Save AIF TX/RX state */
+ aif_tx_state = snd_soc_read(codec, base + ARIZONA_AIF_TX_ENABLES);
+ aif_rx_state = snd_soc_read(codec, base + ARIZONA_AIF_RX_ENABLES);
+ /* Disable AIF TX/RX before configuring it */
+ snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_ENABLES,
+ 0xff, 0x0);
+ snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_ENABLES,
+ 0xff, 0x0);
+
ret = arizona_hw_params_rate(substream, params, dai);
if (ret != 0)
- return ret;
+ goto restore_aif;
regmap_update_bits_async(arizona->regmap,
base + ARIZONA_AIF_BCLK_CTRL,
@@ -1320,7 +1330,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
ARIZONA_AIF1RX_WL_MASK |
ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
- return 0;
+restore_aif:
+ /* Restore AIF TX/RX state */
+ snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_ENABLES,
+ 0xff, aif_tx_state);
+ snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_ENABLES,
+ 0xff, aif_rx_state);
+ return ret;
}
static const char *arizona_dai_clk_str(int clk_id)
--
1.7.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it
2014-07-16 12:10 [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it Richard Fitzgerald
@ 2014-07-17 19:42 ` Mark Brown
2014-07-21 9:01 ` Richard Fitzgerald
2014-07-22 10:42 ` [PATCH v2] " Richard Fitzgerald
1 sibling, 1 reply; 8+ messages in thread
From: Mark Brown @ 2014-07-17 19:42 UTC (permalink / raw)
To: Richard Fitzgerald
Cc: perex, tiwai, lgirdwood, patches, alsa-devel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 563 bytes --]
On Wed, Jul 16, 2014 at 01:10:39PM +0100, Richard Fitzgerald wrote:
> If we don't disable the AIF TX/RX then we may fall into a
> situation where the new AIF settings are ignored by the device.
> For example, this problem manifests when switching between
> different sample rates.
So, what this does is momentarily disable the AIF when reconfiguring.
That will glitch any running audio, making me wonder if the driver
shouldn't be returning an error or at least complaining if it has to
reconfigure instead. What's the use case where this might get
triggered?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it
2014-07-17 19:42 ` Mark Brown
@ 2014-07-21 9:01 ` Richard Fitzgerald
2014-07-21 9:04 ` Takashi Iwai
0 siblings, 1 reply; 8+ messages in thread
From: Richard Fitzgerald @ 2014-07-21 9:01 UTC (permalink / raw)
To: Mark Brown; +Cc: perex, tiwai, lgirdwood, patches, alsa-devel, linux-kernel
On Thu, Jul 17, 2014 at 08:42:15PM +0100, Mark Brown wrote:
> On Wed, Jul 16, 2014 at 01:10:39PM +0100, Richard Fitzgerald wrote:
>
> > If we don't disable the AIF TX/RX then we may fall into a
> > situation where the new AIF settings are ignored by the device.
> > For example, this problem manifests when switching between
> > different sample rates.
>
> So, what this does is momentarily disable the AIF when reconfiguring.
> That will glitch any running audio, making me wonder if the driver
> shouldn't be returning an error or at least complaining if it has to
> reconfigure instead. What's the use case where this might get
> triggered?
The case being fixed is like this:
aplay 48kHz.wav; aplay 96kHz.wav
The second open happens before pmdown_time so the AIF is still enabled.
Writes to the AIF config registers only take effect if the AIF is disabled.
Without this patch, the 96kHz.wav will play at 48kHz
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it
2014-07-21 9:01 ` Richard Fitzgerald
@ 2014-07-21 9:04 ` Takashi Iwai
2014-07-21 10:33 ` Richard Fitzgerald
0 siblings, 1 reply; 8+ messages in thread
From: Takashi Iwai @ 2014-07-21 9:04 UTC (permalink / raw)
To: Richard Fitzgerald
Cc: Mark Brown, perex, lgirdwood, patches, alsa-devel, linux-kernel
At Mon, 21 Jul 2014 10:01:22 +0100,
Richard Fitzgerald wrote:
>
> On Thu, Jul 17, 2014 at 08:42:15PM +0100, Mark Brown wrote:
> > On Wed, Jul 16, 2014 at 01:10:39PM +0100, Richard Fitzgerald wrote:
> >
> > > If we don't disable the AIF TX/RX then we may fall into a
> > > situation where the new AIF settings are ignored by the device.
> > > For example, this problem manifests when switching between
> > > different sample rates.
> >
> > So, what this does is momentarily disable the AIF when reconfiguring.
> > That will glitch any running audio, making me wonder if the driver
> > shouldn't be returning an error or at least complaining if it has to
> > reconfigure instead. What's the use case where this might get
> > triggered?
>
> The case being fixed is like this:
>
> aplay 48kHz.wav; aplay 96kHz.wav
>
> The second open happens before pmdown_time so the AIF is still enabled.
> Writes to the AIF config registers only take effect if the AIF is disabled.
> Without this patch, the 96kHz.wav will play at 48kHz
If the glitch really matters, the driver can minimize by checking the
change of sample rate and doing temporary turn on/off only when
required.
Takashi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it
2014-07-21 9:04 ` Takashi Iwai
@ 2014-07-21 10:33 ` Richard Fitzgerald
2014-07-21 16:24 ` Mark Brown
0 siblings, 1 reply; 8+ messages in thread
From: Richard Fitzgerald @ 2014-07-21 10:33 UTC (permalink / raw)
To: Takashi Iwai
Cc: Mark Brown, perex, lgirdwood, patches, alsa-devel, linux-kernel
On Mon, Jul 21, 2014 at 11:04:56AM +0200, Takashi Iwai wrote:
> At Mon, 21 Jul 2014 10:01:22 +0100,
> Richard Fitzgerald wrote:
> >
> > On Thu, Jul 17, 2014 at 08:42:15PM +0100, Mark Brown wrote:
> > > On Wed, Jul 16, 2014 at 01:10:39PM +0100, Richard Fitzgerald wrote:
> > >
> > > > If we don't disable the AIF TX/RX then we may fall into a
> > > > situation where the new AIF settings are ignored by the device.
> > > > For example, this problem manifests when switching between
> > > > different sample rates.
> > >
> > > So, what this does is momentarily disable the AIF when reconfiguring.
> > > That will glitch any running audio, making me wonder if the driver
> > > shouldn't be returning an error or at least complaining if it has to
> > > reconfigure instead. What's the use case where this might get
> > > triggered?
> >
> > The case being fixed is like this:
> >
> > aplay 48kHz.wav; aplay 96kHz.wav
> >
> > The second open happens before pmdown_time so the AIF is still enabled.
> > Writes to the AIF config registers only take effect if the AIF is disabled.
> > Without this patch, the 96kHz.wav will play at 48kHz
>
> If the glitch really matters, the driver can minimize by checking the
> change of sample rate and doing temporary turn on/off only when
> required.
>
>
> Takashi
That's a fair point.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it
2014-07-21 10:33 ` Richard Fitzgerald
@ 2014-07-21 16:24 ` Mark Brown
0 siblings, 0 replies; 8+ messages in thread
From: Mark Brown @ 2014-07-21 16:24 UTC (permalink / raw)
To: Richard Fitzgerald
Cc: Takashi Iwai, perex, lgirdwood, patches, alsa-devel, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 938 bytes --]
On Mon, Jul 21, 2014 at 11:33:27AM +0100, Richard Fitzgerald wrote:
> On Mon, Jul 21, 2014 at 11:04:56AM +0200, Takashi Iwai wrote:
> > Richard Fitzgerald wrote:
> > > The case being fixed is like this:
> > > aplay 48kHz.wav; aplay 96kHz.wav
> > > The second open happens before pmdown_time so the AIF is still enabled.
> > > Writes to the AIF config registers only take effect if the AIF is disabled.
> > > Without this patch, the 96kHz.wav will play at 48kHz
> > If the glitch really matters, the driver can minimize by checking the
> > change of sample rate and doing temporary turn on/off only when
> > required.
> That's a fair point.
The case I was particularly worrying about here was simultaneous
playback and capture - we won't be changing rates here since these
devices currently require symmetry which is enforced via constraints but
we are likely to at least be starting multiple streams close to each
other frequently.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] ASoC: arizona: Disable AIF TX/RX before configuring it
2014-07-16 12:10 [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it Richard Fitzgerald
2014-07-17 19:42 ` Mark Brown
@ 2014-07-22 10:42 ` Richard Fitzgerald
2014-07-22 22:22 ` Mark Brown
1 sibling, 1 reply; 8+ messages in thread
From: Richard Fitzgerald @ 2014-07-22 10:42 UTC (permalink / raw)
To: perex, tiwai, lgirdwood, broonie; +Cc: alsa-devel, patches, linux-kernel
Changes to the AIF configuration registers only take
effect when the AIF is disabled. If the configuration
is being changed from the previous setup, temporarily
disable the AIF.
Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
sound/soc/codecs/arizona.c | 87 +++++++++++++++++++++++++++++++++++---------
1 files changed, 69 insertions(+), 18 deletions(-)
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index fb30c82..bd41ee4 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1234,6 +1234,27 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
return 0;
}
+static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
+ int base, int bclk, int lrclk, int frame)
+{
+ int val;
+
+ val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
+ if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
+ return true;
+
+ val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
+ if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
+ return true;
+
+ val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
+ if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
+ ARIZONA_AIF1TX_SLOT_LEN_MASK)))
+ return true;
+
+ return false;
+}
+
static int arizona_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -1249,6 +1270,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
int tdm_width = arizona->tdm_width[dai->id - 1];
int tdm_slots = arizona->tdm_slots[dai->id - 1];
int bclk, lrclk, wl, frame, bclk_target;
+ bool reconfig;
+ unsigned int aif_tx_state, aif_rx_state;
if (params_rate(params) % 8000)
rates = &arizona_44k1_bclk_rates[0];
@@ -1299,28 +1322,56 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
wl = snd_pcm_format_width(params_format(params));
frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
+ reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
+
+ if (reconfig) {
+ /* Save AIF TX/RX state */
+ aif_tx_state = snd_soc_read(codec,
+ base + ARIZONA_AIF_TX_ENABLES);
+ aif_rx_state = snd_soc_read(codec,
+ base + ARIZONA_AIF_RX_ENABLES);
+ /* Disable AIF TX/RX before reconfiguring it */
+ regmap_update_bits_async(arizona->regmap,
+ base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
+ regmap_update_bits(arizona->regmap,
+ base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
+ }
+
ret = arizona_hw_params_rate(substream, params, dai);
if (ret != 0)
- return ret;
+ goto restore_aif;
- regmap_update_bits_async(arizona->regmap,
- base + ARIZONA_AIF_BCLK_CTRL,
- ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
- regmap_update_bits_async(arizona->regmap,
- base + ARIZONA_AIF_TX_BCLK_RATE,
- ARIZONA_AIF1TX_BCPF_MASK, lrclk);
- regmap_update_bits_async(arizona->regmap,
- base + ARIZONA_AIF_RX_BCLK_RATE,
- ARIZONA_AIF1RX_BCPF_MASK, lrclk);
- regmap_update_bits_async(arizona->regmap,
- base + ARIZONA_AIF_FRAME_CTRL_1,
- ARIZONA_AIF1TX_WL_MASK |
- ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
- regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FRAME_CTRL_2,
- ARIZONA_AIF1RX_WL_MASK |
- ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
+ if (reconfig) {
+ regmap_update_bits_async(arizona->regmap,
+ base + ARIZONA_AIF_BCLK_CTRL,
+ ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
+ regmap_update_bits_async(arizona->regmap,
+ base + ARIZONA_AIF_TX_BCLK_RATE,
+ ARIZONA_AIF1TX_BCPF_MASK, lrclk);
+ regmap_update_bits_async(arizona->regmap,
+ base + ARIZONA_AIF_RX_BCLK_RATE,
+ ARIZONA_AIF1RX_BCPF_MASK, lrclk);
+ regmap_update_bits_async(arizona->regmap,
+ base + ARIZONA_AIF_FRAME_CTRL_1,
+ ARIZONA_AIF1TX_WL_MASK |
+ ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
+ regmap_update_bits(arizona->regmap,
+ base + ARIZONA_AIF_FRAME_CTRL_2,
+ ARIZONA_AIF1RX_WL_MASK |
+ ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
+ }
- return 0;
+restore_aif:
+ if (reconfig) {
+ /* Restore AIF TX/RX state */
+ regmap_update_bits_async(arizona->regmap,
+ base + ARIZONA_AIF_TX_ENABLES,
+ 0xff, aif_tx_state);
+ regmap_update_bits(arizona->regmap,
+ base + ARIZONA_AIF_RX_ENABLES,
+ 0xff, aif_rx_state);
+ }
+ return ret;
}
static const char *arizona_dai_clk_str(int clk_id)
--
1.7.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] ASoC: arizona: Disable AIF TX/RX before configuring it
2014-07-22 10:42 ` [PATCH v2] " Richard Fitzgerald
@ 2014-07-22 22:22 ` Mark Brown
0 siblings, 0 replies; 8+ messages in thread
From: Mark Brown @ 2014-07-22 22:22 UTC (permalink / raw)
To: Richard Fitzgerald
Cc: perex, tiwai, lgirdwood, alsa-devel, patches, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 272 bytes --]
On Tue, Jul 22, 2014 at 11:42:06AM +0100, Richard Fitzgerald wrote:
> Changes to the AIF configuration registers only take
> effect when the AIF is disabled. If the configuration
> is being changed from the previous setup, temporarily
> disable the AIF.
Applied, thanks.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-07-22 22:22 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-16 12:10 [PATCH] ASoC: arizona: Disable AIF TX/RX before configuring it Richard Fitzgerald
2014-07-17 19:42 ` Mark Brown
2014-07-21 9:01 ` Richard Fitzgerald
2014-07-21 9:04 ` Takashi Iwai
2014-07-21 10:33 ` Richard Fitzgerald
2014-07-21 16:24 ` Mark Brown
2014-07-22 10:42 ` [PATCH v2] " Richard Fitzgerald
2014-07-22 22:22 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox