xref: /openbmc/linux/sound/soc/fsl/fsl_ssi.c (revision f42b3800)
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");
645