ASoC: support more sample rates on raumfeld devices
[sfrench/cifs-2.6.git] / sound / soc / imx / mxc-ssi.c
1 /*
2  * mxc-ssi.c  --  SSI driver for Freescale IMX
3  *
4  * Copyright 2006 Wolfson Microelectronics PLC.
5  * Author: Liam Girdwood
6  *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7  *
8  *  Based on mxc-alsa-mc13783 (C) 2006 Freescale.
9  *
10  *  This program is free software; you can redistribute  it and/or modify it
11  *  under  the terms of  the GNU General  Public License as published by the
12  *  Free Software Foundation;  either version 2 of the  License, or (at your
13  *  option) any later version.
14  *
15  * TODO:
16  *   Need to rework SSI register defs when new defs go into mainline.
17  *   Add support for TDM and FIFO 1.
18  *   Add support for i.mx3x DMA interface.
19  *
20  */
21
22
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/platform_device.h>
26 #include <linux/slab.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/clk.h>
29 #include <sound/core.h>
30 #include <sound/pcm.h>
31 #include <sound/pcm_params.h>
32 #include <sound/soc.h>
33 #include <mach/dma-mx1-mx2.h>
34 #include <asm/mach-types.h>
35
36 #include "mxc-ssi.h"
37 #include "mx1_mx2-pcm.h"
38
39 #define SSI1_PORT       0
40 #define SSI2_PORT       1
41
42 static int ssi_active[2] = {0, 0};
43
44 /* DMA information for mx1_mx2 platforms */
45 static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out0 = {
46         .name                   = "SSI1 PCM Stereo out 0",
47         .transfer_type = DMA_MODE_WRITE,
48         .per_address = SSI1_BASE_ADDR + STX0,
49         .event_id = DMA_REQ_SSI1_TX0,
50         .watermark_level = TXFIFO_WATERMARK,
51         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
52         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
53 };
54
55 static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out1 = {
56         .name                   = "SSI1 PCM Stereo out 1",
57         .transfer_type = DMA_MODE_WRITE,
58         .per_address = SSI1_BASE_ADDR + STX1,
59         .event_id = DMA_REQ_SSI1_TX1,
60         .watermark_level = TXFIFO_WATERMARK,
61         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
62         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
63 };
64
65 static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in0 = {
66         .name                   = "SSI1 PCM Stereo in 0",
67         .transfer_type = DMA_MODE_READ,
68         .per_address = SSI1_BASE_ADDR + SRX0,
69         .event_id = DMA_REQ_SSI1_RX0,
70         .watermark_level = RXFIFO_WATERMARK,
71         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
72         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
73 };
74
75 static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in1 = {
76         .name                   = "SSI1 PCM Stereo in 1",
77         .transfer_type = DMA_MODE_READ,
78         .per_address = SSI1_BASE_ADDR + SRX1,
79         .event_id = DMA_REQ_SSI1_RX1,
80         .watermark_level = RXFIFO_WATERMARK,
81         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
82         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
83 };
84
85 static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out0 = {
86         .name                   = "SSI2 PCM Stereo out 0",
87         .transfer_type = DMA_MODE_WRITE,
88         .per_address = SSI2_BASE_ADDR + STX0,
89         .event_id = DMA_REQ_SSI2_TX0,
90         .watermark_level = TXFIFO_WATERMARK,
91         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
92         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
93 };
94
95 static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out1 = {
96         .name                   = "SSI2 PCM Stereo out 1",
97         .transfer_type = DMA_MODE_WRITE,
98         .per_address = SSI2_BASE_ADDR + STX1,
99         .event_id = DMA_REQ_SSI2_TX1,
100         .watermark_level = TXFIFO_WATERMARK,
101         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
102         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
103 };
104
105 static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in0 = {
106         .name                   = "SSI2 PCM Stereo in 0",
107         .transfer_type = DMA_MODE_READ,
108         .per_address = SSI2_BASE_ADDR + SRX0,
109         .event_id = DMA_REQ_SSI2_RX0,
110         .watermark_level = RXFIFO_WATERMARK,
111         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
112         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
113 };
114
115 static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in1 = {
116         .name                   = "SSI2 PCM Stereo in 1",
117         .transfer_type = DMA_MODE_READ,
118         .per_address = SSI2_BASE_ADDR + SRX1,
119         .event_id = DMA_REQ_SSI2_RX1,
120         .watermark_level = RXFIFO_WATERMARK,
121         .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
122         .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
123 };
124
125 static struct clk *ssi_clk0, *ssi_clk1;
126
127 int get_ssi_clk(int ssi, struct device *dev)
128 {
129         switch (ssi) {
130         case 0:
131                 ssi_clk0 = clk_get(dev, "ssi1");
132                 if (IS_ERR(ssi_clk0))
133                         return PTR_ERR(ssi_clk0);
134                 return 0;
135         case 1:
136                 ssi_clk1 = clk_get(dev, "ssi2");
137                 if (IS_ERR(ssi_clk1))
138                         return PTR_ERR(ssi_clk1);
139                 return 0;
140         default:
141                 return -EINVAL;
142         }
143 }
144 EXPORT_SYMBOL(get_ssi_clk);
145
146 void put_ssi_clk(int ssi)
147 {
148         switch (ssi) {
149         case 0:
150                 clk_put(ssi_clk0);
151                 ssi_clk0 = NULL;
152                 break;
153         case 1:
154                 clk_put(ssi_clk1);
155                 ssi_clk1 = NULL;
156                 break;
157         }
158 }
159 EXPORT_SYMBOL(put_ssi_clk);
160
161 /*
162  * SSI system clock configuration.
163  * Should only be called when port is inactive (i.e. SSIEN = 0).
164  */
165 static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
166         int clk_id, unsigned int freq, int dir)
167 {
168         u32 scr;
169
170         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
171                 scr = SSI1_SCR;
172                 pr_debug("%s: SCR for SSI1 is %x\n", __func__, scr);
173         } else {
174                 scr = SSI2_SCR;
175                 pr_debug("%s: SCR for SSI2 is %x\n", __func__, scr);
176         }
177
178         if (scr & SSI_SCR_SSIEN) {
179                 printk(KERN_WARNING "Warning ssi already enabled\n");
180                 return 0;
181         }
182
183         switch (clk_id) {
184         case IMX_SSP_SYS_CLK:
185                 if (dir == SND_SOC_CLOCK_OUT) {
186                         scr |= SSI_SCR_SYS_CLK_EN;
187                         pr_debug("%s: clk of is output\n", __func__);
188                 } else {
189                         scr &= ~SSI_SCR_SYS_CLK_EN;
190                         pr_debug("%s: clk of is input\n", __func__);
191                 }
192                 break;
193         default:
194                 return -EINVAL;
195         }
196
197         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
198                 pr_debug("%s: writeback of SSI1_SCR\n", __func__);
199                 SSI1_SCR = scr;
200         } else {
201                 pr_debug("%s: writeback of SSI2_SCR\n", __func__);
202                 SSI2_SCR = scr;
203         }
204
205         return 0;
206 }
207
208 /*
209  * SSI Clock dividers
210  * Should only be called when port is inactive (i.e. SSIEN = 0).
211  */
212 static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
213         int div_id, int div)
214 {
215         u32 stccr, srccr;
216
217         pr_debug("%s\n", __func__);
218         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
219                 if (SSI1_SCR & SSI_SCR_SSIEN)
220                         return 0;
221                 srccr = SSI1_STCCR;
222                 stccr = SSI1_STCCR;
223         } else {
224                 if (SSI2_SCR & SSI_SCR_SSIEN)
225                         return 0;
226                 srccr = SSI2_STCCR;
227                 stccr = SSI2_STCCR;
228         }
229
230         switch (div_id) {
231         case IMX_SSI_TX_DIV_2:
232                 stccr &= ~SSI_STCCR_DIV2;
233                 stccr |= div;
234                 break;
235         case IMX_SSI_TX_DIV_PSR:
236                 stccr &= ~SSI_STCCR_PSR;
237                 stccr |= div;
238                 break;
239         case IMX_SSI_TX_DIV_PM:
240                 stccr &= ~0xff;
241                 stccr |= SSI_STCCR_PM(div);
242                 break;
243         case IMX_SSI_RX_DIV_2:
244                 stccr &= ~SSI_STCCR_DIV2;
245                 stccr |= div;
246                 break;
247         case IMX_SSI_RX_DIV_PSR:
248                 stccr &= ~SSI_STCCR_PSR;
249                 stccr |= div;
250                 break;
251         case IMX_SSI_RX_DIV_PM:
252                 stccr &= ~0xff;
253                 stccr |= SSI_STCCR_PM(div);
254                 break;
255         default:
256                 return -EINVAL;
257         }
258
259         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
260                 SSI1_STCCR = stccr;
261                 SSI1_SRCCR = srccr;
262         } else {
263                 SSI2_STCCR = stccr;
264                 SSI2_SRCCR = srccr;
265         }
266         return 0;
267 }
268
269 /*
270  * SSI Network Mode or TDM slots configuration.
271  * Should only be called when port is inactive (i.e. SSIEN = 0).
272  */
273 static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
274         unsigned int mask, int slots)
275 {
276         u32 stmsk, srmsk, stccr;
277
278         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
279                 if (SSI1_SCR & SSI_SCR_SSIEN) {
280                         printk(KERN_WARNING "Warning ssi already enabled\n");
281                         return 0;
282                 }
283                 stccr = SSI1_STCCR;
284         } else {
285                 if (SSI2_SCR & SSI_SCR_SSIEN) {
286                         printk(KERN_WARNING "Warning ssi already enabled\n");
287                         return 0;
288                 }
289                 stccr = SSI2_STCCR;
290         }
291
292         stmsk = srmsk = mask;
293         stccr &= ~SSI_STCCR_DC_MASK;
294         stccr |= SSI_STCCR_DC(slots - 1);
295
296         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
297                 SSI1_STMSK = stmsk;
298                 SSI1_SRMSK = srmsk;
299                 SSI1_SRCCR = SSI1_STCCR = stccr;
300         } else {
301                 SSI2_STMSK = stmsk;
302                 SSI2_SRMSK = srmsk;
303                 SSI2_SRCCR = SSI2_STCCR = stccr;
304         }
305
306         return 0;
307 }
308
309 /*
310  * SSI DAI format configuration.
311  * Should only be called when port is inactive (i.e. SSIEN = 0).
312  * Note: We don't use the I2S modes but instead manually configure the
313  * SSI for I2S.
314  */
315 static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai,
316                 unsigned int fmt)
317 {
318         u32 stcr = 0, srcr = 0, scr;
319
320         /*
321          * This is done to avoid this function to modify
322          * previous set values in stcr
323          */
324         stcr = SSI1_STCR;
325
326         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
327                 scr = SSI1_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
328         else
329                 scr = SSI2_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
330
331         if (scr & SSI_SCR_SSIEN) {
332                 printk(KERN_WARNING "Warning ssi already enabled\n");
333                 return 0;
334         }
335
336         /* DAI mode */
337         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
338         case SND_SOC_DAIFMT_I2S:
339                 /* data on rising edge of bclk, frame low 1clk before data */
340                 stcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
341                 srcr |= SSI_SRCR_RFSI | SSI_SRCR_REFS | SSI_SRCR_RXBIT0;
342                 break;
343         case SND_SOC_DAIFMT_LEFT_J:
344                 /* data on rising edge of bclk, frame high with data */
345                 stcr |= SSI_STCR_TXBIT0;
346                 srcr |= SSI_SRCR_RXBIT0;
347                 break;
348         case SND_SOC_DAIFMT_DSP_B:
349                 /* data on rising edge of bclk, frame high with data */
350                 stcr |= SSI_STCR_TFSL;
351                 srcr |= SSI_SRCR_RFSL;
352                 break;
353         case SND_SOC_DAIFMT_DSP_A:
354                 /* data on rising edge of bclk, frame high 1clk before data */
355                 stcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
356                 srcr |= SSI_SRCR_RFSL | SSI_SRCR_REFS;
357                 break;
358         }
359
360         /* DAI clock inversion */
361         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
362         case SND_SOC_DAIFMT_IB_IF:
363                 stcr |= SSI_STCR_TFSI;
364                 stcr &= ~SSI_STCR_TSCKP;
365                 srcr |= SSI_SRCR_RFSI;
366                 srcr &= ~SSI_SRCR_RSCKP;
367                 break;
368         case SND_SOC_DAIFMT_IB_NF:
369                 stcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
370                 srcr &= ~(SSI_SRCR_RSCKP | SSI_SRCR_RFSI);
371                 break;
372         case SND_SOC_DAIFMT_NB_IF:
373                 stcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
374                 srcr |= SSI_SRCR_RFSI | SSI_SRCR_RSCKP;
375                 break;
376         case SND_SOC_DAIFMT_NB_NF:
377                 stcr &= ~SSI_STCR_TFSI;
378                 stcr |= SSI_STCR_TSCKP;
379                 srcr &= ~SSI_SRCR_RFSI;
380                 srcr |= SSI_SRCR_RSCKP;
381                 break;
382         }
383
384         /* DAI clock master masks */
385         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
386         case SND_SOC_DAIFMT_CBS_CFS:
387                 stcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR;
388                 srcr |= SSI_SRCR_RFDIR | SSI_SRCR_RXDIR;
389                 break;
390         case SND_SOC_DAIFMT_CBM_CFS:
391                 stcr |= SSI_STCR_TFDIR;
392                 srcr |= SSI_SRCR_RFDIR;
393                 break;
394         case SND_SOC_DAIFMT_CBS_CFM:
395                 stcr |= SSI_STCR_TXDIR;
396                 srcr |= SSI_SRCR_RXDIR;
397                 break;
398         }
399
400         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
401                 SSI1_STCR = stcr;
402                 SSI1_SRCR = srcr;
403                 SSI1_SCR = scr;
404         } else {
405                 SSI2_STCR = stcr;
406                 SSI2_SRCR = srcr;
407                 SSI2_SCR = scr;
408         }
409
410         return 0;
411 }
412
413 static int imx_ssi_startup(struct snd_pcm_substream *substream,
414                         struct snd_soc_dai *dai)
415 {
416         struct snd_soc_pcm_runtime *rtd = substream->private_data;
417         struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
418
419         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
420                 /* set up TX DMA params */
421                 switch (cpu_dai->id) {
422                 case IMX_DAI_SSI0:
423                         cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out0;
424                         break;
425                 case IMX_DAI_SSI1:
426                         cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out1;
427                         break;
428                 case IMX_DAI_SSI2:
429                         cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out0;
430                         break;
431                 case IMX_DAI_SSI3:
432                         cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out1;
433                 }
434                 pr_debug("%s: (playback)\n", __func__);
435         } else {
436                 /* set up RX DMA params */
437                 switch (cpu_dai->id) {
438                 case IMX_DAI_SSI0:
439                         cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in0;
440                         break;
441                 case IMX_DAI_SSI1:
442                         cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in1;
443                         break;
444                 case IMX_DAI_SSI2:
445                         cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in0;
446                         break;
447                 case IMX_DAI_SSI3:
448                         cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in1;
449                 }
450                 pr_debug("%s: (capture)\n", __func__);
451         }
452
453         /*
454          * we cant really change any SSI values after SSI is enabled
455          * need to fix in software for max flexibility - lrg
456          */
457         if (cpu_dai->active) {
458                 printk(KERN_WARNING "Warning ssi already enabled\n");
459                 return 0;
460         }
461
462         /* reset the SSI port - Sect 45.4.4 */
463         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
464
465                 if (!ssi_clk0)
466                         return -EINVAL;
467
468                 if (ssi_active[SSI1_PORT]++) {
469                         pr_debug("%s: exit before reset\n", __func__);
470                         return 0;
471                 }
472
473                 /* SSI1 Reset */
474                 SSI1_SCR = 0;
475
476                 SSI1_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
477                         SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
478                         SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
479                         SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
480         } else {
481
482                 if (!ssi_clk1)
483                         return -EINVAL;
484
485                 if (ssi_active[SSI2_PORT]++) {
486                         pr_debug("%s: exit before reset\n", __func__);
487                         return 0;
488                 }
489
490                 /* SSI2 Reset */
491                 SSI2_SCR = 0;
492
493                 SSI2_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
494                         SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
495                         SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
496                         SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
497         }
498
499         return 0;
500 }
501
502 int imx_ssi_hw_tx_params(struct snd_pcm_substream *substream,
503                                 struct snd_pcm_hw_params *params)
504 {
505         struct snd_soc_pcm_runtime *rtd = substream->private_data;
506         struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
507         u32 stccr, stcr, sier;
508
509         pr_debug("%s\n", __func__);
510
511         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
512                 stccr = SSI1_STCCR & ~SSI_STCCR_WL_MASK;
513                 stcr = SSI1_STCR;
514                 sier = SSI1_SIER;
515         } else {
516                 stccr = SSI2_STCCR & ~SSI_STCCR_WL_MASK;
517                 stcr = SSI2_STCR;
518                 sier = SSI2_SIER;
519         }
520
521         /* DAI data (word) size */
522         switch (params_format(params)) {
523         case SNDRV_PCM_FORMAT_S16_LE:
524                 stccr |= SSI_STCCR_WL(16);
525                 break;
526         case SNDRV_PCM_FORMAT_S20_3LE:
527                 stccr |= SSI_STCCR_WL(20);
528                 break;
529         case SNDRV_PCM_FORMAT_S24_LE:
530                 stccr |= SSI_STCCR_WL(24);
531                 break;
532         }
533
534         /* enable interrupts */
535         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
536                 stcr |= SSI_STCR_TFEN0;
537         else
538                 stcr |= SSI_STCR_TFEN1;
539         sier |= SSI_SIER_TDMAE;
540
541         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
542                 SSI1_STCR = stcr;
543                 SSI1_STCCR = stccr;
544                 SSI1_SIER = sier;
545         } else {
546                 SSI2_STCR = stcr;
547                 SSI2_STCCR = stccr;
548                 SSI2_SIER = sier;
549         }
550
551         return 0;
552 }
553
554 int imx_ssi_hw_rx_params(struct snd_pcm_substream *substream,
555                                 struct snd_pcm_hw_params *params)
556 {
557         struct snd_soc_pcm_runtime *rtd = substream->private_data;
558         struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
559         u32 srccr, srcr, sier;
560
561         pr_debug("%s\n", __func__);
562
563         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
564                 srccr = SSI1_SRCCR & ~SSI_SRCCR_WL_MASK;
565                 srcr = SSI1_SRCR;
566                 sier = SSI1_SIER;
567         } else {
568                 srccr = SSI2_SRCCR & ~SSI_SRCCR_WL_MASK;
569                 srcr = SSI2_SRCR;
570                 sier = SSI2_SIER;
571         }
572
573         /* DAI data (word) size */
574         switch (params_format(params)) {
575         case SNDRV_PCM_FORMAT_S16_LE:
576                 srccr |= SSI_SRCCR_WL(16);
577                 break;
578         case SNDRV_PCM_FORMAT_S20_3LE:
579                 srccr |= SSI_SRCCR_WL(20);
580                 break;
581         case SNDRV_PCM_FORMAT_S24_LE:
582                 srccr |= SSI_SRCCR_WL(24);
583                 break;
584         }
585
586         /* enable interrupts */
587         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
588                 srcr |= SSI_SRCR_RFEN0;
589         else
590                 srcr |= SSI_SRCR_RFEN1;
591         sier |= SSI_SIER_RDMAE;
592
593         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
594                 SSI1_SRCR = srcr;
595                 SSI1_SRCCR = srccr;
596                 SSI1_SIER = sier;
597         } else {
598                 SSI2_SRCR = srcr;
599                 SSI2_SRCCR = srccr;
600                 SSI2_SIER = sier;
601         }
602
603         return 0;
604 }
605
606 /*
607  * Should only be called when port is inactive (i.e. SSIEN = 0),
608  * although can be called multiple times by upper layers.
609  */
610 int imx_ssi_hw_params(struct snd_pcm_substream *substream,
611                                 struct snd_pcm_hw_params *params,
612                                 struct snd_soc_dai *dai)
613 {
614         struct snd_soc_pcm_runtime *rtd = substream->private_data;
615         struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
616
617         int ret;
618
619         /* cant change any parameters when SSI is running */
620         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
621                 if (SSI1_SCR & SSI_SCR_SSIEN) {
622                         printk(KERN_WARNING "Warning ssi already enabled\n");
623                         return 0;
624                 }
625         } else {
626                 if (SSI2_SCR & SSI_SCR_SSIEN) {
627                         printk(KERN_WARNING "Warning ssi already enabled\n");
628                         return 0;
629                 }
630         }
631
632         /*
633          * Configure both tx and rx params with the same settings. This is
634          * really a harware restriction because SSI must be disabled until
635          * we can change those values. If there is an active audio stream in
636          * one direction, enabling the other direction with different
637          * settings would mean disturbing the running one.
638          */
639         ret = imx_ssi_hw_tx_params(substream, params);
640         if (ret < 0)
641                 return ret;
642         return imx_ssi_hw_rx_params(substream, params);
643 }
644
645 int imx_ssi_prepare(struct snd_pcm_substream *substream,
646                         struct snd_soc_dai *dai)
647 {
648         struct snd_soc_pcm_runtime *rtd = substream->private_data;
649         struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
650         int ret;
651
652         pr_debug("%s\n", __func__);
653
654         /* Enable clks here to follow SSI recommended init sequence */
655         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
656                 ret = clk_enable(ssi_clk0);
657                 if (ret < 0)
658                         printk(KERN_ERR "Unable to enable ssi_clk0\n");
659         } else {
660                 ret = clk_enable(ssi_clk1);
661                 if (ret < 0)
662                         printk(KERN_ERR "Unable to enable ssi_clk1\n");
663         }
664
665         return 0;
666 }
667
668 static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
669                         struct snd_soc_dai *dai)
670 {
671         struct snd_soc_pcm_runtime *rtd = substream->private_data;
672         struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
673         u32 scr;
674
675         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
676                 scr = SSI1_SCR;
677         else
678                 scr = SSI2_SCR;
679
680         switch (cmd) {
681         case SNDRV_PCM_TRIGGER_START:
682         case SNDRV_PCM_TRIGGER_RESUME:
683         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
684                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
685                         scr |= SSI_SCR_TE | SSI_SCR_SSIEN;
686                 else
687                         scr |= SSI_SCR_RE | SSI_SCR_SSIEN;
688                 break;
689         case SNDRV_PCM_TRIGGER_SUSPEND:
690         case SNDRV_PCM_TRIGGER_STOP:
691         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
692                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
693                         scr &= ~SSI_SCR_TE;
694                 else
695                         scr &= ~SSI_SCR_RE;
696                 break;
697         default:
698                 return -EINVAL;
699         }
700
701         if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
702                 SSI1_SCR = scr;
703         else
704                 SSI2_SCR = scr;
705
706         return 0;
707 }
708
709 static void imx_ssi_shutdown(struct snd_pcm_substream *substream,
710                         struct snd_soc_dai *dai)
711 {
712         struct snd_soc_pcm_runtime *rtd = substream->private_data;
713         struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
714
715         /* shutdown SSI if neither Tx or Rx is active */
716         if (!cpu_dai->active) {
717
718                 if (cpu_dai->id == IMX_DAI_SSI0 ||
719                         cpu_dai->id == IMX_DAI_SSI2) {
720
721                         if (--ssi_active[SSI1_PORT] > 1)
722                                 return;
723
724                         SSI1_SCR = 0;
725                         clk_disable(ssi_clk0);
726                 } else {
727                         if (--ssi_active[SSI2_PORT])
728                                 return;
729                         SSI2_SCR = 0;
730                         clk_disable(ssi_clk1);
731                 }
732         }
733 }
734
735 #ifdef CONFIG_PM
736 static int imx_ssi_suspend(struct platform_device *dev,
737         struct snd_soc_dai *dai)
738 {
739         return 0;
740 }
741
742 static int imx_ssi_resume(struct platform_device *pdev,
743         struct snd_soc_dai *dai)
744 {
745         return 0;
746 }
747
748 #else
749 #define imx_ssi_suspend NULL
750 #define imx_ssi_resume  NULL
751 #endif
752
753 #define IMX_SSI_RATES \
754         (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
755         SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
756         SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
757         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
758         SNDRV_PCM_RATE_96000)
759
760 #define IMX_SSI_BITS \
761         (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
762         SNDRV_PCM_FMTBIT_S24_LE)
763
764 static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
765         .startup = imx_ssi_startup,
766         .shutdown = imx_ssi_shutdown,
767         .trigger = imx_ssi_trigger,
768         .prepare = imx_ssi_prepare,
769         .hw_params = imx_ssi_hw_params,
770         .set_sysclk = imx_ssi_set_dai_sysclk,
771         .set_clkdiv = imx_ssi_set_dai_clkdiv,
772         .set_fmt = imx_ssi_set_dai_fmt,
773         .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
774 };
775
776 struct snd_soc_dai imx_ssi_pcm_dai[] = {
777 {
778         .name = "imx-i2s-1-0",
779         .id = IMX_DAI_SSI0,
780         .suspend = imx_ssi_suspend,
781         .resume = imx_ssi_resume,
782         .playback = {
783                 .channels_min = 1,
784                 .channels_max = 2,
785                 .formats = IMX_SSI_BITS,
786                 .rates = IMX_SSI_RATES,},
787         .capture = {
788                 .channels_min = 1,
789                 .channels_max = 2,
790                 .formats = IMX_SSI_BITS,
791                 .rates = IMX_SSI_RATES,},
792         .ops = &imx_ssi_pcm_dai_ops,
793 },
794 {
795         .name = "imx-i2s-2-0",
796         .id = IMX_DAI_SSI1,
797         .playback = {
798                 .channels_min = 1,
799                 .channels_max = 2,
800                 .formats = IMX_SSI_BITS,
801                 .rates = IMX_SSI_RATES,},
802         .capture = {
803                 .channels_min = 1,
804                 .channels_max = 2,
805                 .formats = IMX_SSI_BITS,
806                 .rates = IMX_SSI_RATES,},
807         .ops = &imx_ssi_pcm_dai_ops,
808 },
809 {
810         .name = "imx-i2s-1-1",
811         .id = IMX_DAI_SSI2,
812         .suspend = imx_ssi_suspend,
813         .resume = imx_ssi_resume,
814         .playback = {
815                 .channels_min = 1,
816                 .channels_max = 2,
817                 .formats = IMX_SSI_BITS,
818                 .rates = IMX_SSI_RATES,},
819         .capture = {
820                 .channels_min = 1,
821                 .channels_max = 2,
822                 .formats = IMX_SSI_BITS,
823                 .rates = IMX_SSI_RATES,},
824         .ops = &imx_ssi_pcm_dai_ops,
825 },
826 {
827         .name = "imx-i2s-2-1",
828         .id = IMX_DAI_SSI3,
829         .playback = {
830                 .channels_min = 1,
831                 .channels_max = 2,
832                 .formats = IMX_SSI_BITS,
833                 .rates = IMX_SSI_RATES,},
834         .capture = {
835                 .channels_min = 1,
836                 .channels_max = 2,
837                 .formats = IMX_SSI_BITS,
838                 .rates = IMX_SSI_RATES,},
839         .ops = &imx_ssi_pcm_dai_ops,
840 },
841 };
842 EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
843
844 static int __init imx_ssi_init(void)
845 {
846         return snd_soc_register_dais(imx_ssi_pcm_dai,
847                                 ARRAY_SIZE(imx_ssi_pcm_dai));
848 }
849
850 static void __exit imx_ssi_exit(void)
851 {
852         snd_soc_unregister_dais(imx_ssi_pcm_dai,
853                                 ARRAY_SIZE(imx_ssi_pcm_dai));
854 }
855
856 module_init(imx_ssi_init);
857 module_exit(imx_ssi_exit);
858 MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com");
859 MODULE_DESCRIPTION("i.MX ASoC I2S driver");
860 MODULE_LICENSE("GPL");