diff options
-rw-r--r-- | drivers/mxc/asrc/mxc_asrc.c | 95 | ||||
-rw-r--r-- | include/linux/mxc_asrc.h | 14 |
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, |