[alsa-devel] [PATCH 1/3] ALSA: ASoC: cs4271: fix sparse warning
Make the flag in the pdata of type bool to fix a sparse warning.
Signed-off-by: Daniel Mack zonque@gmail.com Reported-by: Fengguang Wu fengguang.wu@intel.com --- include/sound/cs4271.h | 2 +- sound/soc/codecs/cs4271.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h index 6d9e15e..dd8c48d 100644 --- a/include/sound/cs4271.h +++ b/include/sound/cs4271.h @@ -19,7 +19,7 @@
struct cs4271_platform_data { int gpio_nreset; /* GPIO driving Reset pin, if any */ - int amutec_eq_bmutec:1; /* flag to enable AMUTEC=BMUTEC */ + bool amutec_eq_bmutec; /* flag to enable AMUTEC=BMUTEC */ };
#endif /* __CS4271_H */ diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 6ad3878..70de900 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -474,7 +474,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; int ret; int gpio_nreset = -EINVAL; - int amutec_eq_bmutec = 0; + bool amutec_eq_bmutec = false;
#ifdef CONFIG_OF if (of_match_device(cs4271_dt_ids, codec->dev)) { @@ -483,7 +483,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
if (!of_get_property(codec->dev->of_node, "cirrus,amutec-eq-bmutec", NULL)) - amutec_eq_bmutec = 1; + amutec_eq_bmutec = true; } #endif
The driver had the property check for 'cirrus,amutec_eq_bmutec' the wrong way around. That happens if you misspell the property in the bindings during tests.
Signed-off-by: Daniel Mack zonque@gmail.com --- sound/soc/codecs/cs4271.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 70de900..ac99238 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -481,7 +481,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) gpio_nreset = of_get_named_gpio(codec->dev->of_node, "reset-gpio", 0);
- if (!of_get_property(codec->dev->of_node, + if (of_get_property(codec->dev->of_node, "cirrus,amutec-eq-bmutec", NULL)) amutec_eq_bmutec = true; }
On Fri, Nov 30, 2012 at 11:28:56AM +0100, Daniel Mack wrote:
The driver had the property check for 'cirrus,amutec_eq_bmutec' the wrong way around. That happens if you misspell the property in the bindings during tests.
Applied, thanks.
The CS4271 requires its LRCLK and MCLK to be stable before its RESET line is de-asserted. That also means that clocks cannot be changed without putting the chip back into hardware reset, which also requires a complete re-initialization of all registers.
One (undocumented) workaround is to assert and de-assert the PDN bit in the MODE2 register in the startup hook, in case the other channel of the codec is not currently running.
This patch adds a new flag to both the DT bindings as well as to the platform data to enable that workaround.
Signed-off-by: Daniel Mack zonque@gmail.com --- Documentation/devicetree/bindings/sound/cs4271.txt | 12 +++++++ include/sound/cs4271.h | 15 +++++++++ sound/soc/codecs/cs4271.c | 39 ++++++++++++++++++++++ 3 files changed, 66 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/cs4271.txt b/Documentation/devicetree/bindings/sound/cs4271.txt index a850fb9..e2cd1d7 100644 --- a/Documentation/devicetree/bindings/sound/cs4271.txt +++ b/Documentation/devicetree/bindings/sound/cs4271.txt @@ -20,6 +20,18 @@ Optional properties: !RESET pin - cirrus,amuteb-eq-bmutec: When given, the Codec's AMUTEB=BMUTEC flag is enabled. + - cirrus,enable-soft-reset: + The CS4271 requires its LRCLK and MCLK to be stable before its RESET + line is de-asserted. That also means that clocks cannot be changed + without putting the chip back into hardware reset, which also requires + a complete re-initialization of all registers. + + One (undocumented) workaround is to assert and de-assert the PDN bit + in the MODE2 register. This workaround can be enabled with this DT + property. + + Note that this is not needed in case the clocks are stable + throughout the entire runtime of the codec.
Examples:
diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h index dd8c48d..70f4535 100644 --- a/include/sound/cs4271.h +++ b/include/sound/cs4271.h @@ -20,6 +20,21 @@ struct cs4271_platform_data { int gpio_nreset; /* GPIO driving Reset pin, if any */ bool amutec_eq_bmutec; /* flag to enable AMUTEC=BMUTEC */ + + /* + * The CS4271 requires its LRCLK and MCLK to be stable before its RESET + * line is de-asserted. That also means that clocks cannot be changed + * without putting the chip back into hardware reset, which also requires + * a complete re-initialization of all registers. + * + * One (undocumented) workaround is to assert and de-assert the PDN bit + * in the MODE2 register. This workaround can be enabled with the + * following flag. + * + * Note that this is not needed in case the clocks are stable + * throughout the entire runtime of the codec. + */ + bool enable_soft_reset; };
#endif /* __CS4271_H */ diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index ac99238..bbc83ef 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -167,6 +167,8 @@ struct cs4271_private { int gpio_nreset; /* GPIO that disable serial bus, if any */ int gpio_disable; + /* enable soft reset workaround */ + bool enable_soft_reset; };
/* @@ -403,11 +405,43 @@ static const struct snd_kcontrol_new cs4271_snd_controls[] = { 7, 1, 1), };
+static int cs4271_startup(struct snd_pcm_substream *subs, + struct snd_soc_dai *codec_dai) +{ + int ret; + struct snd_soc_codec *codec = codec_dai->codec; + struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); + + if (!cs4271->enable_soft_reset) + return 0; + + /* + * Put the codec in soft reset and back again in case it's not + * currently streaming data. This way of bringing the codec in + * sync to the current clocks is not explicitly documented in + * the data sheet, but it seems to work fine. + */ + + if ((subs->stream == SNDRV_PCM_STREAM_PLAYBACK && + codec_dai->capture_active) || + (subs->stream == SNDRV_PCM_STREAM_CAPTURE && + codec_dai->playback_active)) + return 0; + + ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, + CS4271_MODE2_PDN); + if (ret < 0) + return ret; + + return snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); +} + static const struct snd_soc_dai_ops cs4271_dai_ops = { .hw_params = cs4271_hw_params, .set_sysclk = cs4271_set_dai_sysclk, .set_fmt = cs4271_set_dai_fmt, .digital_mute = cs4271_digital_mute, + .startup = cs4271_startup, };
static struct snd_soc_dai_driver cs4271_dai = { @@ -484,6 +518,10 @@ static int cs4271_probe(struct snd_soc_codec *codec) if (of_get_property(codec->dev->of_node, "cirrus,amutec-eq-bmutec", NULL)) amutec_eq_bmutec = true; + + if (of_get_property(codec->dev->of_node, + "cirrus,enable-soft-reset", NULL)) + cs4271->enable_soft_reset = true; } #endif
@@ -492,6 +530,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) gpio_nreset = cs4271plat->gpio_nreset;
amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; + cs4271->enable_soft_reset = cs4271plat->enable_soft_reset; }
if (gpio_nreset >= 0)
On Fri, Nov 30, 2012 at 11:28:57AM +0100, Daniel Mack wrote:
- Note that this is not needed in case the clocks are stable
- throughout the entire runtime of the codec.
That's really quite rare for embeded systems, though - normally at least the LRCLK is going to be enabled only when there's audio.
+static int cs4271_startup(struct snd_pcm_substream *subs,
struct snd_soc_dai *codec_dai)
+{
- int ret;
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- if (!cs4271->enable_soft_reset)
return 0;
- /*
* Put the codec in soft reset and back again in case it's not
* currently streaming data. This way of bringing the codec in
* sync to the current clocks is not explicitly documented in
* the data sheet, but it seems to work fine.
*/
Since startup() is called before hw_params() you might well find even an active LRCLK is going to change underneath the driver here...
On 02.12.2012 05:02, Mark Brown wrote:
On Fri, Nov 30, 2012 at 11:28:57AM +0100, Daniel Mack wrote:
- Note that this is not needed in case the clocks are stable
- throughout the entire runtime of the codec.
That's really quite rare for embeded systems, though - normally at least the LRCLK is going to be enabled only when there's audio.
I agree, but I don't know which system the original driver was written for. As it seems to work there, I didn't want to unconditionally introduce this new reset command.
+static int cs4271_startup(struct snd_pcm_substream *subs,
struct snd_soc_dai *codec_dai)
+{
- int ret;
- struct snd_soc_codec *codec = codec_dai->codec;
- struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
- if (!cs4271->enable_soft_reset)
return 0;
- /*
* Put the codec in soft reset and back again in case it's not
* currently streaming data. This way of bringing the codec in
* sync to the current clocks is not explicitly documented in
* the data sheet, but it seems to work fine.
*/
Since startup() is called before hw_params() you might well find even an active LRCLK is going to change underneath the driver here...
Hmm ok, so you're saying this quirk should go in hwparams() then?
Thanks, Daniel
participants (2)
-
Daniel Mack
-
Mark Brown