]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/mxc/asrc/mxc_asrc.c
ENGR00218774 ESAI ASRC: fix multi channel p2pplayback bug
[karo-tx-linux.git] / drivers / mxc / asrc / mxc_asrc.c
1 /*
2  * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
3  */
4
5 /*
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:
9  *
10  * http://www.opensource.org/licenses/gpl-license.html
11  * http://www.gnu.org/copyleft/gpl.html
12  */
13
14 /*!
15  * @file mxc_asrc.c
16  *
17  * @brief MXC Asynchronous Sample Rate Converter
18  *
19  * @ingroup SOUND
20  */
21
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>
27 #include <linux/fs.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>
40 #include <asm/irq.h>
41 #include <asm/memory.h>
42 #include <mach/dma.h>
43 #include <mach/mxc_asrc.h>
44
45 #define ASRC_PROC_PATH        "driver/asrc"
46
47 #define ASRC_RATIO_DECIMAL_DEPTH 26
48
49 DEFINE_SPINLOCK(data_lock);
50 DEFINE_SPINLOCK(input_int_lock);
51 DEFINE_SPINLOCK(output_int_lock);
52
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 */
65
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",
73 };
74
75 enum asrc_status {
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,
98 };
99
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 */
103 /*5512Hz*/
104         {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
105 /*8kHz*/
106         {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
107 /*11025Hz*/
108         {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
109 /*16kHz*/
110         {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
111 /*22050Hz*/
112         {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},
113 /*32kHz*/
114         {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},},
115 /*44.1kHz*/
116         {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},
117 /*48kHz*/
118         {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},
119 /*64kHz*/
120         {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},},
121 /*88.2kHz*/
122         {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},
123 /*96kHz*/
124         {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},
125 /*176kHz*/
126         {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},
127 /*192kHz*/
128         {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},
129 };
130
131 static struct asrc_data *g_asrc;
132
133 /* The following tables map the relationship between asrc_inclk/asrc_outclk in
134  * mxc_asrc.h and the registers of ASRCSR
135  */
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,
138 };
139
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,
142 };
143
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,
146 };
147
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,
150 };
151
152 static unsigned char *input_clk_map, *output_clk_map;
153
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);
161
162 static int asrc_set_clock_ratio(enum asrc_pair_index index,
163                                 int input_sample_rate, int output_sample_rate)
164 {
165         int i;
166         int integ = 0;
167         unsigned long reg_val = 0;
168
169         if (output_sample_rate == 0)
170                 return -1;
171         while (input_sample_rate >= output_sample_rate) {
172                 input_sample_rate -= output_sample_rate;
173                 integ++;
174         }
175         reg_val |= (integ << 26);
176
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));
180                         input_sample_rate =
181                             input_sample_rate * 2 - output_sample_rate;
182                 } else
183                         input_sample_rate = input_sample_rate << 1;
184
185                 if (input_sample_rate == 0)
186                         break;
187         }
188
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)));
193         return 0;
194 }
195
196 static int asrc_set_process_configuration(enum asrc_pair_index index,
197                                           int input_sample_rate,
198                                           int output_sample_rate)
199 {
200         int i = 0, j = 0;
201         unsigned long reg;
202         switch (input_sample_rate) {
203         case 5512:
204                 i = 0;
205         case 8000:
206                 i = 1;
207                 break;
208         case 11025:
209                 i = 2;
210                 break;
211         case 16000:
212                 i = 3;
213                 break;
214         case 22050:
215                 i = 4;
216                 break;
217         case 32000:
218                 i = 5;
219                 break;
220         case 44100:
221                 i = 6;
222                 break;
223         case 48000:
224                 i = 7;
225                 break;
226         case 64000:
227                 i = 8;
228                 break;
229         case 88200:
230                 i = 9;
231                 break;
232         case 96000:
233                 i = 10;
234                 break;
235         case 176400:
236                 i = 11;
237                 break;
238         case 192000:
239                 i = 12;
240                 break;
241         default:
242                 return -1;
243         }
244
245         switch (output_sample_rate) {
246         case 32000:
247                 j = 0;
248                 break;
249         case 44100:
250                 j = 1;
251                 break;
252         case 48000:
253                 j = 2;
254                 break;
255         case 64000:
256                 j = 3;
257                 break;
258         case 88200:
259                 j = 4;
260                 break;
261         case 96000:
262                 j = 5;
263                 break;
264         case 176400:
265                 j = 6;
266                 break;
267         case 192000:
268                 j = 7;
269                 break;
270         default:
271                 return -1;
272         }
273
274         reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCFG_REG);
275         reg &= ~(0x0f << (6 + (index << 2)));
276         reg |=
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);
280
281         return 0;
282 }
283
284 static int asrc_get_asrck_clock_divider(int samplerate)
285 {
286         unsigned int prescaler, divider;
287         unsigned int i;
288         unsigned int ratio, ra;
289         unsigned long bitclk;
290
291         bitclk = clk_get_rate(g_asrc->mxc_asrc_data->asrc_audio_clk);
292
293         ra = bitclk/samplerate;
294         ratio = ra;
295         /*calculate the prescaler*/
296         i = 0;
297         while (ratio > 8) {
298                 i++;
299                 ratio = ratio >> 1;
300         }
301         prescaler = i;
302         /*calculate the divider*/
303         if (i >= 1)
304                 divider = ((ra + (1 << (i - 1)) - 1) >> i) - 1;
305         else
306                 divider = ra - 1;
307         /*the totally divider is (2^prescaler)*divider*/
308         return (divider << 3) + prescaler;
309 }
310
311 int asrc_req_pair(int chn_num, enum asrc_pair_index *index)
312 {
313         int err = 0;
314         unsigned long lock_flags;
315         struct asrc_pair *pair;
316         spin_lock_irqsave(&data_lock, lock_flags);
317
318         if (chn_num > 2) {
319                 pair = &g_asrc->asrc_pair[ASRC_PAIR_C];
320                 if (pair->active || (chn_num > pair->chn_max))
321                         err = -EBUSY;
322                 else {
323                         *index = ASRC_PAIR_C;
324                         pair->chn_num = chn_num;
325                         pair->active = 1;
326                 }
327         } else {
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))
332                                 err = -EBUSY;
333                         else {
334                                 *index = ASRC_PAIR_B;
335                                 pair->chn_num = 2;
336                                 pair->active = 1;
337                         }
338                 } else {
339                         *index = ASRC_PAIR_A;
340                         pair->chn_num = 2;
341                         pair->active = 1;
342                 }
343         }
344         spin_unlock_irqrestore(&data_lock, lock_flags);
345
346         if (!err) {
347                 clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
348                 clk_enable(g_asrc->mxc_asrc_data->asrc_audio_clk);
349         }
350         return err;
351 }
352
353 EXPORT_SYMBOL(asrc_req_pair);
354
355 void asrc_release_pair(enum asrc_pair_index index)
356 {
357         unsigned long reg;
358         unsigned long lock_flags;
359         struct asrc_pair *pair;
360         pair = &g_asrc->asrc_pair[index];
361
362         spin_lock_irqsave(&data_lock, lock_flags);
363         pair->active = 0;
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);
370 }
371
372 EXPORT_SYMBOL(asrc_release_pair);
373
374 int asrc_config_pair(struct asrc_config *config)
375 {
376         int err = 0;
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);
384         reg &=
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;
389         else
390                 channel_num = (config->channel_num + 1) / 2;
391         tmp = channel_num <<
392                 (g_asrc->mxc_asrc_data->channel_bits * config->pair);
393         reg |= tmp;
394         __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCNCR_REG);
395
396         /* Set the clock source */
397         reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCSR_REG);
398         tmp = ~(0x0f << (config->pair << 2));
399         reg &= tmp;
400         tmp = ~(0x0f << (12 + (config->pair << 2)));
401         reg &= tmp;
402         reg |= ((input_clk_map[config->inclk] << (config->pair << 2)) |
403                 (output_clk_map[config->outclk] << (12 + (config->pair << 2))));
404
405         __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCSR_REG);
406
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)));
412
413         __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCTR_REG);
414
415         reg = __raw_readl(g_asrc->vaddr + ASRC_ASRRA_REG);
416         reg &= 0xffbfffff;
417         __raw_writel(reg, g_asrc->vaddr + ASRC_ASRRA_REG);
418
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);
422
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);
427                 reg &= 0xfc0fc0;
428                 /* Input Part */
429                 if ((config->inclk & 0x0f) == INCLK_SPDIF_RX)
430                         reg |= 7 << AICPA;
431                 else if ((config->inclk & 0x0f) == INCLK_SPDIF_TX)
432                         reg |= 6 << AICPA;
433                 else if ((config->inclk & 0x0f) == INCLK_ASRCK1_CLK) {
434                         tmp =
435                             asrc_get_asrck_clock_divider(config->
436                                                          input_sample_rate);
437                         reg |= tmp << AICPA;
438                 } else {
439                         if (config->input_word_width == ASRC_WIDTH_16_BIT)
440                                 reg |= 5 << AICPA;
441                         else if (config->input_word_width == ASRC_WIDTH_24_BIT)
442                                 reg |= 6 << AICPA;
443                         else
444                                 err = -EFAULT;
445                 }
446                 /* Output Part */
447                 if ((config->outclk & 0x0f) == OUTCLK_SPDIF_RX)
448                         reg |= 7 << AOCPA;
449                 else if ((config->outclk & 0x0f) == OUTCLK_SPDIF_TX)
450                         reg |= 6 << AOCPA;
451                 else if ((config->outclk & 0x0f) == OUTCLK_ASRCK1_CLK) {
452                         tmp =
453                             asrc_get_asrck_clock_divider(config->
454                                                          output_sample_rate);
455                         reg |= tmp << AOCPA;
456                 } else {
457                         if (config->output_word_width == ASRC_WIDTH_16_BIT)
458                                 reg |= 5 << AOCPA;
459                         else if (config->output_word_width == ASRC_WIDTH_24_BIT)
460                                 reg |= 6 << AOCPA;
461                         else
462                                 err = -EFAULT;
463                 }
464
465                 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCDR1_REG);
466
467         } else if (config->pair == ASRC_PAIR_B) {
468                 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCDR1_REG);
469                 reg &= 0x03f03f;
470                 /* Input Part */
471                 if ((config->inclk & 0x0f) == INCLK_SPDIF_RX)
472                         reg |= 7 << AICPB;
473                 else if ((config->inclk & 0x0f) == INCLK_SPDIF_TX)
474                         reg |= 6 << AICPB;
475                 else if ((config->inclk & 0x0f) == INCLK_ASRCK1_CLK) {
476                         tmp =
477                             asrc_get_asrck_clock_divider(config->
478                                                          input_sample_rate);
479                         reg |= tmp << AICPB;
480                 } else {
481                         if (config->input_word_width == ASRC_WIDTH_16_BIT)
482                                 reg |= 5 << AICPB;
483                         else if (config->input_word_width == ASRC_WIDTH_24_BIT)
484                                 reg |= 6 << AICPB;
485                         else
486                                 err = -EFAULT;
487                 }
488                 /* Output Part */
489                 if ((config->outclk & 0x0f) == OUTCLK_SPDIF_RX)
490                         reg |= 7 << AOCPB;
491                 else if ((config->outclk & 0x0f) == OUTCLK_SPDIF_TX)
492                         reg |= 6 << AOCPB;
493                 else if ((config->outclk & 0x0f) == OUTCLK_ASRCK1_CLK) {
494                         tmp =
495                             asrc_get_asrck_clock_divider(config->
496                                                          output_sample_rate);
497                         reg |= tmp << AOCPB;
498                 } else {
499                         if (config->output_word_width == ASRC_WIDTH_16_BIT)
500                                 reg |= 5 << AOCPB;
501                         else if (config->output_word_width == ASRC_WIDTH_24_BIT)
502                                 reg |= 6 << AOCPB;
503                         else
504                                 err = -EFAULT;
505                 }
506
507                 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCDR1_REG);
508
509         } else {
510                 reg = __raw_readl(g_asrc->vaddr + ASRC_ASRCDR2_REG);
511                 reg &= 0;
512                 /* Input Part */
513                 if ((config->inclk & 0x0f) == INCLK_SPDIF_RX)
514                         reg |= 7 << AICPC;
515                 else if ((config->inclk & 0x0f) == INCLK_SPDIF_TX)
516                         reg |= 6 << AICPC;
517                 else if ((config->inclk & 0x0f) == INCLK_ASRCK1_CLK) {
518                         tmp =
519                             asrc_get_asrck_clock_divider(config->
520                                                          input_sample_rate);
521                         reg |= tmp << AICPC;
522                 } else {
523                         if (config->input_word_width == ASRC_WIDTH_16_BIT)
524                                 reg |= 5 << AICPC;
525                         else if (config->input_word_width == ASRC_WIDTH_24_BIT)
526                                 reg |= 6 << AICPC;
527                         else
528                                 err = -EFAULT;
529                 }
530                 /* Output Part */
531                 if ((config->outclk & 0x0f) == OUTCLK_SPDIF_RX)
532                         reg |= 7 << AOCPC;
533                 else if ((config->outclk & 0x0f) == OUTCLK_SPDIF_TX)
534                         reg |= 6 << AOCPC;
535                 else if ((config->outclk & 0x0f) == OUTCLK_ASRCK1_CLK) {
536                         tmp =
537                             asrc_get_asrck_clock_divider(config->
538                                                          output_sample_rate);
539                         reg |= tmp << AOCPC;
540                 } else {
541                         if (config->output_word_width == ASRC_WIDTH_16_BIT)
542                                 reg |= 5 << AOCPC;
543                         else if (config->output_word_width == ASRC_WIDTH_24_BIT)
544                                 reg |= 6 << AOCPC;
545                         else
546                                 err = -EFAULT;
547                 }
548                 __raw_writel(reg, g_asrc->vaddr + ASRC_ASRCDR2_REG);
549
550         }
551
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);
561                 if (err < 0)
562                         return err;
563
564                 err = asrc_set_process_configuration(config->pair,
565                                                      config->input_sample_rate,
566                                                      config->
567                                                      output_sample_rate);
568                 if (err < 0)
569                         return err;
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);
575                         err = -EFAULT;
576                 }
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);
582                         err = -EFAULT;
583                 }
584         }
585
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);
595                 if (err < 0)
596                         return err;
597         }
598
599         /* Config input and output wordwidth */
600         reg = __raw_readl(
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 */
604         reg &= ~0xE01;
605         switch (config->input_word_width) {
606         case ASRC_WIDTH_16_BIT:
607                 reg |= 1 << 9;
608                 break;
609         case ASRC_WIDTH_24_BIT:
610                 reg |= 0 << 9;
611                 break;
612         default:
613                 return -EINVAL;
614         }
615
616         switch (config->output_word_width) {
617         case ASRC_WIDTH_16_BIT:
618                 reg |= 1;
619                 break;
620         case ASRC_WIDTH_24_BIT:
621                 reg |= 0;
622                 break;
623         default:
624                 return -EINVAL;
625         }
626         __raw_writel(reg,
627                  g_asrc->vaddr + ASRC_ASRMCR1A_REG + (config->pair << 2));
628
629         return err;
630 }
631
632 EXPORT_SYMBOL(asrc_config_pair);
633
634 void asrc_start_conv(enum asrc_pair_index index)
635 {
636         int reg, reg_1;
637         unsigned long lock_flags;
638         int i;
639
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);
644
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);
649
650         reg = 0;
651         for (i = 0; i < 20; i++) {
652                 __raw_writel(reg,
653                              g_asrc->vaddr + ASRC_ASRDIA_REG +
654                              (index << 3));
655                 __raw_writel(reg,
656                              g_asrc->vaddr + ASRC_ASRDIA_REG +
657                              (index << 3));
658                 __raw_writel(reg,
659                              g_asrc->vaddr + ASRC_ASRDIA_REG +
660                              (index << 3));
661                 __raw_writel(reg,
662                              g_asrc->vaddr + ASRC_ASRDIA_REG +
663                              (index << 3));
664                 __raw_writel(reg,
665                              g_asrc->vaddr + ASRC_ASRDIA_REG +
666                              (index << 3));
667                 __raw_writel(reg,
668                              g_asrc->vaddr + ASRC_ASRDIA_REG +
669                              (index << 3));
670                 __raw_writel(reg,
671                              g_asrc->vaddr + ASRC_ASRDIA_REG +
672                              (index << 3));
673                 __raw_writel(reg,
674                              g_asrc->vaddr + ASRC_ASRDIA_REG +
675                              (index << 3));
676         }
677
678         __raw_writel(0x40, g_asrc->vaddr + ASRC_ASRIER_REG);
679         spin_unlock_irqrestore(&data_lock, lock_flags);
680         return;
681 }
682
683 EXPORT_SYMBOL(asrc_start_conv);
684
685 void asrc_stop_conv(enum asrc_pair_index index)
686 {
687         int reg;
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);
694
695         return;
696 }
697
698 EXPORT_SYMBOL(asrc_stop_conv);
699
700 void asrc_finish_conv(enum asrc_pair_index index)
701 {
702         clk_disable(g_asrc->mxc_asrc_data->asrc_audio_clk);
703         clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
704
705         return;
706 }
707 EXPORT_SYMBOL(asrc_finish_conv);
708
709 int asrc_get_dma_request(enum asrc_pair_index index, bool in)
710 {
711         if (in)
712                 return g_asrc->dmarx[index];
713         else
714                 return g_asrc->dmatx[index];
715 }
716
717 EXPORT_SYMBOL(asrc_get_dma_request);
718
719 /*!
720  * @brief asrc interrupt handler
721  */
722 static irqreturn_t asrc_isr(int irq, void *dev_id)
723 {
724         unsigned long status;
725         int reg = 0x40;
726
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;
776         }
777         /* try to clean the overload error  */
778         __raw_writel(reg, g_asrc->vaddr + ASRC_ASRSTR_REG);
779
780         return IRQ_HANDLED;
781 }
782
783 void asrc_get_status(struct asrc_status_flags *flags)
784 {
785         unsigned long lock_flags;
786         enum asrc_pair_index index;
787
788         spin_lock_irqsave(&data_lock, lock_flags);
789         index = flags->index;
790         flags->overload_error = g_asrc->asrc_pair[index].overload_error;
791
792         spin_unlock_irqrestore(&data_lock, lock_flags);
793         return;
794 }
795
796 EXPORT_SYMBOL(asrc_get_status);
797
798 u32 asrc_get_per_addr(enum asrc_pair_index index, bool in)
799 {
800         if (in)
801                 return g_asrc->paddr + ASRC_ASRDIA_REG + (index << 3);
802         else
803                 return g_asrc->paddr + ASRC_ASRDOA_REG + (index << 3);
804 }
805
806 EXPORT_SYMBOL(asrc_get_per_addr);
807
808 static int mxc_init_asrc(void)
809 {
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);
812
813         /* Enable overflow interrupt */
814         __raw_writel(0x00, g_asrc->vaddr + ASRC_ASRIER_REG);
815
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);
820
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);
827
828         __raw_writel(0x001f00, g_asrc->vaddr + ASRC_ASRTFR1);
829
830         /* Set the processing clock for 76KHz, 133M  */
831         __raw_writel(0x30E, g_asrc->vaddr + ASRC_ASR76K_REG);
832
833         /* Set the processing clock for 56KHz, 133M */
834         __raw_writel(0x0426, g_asrc->vaddr + ASRC_ASR56K_REG);
835
836         return 0;
837 }
838
839 static void asrc_input_dma_callback(void *data)
840 {
841         struct asrc_pair_params *params;
842         unsigned long lock_flags;
843
844         params = data;
845         spin_lock_irqsave(&input_int_lock, lock_flags);
846         params->input_queue_empty--;
847         params->input_counter++;
848         wake_up_interruptible(&params->input_wait_queue);
849         spin_unlock_irqrestore(&input_int_lock, lock_flags);
850         return;
851 }
852
853 static void asrc_output_dma_callback(void *data)
854 {
855         struct asrc_pair_params *params;
856         unsigned long lock_flags;
857
858         params = data;
859
860         spin_lock_irqsave(&output_int_lock, lock_flags);
861         params->output_queue_empty--;
862         params->output_counter++;
863         wake_up_interruptible(&params->output_wait_queue);
864         spin_unlock_irqrestore(&output_int_lock, lock_flags);
865         return;
866 }
867
868 static void mxc_free_dma_buf(struct asrc_pair_params *params)
869 {
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;
876         }
877
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;
884         }
885
886         return;
887 }
888
889 static int mxc_allocate_dma_buf(struct asrc_pair_params *params)
890 {
891         int i;
892         struct dma_block *input_a, *output_a;
893
894         input_a = &params->input_dma_total;
895         output_a = &params->output_dma_total;
896
897         input_a->dma_vaddr =
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)
902                 goto exit;
903
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)
910                         goto exit;
911         }
912
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)
918                 goto exit;
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)
925                         goto exit;
926         }
927         return 0;
928
929 exit:
930         mxc_free_dma_buf(params);
931         pr_err("can't allocate buffer\n");
932         return -ENOBUFS;
933 }
934
935 static bool filter(struct dma_chan *chan, void *param)
936 {
937
938         if (!imx_dma_is_general_purpose(chan))
939                 return false;
940
941         chan->private = param;
942         return true;
943 }
944
945 static struct dma_chan *imx_asrc_dma_alloc(u32 dma_req)
946 {
947         dma_cap_mask_t mask;
948         struct imx_dma_data dma_data = {0};
949
950         dma_data.peripheral_type = IMX_DMATYPE_ASRC;
951         dma_data.priority = DMA_PRIO_MEDIUM;
952         dma_data.dma_request = dma_req;
953
954         /* Try to grab a DMA channel */
955         dma_cap_zero(mask);
956         dma_cap_set(DMA_SLAVE, mask);
957         return dma_request_channel(mask, filter, &dma_data);
958 }
959
960
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)
967 {
968         struct dma_slave_config slave_config;
969         enum dma_slave_buswidth buswidth;
970         int ret;
971
972         switch (word_width) {
973         case ASRC_WIDTH_16_BIT:
974                 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
975                 break;
976         case ASRC_WIDTH_24_BIT:
977                 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
978                 break;
979         default:
980                 pr_err("Error word_width\n");
981                 return NULL;
982         }
983
984         if (in) {
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;
990         } else {
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;
996         }
997         ret = dmaengine_slave_config(chan, &slave_config);
998         if (ret) {
999                 pr_err("imx_asrc_dma_config(%d) failed\r\n", in);
1000                 return NULL;
1001         }
1002
1003         return chan->device->device_prep_dma_cyclic(chan, buf_addr,
1004                         buf_len * params->buffer_num,
1005                         buf_len,
1006                         in == true ?
1007                         DMA_TO_DEVICE : DMA_FROM_DEVICE);
1008 }
1009
1010 /*!
1011  * asrc interface -  function
1012  *
1013  * @param inode      struct inode *
1014  *
1015  * @param file       struct file *
1016  *
1017  * @param cmd    unsigned int
1018  *
1019  * @param arg        unsigned long
1020  *
1021  * @return           0 success, ENODEV for invalid device instance,
1022  *                   -1 for other errors.
1023  */
1024 static long asrc_ioctl(struct file *file,
1025                       unsigned int cmd, unsigned long arg)
1026 {
1027         int err = 0;
1028         struct asrc_pair_params *params;
1029         params = file->private_data;
1030
1031         switch (cmd) {
1032         case ASRC_REQ_PAIR:
1033                 {
1034                         struct asrc_req req;
1035                         if (copy_from_user(&req, (void __user *)arg,
1036                                            sizeof(struct asrc_req))) {
1037                                 err = -EFAULT;
1038                                 break;
1039                         }
1040                         err = asrc_req_pair(req.chn_num, &req.index);
1041                         if (err < 0)
1042                                 break;
1043                         params->pair_hold = 1;
1044                         params->index = req.index;
1045                         params->channel_nums = req.chn_num;
1046                         if (copy_to_user
1047                             ((void __user *)arg, &req, sizeof(struct asrc_req)))
1048                                 err = -EFAULT;
1049
1050                         break;
1051                 }
1052         case ASRC_CONFIG_PAIR:
1053                 {
1054                         struct asrc_config config;
1055                         u32 rx_id, tx_id;
1056                         char *rx_name, *tx_name;
1057                         if (copy_from_user
1058                             (&config, (void __user *)arg,
1059                              sizeof(struct asrc_config))) {
1060                                 err = -EFAULT;
1061                                 break;
1062                         }
1063                         err = asrc_config_pair(&config);
1064                         if (err < 0)
1065                                 break;
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;
1070                         else
1071                                 params->buffer_num = config.buffer_num;
1072
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;
1077
1078                         err = mxc_allocate_dma_buf(params);
1079                         if (err < 0)
1080                                 break;
1081
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];
1093                         } else {
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];
1098                         }
1099
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);
1103                                 err = -EBUSY;
1104                         }
1105
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;
1116                         } else {
1117                                 pr_err("unable to get desc_in\r\n");
1118                                 err = -EINVAL;
1119                                 break;
1120                         }
1121
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);
1125                                 err = -EBUSY;
1126                         }
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;
1137                         } else {
1138                                 pr_err("unable to get desc_out\r\n");
1139                                 err = -EINVAL;
1140                                 break;
1141                         }
1142
1143                         params->input_queue_empty = 0;
1144                         params->output_queue_empty = 0;
1145                         INIT_LIST_HEAD(&params->input_queue);
1146                         INIT_LIST_HEAD(&params->input_done_queue);
1147                         INIT_LIST_HEAD(&params->output_queue);
1148                         INIT_LIST_HEAD(&params->output_done_queue);
1149                         init_waitqueue_head(&params->input_wait_queue);
1150                         init_waitqueue_head(&params->output_wait_queue);
1151
1152                         if (copy_to_user
1153                             ((void __user *)arg, &config,
1154                              sizeof(struct asrc_config)))
1155                                 err = -EFAULT;
1156                         break;
1157                 }
1158         case ASRC_QUERYBUF:
1159                 {
1160                         struct asrc_querybuf buffer;
1161                         unsigned int index_n;
1162                         if (copy_from_user
1163                             (&buffer, (void __user *)arg,
1164                              sizeof(struct asrc_querybuf))) {
1165                                 err = -EFAULT;
1166                                 break;
1167                         }
1168                         index_n = buffer.buffer_index;
1169
1170                         buffer.input_offset = (unsigned long)
1171                                 params->input_dma[index_n].dma_paddr;
1172                         buffer.input_length = params->input_buffer_size;
1173
1174                         buffer.output_offset = (unsigned long)
1175                                 params->output_dma[index_n].dma_paddr;
1176                         buffer.output_length = params->output_buffer_size;
1177
1178                         if (copy_to_user
1179                             ((void __user *)arg, &buffer,
1180                              sizeof(struct asrc_querybuf)))
1181                                 err = -EFAULT;
1182                         break;
1183                 }
1184         case ASRC_RELEASE_PAIR:
1185                 {
1186                         enum asrc_pair_index index;
1187                         if (copy_from_user
1188                             (&index, (void __user *)arg,
1189                              sizeof(enum asrc_pair_index))) {
1190                                 err = -EFAULT;
1191                                 break;
1192                         }
1193
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);
1198
1199                         mxc_free_dma_buf(params);
1200                         asrc_release_pair(index);
1201                         asrc_finish_conv(index);
1202                         params->pair_hold = 0;
1203                         break;
1204                 }
1205         case ASRC_Q_INBUF:
1206                 {
1207                         struct asrc_buffer buf;
1208                         struct dma_block *block;
1209                         unsigned long lock_flags;
1210                         if (copy_from_user
1211                             (&buf, (void __user *)arg,
1212                              sizeof(struct asrc_buffer))) {
1213                                 err = -EFAULT;
1214                                 break;
1215                         }
1216
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(&params->input_dma[buf.index].
1221                                       queue, &params->input_queue);
1222                         if (!list_empty(&params->input_queue)) {
1223                                 block =
1224                                     list_entry(params->input_queue.next,
1225                                                struct dma_block, queue);
1226
1227                                 params->input_queue_empty++;
1228                                 list_del(params->input_queue.next);
1229                                 list_add_tail(&block->queue,
1230                                               &params->input_done_queue);
1231                         }
1232                         spin_unlock_irqrestore(&input_int_lock, lock_flags);
1233                         break;
1234                 }
1235         case ASRC_DQ_INBUF:{
1236                         struct asrc_buffer buf;
1237                         struct dma_block *block;
1238                         unsigned long lock_flags;
1239                         if (copy_from_user
1240                             (&buf, (void __user *)arg,
1241                              sizeof(struct asrc_buffer))) {
1242                                 err = -EFAULT;
1243                                 break;
1244                         }
1245                         /* if ASRC is inactive, nonsense to DQ buffer */
1246                         if (params->asrc_active == 0) {
1247                                 err = -EFAULT;
1248                                 buf.buf_valid = ASRC_BUF_NA;
1249                                 if (copy_to_user
1250                                     ((void __user *)arg, &buf,
1251                                      sizeof(struct asrc_buffer)))
1252                                         err = -EFAULT;
1253                                 break;
1254                         }
1255
1256                         if (!wait_event_interruptible_timeout
1257                             (params->input_wait_queue,
1258                              params->input_counter != 0, 10 * HZ)) {
1259                                 pr_info
1260                                     ("ASRC_DQ_INBUF timeout counter %x\n",
1261                                      params->input_counter);
1262                                 err = -ETIME;
1263                                 break;
1264                         } else if (signal_pending(current)) {
1265                                 pr_info("ASRC_DQ_INBUF interrupt received\n");
1266                                 err = -ERESTARTSYS;
1267                                 break;
1268                         }
1269                         spin_lock_irqsave(&input_int_lock, lock_flags);
1270                         params->input_counter--;
1271                         block =
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;
1279                         if (copy_to_user
1280                             ((void __user *)arg, &buf,
1281                              sizeof(struct asrc_buffer)))
1282                                 err = -EFAULT;
1283
1284                         break;
1285                 }
1286         case ASRC_Q_OUTBUF:{
1287                         struct asrc_buffer buf;
1288                         struct dma_block *block;
1289                         unsigned long lock_flags;
1290                         if (copy_from_user
1291                             (&buf, (void __user *)arg,
1292                              sizeof(struct asrc_buffer))) {
1293                                 err = -EFAULT;
1294                                 break;
1295                         }
1296
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(&params->output_dma[buf.index].
1301                                       queue, &params->output_queue);
1302                         if (!list_empty(&params->output_queue)) {
1303                                 block =
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                                               &params->output_done_queue);
1309                                 params->output_queue_empty++;
1310                         }
1311
1312                         spin_unlock_irqrestore(&output_int_lock, lock_flags);
1313                         break;
1314                 }
1315         case ASRC_DQ_OUTBUF:{
1316                         struct asrc_buffer buf;
1317                         struct dma_block *block;
1318                         unsigned long lock_flags;
1319                         if (copy_from_user
1320                             (&buf, (void __user *)arg,
1321                              sizeof(struct asrc_buffer))) {
1322                                 err = -EFAULT;
1323                                 break;
1324                         }
1325                         /* if ASRC is inactive, nonsense to DQ buffer */
1326                         if (params->asrc_active == 0) {
1327                                 buf.buf_valid = ASRC_BUF_NA;
1328                                 err = -EFAULT;
1329                                 if (copy_to_user
1330                                     ((void __user *)arg, &buf,
1331                                      sizeof(struct asrc_buffer)))
1332                                         err = -EFAULT;
1333                                 break;
1334                         }
1335
1336                         if (!wait_event_interruptible_timeout
1337                             (params->output_wait_queue,
1338                              params->output_counter != 0, 10 * HZ)) {
1339                                 pr_info
1340                                     ("ASRC_DQ_OUTBUF timeout counter %x\n",
1341                                      params->output_counter);
1342                                 err = -ETIME;
1343                                 break;
1344                         } else if (signal_pending(current)) {
1345                                 pr_info("ASRC_DQ_INBUF interrupt received\n");
1346                                 err = -ERESTARTSYS;
1347                                 break;
1348                         }
1349                         spin_lock_irqsave(&output_int_lock, lock_flags);
1350                         params->output_counter--;
1351                         block =
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;
1359                         if (copy_to_user
1360                             ((void __user *)arg, &buf,
1361                              sizeof(struct asrc_buffer)))
1362                                 err = -EFAULT;
1363
1364                         break;
1365                 }
1366         case ASRC_START_CONV:{
1367                         enum asrc_pair_index index;
1368                         unsigned long lock_flags;
1369                         if (copy_from_user
1370                             (&index, (void __user *)arg,
1371                              sizeof(enum asrc_pair_index))) {
1372                                 err = -EFAULT;
1373                                 break;
1374                         }
1375                         spin_lock_irqsave(&input_int_lock, lock_flags);
1376                         if (params->input_queue_empty == 0) {
1377                                 err = -EFAULT;
1378                                 pr_info
1379                                     ("ASRC_START_CONV - no block available\n");
1380                                 break;
1381                         }
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);
1386
1387                         asrc_start_conv(index);
1388
1389                         break;
1390                 }
1391         case ASRC_STOP_CONV:{
1392                         enum asrc_pair_index index;
1393                         if (copy_from_user
1394                             (&index, (void __user *)arg,
1395                              sizeof(enum asrc_pair_index))) {
1396                                 err = -EFAULT;
1397                                 break;
1398                         }
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;
1403                         break;
1404                 }
1405         case ASRC_STATUS:{
1406                         struct asrc_status_flags flags;
1407                         if (copy_from_user
1408                             (&flags, (void __user *)arg,
1409                              sizeof(struct asrc_status_flags))) {
1410                                 err = -EFAULT;
1411                                 break;
1412                         }
1413                         asrc_get_status(&flags);
1414                         if (copy_to_user
1415                             ((void __user *)arg, &flags,
1416                              sizeof(struct asrc_status_flags)))
1417                                 err = -EFAULT;
1418                         break;
1419                 }
1420         case ASRC_FLUSH:{
1421                         /* flush input dma buffer */
1422                         unsigned long lock_flags;
1423                         u32 rx_id, tx_id;
1424                         char *rx_name, *tx_name;
1425                         spin_lock_irqsave(&input_int_lock, lock_flags);
1426                         while (!list_empty(&params->input_queue))
1427                                 list_del(params->input_queue.next);
1428                         while (!list_empty(&params->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);
1433
1434                         /* flush output dma buffer */
1435                         spin_lock_irqsave(&output_int_lock, lock_flags);
1436                         while (!list_empty(&params->output_queue))
1437                                 list_del(params->output_queue.next);
1438                         while (!list_empty(&params->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);
1443
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];
1457                         } else {
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];
1462                         }
1463
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);
1467                                 err = -EBUSY;
1468                         }
1469
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);
1473                                 err = -EBUSY;
1474                         }
1475
1476                         break;
1477                 }
1478         default:
1479                 break;
1480         }
1481
1482         return err;
1483 }
1484
1485 /*!
1486  * asrc interface - open function
1487  *
1488  * @param inode        structure inode *
1489  *
1490  * @param file         structure file *
1491  *
1492  * @return  status    0 success, ENODEV invalid device instance,
1493  *      ENOBUFS failed to allocate buffer, ERESTARTSYS interrupted by user
1494  */
1495 static int mxc_asrc_open(struct inode *inode, struct file *file)
1496 {
1497         int err = 0;
1498         struct asrc_pair_params *pair_params;
1499
1500         if (signal_pending(current))
1501                 return -EINTR;
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");
1505                 err = -ENOBUFS;
1506         }
1507         file->private_data = pair_params;
1508         return err;
1509 }
1510
1511 /*!
1512  * asrc interface - close function
1513  *
1514  * @param inode    struct inode *
1515  * @param file        structure file *
1516  *
1517  * @return status     0 Success, EINTR busy lock error, ENOBUFS remap_page error
1518  */
1519 static int mxc_asrc_close(struct inode *inode, struct file *file)
1520 {
1521         struct asrc_pair_params *pair_params;
1522         pair_params = file->private_data;
1523         if (pair_params) {
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);
1532                 }
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);
1543                 }
1544                 kfree(pair_params);
1545                 file->private_data = NULL;
1546         }
1547         return 0;
1548 }
1549
1550 /*!
1551  * asrc interface - mmap function
1552  *
1553  * @param file        structure file *
1554  *
1555  * @param vma         structure vm_area_struct *
1556  *
1557  * @return status     0 Success, EINTR busy lock error, ENOBUFS remap_page error
1558  */
1559 static int mxc_asrc_mmap(struct file *file, struct vm_area_struct *vma)
1560 {
1561         unsigned long size;
1562         int res = 0;
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))
1567                 return -ENOBUFS;
1568
1569         vma->vm_flags &= ~VM_IO;
1570         return res;
1571 }
1572
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,
1579 };
1580
1581 static int asrc_read_proc_attr(char *page, char **start, off_t off,
1582                                int count, int *eof, void *data)
1583 {
1584         unsigned long reg;
1585         int len = 0;
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);
1589
1590         len += sprintf(page, "ANCA: %d\n",
1591                        (int)(reg &
1592                              (0xFFFFFFFF >>
1593                               (32 - g_asrc->mxc_asrc_data->channel_bits))));
1594         len +=
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))));
1599         len +=
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))));
1603
1604         if (off > len)
1605                 return 0;
1606
1607         *eof = (len <= count) ? 1 : 0;
1608         *start = page + off;
1609
1610         return min(count, len - (int)off);
1611 }
1612
1613 static int asrc_write_proc_attr(struct file *file, const char *buffer,
1614                                 unsigned long count, void *data)
1615 {
1616         char buf[50];
1617         unsigned long reg;
1618         int na, nb, nc;
1619         int total;
1620         if (count > 48)
1621                 return -EINVAL;
1622         if (copy_from_user(buf, buffer, count)) {
1623                 pr_debug("Attr proc write, Failed to copy buffer from user\n");
1624                 return -EFAULT;
1625         }
1626
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)
1632                 total = 10;
1633         else
1634                 total = 5;
1635         if ((na + nb + nc) != total) {
1636                 pr_info("Wrong ASRCNR settings\n");
1637                 return -EFAULT;
1638         }
1639         reg = na | (nb << g_asrc->mxc_asrc_data->channel_bits) |
1640                 (nc << (g_asrc->mxc_asrc_data->channel_bits * 2));
1641
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);
1645
1646         return count;
1647 }
1648
1649 static void asrc_proc_create(void)
1650 {
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",
1655                                               S_IFREG | S_IRUGO |
1656                                               S_IWUSR, g_asrc->proc_asrc);
1657                 if (proc_attr) {
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;
1662                 } else {
1663                         remove_proc_entry(ASRC_PROC_PATH, NULL);
1664                         pr_info("Failed to create proc attribute entry \n");
1665                 }
1666         } else {
1667                 pr_info("ASRC: Failed to create proc entry %s\n",
1668                         ASRC_PROC_PATH);
1669         }
1670 }
1671
1672 /*!
1673  * Entry point for the asrc device
1674  *
1675  * @param       pdev Pionter to the registered platform device
1676  * @return  Error code indicating success or failure
1677  */
1678 static int mxc_asrc_probe(struct platform_device *pdev)
1679 {
1680         int err = 0;
1681         struct resource *res;
1682         struct device *temp_class;
1683         int irq;
1684         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1685         if (!res)
1686                 return -ENOENT;
1687
1688         g_asrc = kzalloc(sizeof(struct asrc_data), GFP_KERNEL);
1689
1690         if (g_asrc == NULL) {
1691                 pr_info("Failed to allocate g_asrc\n");
1692                 return -ENOMEM;
1693         }
1694
1695         g_asrc->dev = &pdev->dev;
1696         g_asrc->dev->coherent_dma_mask = DMA_BIT_MASK(32);
1697
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;
1704
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");
1709                 err = -EBUSY;
1710                 goto error;
1711         }
1712
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;
1717         }
1718
1719         temp_class =
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);
1724                 goto err_out_class;
1725         }
1726
1727         g_asrc->paddr = res->start;
1728         g_asrc->vaddr =
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;
1732
1733         clk_enable(g_asrc->mxc_asrc_data->asrc_core_clk);
1734
1735         switch (g_asrc->mxc_asrc_data->clk_map_ver) {
1736         case 1:
1737                 input_clk_map = &input_clk_map_v1[0];
1738                 output_clk_map = &output_clk_map_v1[0];
1739                 break;
1740         case 2:
1741         default:
1742                 input_clk_map = &input_clk_map_v2[0];
1743                 output_clk_map = &output_clk_map_v2[0];
1744                 break;
1745         }
1746
1747         res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx1");
1748         if (res)
1749                 g_asrc->dmatx[0] = res->start;
1750
1751         res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx1");
1752         if (res)
1753                 g_asrc->dmarx[0] = res->start;
1754
1755         res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx2");
1756         if (res)
1757                 g_asrc->dmatx[1] = res->start;
1758
1759         res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx2");
1760         if (res)
1761                 g_asrc->dmarx[1] = res->start;
1762
1763         res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx3");
1764         if (res)
1765                 g_asrc->dmatx[2] = res->start;
1766
1767         res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx3");
1768         if (res)
1769                 g_asrc->dmarx[2] = res->start;
1770
1771         irq = platform_get_irq(pdev, 0);
1772         if (request_irq(irq, asrc_isr, 0, "asrc", NULL))
1773                 return -1;
1774
1775         asrc_proc_create();
1776         err = mxc_init_asrc();
1777         if (err < 0)
1778                 goto err_out_class;
1779
1780         goto out;
1781
1782       err_out_class:
1783         device_destroy(g_asrc->asrc_class, MKDEV(g_asrc->asrc_major, 0));
1784         class_destroy(g_asrc->asrc_class);
1785       err_out_chrdev:
1786         unregister_chrdev(g_asrc->asrc_major, "mxc_asrc");
1787       error:
1788         kfree(g_asrc);
1789       out:
1790         clk_disable(g_asrc->mxc_asrc_data->asrc_core_clk);
1791         pr_info("mxc_asrc registered\n");
1792         return err;
1793 }
1794
1795 /*!
1796  * Exit asrc device
1797  *
1798  * @param       pdev Pionter to the registered platform device
1799  * @return  Error code indicating success or failure
1800  */
1801 static int mxc_asrc_remove(struct platform_device *pdev)
1802 {
1803         int irq = platform_get_irq(pdev, 0);
1804         free_irq(irq, NULL);
1805         kfree(g_asrc);
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");
1813         return 0;
1814 }
1815
1816 /*! mxc asrc driver definition
1817  *
1818  */
1819 static struct platform_driver mxc_asrc_driver = {
1820         .driver = {
1821                    .name = "mxc_asrc",
1822                    },
1823         .probe = mxc_asrc_probe,
1824         .remove = mxc_asrc_remove,
1825 };
1826
1827 /*!
1828  * Register asrc driver
1829  *
1830  */
1831 static __init int asrc_init(void)
1832 {
1833         int ret;
1834         ret = platform_driver_register(&mxc_asrc_driver);
1835         return ret;
1836 }
1837
1838 /*!
1839  * Exit and free the asrc data
1840  *
1841  */ static void __exit asrc_exit(void)
1842 {
1843         platform_driver_unregister(&mxc_asrc_driver);
1844         return;
1845 }
1846
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");