summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mxc/asrc/mxc_asrc.c95
-rw-r--r--include/linux/mxc_asrc.h14
2 files changed, 66 insertions, 43 deletions
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c
index d9888a483de2..d16d7166ed5a 100644
--- a/drivers/mxc/asrc/mxc_asrc.c
+++ b/drivers/mxc/asrc/mxc_asrc.c
@@ -886,11 +886,26 @@ static unsigned int asrc_get_output_FIFO_size(enum asrc_pair_index index)
>> ASRC_ASRFSTX_OUTPUT_FIFO_OFFSET;
}
+static unsigned int asrc_get_input_FIFO_size(enum asrc_pair_index index)
+{
+ u32 reg;
+
+ reg = __raw_readl(g_asrc->vaddr + ASRC_ASRFSTA_REG + (index << 3));
+ return (reg & ASRC_ASRFSTX_INPUT_FIFO_MASK) >>
+ ASRC_ASRFSTX_INPUT_FIFO_OFFSET;
+}
+
+
static u32 asrc_read_one_from_output_FIFO(enum asrc_pair_index index)
{
return __raw_readl(g_asrc->vaddr + ASRC_ASRDOA_REG + (index << 3));
}
+static void asrc_write_one_to_output_FIFO(enum asrc_pair_index index, u32 value)
+{
+ __raw_writel(value, g_asrc->vaddr + ASRC_ASRDIA_REG + (index << 3));
+}
+
static void asrc_read_output_FIFO_S16(struct asrc_pair_params *params)
{
u32 size, i, j, reg, t_size;
@@ -1335,6 +1350,37 @@ int mxc_asrc_process_input_buffer(struct asrc_pair_params *params,
return 0;
}
+static void mxc_asrc_submit_dma(struct asrc_pair_params *params)
+{
+ enum asrc_pair_index index;
+ u32 size, i, j;
+ index = params->index;
+
+ /* read all data in OUTPUT FIFO*/
+ size = asrc_get_output_FIFO_size(params->index);
+ while (size) {
+ for (j = 0; j < size; j++) {
+ for (i = 0; i < params->channel_nums; i++)
+ asrc_read_one_from_output_FIFO(params->index);
+ }
+ mdelay(1);
+ size = asrc_get_output_FIFO_size(params->index);
+ }
+
+ /* Fill the input FIFO until reach the stall level */
+ size = asrc_get_input_FIFO_size(params->index);
+ while (size < 3) {
+ for (i = 0; i < params->channel_nums; i++)
+ asrc_write_one_to_output_FIFO(params->index, 0);
+ size = asrc_get_input_FIFO_size(params->index);
+ }
+
+ /* submit dma request */
+ dmaengine_submit(params->desc_in);
+ dmaengine_submit(params->desc_out);
+ sdma_set_event_pending(params->input_dma_channel);
+
+}
/*!
* asrc interface - function
@@ -1477,7 +1523,7 @@ static long asrc_ioctl(struct file *file,
params->pair_hold = 0;
break;
}
- case ASRC_Q_INBUF:
+ case ASRC_CONVERT:
{
struct asrc_convert_buffer buf;
if (copy_from_user
@@ -1488,43 +1534,27 @@ static long asrc_ioctl(struct file *file,
}
err = mxc_asrc_prepare_input_buffer(params, &buf);
+ if (err)
+ break;
- break;
- }
- case ASRC_DQ_INBUF:{
- struct asrc_convert_buffer buf;
- if (copy_from_user
- (&buf, (void __user *)arg,
- sizeof(struct asrc_convert_buffer))) {
- err = -EFAULT;
+ err = mxc_asrc_prepare_output_buffer(params, &buf);
+ if (err)
break;
- }
- err = mxc_asrc_process_input_buffer(params, &buf);
+ mxc_asrc_submit_dma(params);
- break;
- }
- case ASRC_Q_OUTBUF:{
- struct asrc_convert_buffer buf;
- if (copy_from_user
- (&buf, (void __user *)arg,
- sizeof(struct asrc_convert_buffer))) {
- err = -EFAULT;
+ err = mxc_asrc_process_output_buffer(params, &buf);
+ if (err)
break;
- }
- err = mxc_asrc_prepare_output_buffer(params, &buf);
- break;
- }
- case ASRC_DQ_OUTBUF:{
- struct asrc_convert_buffer buf;
- if (copy_from_user
- (&buf, (void __user *)arg,
- sizeof(struct asrc_convert_buffer))) {
- err = -EFAULT;
+ err = mxc_asrc_process_input_buffer(params, &buf);
+ if (err)
break;
- }
- err = mxc_asrc_process_output_buffer(params, &buf);
+
+ if (copy_to_user
+ ((void __user *)arg, &buf,
+ sizeof(struct asrc_convert_buffer)))
+ err = -EFAULT;
break;
}
@@ -1538,9 +1568,6 @@ static long asrc_ioctl(struct file *file,
}
params->asrc_active = 1;
- dmaengine_submit(params->desc_in);
- dmaengine_submit(params->desc_out);
-
asrc_start_conv(index);
break;
diff --git a/include/linux/mxc_asrc.h b/include/linux/mxc_asrc.h
index d1b313699477..8c0c45d86cfd 100644
--- a/include/linux/mxc_asrc.h
+++ b/include/linux/mxc_asrc.h
@@ -27,15 +27,11 @@
#define ASRC_REQ_PAIR _IOWR(ASRC_IOC_MAGIC, 0, struct asrc_req)
#define ASRC_CONFIG_PAIR _IOWR(ASRC_IOC_MAGIC, 1, struct asrc_config)
#define ASRC_RELEASE_PAIR _IOW(ASRC_IOC_MAGIC, 2, enum asrc_pair_index)
-#define ASRC_Q_INBUF _IOW(ASRC_IOC_MAGIC, 4, struct asrc_buffer)
-#define ASRC_DQ_INBUF _IOW(ASRC_IOC_MAGIC, 5, struct asrc_buffer)
-#define ASRC_Q_OUTBUF _IOW(ASRC_IOC_MAGIC, 6, struct asrc_buffer)
-#define ASRC_DQ_OUTBUF _IOW(ASRC_IOC_MAGIC, 7, struct asrc_buffer)
-#define ASRC_START_CONV _IOW(ASRC_IOC_MAGIC, 8, enum asrc_pair_index)
-#define ASRC_STOP_CONV _IOW(ASRC_IOC_MAGIC, 9, enum asrc_pair_index)
-#define ASRC_STATUS _IOW(ASRC_IOC_MAGIC, 10, struct asrc_status_flags)
-#define ASRC_FLUSH _IOW(ASRC_IOC_MAGIC, 11, enum asrc_pair_index)
-
+#define ASRC_CONVERT _IOW(ASRC_IOC_MAGIC, 3, struct asrc_convert_buffer)
+#define ASRC_START_CONV _IOW(ASRC_IOC_MAGIC, 4, enum asrc_pair_index)
+#define ASRC_STOP_CONV _IOW(ASRC_IOC_MAGIC, 5, enum asrc_pair_index)
+#define ASRC_STATUS _IOW(ASRC_IOC_MAGIC, 6, struct asrc_status_flags)
+#define ASRC_FLUSH _IOW(ASRC_IOC_MAGIC, 7, enum asrc_pair_index)
enum asrc_pair_index {
ASRC_PAIR_A,