aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabio Baltieri <fabio.baltieri@linaro.org>2013-05-28 10:16:39 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-05-28 10:23:23 -0400
commita130243b96622e16af7c1ac7ba903b4cec7aa81b (patch)
treefde9e0bf8d8033531e57233dfda08c410cc7c1d9
parentf82030f978ae21ee790a90610ff21ce72667958e (diff)
ASoC: ux500: Ensure consistent configuration between DAIs
Current implementation of mop500_ab8500 allows for inconsistent sample rate and channel count configuration between the playback and recording interfaces, through in the hardware the two MSP controllers share common clock and frame sync signals. This patch adds the necessary code to ensure that the two device are configure consistently. The check is added at machine driver level, as how to lock DAI configuration depend of the actual hardware implementation. Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/ux500/mop500_ab8500.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c
index 5e0f14634271..7e923ecf8901 100644
--- a/sound/soc/ux500/mop500_ab8500.c
+++ b/sound/soc/ux500/mop500_ab8500.c
@@ -16,6 +16,7 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/mutex.h>
19 20
20#include <sound/soc.h> 21#include <sound/soc.h>
21#include <sound/soc-dapm.h> 22#include <sound/soc-dapm.h>
@@ -44,6 +45,12 @@
44static unsigned int tx_slots = DEF_TX_SLOTS; 45static unsigned int tx_slots = DEF_TX_SLOTS;
45static unsigned int rx_slots = DEF_RX_SLOTS; 46static unsigned int rx_slots = DEF_RX_SLOTS;
46 47
48/* Configuration consistency parameters */
49static DEFINE_MUTEX(mop500_ab8500_params_lock);
50static unsigned long mop500_ab8500_usage;
51static int mop500_ab8500_rate;
52static int mop500_ab8500_channels;
53
47/* Clocks */ 54/* Clocks */
48static const char * const enum_mclk[] = { 55static const char * const enum_mclk[] = {
49 "SYSCLK", 56 "SYSCLK",
@@ -231,6 +238,21 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
231 substream->name, 238 substream->name,
232 substream->number); 239 substream->number);
233 240
241 /* Ensure configuration consistency between DAIs */
242 mutex_lock(&mop500_ab8500_params_lock);
243 if (mop500_ab8500_usage) {
244 if (mop500_ab8500_rate != params_rate(params) ||
245 mop500_ab8500_channels != params_channels(params)) {
246 mutex_unlock(&mop500_ab8500_params_lock);
247 return -EBUSY;
248 }
249 } else {
250 mop500_ab8500_rate = params_rate(params);
251 mop500_ab8500_channels = params_channels(params);
252 }
253 __set_bit(cpu_dai->id, &mop500_ab8500_usage);
254 mutex_unlock(&mop500_ab8500_params_lock);
255
234 channels = params_channels(params); 256 channels = params_channels(params);
235 257
236 switch (params_format(params)) { 258 switch (params_format(params)) {
@@ -329,9 +351,22 @@ static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
329 return 0; 351 return 0;
330} 352}
331 353
354static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream)
355{
356 struct snd_soc_pcm_runtime *rtd = substream->private_data;
357 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
358
359 mutex_lock(&mop500_ab8500_params_lock);
360 __clear_bit(cpu_dai->id, &mop500_ab8500_usage);
361 mutex_unlock(&mop500_ab8500_params_lock);
362
363 return 0;
364}
365
332struct snd_soc_ops mop500_ab8500_ops[] = { 366struct snd_soc_ops mop500_ab8500_ops[] = {
333 { 367 {
334 .hw_params = mop500_ab8500_hw_params, 368 .hw_params = mop500_ab8500_hw_params,
369 .hw_free = mop500_ab8500_hw_free,
335 .startup = mop500_ab8500_startup, 370 .startup = mop500_ab8500_startup,
336 .shutdown = mop500_ab8500_shutdown, 371 .shutdown = mop500_ab8500_shutdown,
337 } 372 }