summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@linaro.org>2011-03-25 09:43:27 +0100
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 15:14:42 +0200
commit0185e37f689cecb899655c4c39bc4797993e0bf7 (patch)
tree23d81d8a35e41e9f27b6d114310cacffaafc02b2 /sound
parent31c5da5fa5d7ec98742532e2a71abcd781009dd2 (diff)
Ux500 ASoC: Use of cyclic DMA.
Platform driver rewritten to make use of cyclic DMA by sending a cyclic SG-list before playback is started. Updates to support cyclic DMA in MSP I2S-driver. ST-Ericsson ID: ER 278088 Change-Id: I9d143fc4704cff6f5415175ab14085b9ab98d6d4 Signed-off-by: Ola Lilja <ola.o.lilja@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/9353 Reviewed-by: Rabin VINCENT <rabin.vincent@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com> Conflicts: drivers/misc/i2s/i2s.c drivers/misc/i2s/i2s_test_protocol_driver.c drivers/misc/i2s/msp_i2s.c drivers/misc/i2s/msp_i2s.h include/linux/i2s/i2s.h
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c139
-rw-r--r--sound/soc/ux500/ux500_msp_dai.h8
-rw-r--r--sound/soc/ux500/ux500_pcm.c122
-rw-r--r--sound/soc/ux500/ux500_pcm.h12
-rw-r--r--sound/u8500_acodec_ab8500.c11
5 files changed, 164 insertions, 128 deletions
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 36836918a36..432f5646b67 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -11,19 +11,20 @@
* it under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/
-#include <sound/soc.h>
-#include <sound/soc-dai.h>
+#include <linux/slab.h>
#include <asm/dma.h>
-#include "ux500_msp_dai.h"
-#include "ux500_pcm.h"
+#include <linux/bitops.h>
#include <mach/msp.h>
#include <linux/i2s/i2s.h>
-#include <linux/bitops.h>
+
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+#include "ux500_msp_dai.h"
+#include "ux500_pcm.h"
static struct ux500_msp_dai_private ux500_msp_dai_private[UX500_NBR_OF_DAI] = {
{
- .lock = __SPIN_LOCK_UNLOCKED(ux500_msp_dai_private[0].lock),
.i2s = NULL,
.fmt = 0,
.slots = 1,
@@ -32,7 +33,6 @@ static struct ux500_msp_dai_private ux500_msp_dai_private[UX500_NBR_OF_DAI] = {
.slot_width = 16,
},
{
- .lock = __SPIN_LOCK_UNLOCKED(ux500_msp_dai_private[1].lock),
.i2s = NULL,
.fmt = 0,
.slots = 1,
@@ -41,7 +41,6 @@ static struct ux500_msp_dai_private ux500_msp_dai_private[UX500_NBR_OF_DAI] = {
.slot_width = 16,
},
{
- .lock = __SPIN_LOCK_UNLOCKED(ux500_msp_dai_private[2].lock),
.i2s = NULL,
.fmt = 0,
.slots = 1,
@@ -53,19 +52,12 @@ static struct ux500_msp_dai_private ux500_msp_dai_private[UX500_NBR_OF_DAI] = {
static int ux500_msp_dai_i2s_probe(struct i2s_device *i2s)
{
- unsigned long flags;
-
pr_info("%s: Enter (chip_select = %d, i2s = %d).\n",
__func__,
(int)i2s->chip_select, (int)(i2s));
- spin_lock_irqsave(
- &ux500_msp_dai_private[i2s->chip_select].lock,
- flags);
ux500_msp_dai_private[i2s->chip_select].i2s = i2s;
- spin_unlock_irqrestore(
- &ux500_msp_dai_private[i2s->chip_select].lock,
- flags);
+
try_module_get(i2s->controller->dev.parent->driver->owner);
i2s_set_drvdata(
i2s,
@@ -76,7 +68,6 @@ static int ux500_msp_dai_i2s_probe(struct i2s_device *i2s)
static int ux500_msp_dai_i2s_remove(struct i2s_device *i2s)
{
- unsigned long flags;
struct ux500_msp_dai_private *ux500_msp_dai_private =
i2s_get_drvdata(i2s);
@@ -84,13 +75,8 @@ static int ux500_msp_dai_i2s_remove(struct i2s_device *i2s)
__func__,
(int)i2s->chip_select);
- spin_lock_irqsave(&ux500_msp_dai_private->lock, flags);
-
ux500_msp_dai_private->i2s = NULL;
i2s_set_drvdata(i2s, NULL);
- spin_unlock_irqrestore(
- &ux500_msp_dai_private->lock,
- flags);
pr_debug("%s: Calling module_put.\n",
__func__);
@@ -117,22 +103,91 @@ static struct i2s_driver i2sdrv_i2s = {
.id_table = dev_id_table,
};
+bool ux500_msp_dai_i2s_get_underrun_status(int dai_idx)
+{
+ struct ux500_msp_dai_private *dai_private = &ux500_msp_dai_private[dai_idx];
+ int status = i2s_hw_status(dai_private->i2s->controller);
+ return (bool)(status & TRANSMIT_UNDERRUN_ERR_INT);
+}
+
+dma_addr_t ux500_msp_dai_i2s_get_pointer(int dai_idx, int stream_id)
+{
+ struct ux500_msp_dai_private *dai_private = &ux500_msp_dai_private[dai_idx];
+ return i2s_get_pointer(dai_private->i2s->controller,
+ (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
+ I2S_DIRECTION_TX :
+ I2S_DIRECTION_RX);
+}
+
+int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
+ int sg_len,
+ int sg_size,
+ int dai_idx,
+ int stream_id)
+{
+ struct ux500_msp_dai_private *dai_private = &ux500_msp_dai_private[dai_idx];
+ struct i2s_message message;
+ struct i2s_device *i2s_dev;
+ int i;
+ int ret = 0;
+ struct scatterlist *sg;
+
+ pr_debug("%s: Enter (MSP Index: %u, SG-length: %u, SG-size: %u).\n",
+ __func__,
+ dai_idx,
+ sg_len,
+ sg_size);
+
+ if (!ux500_msp_dai[dai_idx].playback.active) {
+ pr_err("%s: The I2S controller is not available."
+ "MSP index:%d\n",
+ __func__,
+ dai_idx);
+ return ret;
+ }
+
+ i2s_dev = dai_private->i2s;
+
+ sg = kzalloc(sizeof(struct scatterlist) * sg_len, GFP_ATOMIC);
+ sg_init_table(sg, sg_len);
+ for (i = 0; i < sg_len; i++) {
+ sg_dma_address(&sg[i]) = dma_addr + i * sg_size;
+ sg_dma_len(&sg[i]) = sg_size;
+ }
+
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_CYCLIC_DMA;
+ message.i2s_direction = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
+ I2S_DIRECTION_TX :
+ I2S_DIRECTION_RX;
+ message.sg = sg;
+ message.sg_len = sg_len;
+
+ ret = i2s_transfer(i2s_dev->controller, &message);
+ if (ret < 0) {
+ pr_err("%s: Error: i2s_transfer failed. MSP index: %d\n",
+ __func__,
+ dai_idx);
+ }
+
+ kfree(sg);
+
+ return ret;
+}
+
int ux500_msp_dai_i2s_send_data(void *data,
size_t bytes,
int dai_idx)
{
- unsigned long flags;
struct ux500_msp_dai_private *dai_private =
&ux500_msp_dai_private[dai_idx];
struct i2s_message message;
struct i2s_device *i2s_dev;
int ret = 0;
- pr_debug("%s: Enter MSP Index:%d bytes = %d).\n",
+ pr_debug("%s: Enter. (MSP-index: %d, bytes = %d).\n",
__func__,
dai_idx,
(int)bytes);
- spin_lock_irqsave(&dai_private->lock, flags);
i2s_dev = dai_private->i2s;
@@ -141,17 +196,13 @@ int ux500_msp_dai_i2s_send_data(void *data,
"MSP index:%d\n",
__func__,
dai_idx);
- spin_unlock_irqrestore(&dai_private->lock, flags);
return ret;
}
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_SINGLE_DMA;
+ message.i2s_direction = I2S_DIRECTION_TX;
message.txbytes = bytes;
message.txdata = data;
- message.rxbytes = 0;
- message.rxdata = NULL;
- message.dma_flag = 1;
-
- spin_unlock_irqrestore(&dai_private->lock, flags);
ret = i2s_transfer(i2s_dev->controller, &message);
if (ret < 0) {
@@ -167,43 +218,37 @@ int ux500_msp_dai_i2s_receive_data(void *data,
size_t bytes,
int dai_idx)
{
- unsigned long flags;
struct ux500_msp_dai_private *dai_private =
&ux500_msp_dai_private[dai_idx];
struct i2s_message message;
struct i2s_device *i2s_dev;
int ret = 0;
- pr_debug("%s: Enter MSP Index: %d, bytes = %d).\n",
+ pr_debug("%s: Enter. (MSP-index: %d, Bytes: %d).\n",
__func__,
dai_idx,
(int)bytes);
- spin_lock_irqsave(&dai_private->lock, flags);
-
i2s_dev = dai_private->i2s;
if (!ux500_msp_dai[dai_idx].capture.active) {
- pr_err("%s: The MSP controller is not available."
- "MSP index: %d\n",
+ pr_err("%s: MSP controller is not available. (MSP-index: %d)\n",
__func__,
dai_idx);
- spin_unlock_irqrestore(&dai_private->lock, flags);
return ret;
}
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_SINGLE_DMA;
+ message.i2s_direction = I2S_DIRECTION_RX;
message.rxbytes = bytes;
message.rxdata = data;
- message.txbytes = 0;
- message.txdata = NULL;
message.dma_flag = 1;
- spin_unlock_irqrestore(&dai_private->lock, flags);
-
ret = i2s_transfer(i2s_dev->controller, &message);
if (ret < 0) {
- pr_err("%s: Error: i2s_transfer failed. Msp index: %d\n",
+ pr_err("%s: i2s_transfer failed (%d)! (MSP-index: %d)\n",
__func__,
+ ret,
dai_idx);
}
@@ -598,7 +643,6 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *msp_dai)
{
int ret = 0;
- unsigned long flags_private;
struct ux500_msp_dai_private *dai_private = msp_dai->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
struct msp_config msp_config;
@@ -613,10 +657,9 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
pr_debug("%s: Setting up dai with rate %u.\n",
__func__,
runtime->rate);
- spin_lock_irqsave(&dai_private->lock, flags_private);
+
ux500_msp_dai_compile_msp_config(substream, dai_private,
runtime->rate, &msp_config);
- spin_unlock_irqrestore(&dai_private->lock, flags_private);
ret = i2s_setup(dai_private->i2s->controller, &msp_config);
if (ret < 0) {
@@ -778,7 +821,6 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
int cmd,
struct snd_soc_dai *msp_dai)
{
- unsigned long flags;
int ret = 0;
struct ux500_msp_dai_private *dai_private =
msp_dai->private_data;
@@ -793,8 +835,6 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
(int)dai_private->i2s->chip_select,
cmd);
- spin_lock_irqsave(&dai_private->lock, flags);
-
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
ret = 0;
@@ -815,7 +855,6 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
break;
}
- spin_unlock_irqrestore(&dai_private->lock, flags);
return ret;
}
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index 0ad8b380318..90bc518fc83 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -39,7 +39,6 @@
#define UX500_MSP_MAX_CHANNELS 8
struct ux500_msp_dai_private {
- spinlock_t lock;
struct i2s_device *i2s;
unsigned int fmt;
unsigned int tx_mask;
@@ -50,6 +49,13 @@ struct ux500_msp_dai_private {
extern struct snd_soc_dai ux500_msp_dai[UX500_NBR_OF_DAI];
+bool ux500_msp_dai_i2s_get_underrun_status(int dai_idx);
+dma_addr_t ux500_msp_dai_i2s_get_pointer(int dai_idx, int stream_id);
+int ux500_msp_dai_i2s_configure_sg(dma_addr_t dma_addr,
+ int sg_len,
+ int sg_size,
+ int dai_idx,
+ int stream_id);
int ux500_msp_dai_i2s_send_data(void *data, size_t bytes, int dai_idx);
int ux500_msp_dai_i2s_receive_data(void *data, size_t bytes, int dai_idx);
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 6a5567e1445..c0765f7a839 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -27,73 +27,49 @@
#include "ux500_msp_dai.h"
static struct snd_pcm_hardware ux500_pcm_hw_playback = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |
- SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE,
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_PAUSE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE |
+ SNDRV_PCM_FMTBIT_U16_BE,
.rates = SNDRV_PCM_RATE_KNOT,
.rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
.rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
.channels_min = UX500_PLATFORM_MIN_CHANNELS,
.channels_max = UX500_PLATFORM_MAX_CHANNELS,
- .buffer_bytes_max = UX500_PLATFORM_BUFFER_SIZE,
- .period_bytes_min = UX500_PLATFORM_MIN_PERIOD_BYTES,
- .period_bytes_max = PAGE_SIZE,
- .periods_min = UX500_PLATFORM_BUFFER_SIZE / PAGE_SIZE,
- .periods_max = UX500_PLATFORM_BUFFER_SIZE /
- UX500_PLATFORM_MIN_PERIOD_BYTES
+ .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
+ .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
+ .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
+ .periods_min = UX500_PLATFORM_PERIODS_MIN,
+ .periods_max = UX500_PLATFORM_PERIODS_MAX,
};
static struct snd_pcm_hardware ux500_pcm_hw_capture = {
- .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |
- SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U16_BE,
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_PAUSE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE |
+ SNDRV_PCM_FMTBIT_U16_BE,
.rates = SNDRV_PCM_RATE_KNOT,
.rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE,
.rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE,
.channels_min = UX500_PLATFORM_MIN_CHANNELS,
.channels_max = UX500_PLATFORM_MAX_CHANNELS,
- .buffer_bytes_max = UX500_PLATFORM_BUFFER_SIZE,
- .period_bytes_min = UX500_PLATFORM_MIN_PERIOD_BYTES,
- .period_bytes_max = PAGE_SIZE,
- .periods_min = UX500_PLATFORM_BUFFER_SIZE / PAGE_SIZE,
- .periods_max = UX500_PLATFORM_BUFFER_SIZE /
- UX500_PLATFORM_MIN_PERIOD_BYTES
+ .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
+ .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
+ .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
+ .periods_min = UX500_PLATFORM_PERIODS_MIN,
+ .periods_max = UX500_PLATFORM_PERIODS_MAX,
};
-static void ux500_pcm_dma_enqueue(struct snd_pcm_substream *substream)
-{
- unsigned int dma_size;
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct ux500_pcm_private *private = substream->runtime->private_data;
-
- pr_debug("%s: Enter MSP Index: %d.\n",
- __func__,
- private->msp_id);
-
- dma_size = frames_to_bytes(runtime, runtime->period_size);
- if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ux500_msp_dai_i2s_send_data(
- (void *)(runtime->dma_addr + private->offset),
- dma_size,
- private->msp_id);
- } else{
- ux500_msp_dai_i2s_receive_data(
- (void *)(runtime->dma_addr + private->offset),
- dma_size,
- private->msp_id);
- }
-
- private->period++;
- private->period %= runtime->periods;
- private->offset =
- frames_to_bytes(runtime, runtime->period_size) *
- private->period;
-}
-
static void ux500_pcm_dma_hw_free(struct device *dev,
- struct snd_pcm_substream *substream)
+ struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dma_buffer *buf = runtime->dma_buffer_p;
@@ -125,10 +101,10 @@ void ux500_pcm_dma_eot_handler(void *data)
runtime = substream->runtime;
private = substream->runtime->private_data;
- snd_pcm_period_elapsed(substream);
+ if (ux500_msp_dai_i2s_get_underrun_status(private->msp_id))
+ private->no_of_underruns++;
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
- ux500_pcm_dma_enqueue(substream);
+ snd_pcm_period_elapsed(substream);
}
}
EXPORT_SYMBOL(ux500_pcm_dma_eot_handler);
@@ -237,22 +213,37 @@ static int ux500_pcm_prepare(struct snd_pcm_substream *substream)
static int ux500_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
- int i;
- struct ux500_pcm_private *private = substream->runtime->private_data;
+ int ret;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct ux500_pcm_private *private = runtime->private_data;
+ int stream_id = substream->pstr->stream;
pr_debug("%s: Enter\n", __func__);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- for (i = 0; i < UX500_PLATFORM_PERIODS_QUEUED_DMA; i++)
- ux500_pcm_dma_enqueue(substream);
+ private->no_of_underruns = 0;
+ ret = ux500_msp_dai_i2s_configure_sg(runtime->dma_addr,
+ runtime->periods,
+ frames_to_bytes(runtime,
+ runtime->period_size),
+ private->msp_id,
+ stream_id);
+ if (ret) {
+ pr_err("%s: Failed to configure sg-list!\n", __func__);
+ return -EINVAL;
+ }
break;
+
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
break;
+
case SNDRV_PCM_TRIGGER_STOP:
pr_debug("%s: SNDRV_PCM_TRIGGER_STOP\n", __func__);
- private->period = 0;
+ pr_debug("%s: no_of_underruns = %u\n",
+ __func__,
+ private->no_of_underruns);
break;
default:
@@ -266,18 +257,17 @@ static int ux500_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
static snd_pcm_uframes_t ux500_pcm_pointer(struct snd_pcm_substream *substream)
{
- unsigned int offset;
struct snd_pcm_runtime *runtime = substream->runtime;
struct ux500_pcm_private *private = substream->runtime->private_data;
+ int stream_id = substream->pstr->stream;
+ unsigned int offset;
+ dma_addr_t addr;
pr_debug("%s: Enter\n", __func__);
- offset = bytes_to_frames(runtime, private->offset);
- if (offset < 0 || private->offset < 0)
- pr_debug("%s: Offset=%i %i\n",
- __func__,
- offset,
- private->offset);
+ addr = ux500_msp_dai_i2s_get_pointer(private->msp_id, stream_id);
+ offset = bytes_to_frames(runtime, addr - runtime->dma_addr);
+ pr_debug("%s: Offset = %u\n", __func__, offset);
return offset;
}
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
index 80f050128c8..9d8b36d9b6f 100644
--- a/sound/soc/ux500/ux500_pcm.h
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -16,8 +16,6 @@
#include <mach/msp.h>
-#define UX500_PLATFORM_BUFFER_SIZE (64*1024)
-
#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
@@ -25,17 +23,19 @@
#define UX500_PLATFORM_MIN_CHANNELS 1
#define UX500_PLATFORM_MAX_CHANNELS 8
-#define UX500_PLATFORM_MIN_PERIOD_BYTES 128
-#define UX500_PLATFORM_PERIODS_QUEUED_DMA 5
+#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
+#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
+#define UX500_PLATFORM_PERIODS_MIN 2
+#define UX500_PLATFORM_PERIODS_MAX 48
+#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
extern struct snd_soc_platform ux500_soc_platform;
struct ux500_pcm_private {
int msp_id;
int stream_id;
- int period;
- unsigned int offset;
+ unsigned int no_of_underruns;
};
void ux500_pcm_dma_eot_handler(void *data);
diff --git a/sound/u8500_acodec_ab8500.c b/sound/u8500_acodec_ab8500.c
index 2c1ae702b79..c75da368832 100644
--- a/sound/u8500_acodec_ab8500.c
+++ b/sound/u8500_acodec_ab8500.c
@@ -333,10 +333,11 @@ t_ab8500_codec_error u8500_acodec_send_data(int client_id, void *data,
stm_dbg(DBG_ST.acodec, " I2S controller not available\n");
return -1;
}
+
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_SINGLE_DMA;
+ message.i2s_direction = I2S_DIRECTION_TX;
message.txbytes = bytes;
message.txdata = data;
- message.rxbytes = 0;
- message.rxdata = NULL;
message.dma_flag = dma_flag;
bytes_transmit = i2s_transfer(i2s_dev->controller, &message);
@@ -369,12 +370,12 @@ t_ab8500_codec_error u8500_acodec_loopback_configure(int client_id, void *data,
return -1;
}
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_INF_LOOPBACK;
message.rxbytes = bytes;
message.rxdata = data;
message.txbytes = bytes;
message.txdata = data;
message.dma_flag = dma_flag;
- message.inf_loopback_xfer = true;
bytes_receive = i2s_transfer(i2s_dev->controller, &message);
@@ -406,10 +407,10 @@ t_ab8500_codec_error u8500_acodec_receive_data(int client_id, void *data,
return -1;
}
+ message.i2s_transfer_mode = I2S_TRANSFER_MODE_SINGLE_DMA;
+ message.i2s_direction = I2S_DIRECTION_RX;
message.rxbytes = bytes;
message.rxdata = data;
- message.txbytes = 0;
- message.txdata = NULL;
message.dma_flag = dma_flag;
bytes_receive = i2s_transfer(i2s_dev->controller, &message);