2 * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
17 * @brief MXC Asynchronous Sample Rate Converter
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/kernel.h>
25 #include <linux/init.h>
26 #include <linux/clk.h>
28 #include <linux/slab.h>
29 #include <linux/ctype.h>
30 #include <linux/pagemap.h>
31 #include <linux/vmalloc.h>
32 #include <linux/types.h>
33 #include <linux/version.h>
34 #include <linux/interrupt.h>
35 #include <linux/proc_fs.h>
36 #include <linux/dma-mapping.h>
37 #include <linux/mxc_asrc.h>
38 #include <linux/fsl_devices.h>
39 #include <linux/sched.h>
41 #include <asm/memory.h>
43 #include <mach/mxc_asrc.h>
45 #define ASRC_PROC_PATH "driver/asrc"
47 #define ASRC_RATIO_DECIMAL_DEPTH 26
49 DEFINE_SPINLOCK(data_lock);
50 DEFINE_SPINLOCK(input_int_lock);
51 DEFINE_SPINLOCK(output_int_lock);
53 #define AICPA 0 /* Input Clock Divider A Offset */
54 #define AICDA 3 /* Input Clock Prescaler A Offset */
55 #define AICPB 6 /* Input Clock Divider B Offset */
56 #define AICDB 9 /* Input Clock Prescaler B Offset */
57 #define AOCPA 12 /* Output Clock Divider A Offset */
58 #define AOCDA 15 /* Output Clock Prescaler A Offset */
59 #define AOCPB 18 /* Output Clock Divider B Offset */
60 #define AOCDB 21 /* Output Clock Prescaler B Offset */
61 #define AICPC 0 /* Input Clock Divider C Offset */
62 #define AICDC 3 /* Input Clock Prescaler C Offset */
63 #define AOCDC 6 /* Output Clock Prescaler C Offset */
64 #define AOCPC 9 /* Output Clock Divider C Offset */
66 char *asrc_pair_id[] = {
67 [0] = "ASRC RX PAIR A",
68 [1] = "ASRC TX PAIR A",
69 [2] = "ASRC RX PAIR B",
70 [3] = "ASRC TX PAIR B",
71 [4] = "ASRC RX PAIR C",
72 [5] = "ASRC TX PAIR C",
76 ASRC_ASRSTR_AIDEA = 0x01,
77 ASRC_ASRSTR_AIDEB = 0x02,
78 ASRC_ASRSTR_AIDEC = 0x04,
79 ASRC_ASRSTR_AODFA = 0x08,
80 ASRC_ASRSTR_AODFB = 0x10,
81 ASRC_ASRSTR_AODFC = 0x20,
82 ASRC_ASRSTR_AOLE = 0x40,
83 ASRC_ASRSTR_FPWT = 0x80,
84 ASRC_ASRSTR_AIDUA = 0x100,
85 ASRC_ASRSTR_AIDUB = 0x200,
86 ASRC_ASRSTR_AIDUC = 0x400,
87 ASRC_ASRSTR_AODOA = 0x800,
88 ASRC_ASRSTR_AODOB = 0x1000,
89 ASRC_ASRSTR_AODOC = 0x2000,
90 ASRC_ASRSTR_AIOLA = 0x4000,
91 ASRC_ASRSTR_AIOLB = 0x8000,
92 ASRC_ASRSTR_AIOLC = 0x10000,
93 ASRC_ASRSTR_AOOLA = 0x20000,
94 ASRC_ASRSTR_AOOLB = 0x40000,
95 ASRC_ASRSTR_AOOLC = 0x80000,
96 ASRC_ASRSTR_ATQOL = 0x100000,
97 ASRC_ASRSTR_DSLCNT = 0x200000,
100 /* Sample rates are aligned with that defined in pcm.h file */
101 static const unsigned char asrc_process_table[][8][2] = {
102 /* 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
104 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
106 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
108 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
110 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
112 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
114 {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},},
116 {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},
118 {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},
120 {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},},
122 {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},
124 {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},
126 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},
128 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},
131 static struct asrc_data *g_asrc;
133 /* The following tables map the relationship between asrc_inclk/asrc_outclk in
134 * mxc_asrc.h and the registers of ASRCSR
136 static unsigned char input_clk_map_v1[] = {
137 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
140 static unsigned char output_clk_map_v1[] = {
141 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
144 static unsigned char input_clk_map_v2[] = {
145 0, 1, 2, 3, 4, 5, 0xf, 0xf, 0xf, 8, 9, 0xa, 0xb, 0xc, 0xf, 0xd,
148 static unsigned char output_clk_map_v2[] = {
149 8, 9, 0xa, 0, 0xc, 0x5, 0xf, 0xf, 0, 1, 2, 0xf, 0xf, 4, 0xf, 0xd,
152 static unsigned char *input_clk_map, *output_clk_map;
154 static struct dma_chan *imx_asrc_dma_alloc(u32 dma_req);
155 struct dma_async_tx_descriptor *imx_asrc_dma_config(
156 struct asrc_pair_params *params,
157 struct dma_chan *chan,
158 u32 dma_addr, dma_addr_t buf_addr,
159 u32 buf_len, bool in,
160 enum asrc_word_width word_width);
162 static int asrc_set_clock_ratio(enum asrc_pair_index index,
163 int input_sample_rate, int output_sample_rate)
167 unsigned long reg_val = 0;
169 if (output_sample_rate == 0)
171 while (input_sample_rate >= output_sample_rate) {
172 input_sample_rate -= output_sample_rate;
175 reg_val |= (integ << 26);
177 for (i = 1; i <= ASRC_RATIO_DECIMAL_DEPTH; i++) {
178 if ((input_sample_rate * 2) >= output_sample_rate) {
179 reg_val |= (1 << (ASRC_RATIO_DECIMAL_DEPTH - i));
181 input_sample_rate * 2 - output_sample_rate;
183 input_sample_rate = input_sample_rate << 1;
185 if (input_sample_rate == 0)
189 __raw_writel(reg_val,
190 (g_asrc->vaddr + ASRC_ASRIDRLA_REG + (index << 3)));
191 __raw_writel((reg_val >> 24),
192 (g_asrc->vaddr + ASRC_ASRIDRHA_REG + (index << 3)));
196 static int asrc_set_process_configuration(enum asrc_pair_index index,
197 int input_sample_rate,
198 int output_sample_rate)
202 switch (input_sample_rate) {
245 switch (output_sample_rate) {
274 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCFG_REG);
275 reg &= ~(0x0f << (6 + (index << 2)));
277 ((asrc_process_table[i][j][0] << (6 + (index << 2))) |
278 (asrc_process_table[i][j][1] << (8 + (index << 2))));
279 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCFG_REG);
284 static int asrc_get_asrck_clock_divider(int samplerate)
286 unsigned int prescaler, divider;
288 unsigned int ratio, ra;
289 unsigned long bitclk;
291 bitclk = clk_get_rate(g_asrc->mxc_asrc_data->asrc_audio_clk);
293 ra = bitclk/samplerate;
295 /*calculate the prescaler*/
302 /*calculate the divider*/
304 divider = ((ra + (1 << (i - 1)) - 1) >> i) - 1;
307 /*the totally divider is (2^prescaler)*divider*/
308 return (divider << 3) + prescaler;
311 int asrc_req_pair(int chn_num, enum asrc_pair_index *index)
314 unsigned long lock_flags;
315 struct asrc_pair *pair;
316 spin_lock_irqsave(&data_lock, lock_flags);
319 pair = &g_asrc->asrc_pair[ASRC_PAIR_C];
320 if (pair->active || (chn_num > pair->chn_max))
323 *index = ASRC_PAIR_C;
324 pair->chn_num = chn_num;
328 pair = &g_asrc->asrc_pair[ASRC_PAIR_A];
329 if (pair->active || (pair->chn_max == 0)) {
330 pair = &g_asrc->asrc_pair[ASRC_PAIR_B];
331 if (pair->active || (pair->chn_max == 0))
334 *index = ASRC_PAIR_B;
339 *index = ASRC_PAIR_A;
344 spin_unlock_irqrestore(&data_lock, lock_flags);
347 clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
348 clk_enable(g_asrc->mxc_asrc_data->asrc_audio_clk);
353 EXPORT_SYMBOL(asrc_req_pair);
355 void asrc_release_pair(enum asrc_pair_index index)
358 unsigned long lock_flags;
359 struct asrc_pair *pair;
360 pair = &g_asrc->asrc_pair[index];
362 spin_lock_irqsave(&data_lock, lock_flags);
364 pair->overload_error = 0;
365 /********Disable PAIR*************/
366 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
367 reg &= ~(1 << (index + 1));
368 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
369 spin_unlock_irqrestore(&data_lock, lock_flags);
372 EXPORT_SYMBOL(asrc_release_pair);
374 int asrc_config_pair(struct asrc_config *config)
377 int reg, tmp, channel_num;
378 unsigned long lock_flags;
379 /* Set the channel number */
380 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCNCR_REG);
381 spin_lock_irqsave(&data_lock, lock_flags);
382 g_asrc->asrc_pair[config->pair].chn_num = config->channel_num;
383 spin_unlock_irqrestore(&data_lock, lock_flags);
385 ~((0xFFFFFFFF >> (32 - g_asrc->mxc_asrc_data->channel_bits)) <<
386 (g_asrc->mxc_asrc_data->channel_bits * config->pair));
387 if (g_asrc->mxc_asrc_data->channel_bits > 3)
388 channel_num = config->channel_num;
390 channel_num = (config->channel_num + 1) / 2;
392 (g_asrc->mxc_asrc_data->channel_bits * config->pair);
394 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCNCR_REG);
396 /* Set the clock source */
397 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCSR_REG);
398 tmp = ~(0x0f << (config->pair << 2));
400 tmp = ~(0x0f << (12 + (config->pair << 2)));
402 reg |= ((input_clk_map[config->inclk] << (config->pair << 2)) |
403 (output_clk_map[config->outclk] << (12 + (config->pair << 2))));
405 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCSR_REG);
407 /* default setting */
408 /* automatic selection for processing mode */
409 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
410 reg |= (1 << (20 + config->pair));
411 reg &= ~(1 << (14 + (config->pair << 1)));
413 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
415 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRRA_REG);
417 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRRA_REG);
419 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
420 reg = reg & (~(1 << 23));
421 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
423 /* Default Clock Divider Setting */
424 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCDR1_REG);
425 if (config->pair == ASRC_PAIR_A) {
426 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCDR1_REG);
429 if ((config->inclk & 0x0f) == INCLK_SPDIF_RX)
431 else if ((config->inclk & 0x0f) == INCLK_SPDIF_TX)
433 else if ((config->inclk & 0x0f) == INCLK_ASRCK1_CLK) {
435 asrc_get_asrck_clock_divider(config->
439 if (config->input_word_width == ASRC_WIDTH_16_BIT)
441 else if (config->input_word_width == ASRC_WIDTH_24_BIT)
447 if ((config->outclk & 0x0f) == OUTCLK_SPDIF_RX)
449 else if ((config->outclk & 0x0f) == OUTCLK_SPDIF_TX)
451 else if ((config->outclk & 0x0f) == OUTCLK_ASRCK1_CLK) {
453 asrc_get_asrck_clock_divider(config->
457 if (config->output_word_width == ASRC_WIDTH_16_BIT)
459 else if (config->output_word_width == ASRC_WIDTH_24_BIT)
465 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCDR1_REG);
467 } else if (config->pair == ASRC_PAIR_B) {
468 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCDR1_REG);
471 if ((config->inclk & 0x0f) == INCLK_SPDIF_RX)
473 else if ((config->inclk & 0x0f) == INCLK_SPDIF_TX)
475 else if ((config->inclk & 0x0f) == INCLK_ASRCK1_CLK) {
477 asrc_get_asrck_clock_divider(config->
481 if (config->input_word_width == ASRC_WIDTH_16_BIT)
483 else if (config->input_word_width == ASRC_WIDTH_24_BIT)
489 if ((config->outclk & 0x0f) == OUTCLK_SPDIF_RX)
491 else if ((config->outclk & 0x0f) == OUTCLK_SPDIF_TX)
493 else if ((config->outclk & 0x0f) == OUTCLK_ASRCK1_CLK) {
495 asrc_get_asrck_clock_divider(config->
499 if (config->output_word_width == ASRC_WIDTH_16_BIT)
501 else if (config->output_word_width == ASRC_WIDTH_24_BIT)
507 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCDR1_REG);
510 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCDR2_REG);
513 if ((config->inclk & 0x0f) == INCLK_SPDIF_RX)
515 else if ((config->inclk & 0x0f) == INCLK_SPDIF_TX)
517 else if ((config->inclk & 0x0f) == INCLK_ASRCK1_CLK) {
519 asrc_get_asrck_clock_divider(config->
523 if (config->input_word_width == ASRC_WIDTH_16_BIT)
525 else if (config->input_word_width == ASRC_WIDTH_24_BIT)
531 if ((config->outclk & 0x0f) == OUTCLK_SPDIF_RX)
533 else if ((config->outclk & 0x0f) == OUTCLK_SPDIF_TX)
535 else if ((config->outclk & 0x0f) == OUTCLK_ASRCK1_CLK) {
537 asrc_get_asrck_clock_divider(config->
541 if (config->output_word_width == ASRC_WIDTH_16_BIT)
543 else if (config->output_word_width == ASRC_WIDTH_24_BIT)
548 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCDR2_REG);
552 /* check whether ideal ratio is a must */
553 if ((config->inclk & 0x0f) == INCLK_NONE) {
554 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
555 reg &= ~(1 << (20 + config->pair));
556 reg |= (0x03 << (13 + (config->pair << 1)));
557 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
558 err = asrc_set_clock_ratio(config->pair,
559 config->input_sample_rate,
560 config->output_sample_rate);
564 err = asrc_set_process_configuration(config->pair,
565 config->input_sample_rate,
570 } else if ((config->inclk & 0x0f) == INCLK_ASRCK1_CLK) {
571 if (config->input_sample_rate == 44100
572 || config->input_sample_rate == 88200) {
573 pr_err("ASRC core clock cann't support sample rate %d\n",
574 config->input_sample_rate);
577 } else if ((config->outclk & 0x0f) == OUTCLK_ASRCK1_CLK) {
578 if (config->output_sample_rate == 44100
579 || config->output_sample_rate == 88200) {
580 pr_err("ASRC core clock cann't support sample rate %d\n",
581 config->input_sample_rate);
586 if ((config->inclk == INCLK_ASRCK1_CLK) &&
587 (config->outclk == OUTCLK_ESAI_TX)) {
588 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
589 reg |= (1 << (20 + config->pair));
590 reg |= (0x02 << (13 + (config->pair << 1)));
591 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
592 err = asrc_set_clock_ratio(config->pair,
593 config->input_sample_rate,
594 config->output_sample_rate);
599 /* Config input and output wordwidth */
601 g_asrc->vaddr + ASRC_ASRMCR1A_REG + (config->pair << 2));
602 /* BIT 11-9 stands for input word width,
603 * BIT 0 stands for output word width */
605 switch (config->input_word_width) {
606 case ASRC_WIDTH_16_BIT:
609 case ASRC_WIDTH_24_BIT:
616 switch (config->output_word_width) {
617 case ASRC_WIDTH_16_BIT:
620 case ASRC_WIDTH_24_BIT:
627 g_asrc->vaddr + ASRC_ASRMCR1A_REG + (config->pair << 2));
632 EXPORT_SYMBOL(asrc_config_pair);
634 void asrc_start_conv(enum asrc_pair_index index)
637 unsigned long lock_flags;
640 spin_lock_irqsave(&data_lock, lock_flags);
641 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
642 reg |= (1 << (1 + index));
643 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
645 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCFG_REG);
646 while (!(reg & (1 << (index + 21))))
647 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCFG_REG);
648 reg_1 = __raw_readl(g_asrc->vaddr + ASRC_ASRSTR_REG);
651 for (i = 0; i < 20; i++) {
653 g_asrc->vaddr + ASRC_ASRDIA_REG +
656 g_asrc->vaddr + ASRC_ASRDIA_REG +
659 g_asrc->vaddr + ASRC_ASRDIA_REG +
662 g_asrc->vaddr + ASRC_ASRDIA_REG +
665 g_asrc->vaddr + ASRC_ASRDIA_REG +
668 g_asrc->vaddr + ASRC_ASRDIA_REG +
671 g_asrc->vaddr + ASRC_ASRDIA_REG +
674 g_asrc->vaddr + ASRC_ASRDIA_REG +
678 __raw_writel(0x40, g_asrc->vaddr + ASRC_ASRIER_REG);
679 spin_unlock_irqrestore(&data_lock, lock_flags);
683 EXPORT_SYMBOL(asrc_start_conv);
685 void asrc_stop_conv(enum asrc_pair_index index)
688 unsigned long lock_flags;
689 spin_lock_irqsave(&data_lock, lock_flags);
690 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCTR_REG);
691 reg &= ~(1 << (1 + index));
692 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
693 spin_unlock_irqrestore(&data_lock, lock_flags);
698 EXPORT_SYMBOL(asrc_stop_conv);
700 void asrc_finish_conv(enum asrc_pair_index index)
702 clk_disable(g_asrc->mxc_asrc_data->asrc_audio_clk);
703 clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
707 EXPORT_SYMBOL(asrc_finish_conv);
709 int asrc_get_dma_request(enum asrc_pair_index index, bool in)
712 return g_asrc->dmarx[index];
714 return g_asrc->dmatx[index];
717 EXPORT_SYMBOL(asrc_get_dma_request);
720 * @brief asrc interrupt handler
722 static irqreturn_t asrc_isr(int irq, void *dev_id)
724 unsigned long status;
727 status = __raw_readl(g_asrc->vaddr + ASRC_ASRSTR_REG);
728 if (g_asrc->asrc_pair[ASRC_PAIR_A].active == 1) {
729 if (status & ASRC_ASRSTR_ATQOL)
730 g_asrc->asrc_pair[ASRC_PAIR_A].overload_error |=
731 ASRC_TASK_Q_OVERLOAD;
732 if (status & ASRC_ASRSTR_AOOLA)
733 g_asrc->asrc_pair[ASRC_PAIR_A].overload_error |=
734 ASRC_OUTPUT_TASK_OVERLOAD;
735 if (status & ASRC_ASRSTR_AIOLA)
736 g_asrc->asrc_pair[ASRC_PAIR_A].overload_error |=
737 ASRC_INPUT_TASK_OVERLOAD;
738 if (status & ASRC_ASRSTR_AODOA)
739 g_asrc->asrc_pair[ASRC_PAIR_A].overload_error |=
740 ASRC_OUTPUT_BUFFER_OVERFLOW;
741 if (status & ASRC_ASRSTR_AIDUA)
742 g_asrc->asrc_pair[ASRC_PAIR_A].overload_error |=
743 ASRC_INPUT_BUFFER_UNDERRUN;
744 } else if (g_asrc->asrc_pair[ASRC_PAIR_B].active == 1) {
745 if (status & ASRC_ASRSTR_ATQOL)
746 g_asrc->asrc_pair[ASRC_PAIR_B].overload_error |=
747 ASRC_TASK_Q_OVERLOAD;
748 if (status & ASRC_ASRSTR_AOOLB)
749 g_asrc->asrc_pair[ASRC_PAIR_B].overload_error |=
750 ASRC_OUTPUT_TASK_OVERLOAD;
751 if (status & ASRC_ASRSTR_AIOLB)
752 g_asrc->asrc_pair[ASRC_PAIR_B].overload_error |=
753 ASRC_INPUT_TASK_OVERLOAD;
754 if (status & ASRC_ASRSTR_AODOB)
755 g_asrc->asrc_pair[ASRC_PAIR_B].overload_error |=
756 ASRC_OUTPUT_BUFFER_OVERFLOW;
757 if (status & ASRC_ASRSTR_AIDUB)
758 g_asrc->asrc_pair[ASRC_PAIR_B].overload_error |=
759 ASRC_INPUT_BUFFER_UNDERRUN;
760 } else if (g_asrc->asrc_pair[ASRC_PAIR_C].active == 1) {
761 if (status & ASRC_ASRSTR_ATQOL)
762 g_asrc->asrc_pair[ASRC_PAIR_C].overload_error |=
763 ASRC_TASK_Q_OVERLOAD;
764 if (status & ASRC_ASRSTR_AOOLC)
765 g_asrc->asrc_pair[ASRC_PAIR_C].overload_error |=
766 ASRC_OUTPUT_TASK_OVERLOAD;
767 if (status & ASRC_ASRSTR_AIOLC)
768 g_asrc->asrc_pair[ASRC_PAIR_C].overload_error |=
769 ASRC_INPUT_TASK_OVERLOAD;
770 if (status & ASRC_ASRSTR_AODOC)
771 g_asrc->asrc_pair[ASRC_PAIR_C].overload_error |=
772 ASRC_OUTPUT_BUFFER_OVERFLOW;
773 if (status & ASRC_ASRSTR_AIDUC)
774 g_asrc->asrc_pair[ASRC_PAIR_C].overload_error |=
775 ASRC_INPUT_BUFFER_UNDERRUN;
777 /* try to clean the overload error */
778 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRSTR_REG);
783 void asrc_get_status(struct asrc_status_flags *flags)
785 unsigned long lock_flags;
786 enum asrc_pair_index index;
788 spin_lock_irqsave(&data_lock, lock_flags);
789 index = flags->index;
790 flags->overload_error = g_asrc->asrc_pair[index].overload_error;
792 spin_unlock_irqrestore(&data_lock, lock_flags);
796 EXPORT_SYMBOL(asrc_get_status);
798 u32 asrc_get_per_addr(enum asrc_pair_index index, bool in)
801 return g_asrc->paddr + ASRC_ASRDIA_REG + (index << 3);
803 return g_asrc->paddr + ASRC_ASRDOA_REG + (index << 3);
806 EXPORT_SYMBOL(asrc_get_per_addr);
808 static int mxc_init_asrc(void)
810 /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
811 __raw_writel(0x0001, g_asrc->vaddr + ASRC_ASRCTR_REG);
813 /* Enable overflow interrupt */
814 __raw_writel(0x00, g_asrc->vaddr + ASRC_ASRIER_REG);
816 /* Default 6: 2: 2 channel assignment */
817 __raw_writel((0x06 << g_asrc->mxc_asrc_data->channel_bits *
818 2) | (0x02 << g_asrc->mxc_asrc_data->channel_bits) | 0x02,
819 g_asrc->vaddr + ASRC_ASRCNCR_REG);
821 /* Parameter Registers recommended settings */
822 __raw_writel(0x7fffff, g_asrc->vaddr + ASRC_ASRPM1_REG);
823 __raw_writel(0x255555, g_asrc->vaddr + ASRC_ASRPM2_REG);
824 __raw_writel(0xff7280, g_asrc->vaddr + ASRC_ASRPM3_REG);
825 __raw_writel(0xff7280, g_asrc->vaddr + ASRC_ASRPM4_REG);
826 __raw_writel(0xff7280, g_asrc->vaddr + ASRC_ASRPM5_REG);
828 __raw_writel(0x001f00, g_asrc->vaddr + ASRC_ASRTFR1);
830 /* Set the processing clock for 76KHz, 133M */
831 __raw_writel(0x30E, g_asrc->vaddr + ASRC_ASR76K_REG);
833 /* Set the processing clock for 56KHz, 133M */
834 __raw_writel(0x0426, g_asrc->vaddr + ASRC_ASR56K_REG);
839 static void asrc_input_dma_callback(void *data)
841 struct asrc_pair_params *params;
842 unsigned long lock_flags;
845 spin_lock_irqsave(&input_int_lock, lock_flags);
846 params->input_queue_empty--;
847 params->input_counter++;
848 wake_up_interruptible(¶ms->input_wait_queue);
849 spin_unlock_irqrestore(&input_int_lock, lock_flags);
853 static void asrc_output_dma_callback(void *data)
855 struct asrc_pair_params *params;
856 unsigned long lock_flags;
860 spin_lock_irqsave(&output_int_lock, lock_flags);
861 params->output_queue_empty--;
862 params->output_counter++;
863 wake_up_interruptible(¶ms->output_wait_queue);
864 spin_unlock_irqrestore(&output_int_lock, lock_flags);
868 static void mxc_free_dma_buf(struct asrc_pair_params *params)
870 if (params->input_dma_total.dma_vaddr != NULL) {
871 dma_free_coherent(g_asrc->dev,
872 params->input_dma_total.length,
873 params->input_dma_total.dma_vaddr,
874 params->input_dma_total.dma_paddr);
875 params->input_dma_total.dma_vaddr = NULL;
878 if (params->output_dma_total.dma_vaddr != NULL) {
879 dma_free_coherent(g_asrc->dev,
880 params->output_dma_total.length,
881 params->output_dma_total.dma_vaddr,
882 params->output_dma_total.dma_paddr);
883 params->output_dma_total.dma_vaddr = NULL;
889 static int mxc_allocate_dma_buf(struct asrc_pair_params *params)
892 struct dma_block *input_a, *output_a;
894 input_a = ¶ms->input_dma_total;
895 output_a = ¶ms->output_dma_total;
898 dma_alloc_coherent(g_asrc->dev,
899 input_a->length, &input_a->dma_paddr,
900 GFP_KERNEL | GFP_DMA);
901 if (!input_a->dma_vaddr)
904 for (i = 0; i < params->buffer_num; i++) {
905 params->input_dma[i].dma_vaddr =
906 input_a->dma_vaddr + i * params->input_buffer_size;
907 params->input_dma[i].dma_paddr =
908 input_a->dma_paddr + i * params->input_buffer_size;
909 if (params->input_dma[i].dma_vaddr == NULL)
913 output_a->dma_vaddr =
914 dma_alloc_coherent(g_asrc->dev,
915 output_a->length, &output_a->dma_paddr,
916 GFP_KERNEL | GFP_DMA);
917 if (!output_a->dma_vaddr)
919 for (i = 0; i < params->buffer_num; i++) {
920 params->output_dma[i].dma_vaddr =
921 output_a->dma_vaddr + i * params->output_buffer_size;
922 params->output_dma[i].dma_paddr =
923 output_a->dma_paddr + i * params->output_buffer_size;
924 if (params->output_dma[i].dma_vaddr == NULL)
930 mxc_free_dma_buf(params);
931 pr_err("can't allocate buffer\n");
935 static bool filter(struct dma_chan *chan, void *param)
938 if (!imx_dma_is_general_purpose(chan))
941 chan->private = param;
945 static struct dma_chan *imx_asrc_dma_alloc(u32 dma_req)
948 struct imx_dma_data dma_data = {0};
950 dma_data.peripheral_type = IMX_DMATYPE_ASRC;
951 dma_data.priority = DMA_PRIO_MEDIUM;
952 dma_data.dma_request = dma_req;
954 /* Try to grab a DMA channel */
956 dma_cap_set(DMA_SLAVE, mask);
957 return dma_request_channel(mask, filter, &dma_data);
961 struct dma_async_tx_descriptor *imx_asrc_dma_config(
962 struct asrc_pair_params *params,
963 struct dma_chan *chan,
964 u32 dma_addr, dma_addr_t buf_addr,
965 u32 buf_len, bool in,
966 enum asrc_word_width word_width)
968 struct dma_slave_config slave_config;
969 enum dma_slave_buswidth buswidth;
972 switch (word_width) {
973 case ASRC_WIDTH_16_BIT:
974 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
976 case ASRC_WIDTH_24_BIT:
977 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
980 pr_err("Error word_width\n");
985 slave_config.direction = DMA_MEM_TO_DEV;
986 slave_config.dst_addr = dma_addr;
987 slave_config.dst_addr_width = buswidth;
988 slave_config.dst_maxburst =
989 ASRC_INPUTFIFO_THRESHOLD * params->channel_nums;
991 slave_config.direction = DMA_DEV_TO_MEM;
992 slave_config.src_addr = dma_addr;
993 slave_config.src_addr_width = buswidth;
994 slave_config.src_maxburst =
995 ASRC_OUTPUTFIFO_THRESHOLD * params->channel_nums;
997 ret = dmaengine_slave_config(chan, &slave_config);
999 pr_err("imx_asrc_dma_config(%d) failed\r\n", in);
1003 return chan->device->device_prep_dma_cyclic(chan, buf_addr,
1004 buf_len * params->buffer_num,
1007 DMA_TO_DEVICE : DMA_FROM_DEVICE);
1011 * asrc interface - function
1013 * @param inode struct inode *
1015 * @param file struct file *
1017 * @param cmd unsigned int
1019 * @param arg unsigned long
1021 * @return 0 success, ENODEV for invalid device instance,
1022 * -1 for other errors.
1024 static long asrc_ioctl(struct file *file,
1025 unsigned int cmd, unsigned long arg)
1028 struct asrc_pair_params *params;
1029 params = file->private_data;
1034 struct asrc_req req;
1035 if (copy_from_user(&req, (void __user *)arg,
1036 sizeof(struct asrc_req))) {
1040 err = asrc_req_pair(req.chn_num, &req.index);
1043 params->pair_hold = 1;
1044 params->index = req.index;
1045 params->channel_nums = req.chn_num;
1047 ((void __user *)arg, &req, sizeof(struct asrc_req)))
1052 case ASRC_CONFIG_PAIR:
1054 struct asrc_config config;
1056 char *rx_name, *tx_name;
1058 (&config, (void __user *)arg,
1059 sizeof(struct asrc_config))) {
1063 err = asrc_config_pair(&config);
1066 params->output_buffer_size = config.dma_buffer_size;
1067 params->input_buffer_size = config.dma_buffer_size;
1068 if (config.buffer_num > ASRC_DMA_BUFFER_NUM)
1069 params->buffer_num = ASRC_DMA_BUFFER_NUM;
1071 params->buffer_num = config.buffer_num;
1073 params->input_dma_total.length =
1074 params->input_buffer_size * params->buffer_num;
1075 params->output_dma_total.length =
1076 params->output_buffer_size * params->buffer_num;
1078 err = mxc_allocate_dma_buf(params);
1082 /* TBD - need to update when new SDMA interface ready */
1083 if (config.pair == ASRC_PAIR_A) {
1084 rx_id = asrc_get_dma_request(ASRC_PAIR_A, 1);
1085 tx_id = asrc_get_dma_request(ASRC_PAIR_A, 0);
1086 rx_name = asrc_pair_id[0];
1087 tx_name = asrc_pair_id[1];
1088 } else if (config.pair == ASRC_PAIR_B) {
1089 rx_id = asrc_get_dma_request(ASRC_PAIR_B, 1);
1090 tx_id = asrc_get_dma_request(ASRC_PAIR_B, 0);
1091 rx_name = asrc_pair_id[2];
1092 tx_name = asrc_pair_id[3];
1094 rx_id = asrc_get_dma_request(ASRC_PAIR_C, 1);
1095 tx_id = asrc_get_dma_request(ASRC_PAIR_C, 0);
1096 rx_name = asrc_pair_id[4];
1097 tx_name = asrc_pair_id[5];
1100 params->input_dma_channel = imx_asrc_dma_alloc(rx_id);
1101 if (params->input_dma_channel == NULL) {
1102 pr_err("unable to get rx channel %d\n", rx_id);
1106 params->desc_in = imx_asrc_dma_config(params,
1107 params->input_dma_channel,
1108 asrc_get_per_addr(params->index, 1),
1109 params->input_dma[0].dma_paddr,
1110 params->input_buffer_size, 1,
1111 config.input_word_width);
1112 if (params->desc_in) {
1113 params->desc_in->callback =
1114 asrc_input_dma_callback;
1115 params->desc_in->callback_param = params;
1117 pr_err("unable to get desc_in\r\n");
1122 params->output_dma_channel = imx_asrc_dma_alloc(tx_id);
1123 if (params->output_dma_channel == NULL) {
1124 pr_err("unable to get tx channel %d\n", tx_id);
1127 params->desc_out = imx_asrc_dma_config(params,
1128 params->output_dma_channel,
1129 asrc_get_per_addr(params->index, 0),
1130 params->output_dma[0].dma_paddr,
1131 params->output_buffer_size, 0,
1132 config.output_word_width);
1133 if (params->desc_out) {
1134 params->desc_out->callback =
1135 asrc_output_dma_callback;
1136 params->desc_out->callback_param = params;
1138 pr_err("unable to get desc_out\r\n");
1143 params->input_queue_empty = 0;
1144 params->output_queue_empty = 0;
1145 INIT_LIST_HEAD(¶ms->input_queue);
1146 INIT_LIST_HEAD(¶ms->input_done_queue);
1147 INIT_LIST_HEAD(¶ms->output_queue);
1148 INIT_LIST_HEAD(¶ms->output_done_queue);
1149 init_waitqueue_head(¶ms->input_wait_queue);
1150 init_waitqueue_head(¶ms->output_wait_queue);
1153 ((void __user *)arg, &config,
1154 sizeof(struct asrc_config)))
1160 struct asrc_querybuf buffer;
1161 unsigned int index_n;
1163 (&buffer, (void __user *)arg,
1164 sizeof(struct asrc_querybuf))) {
1168 index_n = buffer.buffer_index;
1170 buffer.input_offset = (unsigned long)
1171 params->input_dma[index_n].dma_paddr;
1172 buffer.input_length = params->input_buffer_size;
1174 buffer.output_offset = (unsigned long)
1175 params->output_dma[index_n].dma_paddr;
1176 buffer.output_length = params->output_buffer_size;
1179 ((void __user *)arg, &buffer,
1180 sizeof(struct asrc_querybuf)))
1184 case ASRC_RELEASE_PAIR:
1186 enum asrc_pair_index index;
1188 (&index, (void __user *)arg,
1189 sizeof(enum asrc_pair_index))) {
1194 if (params->input_dma_channel)
1195 dma_release_channel(params->input_dma_channel);
1196 if (params->output_dma_channel)
1197 dma_release_channel(params->output_dma_channel);
1199 mxc_free_dma_buf(params);
1200 asrc_release_pair(index);
1201 asrc_finish_conv(index);
1202 params->pair_hold = 0;
1207 struct asrc_buffer buf;
1208 struct dma_block *block;
1209 unsigned long lock_flags;
1211 (&buf, (void __user *)arg,
1212 sizeof(struct asrc_buffer))) {
1217 spin_lock_irqsave(&input_int_lock, lock_flags);
1218 params->input_dma[buf.index].index = buf.index;
1219 params->input_dma[buf.index].length = buf.length;
1220 list_add_tail(¶ms->input_dma[buf.index].
1221 queue, ¶ms->input_queue);
1222 if (!list_empty(¶ms->input_queue)) {
1224 list_entry(params->input_queue.next,
1225 struct dma_block, queue);
1227 params->input_queue_empty++;
1228 list_del(params->input_queue.next);
1229 list_add_tail(&block->queue,
1230 ¶ms->input_done_queue);
1232 spin_unlock_irqrestore(&input_int_lock, lock_flags);
1235 case ASRC_DQ_INBUF:{
1236 struct asrc_buffer buf;
1237 struct dma_block *block;
1238 unsigned long lock_flags;
1240 (&buf, (void __user *)arg,
1241 sizeof(struct asrc_buffer))) {
1245 /* if ASRC is inactive, nonsense to DQ buffer */
1246 if (params->asrc_active == 0) {
1248 buf.buf_valid = ASRC_BUF_NA;
1250 ((void __user *)arg, &buf,
1251 sizeof(struct asrc_buffer)))
1256 if (!wait_event_interruptible_timeout
1257 (params->input_wait_queue,
1258 params->input_counter != 0, 10 * HZ)) {
1260 ("ASRC_DQ_INBUF timeout counter %x\n",
1261 params->input_counter);
1264 } else if (signal_pending(current)) {
1265 pr_info("ASRC_DQ_INBUF interrupt received\n");
1269 spin_lock_irqsave(&input_int_lock, lock_flags);
1270 params->input_counter--;
1272 list_entry(params->input_done_queue.next,
1273 struct dma_block, queue);
1274 list_del(params->input_done_queue.next);
1275 spin_unlock_irqrestore(&input_int_lock, lock_flags);
1276 buf.index = block->index;
1277 buf.length = block->length;
1278 buf.buf_valid = ASRC_BUF_AV;
1280 ((void __user *)arg, &buf,
1281 sizeof(struct asrc_buffer)))
1286 case ASRC_Q_OUTBUF:{
1287 struct asrc_buffer buf;
1288 struct dma_block *block;
1289 unsigned long lock_flags;
1291 (&buf, (void __user *)arg,
1292 sizeof(struct asrc_buffer))) {
1297 spin_lock_irqsave(&output_int_lock, lock_flags);
1298 params->output_dma[buf.index].index = buf.index;
1299 params->output_dma[buf.index].length = buf.length;
1300 list_add_tail(¶ms->output_dma[buf.index].
1301 queue, ¶ms->output_queue);
1302 if (!list_empty(¶ms->output_queue)) {
1304 list_entry(params->output_queue.
1305 next, struct dma_block, queue);
1306 list_del(params->output_queue.next);
1307 list_add_tail(&block->queue,
1308 ¶ms->output_done_queue);
1309 params->output_queue_empty++;
1312 spin_unlock_irqrestore(&output_int_lock, lock_flags);
1315 case ASRC_DQ_OUTBUF:{
1316 struct asrc_buffer buf;
1317 struct dma_block *block;
1318 unsigned long lock_flags;
1320 (&buf, (void __user *)arg,
1321 sizeof(struct asrc_buffer))) {
1325 /* if ASRC is inactive, nonsense to DQ buffer */
1326 if (params->asrc_active == 0) {
1327 buf.buf_valid = ASRC_BUF_NA;
1330 ((void __user *)arg, &buf,
1331 sizeof(struct asrc_buffer)))
1336 if (!wait_event_interruptible_timeout
1337 (params->output_wait_queue,
1338 params->output_counter != 0, 10 * HZ)) {
1340 ("ASRC_DQ_OUTBUF timeout counter %x\n",
1341 params->output_counter);
1344 } else if (signal_pending(current)) {
1345 pr_info("ASRC_DQ_INBUF interrupt received\n");
1349 spin_lock_irqsave(&output_int_lock, lock_flags);
1350 params->output_counter--;
1352 list_entry(params->output_done_queue.next,
1353 struct dma_block, queue);
1354 list_del(params->output_done_queue.next);
1355 spin_unlock_irqrestore(&output_int_lock, lock_flags);
1356 buf.index = block->index;
1357 buf.length = block->length;
1358 buf.buf_valid = ASRC_BUF_AV;
1360 ((void __user *)arg, &buf,
1361 sizeof(struct asrc_buffer)))
1366 case ASRC_START_CONV:{
1367 enum asrc_pair_index index;
1368 unsigned long lock_flags;
1370 (&index, (void __user *)arg,
1371 sizeof(enum asrc_pair_index))) {
1375 spin_lock_irqsave(&input_int_lock, lock_flags);
1376 if (params->input_queue_empty == 0) {
1379 ("ASRC_START_CONV - no block available\n");
1382 spin_unlock_irqrestore(&input_int_lock, lock_flags);
1383 params->asrc_active = 1;
1384 dmaengine_submit(params->desc_in);
1385 dmaengine_submit(params->desc_out);
1387 asrc_start_conv(index);
1391 case ASRC_STOP_CONV:{
1392 enum asrc_pair_index index;
1394 (&index, (void __user *)arg,
1395 sizeof(enum asrc_pair_index))) {
1399 dmaengine_terminate_all(params->input_dma_channel);
1400 dmaengine_terminate_all(params->output_dma_channel);
1401 asrc_stop_conv(index);
1402 params->asrc_active = 0;
1406 struct asrc_status_flags flags;
1408 (&flags, (void __user *)arg,
1409 sizeof(struct asrc_status_flags))) {
1413 asrc_get_status(&flags);
1415 ((void __user *)arg, &flags,
1416 sizeof(struct asrc_status_flags)))
1421 /* flush input dma buffer */
1422 unsigned long lock_flags;
1424 char *rx_name, *tx_name;
1425 spin_lock_irqsave(&input_int_lock, lock_flags);
1426 while (!list_empty(¶ms->input_queue))
1427 list_del(params->input_queue.next);
1428 while (!list_empty(¶ms->input_done_queue))
1429 list_del(params->input_done_queue.next);
1430 params->input_counter = 0;
1431 params->input_queue_empty = 0;
1432 spin_unlock_irqrestore(&input_int_lock, lock_flags);
1434 /* flush output dma buffer */
1435 spin_lock_irqsave(&output_int_lock, lock_flags);
1436 while (!list_empty(¶ms->output_queue))
1437 list_del(params->output_queue.next);
1438 while (!list_empty(¶ms->output_done_queue))
1439 list_del(params->output_done_queue.next);
1440 params->output_counter = 0;
1441 params->output_queue_empty = 0;
1442 spin_unlock_irqrestore(&output_int_lock, lock_flags);
1444 /* release DMA and request again */
1445 dma_release_channel(params->input_dma_channel);
1446 dma_release_channel(params->output_dma_channel);
1447 if (params->index == ASRC_PAIR_A) {
1448 rx_id = g_asrc->dmarx[ASRC_PAIR_A];
1449 tx_id = g_asrc->dmatx[ASRC_PAIR_A];
1450 rx_name = asrc_pair_id[0];
1451 tx_name = asrc_pair_id[1];
1452 } else if (params->index == ASRC_PAIR_B) {
1453 rx_id = g_asrc->dmarx[ASRC_PAIR_B];
1454 tx_id = g_asrc->dmatx[ASRC_PAIR_B];
1455 rx_name = asrc_pair_id[2];
1456 tx_name = asrc_pair_id[3];
1458 rx_id = g_asrc->dmarx[ASRC_PAIR_C];
1459 tx_id = g_asrc->dmatx[ASRC_PAIR_C];
1460 rx_name = asrc_pair_id[4];
1461 tx_name = asrc_pair_id[5];
1464 params->input_dma_channel = imx_asrc_dma_alloc(rx_id);
1465 if (params->input_dma_channel == NULL) {
1466 pr_err("unable to get rx channel %d\n", rx_id);
1470 params->output_dma_channel = imx_asrc_dma_alloc(tx_id);
1471 if (params->output_dma_channel == NULL) {
1472 pr_err("unable to get tx channel %d\n", tx_id);
1486 * asrc interface - open function
1488 * @param inode structure inode *
1490 * @param file structure file *
1492 * @return status 0 success, ENODEV invalid device instance,
1493 * ENOBUFS failed to allocate buffer, ERESTARTSYS interrupted by user
1495 static int mxc_asrc_open(struct inode *inode, struct file *file)
1498 struct asrc_pair_params *pair_params;
1500 if (signal_pending(current))
1502 pair_params = kzalloc(sizeof(struct asrc_pair_params), GFP_KERNEL);
1503 if (pair_params == NULL) {
1504 pr_debug("Failed to allocate pair_params\n");
1507 file->private_data = pair_params;
1512 * asrc interface - close function
1514 * @param inode struct inode *
1515 * @param file structure file *
1517 * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
1519 static int mxc_asrc_close(struct inode *inode, struct file *file)
1521 struct asrc_pair_params *pair_params;
1522 pair_params = file->private_data;
1524 if (pair_params->asrc_active) {
1525 dmaengine_terminate_all(
1526 pair_params->input_dma_channel);
1527 dmaengine_terminate_all(
1528 pair_params->output_dma_channel);
1529 asrc_stop_conv(pair_params->index);
1530 wake_up_interruptible(&pair_params->input_wait_queue);
1531 wake_up_interruptible(&pair_params->output_wait_queue);
1533 if (pair_params->pair_hold) {
1534 if (pair_params->input_dma_channel)
1535 dma_release_channel(
1536 pair_params->input_dma_channel);
1537 if (pair_params->output_dma_channel)
1538 dma_release_channel(
1539 pair_params->output_dma_channel);
1540 mxc_free_dma_buf(pair_params);
1541 asrc_release_pair(pair_params->index);
1542 asrc_finish_conv(pair_params->index);
1545 file->private_data = NULL;
1551 * asrc interface - mmap function
1553 * @param file structure file *
1555 * @param vma structure vm_area_struct *
1557 * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
1559 static int mxc_asrc_mmap(struct file *file, struct vm_area_struct *vma)
1563 size = vma->vm_end - vma->vm_start;
1564 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1565 if (remap_pfn_range(vma, vma->vm_start,
1566 vma->vm_pgoff, size, vma->vm_page_prot))
1569 vma->vm_flags &= ~VM_IO;
1573 static struct file_operations asrc_fops = {
1574 .owner = THIS_MODULE,
1575 .unlocked_ioctl = asrc_ioctl,
1576 .mmap = mxc_asrc_mmap,
1577 .open = mxc_asrc_open,
1578 .release = mxc_asrc_close,
1581 static int asrc_read_proc_attr(char *page, char **start, off_t off,
1582 int count, int *eof, void *data)
1586 clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
1587 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCNCR_REG);
1588 clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
1590 len += sprintf(page, "ANCA: %d\n",
1593 (32 - g_asrc->mxc_asrc_data->channel_bits))));
1595 sprintf(page + len, "ANCB: %d\n",
1596 (int)((reg >> g_asrc->mxc_asrc_data->
1597 channel_bits) & (0xFFFFFFFF >>
1598 (32 - g_asrc->mxc_asrc_data->channel_bits))));
1600 sprintf(page + len, "ANCC: %d\n",
1601 (int)((reg >> (g_asrc->mxc_asrc_data->channel_bits * 2)) &
1602 (0xFFFFFFFF >> (32 - g_asrc->mxc_asrc_data->channel_bits))));
1607 *eof = (len <= count) ? 1 : 0;
1608 *start = page + off;
1610 return min(count, len - (int)off);
1613 static int asrc_write_proc_attr(struct file *file, const char *buffer,
1614 unsigned long count, void *data)
1622 if (copy_from_user(buf, buffer, count)) {
1623 pr_debug("Attr proc write, Failed to copy buffer from user\n");
1627 clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
1628 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCNCR_REG);
1629 clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
1630 sscanf(buf, "ANCA: %d\nANCB: %d\nANCC: %d", &na, &nb, &nc);
1631 if (g_asrc->mxc_asrc_data->channel_bits > 3)
1635 if ((na + nb + nc) != total) {
1636 pr_info("Wrong ASRCNR settings\n");
1639 reg = na | (nb << g_asrc->mxc_asrc_data->channel_bits) |
1640 (nc << (g_asrc->mxc_asrc_data->channel_bits * 2));
1642 clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
1643 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCNCR_REG);
1644 clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
1649 static void asrc_proc_create(void)
1651 struct proc_dir_entry *proc_attr;
1652 g_asrc->proc_asrc = proc_mkdir(ASRC_PROC_PATH, NULL);
1653 if (g_asrc->proc_asrc) {
1654 proc_attr = create_proc_entry("ChSettings",
1656 S_IWUSR, g_asrc->proc_asrc);
1658 proc_attr->read_proc = asrc_read_proc_attr;
1659 proc_attr->write_proc = asrc_write_proc_attr;
1660 proc_attr->size = 48;
1661 proc_attr->uid = proc_attr->gid = 0;
1663 remove_proc_entry(ASRC_PROC_PATH, NULL);
1664 pr_info("Failed to create proc attribute entry \n");
1667 pr_info("ASRC: Failed to create proc entry %s\n",
1673 * Entry point for the asrc device
1675 * @param pdev Pionter to the registered platform device
1676 * @return Error code indicating success or failure
1678 static int mxc_asrc_probe(struct platform_device *pdev)
1681 struct resource *res;
1682 struct device *temp_class;
1684 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1688 g_asrc = kzalloc(sizeof(struct asrc_data), GFP_KERNEL);
1690 if (g_asrc == NULL) {
1691 pr_info("Failed to allocate g_asrc\n");
1695 g_asrc->dev = &pdev->dev;
1696 g_asrc->dev->coherent_dma_mask = DMA_BIT_MASK(32);
1698 g_asrc->asrc_pair[0].chn_max = 2;
1699 g_asrc->asrc_pair[1].chn_max = 2;
1700 g_asrc->asrc_pair[2].chn_max = 6;
1701 g_asrc->asrc_pair[0].overload_error = 0;
1702 g_asrc->asrc_pair[1].overload_error = 0;
1703 g_asrc->asrc_pair[2].overload_error = 0;
1705 g_asrc->asrc_major =
1706 register_chrdev(g_asrc->asrc_major, "mxc_asrc", &asrc_fops);
1707 if (g_asrc->asrc_major < 0) {
1708 pr_info("Unable to register asrc device\n");
1713 g_asrc->asrc_class = class_create(THIS_MODULE, "mxc_asrc");
1714 if (IS_ERR(g_asrc->asrc_class)) {
1715 err = PTR_ERR(g_asrc->asrc_class);
1716 goto err_out_chrdev;
1720 device_create(g_asrc->asrc_class, NULL,
1721 MKDEV(g_asrc->asrc_major, 0), NULL, "mxc_asrc");
1722 if (IS_ERR(temp_class)) {
1723 err = PTR_ERR(temp_class);
1727 g_asrc->paddr = res->start;
1729 (unsigned long)ioremap(res->start, res->end - res->start + 1);
1730 g_asrc->mxc_asrc_data =
1731 (struct imx_asrc_platform_data *)pdev->dev.platform_data;
1733 clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
1735 switch (g_asrc->mxc_asrc_data->clk_map_ver) {
1737 input_clk_map = &input_clk_map_v1[0];
1738 output_clk_map = &output_clk_map_v1[0];
1742 input_clk_map = &input_clk_map_v2[0];
1743 output_clk_map = &output_clk_map_v2[0];
1747 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx1");
1749 g_asrc->dmatx[0] = res->start;
1751 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx1");
1753 g_asrc->dmarx[0] = res->start;
1755 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx2");
1757 g_asrc->dmatx[1] = res->start;
1759 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx2");
1761 g_asrc->dmarx[1] = res->start;
1763 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx3");
1765 g_asrc->dmatx[2] = res->start;
1767 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx3");
1769 g_asrc->dmarx[2] = res->start;
1771 irq = platform_get_irq(pdev, 0);
1772 if (request_irq(irq, asrc_isr, 0, "asrc", NULL))
1776 err = mxc_init_asrc();
1783 device_destroy(g_asrc->asrc_class, MKDEV(g_asrc->asrc_major, 0));
1784 class_destroy(g_asrc->asrc_class);
1786 unregister_chrdev(g_asrc->asrc_major, "mxc_asrc");
1790 clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
1791 pr_info("mxc_asrc registered\n");
1798 * @param pdev Pionter to the registered platform device
1799 * @return Error code indicating success or failure
1801 static int mxc_asrc_remove(struct platform_device *pdev)
1803 int irq = platform_get_irq(pdev, 0);
1804 free_irq(irq, NULL);
1806 g_asrc->mxc_asrc_data = NULL;
1807 iounmap((unsigned long __iomem *)g_asrc->vaddr);
1808 remove_proc_entry("ChSettings", g_asrc->proc_asrc);
1809 remove_proc_entry(ASRC_PROC_PATH, NULL);
1810 device_destroy(g_asrc->asrc_class, MKDEV(g_asrc->asrc_major, 0));
1811 class_destroy(g_asrc->asrc_class);
1812 unregister_chrdev(g_asrc->asrc_major, "mxc_asrc");
1816 /*! mxc asrc driver definition
1819 static struct platform_driver mxc_asrc_driver = {
1823 .probe = mxc_asrc_probe,
1824 .remove = mxc_asrc_remove,
1828 * Register asrc driver
1831 static __init int asrc_init(void)
1834 ret = platform_driver_register(&mxc_asrc_driver);
1839 * Exit and free the asrc data
1841 */ static void __exit asrc_exit(void)
1843 platform_driver_unregister(&mxc_asrc_driver);
1847 module_init(asrc_init);
1848 module_exit(asrc_exit);
1849 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1850 MODULE_DESCRIPTION("Asynchronous Sample Rate Converter");
1851 MODULE_LICENSE("GPL");