aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2012-12-10 04:30:04 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-24 10:53:28 -0500
commitfd23fb9f6bfd43a6e62b2646d18d5ca3edc3ebe3 (patch)
treea1033cbc88a3ccba164e8d0f6c7469f9efd6713a
parent133d2e6188de86df3ed84cd42ac66e9c5d328c04 (diff)
ALSA: ASoC: cs4271: add optional soft reset workaround
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 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> Acked-by: Alexander Sverdlin <subaparts@yandex.ru> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--Documentation/devicetree/bindings/sound/cs4271.txt12
-rw-r--r--include/sound/cs4271.h15
-rw-r--r--sound/soc/codecs/cs4271.c34
3 files changed, 61 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/cs4271.txt b/Documentation/devicetree/bindings/sound/cs4271.txt
index a850fb9c88ea..e2cd1d7539e5 100644
--- a/Documentation/devicetree/bindings/sound/cs4271.txt
+++ b/Documentation/devicetree/bindings/sound/cs4271.txt
@@ -20,6 +20,18 @@ Optional properties:
20 !RESET pin 20 !RESET pin
21 - cirrus,amuteb-eq-bmutec: When given, the Codec's AMUTEB=BMUTEC flag 21 - cirrus,amuteb-eq-bmutec: When given, the Codec's AMUTEB=BMUTEC flag
22 is enabled. 22 is enabled.
23 - cirrus,enable-soft-reset:
24 The CS4271 requires its LRCLK and MCLK to be stable before its RESET
25 line is de-asserted. That also means that clocks cannot be changed
26 without putting the chip back into hardware reset, which also requires
27 a complete re-initialization of all registers.
28
29 One (undocumented) workaround is to assert and de-assert the PDN bit
30 in the MODE2 register. This workaround can be enabled with this DT
31 property.
32
33 Note that this is not needed in case the clocks are stable
34 throughout the entire runtime of the codec.
23 35
24Examples: 36Examples:
25 37
diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h
index dd8c48d14ed9..70f45355acaa 100644
--- a/include/sound/cs4271.h
+++ b/include/sound/cs4271.h
@@ -20,6 +20,21 @@
20struct cs4271_platform_data { 20struct cs4271_platform_data {
21 int gpio_nreset; /* GPIO driving Reset pin, if any */ 21 int gpio_nreset; /* GPIO driving Reset pin, if any */
22 bool amutec_eq_bmutec; /* flag to enable AMUTEC=BMUTEC */ 22 bool amutec_eq_bmutec; /* flag to enable AMUTEC=BMUTEC */
23
24 /*
25 * The CS4271 requires its LRCLK and MCLK to be stable before its RESET
26 * line is de-asserted. That also means that clocks cannot be changed
27 * without putting the chip back into hardware reset, which also requires
28 * a complete re-initialization of all registers.
29 *
30 * One (undocumented) workaround is to assert and de-assert the PDN bit
31 * in the MODE2 register. This workaround can be enabled with the
32 * following flag.
33 *
34 * Note that this is not needed in case the clocks are stable
35 * throughout the entire runtime of the codec.
36 */
37 bool enable_soft_reset;
23}; 38};
24 39
25#endif /* __CS4271_H */ 40#endif /* __CS4271_H */
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index ac8742a1f25a..2415a4118dbd 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -167,6 +167,8 @@ struct cs4271_private {
167 int gpio_nreset; 167 int gpio_nreset;
168 /* GPIO that disable serial bus, if any */ 168 /* GPIO that disable serial bus, if any */
169 int gpio_disable; 169 int gpio_disable;
170 /* enable soft reset workaround */
171 bool enable_soft_reset;
170}; 172};
171 173
172/* 174/*
@@ -325,6 +327,33 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
325 int i, ret; 327 int i, ret;
326 unsigned int ratio, val; 328 unsigned int ratio, val;
327 329
330 if (cs4271->enable_soft_reset) {
331 /*
332 * Put the codec in soft reset and back again in case it's not
333 * currently streaming data. This way of bringing the codec in
334 * sync to the current clocks is not explicitly documented in
335 * the data sheet, but it seems to work fine, and in contrast
336 * to a read hardware reset, we don't have to sync back all
337 * registers every time.
338 */
339
340 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
341 !dai->capture_active) ||
342 (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
343 !dai->playback_active)) {
344 ret = snd_soc_update_bits(codec, CS4271_MODE2,
345 CS4271_MODE2_PDN,
346 CS4271_MODE2_PDN);
347 if (ret < 0)
348 return ret;
349
350 ret = snd_soc_update_bits(codec, CS4271_MODE2,
351 CS4271_MODE2_PDN, 0);
352 if (ret < 0)
353 return ret;
354 }
355 }
356
328 cs4271->rate = params_rate(params); 357 cs4271->rate = params_rate(params);
329 358
330 /* Configure DAC */ 359 /* Configure DAC */
@@ -484,6 +513,10 @@ static int cs4271_probe(struct snd_soc_codec *codec)
484 if (of_get_property(codec->dev->of_node, 513 if (of_get_property(codec->dev->of_node,
485 "cirrus,amutec-eq-bmutec", NULL)) 514 "cirrus,amutec-eq-bmutec", NULL))
486 amutec_eq_bmutec = true; 515 amutec_eq_bmutec = true;
516
517 if (of_get_property(codec->dev->of_node,
518 "cirrus,enable-soft-reset", NULL))
519 cs4271->enable_soft_reset = true;
487 } 520 }
488#endif 521#endif
489 522
@@ -492,6 +525,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
492 gpio_nreset = cs4271plat->gpio_nreset; 525 gpio_nreset = cs4271plat->gpio_nreset;
493 526
494 amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; 527 amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec;
528 cs4271->enable_soft_reset = cs4271plat->enable_soft_reset;
495 } 529 }
496 530
497 if (gpio_nreset >= 0) 531 if (gpio_nreset >= 0)