aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Rosin <peda@axentia.se>2014-10-24 15:25:59 -0400
committerMark Brown <broonie@kernel.org>2014-11-03 07:45:27 -0500
commiteb58960e9ebf15cde8ca1248e15ecb0c8f3a28bd (patch)
tree1f0958df05bb3758e20371a25d10e24fb5f9f782
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (diff)
ASoC: atmel_ssc_dai: Match the CMR divider only in full duplex.
The CMR divider register is shared by playback and capture. The SSC driver therefore tries to enforce rules so that the needed register content do not conflict during simultaneous playback/capture. However, the implementation also prevents changing the register content in half-duplex scenarios, which is needed when using the OSS API. Thus, only lock the divider if there is a stream in the other direction. Fixes the below program to not fail with the atmel ssc dai in master mode. int main(void) { int fd; int format; int channels; int speed; if ((fd = open("/dev/dsp", O_WRONLY, 0)) == -1) { perror("open"); return 1; } format = AFMT_S16_LE; if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1) { perror("SNDCTL_DSP_SETFMT"); return 1; } channels = 2; if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { perror("SNDCTL_DSP_CHANNELS"); return 1; } speed = 22025; if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) == -1) { perror("SNDCTL_DSP_SPEED"); return 1; } return 0; } Signed-off-by: Peter Rosin <peda@axentia.se> Acked-by: Bo Shen <voice.shen@atmel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index f403f399808a..b1cc2a4a7fc0 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -310,7 +310,10 @@ static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
310 * transmit and receive, so if a value has already 310 * transmit and receive, so if a value has already
311 * been set, it must match this value. 311 * been set, it must match this value.
312 */ 312 */
313 if (ssc_p->cmr_div == 0) 313 if (ssc_p->dir_mask !=
314 (SSC_DIR_MASK_PLAYBACK | SSC_DIR_MASK_CAPTURE))
315 ssc_p->cmr_div = div;
316 else if (ssc_p->cmr_div == 0)
314 ssc_p->cmr_div = div; 317 ssc_p->cmr_div = div;
315 else 318 else
316 if (div != ssc_p->cmr_div) 319 if (div != ssc_p->cmr_div)