From 86f1764a87d4149afb903ad1782a9147e43ffff5 Mon Sep 17 00:00:00 2001 From: Chen Liangjun Date: Wed, 31 Oct 2012 17:27:23 +0800 Subject: [PATCH] ENGR00231773-8 ASRC: prevent user app from processing input/output processing To finish a buffer convert in ASRC, user should 1. prepare input buffer, 2. prepare output buffer 3. wait for output buffer's completion 4.wait for input buffer's comletion. The flow make user application ugly. In this patch, pack steps above to 1 stop: ASRC_CONVERT. Signed-off-by: Chen Liangjun --- drivers/mxc/asrc/mxc_asrc.c | 95 ++++++++++++++++++++++++------------- 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, -- 2.39.5