aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
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 /sound/soc/codecs
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>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/cs4271.c34
1 files changed, 34 insertions, 0 deletions
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)