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