Merge branches 'release' and 'autoload' into release
[sfrench/cifs-2.6.git] / sound / soc / fsl / fsl_ssi.c
1 /*
2  * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
3  *
4  * Author: Timur Tabi <timur@freescale.com>
5  *
6  * Copyright 2007-2008 Freescale Semiconductor, Inc.  This file is licensed
7  * under the terms of the GNU General Public License version 2.  This
8  * program is licensed "as is" without any warranty of any kind, whether
9  * express or implied.
10  */
11
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/interrupt.h>
15 #include <linux/device.h>
16 #include <linux/delay.h>
17
18 #include <sound/driver.h>
19 #include <sound/core.h>
20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h>
22 #include <sound/initval.h>
23 #include <sound/soc.h>
24
25 #include <asm/immap_86xx.h>
26
27 #include "fsl_ssi.h"
28
29 /**
30  * FSLSSI_I2S_RATES: sample rates supported by the I2S
31  *
32  * This driver currently only supports the SSI running in I2S slave mode,
33  * which means the codec determines the sample rate.  Therefore, we tell
34  * ALSA that we support all rates and let the codec driver decide what rates
35  * are really supported.
36  */
37 #define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
38                           SNDRV_PCM_RATE_CONTINUOUS)
39
40 /**
41  * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
42  *
43  * This driver currently only supports the SSI running in I2S slave mode.
44  *
45  * The SSI has a limitation in that the samples must be in the same byte
46  * order as the host CPU.  This is because when multiple bytes are written
47  * to the STX register, the bytes and bits must be written in the same
48  * order.  The STX is a shift register, so all the bits need to be aligned
49  * (bit-endianness must match byte-endianness).  Processors typically write
50  * the bits within a byte in the same order that the bytes of a word are
51  * written in.  So if the host CPU is big-endian, then only big-endian
52  * samples will be written to STX properly.
53  */
54 #ifdef __BIG_ENDIAN
55 #define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
56          SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_S20_3BE | \
57          SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_S24_BE)
58 #else
59 #define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
60          SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \
61          SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
62 #endif
63
64 /**
65  * fsl_ssi_private: per-SSI private data
66  *
67  * @name: short name for this device ("SSI0", "SSI1", etc)
68  * @ssi: pointer to the SSI's registers
69  * @ssi_phys: physical address of the SSI registers
70  * @irq: IRQ of this SSI
71  * @dev: struct device pointer
72  * @playback: the number of playback streams opened
73  * @capture: the number of capture streams opened
74  * @cpu_dai: the CPU DAI for this device
75  * @dev_attr: the sysfs device attribute structure
76  * @stats: SSI statistics
77  */
78 struct fsl_ssi_private {
79         char name[8];
80         struct ccsr_ssi __iomem *ssi;
81         dma_addr_t ssi_phys;
82         unsigned int irq;
83         struct device *dev;
84         unsigned int playback;
85         unsigned int capture;
86         struct snd_soc_cpu_dai cpu_dai;
87         struct device_attribute dev_attr;
88
89         struct {
90                 unsigned int rfrc;
91                 unsigned int tfrc;
92                 unsigned int cmdau;
93                 unsigned int cmddu;
94                 unsigned int rxt;
95                 unsigned int rdr1;
96                 unsigned int rdr0;
97                 unsigned int tde1;
98                 unsigned int tde0;
99                 unsigned int roe1;
100                 unsigned int roe0;
101                 unsigned int tue1;
102                 unsigned int tue0;
103                 unsigned int tfs;
104                 unsigned int rfs;
105                 unsigned int tls;
106                 unsigned int rls;
107                 unsigned int rff1;
108                 unsigned int rff0;
109                 unsigned int tfe1;
110                 unsigned int tfe0;
111         } stats;
112 };
113
114 /**
115  * fsl_ssi_isr: SSI interrupt handler
116  *
117  * Although it's possible to use the interrupt handler to send and receive
118  * data to/from the SSI, we use the DMA instead.  Programming is more
119  * complicated, but the performance is much better.
120  *
121  * This interrupt handler is used only to gather statistics.
122  *
123  * @irq: IRQ of the SSI device
124  * @dev_id: pointer to the ssi_private structure for this SSI device
125  */
126 static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
127 {
128         struct fsl_ssi_private *ssi_private = dev_id;
129         struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
130         irqreturn_t ret = IRQ_NONE;
131         __be32 sisr;
132         __be32 sisr2 = 0;
133
134         /* We got an interrupt, so read the status register to see what we
135            were interrupted for.  We mask it with the Interrupt Enable register
136            so that we only check for events that we're interested in.
137          */
138         sisr = in_be32(&ssi->sisr) & in_be32(&ssi->sier);
139
140         if (sisr & CCSR_SSI_SISR_RFRC) {
141                 ssi_private->stats.rfrc++;
142                 sisr2 |= CCSR_SSI_SISR_RFRC;
143                 ret = IRQ_HANDLED;
144         }
145
146         if (sisr & CCSR_SSI_SISR_TFRC) {
147                 ssi_private->stats.tfrc++;
148                 sisr2 |= CCSR_SSI_SISR_TFRC;
149                 ret = IRQ_HANDLED;
150         }
151
152         if (sisr & CCSR_SSI_SISR_CMDAU) {
153                 ssi_private->stats.cmdau++;
154                 ret = IRQ_HANDLED;
155         }
156
157         if (sisr & CCSR_SSI_SISR_CMDDU) {
158                 ssi_private->stats.cmddu++;
159                 ret = IRQ_HANDLED;
160         }
161
162         if (sisr & CCSR_SSI_SISR_RXT) {
163                 ssi_private->stats.rxt++;
164                 ret = IRQ_HANDLED;
165         }
166
167         if (sisr & CCSR_SSI_SISR_RDR1) {
168                 ssi_private->stats.rdr1++;
169                 ret = IRQ_HANDLED;
170         }
171
172         if (sisr & CCSR_SSI_SISR_RDR0) {
173                 ssi_private->stats.rdr0++;
174                 ret = IRQ_HANDLED;
175         }
176
177         if (sisr & CCSR_SSI_SISR_TDE1) {
178                 ssi_private->stats.tde1++;
179                 ret = IRQ_HANDLED;
180         }
181
182         if (sisr & CCSR_SSI_SISR_TDE0) {
183                 ssi_private->stats.tde0++;
184                 ret = IRQ_HANDLED;
185         }
186
187         if (sisr & CCSR_SSI_SISR_ROE1) {
188                 ssi_private->stats.roe1++;
189                 sisr2 |= CCSR_SSI_SISR_ROE1;
190                 ret = IRQ_HANDLED;
191         }
192
193         if (sisr & CCSR_SSI_SISR_ROE0) {
194                 ssi_private->stats.roe0++;
195                 sisr2 |= CCSR_SSI_SISR_ROE0;
196                 ret = IRQ_HANDLED;
197         }
198
199         if (sisr & CCSR_SSI_SISR_TUE1) {
200                 ssi_private->stats.tue1++;
201                 sisr2 |= CCSR_SSI_SISR_TUE1;
202                 ret = IRQ_HANDLED;
203         }
204
205         if (sisr & CCSR_SSI_SISR_TUE0) {
206                 ssi_private->stats.tue0++;
207                 sisr2 |= CCSR_SSI_SISR_TUE0;
208                 ret = IRQ_HANDLED;
209         }
210
211         if (sisr & CCSR_SSI_SISR_TFS) {
212                 ssi_private->stats.tfs++;
213                 ret = IRQ_HANDLED;
214         }
215
216         if (sisr & CCSR_SSI_SISR_RFS) {
217                 ssi_private->stats.rfs++;
218                 ret = IRQ_HANDLED;
219         }
220
221         if (sisr & CCSR_SSI_SISR_TLS) {
222                 ssi_private->stats.tls++;
223                 ret = IRQ_HANDLED;
224         }
225
226         if (sisr & CCSR_SSI_SISR_RLS) {
227                 ssi_private->stats.rls++;
228                 ret = IRQ_HANDLED;
229         }
230
231         if (sisr & CCSR_SSI_SISR_RFF1) {
232                 ssi_private->stats.rff1++;
233                 ret = IRQ_HANDLED;
234         }
235
236         if (sisr & CCSR_SSI_SISR_RFF0) {
237                 ssi_private->stats.rff0++;
238                 ret = IRQ_HANDLED;
239         }
240
241         if (sisr & CCSR_SSI_SISR_TFE1) {
242                 ssi_private->stats.tfe1++;
243                 ret = IRQ_HANDLED;
244         }
245
246         if (sisr & CCSR_SSI_SISR_TFE0) {
247                 ssi_private->stats.tfe0++;
248                 ret = IRQ_HANDLED;
249         }
250
251         /* Clear the bits that we set */
252         if (sisr2)
253                 out_be32(&ssi->sisr, sisr2);
254
255         return ret;
256 }
257
258 /**
259  * fsl_ssi_startup: create a new substream
260  *
261  * This is the first function called when a stream is opened.
262  *
263  * If this is the first stream open, then grab the IRQ and program most of
264  * the SSI registers.
265  */
266 static int fsl_ssi_startup(struct snd_pcm_substream *substream)
267 {
268         struct snd_soc_pcm_runtime *rtd = substream->private_data;
269         struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
270
271         /*
272          * If this is the first stream opened, then request the IRQ
273          * and initialize the SSI registers.
274          */
275         if (!ssi_private->playback && !ssi_private->capture) {
276                 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
277                 int ret;
278
279                 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
280                                   ssi_private->name, ssi_private);
281                 if (ret < 0) {
282                         dev_err(substream->pcm->card->dev,
283                                 "could not claim irq %u\n", ssi_private->irq);
284                         return ret;
285                 }
286
287                 /*
288                  * Section 16.5 of the MPC8610 reference manual says that the
289                  * SSI needs to be disabled before updating the registers we set
290                  * here.
291                  */
292                 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
293
294                 /*
295                  * Program the SSI into I2S Slave Non-Network Synchronous mode.
296                  * Also enable the transmit and receive FIFO.
297                  *
298                  * FIXME: Little-endian samples require a different shift dir
299                  */
300                 clrsetbits_be32(&ssi->scr, CCSR_SSI_SCR_I2S_MODE_MASK,
301                         CCSR_SSI_SCR_TFR_CLK_DIS |
302                         CCSR_SSI_SCR_I2S_MODE_SLAVE | CCSR_SSI_SCR_SYN);
303
304                 out_be32(&ssi->stcr,
305                          CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
306                          CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
307                          CCSR_SSI_STCR_TSCKP);
308
309                 out_be32(&ssi->srcr,
310                          CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
311                          CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
312                          CCSR_SSI_SRCR_RSCKP);
313
314                 /*
315                  * The DC and PM bits are only used if the SSI is the clock
316                  * master.
317                  */
318
319                 /* 4. Enable the interrupts and DMA requests */
320                 out_be32(&ssi->sier,
321                          CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE |
322                          CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN |
323                          CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN |
324                          CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE |
325                          CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN);
326
327                 /*
328                  * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
329                  * don't use FIFO 1.  Since the SSI only supports stereo, the
330                  * watermark should never be an odd number.
331                  */
332                 out_be32(&ssi->sfcsr,
333                          CCSR_SSI_SFCSR_TFWM0(6) | CCSR_SSI_SFCSR_RFWM0(2));
334
335                 /*
336                  * We keep the SSI disabled because if we enable it, then the
337                  * DMA controller will start.  It's not supposed to start until
338                  * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
339                  * DMA controller will transfer one "BWC" of data (i.e. the
340                  * amount of data that the MR.BWC bits are set to).  The reason
341                  * this is bad is because at this point, the PCM driver has not
342                  * finished initializing the DMA controller.
343                  */
344         }
345
346         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
347                 ssi_private->playback++;
348
349         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
350                 ssi_private->capture++;
351
352         return 0;
353 }
354
355 /**
356  * fsl_ssi_prepare: prepare the SSI.
357  *
358  * Most of the SSI registers have been programmed in the startup function,
359  * but the word length must be programmed here.  Unfortunately, programming
360  * the SxCCR.WL bits requires the SSI to be temporarily disabled.  This can
361  * cause a problem with supporting simultaneous playback and capture.  If
362  * the SSI is already playing a stream, then that stream may be temporarily
363  * stopped when you start capture.
364  *
365  * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
366  * clock master.
367  */
368 static int fsl_ssi_prepare(struct snd_pcm_substream *substream)
369 {
370         struct snd_pcm_runtime *runtime = substream->runtime;
371         struct snd_soc_pcm_runtime *rtd = substream->private_data;
372         struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
373
374         struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
375         u32 wl;
376
377         wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format));
378
379         clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
380
381         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
382                 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
383         else
384                 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
385
386         setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
387
388         return 0;
389 }
390
391 /**
392  * fsl_ssi_trigger: start and stop the DMA transfer.
393  *
394  * This function is called by ALSA to start, stop, pause, and resume the DMA
395  * transfer of data.
396  *
397  * The DMA channel is in external master start and pause mode, which
398  * means the SSI completely controls the flow of data.
399  */
400 static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
401 {
402         struct snd_soc_pcm_runtime *rtd = substream->private_data;
403         struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
404         struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
405
406         switch (cmd) {
407         case SNDRV_PCM_TRIGGER_START:
408         case SNDRV_PCM_TRIGGER_RESUME:
409         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
410                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
411                         setbits32(&ssi->scr, CCSR_SSI_SCR_TE);
412                 } else {
413                         setbits32(&ssi->scr, CCSR_SSI_SCR_RE);
414
415                         /*
416                          * I think we need this delay to allow time for the SSI
417                          * to put data into its FIFO.  Without it, ALSA starts
418                          * to complain about overruns.
419                          */
420                         msleep(1);
421                 }
422                 break;
423
424         case SNDRV_PCM_TRIGGER_STOP:
425         case SNDRV_PCM_TRIGGER_SUSPEND:
426         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
427                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
428                         clrbits32(&ssi->scr, CCSR_SSI_SCR_TE);
429                 else
430                         clrbits32(&ssi->scr, CCSR_SSI_SCR_RE);
431                 break;
432
433         default:
434                 return -EINVAL;
435         }
436
437         return 0;
438 }
439
440 /**
441  * fsl_ssi_shutdown: shutdown the SSI
442  *
443  * Shutdown the SSI if there are no other substreams open.
444  */
445 static void fsl_ssi_shutdown(struct snd_pcm_substream *substream)
446 {
447         struct snd_soc_pcm_runtime *rtd = substream->private_data;
448         struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
449
450         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
451                 ssi_private->playback--;
452
453         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
454                 ssi_private->capture--;
455
456         /*
457          * If this is the last active substream, disable the SSI and release
458          * the IRQ.
459          */
460         if (!ssi_private->playback && !ssi_private->capture) {
461                 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
462
463                 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
464
465                 free_irq(ssi_private->irq, ssi_private);
466         }
467 }
468
469 /**
470  * fsl_ssi_set_sysclk: set the clock frequency and direction
471  *
472  * This function is called by the machine driver to tell us what the clock
473  * frequency and direction are.
474  *
475  * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
476  * and we don't care about the frequency.  Return an error if the direction
477  * is not SND_SOC_CLOCK_IN.
478  *
479  * @clk_id: reserved, should be zero
480  * @freq: the frequency of the given clock ID, currently ignored
481  * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
482  */
483 static int fsl_ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai,
484                               int clk_id, unsigned int freq, int dir)
485 {
486
487         return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
488 }
489
490 /**
491  * fsl_ssi_set_fmt: set the serial format.
492  *
493  * This function is called by the machine driver to tell us what serial
494  * format to use.
495  *
496  * Currently, we only support I2S mode.  Return an error if the format is
497  * not SND_SOC_DAIFMT_I2S.
498  *
499  * @format: one of SND_SOC_DAIFMT_xxx
500  */
501 static int fsl_ssi_set_fmt(struct snd_soc_cpu_dai *cpu_dai, unsigned int format)
502 {
503         return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
504 }
505
506 /**
507  * fsl_ssi_dai_template: template CPU DAI for the SSI
508  */
509 static struct snd_soc_cpu_dai fsl_ssi_dai_template = {
510         .playback = {
511                 /* The SSI does not support monaural audio. */
512                 .channels_min = 2,
513                 .channels_max = 2,
514                 .rates = FSLSSI_I2S_RATES,
515                 .formats = FSLSSI_I2S_FORMATS,
516         },
517         .capture = {
518                 .channels_min = 2,
519                 .channels_max = 2,
520                 .rates = FSLSSI_I2S_RATES,
521                 .formats = FSLSSI_I2S_FORMATS,
522         },
523         .ops = {
524                 .startup = fsl_ssi_startup,
525                 .prepare = fsl_ssi_prepare,
526                 .shutdown = fsl_ssi_shutdown,
527                 .trigger = fsl_ssi_trigger,
528         },
529         .dai_ops = {
530                 .set_sysclk = fsl_ssi_set_sysclk,
531                 .set_fmt = fsl_ssi_set_fmt,
532         },
533 };
534
535 /**
536  * fsl_sysfs_ssi_show: display SSI statistics
537  *
538  * Display the statistics for the current SSI device.
539  */
540 static ssize_t fsl_sysfs_ssi_show(struct device *dev,
541         struct device_attribute *attr, char *buf)
542 {
543         struct fsl_ssi_private *ssi_private =
544         container_of(attr, struct fsl_ssi_private, dev_attr);
545         ssize_t length;
546
547         length = sprintf(buf, "rfrc=%u", ssi_private->stats.rfrc);
548         length += sprintf(buf + length, "\ttfrc=%u", ssi_private->stats.tfrc);
549         length += sprintf(buf + length, "\tcmdau=%u", ssi_private->stats.cmdau);
550         length += sprintf(buf + length, "\tcmddu=%u", ssi_private->stats.cmddu);
551         length += sprintf(buf + length, "\trxt=%u", ssi_private->stats.rxt);
552         length += sprintf(buf + length, "\trdr1=%u", ssi_private->stats.rdr1);
553         length += sprintf(buf + length, "\trdr0=%u", ssi_private->stats.rdr0);
554         length += sprintf(buf + length, "\ttde1=%u", ssi_private->stats.tde1);
555         length += sprintf(buf + length, "\ttde0=%u", ssi_private->stats.tde0);
556         length += sprintf(buf + length, "\troe1=%u", ssi_private->stats.roe1);
557         length += sprintf(buf + length, "\troe0=%u", ssi_private->stats.roe0);
558         length += sprintf(buf + length, "\ttue1=%u", ssi_private->stats.tue1);
559         length += sprintf(buf + length, "\ttue0=%u", ssi_private->stats.tue0);
560         length += sprintf(buf + length, "\ttfs=%u", ssi_private->stats.tfs);
561         length += sprintf(buf + length, "\trfs=%u", ssi_private->stats.rfs);
562         length += sprintf(buf + length, "\ttls=%u", ssi_private->stats.tls);
563         length += sprintf(buf + length, "\trls=%u", ssi_private->stats.rls);
564         length += sprintf(buf + length, "\trff1=%u", ssi_private->stats.rff1);
565         length += sprintf(buf + length, "\trff0=%u", ssi_private->stats.rff0);
566         length += sprintf(buf + length, "\ttfe1=%u", ssi_private->stats.tfe1);
567         length += sprintf(buf + length, "\ttfe0=%u\n", ssi_private->stats.tfe0);
568
569         return length;
570 }
571
572 /**
573  * fsl_ssi_create_dai: create a snd_soc_cpu_dai structure
574  *
575  * This function is called by the machine driver to create a snd_soc_cpu_dai
576  * structure.  The function creates an ssi_private object, which contains
577  * the snd_soc_cpu_dai.  It also creates the sysfs statistics device.
578  */
579 struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
580 {
581         struct snd_soc_cpu_dai *fsl_ssi_dai;
582         struct fsl_ssi_private *ssi_private;
583         int ret = 0;
584         struct device_attribute *dev_attr;
585
586         ssi_private = kzalloc(sizeof(struct fsl_ssi_private), GFP_KERNEL);
587         if (!ssi_private) {
588                 dev_err(ssi_info->dev, "could not allocate DAI object\n");
589                 return NULL;
590         }
591         memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template,
592                sizeof(struct snd_soc_cpu_dai));
593
594         fsl_ssi_dai = &ssi_private->cpu_dai;
595         dev_attr = &ssi_private->dev_attr;
596
597         sprintf(ssi_private->name, "ssi%u", (u8) ssi_info->id);
598         ssi_private->ssi = ssi_info->ssi;
599         ssi_private->ssi_phys = ssi_info->ssi_phys;
600         ssi_private->irq = ssi_info->irq;
601         ssi_private->dev = ssi_info->dev;
602
603         ssi_private->dev->driver_data = fsl_ssi_dai;
604
605         /* Initialize the the device_attribute structure */
606         dev_attr->attr.name = "ssi-stats";
607         dev_attr->attr.mode = S_IRUGO;
608         dev_attr->show = fsl_sysfs_ssi_show;
609
610         ret = device_create_file(ssi_private->dev, dev_attr);
611         if (ret) {
612                 dev_err(ssi_info->dev, "could not create sysfs %s file\n",
613                         ssi_private->dev_attr.attr.name);
614                 kfree(fsl_ssi_dai);
615                 return NULL;
616         }
617
618         fsl_ssi_dai->private_data = ssi_private;
619         fsl_ssi_dai->name = ssi_private->name;
620         fsl_ssi_dai->id = ssi_info->id;
621
622         return fsl_ssi_dai;
623 }
624 EXPORT_SYMBOL_GPL(fsl_ssi_create_dai);
625
626 /**
627  * fsl_ssi_destroy_dai: destroy the snd_soc_cpu_dai object
628  *
629  * This function undoes the operations of fsl_ssi_create_dai()
630  */
631 void fsl_ssi_destroy_dai(struct snd_soc_cpu_dai *fsl_ssi_dai)
632 {
633         struct fsl_ssi_private *ssi_private =
634         container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai);
635
636         device_remove_file(ssi_private->dev, &ssi_private->dev_attr);
637
638         kfree(ssi_private);
639 }
640 EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
641
642 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
643 MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
644 MODULE_LICENSE("GPL");