• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/sound/soc/fsl/
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#include <linux/slab.h>
18
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/* SIER bitflag of interrupts to enable */
65#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
66		    CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
67		    CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
68		    CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
69		    CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
70
71/**
72 * fsl_ssi_private: per-SSI private data
73 *
74 * @name: short name for this device ("SSI0", "SSI1", etc)
75 * @ssi: pointer to the SSI's registers
76 * @ssi_phys: physical address of the SSI registers
77 * @irq: IRQ of this SSI
78 * @first_stream: pointer to the stream that was opened first
79 * @second_stream: pointer to second stream
80 * @dev: struct device pointer
81 * @playback: the number of playback streams opened
82 * @capture: the number of capture streams opened
83 * @asynchronous: 0=synchronous mode, 1=asynchronous mode
84 * @cpu_dai: the CPU DAI for this device
85 * @dev_attr: the sysfs device attribute structure
86 * @stats: SSI statistics
87 */
88struct fsl_ssi_private {
89	char name[8];
90	struct ccsr_ssi __iomem *ssi;
91	dma_addr_t ssi_phys;
92	unsigned int irq;
93	struct snd_pcm_substream *first_stream;
94	struct snd_pcm_substream *second_stream;
95	struct device *dev;
96	unsigned int playback;
97	unsigned int capture;
98	int asynchronous;
99	struct snd_soc_dai cpu_dai;
100	struct device_attribute dev_attr;
101
102	struct {
103		unsigned int rfrc;
104		unsigned int tfrc;
105		unsigned int cmdau;
106		unsigned int cmddu;
107		unsigned int rxt;
108		unsigned int rdr1;
109		unsigned int rdr0;
110		unsigned int tde1;
111		unsigned int tde0;
112		unsigned int roe1;
113		unsigned int roe0;
114		unsigned int tue1;
115		unsigned int tue0;
116		unsigned int tfs;
117		unsigned int rfs;
118		unsigned int tls;
119		unsigned int rls;
120		unsigned int rff1;
121		unsigned int rff0;
122		unsigned int tfe1;
123		unsigned int tfe0;
124	} stats;
125};
126
127/**
128 * fsl_ssi_isr: SSI interrupt handler
129 *
130 * Although it's possible to use the interrupt handler to send and receive
131 * data to/from the SSI, we use the DMA instead.  Programming is more
132 * complicated, but the performance is much better.
133 *
134 * This interrupt handler is used only to gather statistics.
135 *
136 * @irq: IRQ of the SSI device
137 * @dev_id: pointer to the ssi_private structure for this SSI device
138 */
139static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
140{
141	struct fsl_ssi_private *ssi_private = dev_id;
142	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
143	irqreturn_t ret = IRQ_NONE;
144	__be32 sisr;
145	__be32 sisr2 = 0;
146
147	/* We got an interrupt, so read the status register to see what we
148	   were interrupted for.  We mask it with the Interrupt Enable register
149	   so that we only check for events that we're interested in.
150	 */
151	sisr = in_be32(&ssi->sisr) & SIER_FLAGS;
152
153	if (sisr & CCSR_SSI_SISR_RFRC) {
154		ssi_private->stats.rfrc++;
155		sisr2 |= CCSR_SSI_SISR_RFRC;
156		ret = IRQ_HANDLED;
157	}
158
159	if (sisr & CCSR_SSI_SISR_TFRC) {
160		ssi_private->stats.tfrc++;
161		sisr2 |= CCSR_SSI_SISR_TFRC;
162		ret = IRQ_HANDLED;
163	}
164
165	if (sisr & CCSR_SSI_SISR_CMDAU) {
166		ssi_private->stats.cmdau++;
167		ret = IRQ_HANDLED;
168	}
169
170	if (sisr & CCSR_SSI_SISR_CMDDU) {
171		ssi_private->stats.cmddu++;
172		ret = IRQ_HANDLED;
173	}
174
175	if (sisr & CCSR_SSI_SISR_RXT) {
176		ssi_private->stats.rxt++;
177		ret = IRQ_HANDLED;
178	}
179
180	if (sisr & CCSR_SSI_SISR_RDR1) {
181		ssi_private->stats.rdr1++;
182		ret = IRQ_HANDLED;
183	}
184
185	if (sisr & CCSR_SSI_SISR_RDR0) {
186		ssi_private->stats.rdr0++;
187		ret = IRQ_HANDLED;
188	}
189
190	if (sisr & CCSR_SSI_SISR_TDE1) {
191		ssi_private->stats.tde1++;
192		ret = IRQ_HANDLED;
193	}
194
195	if (sisr & CCSR_SSI_SISR_TDE0) {
196		ssi_private->stats.tde0++;
197		ret = IRQ_HANDLED;
198	}
199
200	if (sisr & CCSR_SSI_SISR_ROE1) {
201		ssi_private->stats.roe1++;
202		sisr2 |= CCSR_SSI_SISR_ROE1;
203		ret = IRQ_HANDLED;
204	}
205
206	if (sisr & CCSR_SSI_SISR_ROE0) {
207		ssi_private->stats.roe0++;
208		sisr2 |= CCSR_SSI_SISR_ROE0;
209		ret = IRQ_HANDLED;
210	}
211
212	if (sisr & CCSR_SSI_SISR_TUE1) {
213		ssi_private->stats.tue1++;
214		sisr2 |= CCSR_SSI_SISR_TUE1;
215		ret = IRQ_HANDLED;
216	}
217
218	if (sisr & CCSR_SSI_SISR_TUE0) {
219		ssi_private->stats.tue0++;
220		sisr2 |= CCSR_SSI_SISR_TUE0;
221		ret = IRQ_HANDLED;
222	}
223
224	if (sisr & CCSR_SSI_SISR_TFS) {
225		ssi_private->stats.tfs++;
226		ret = IRQ_HANDLED;
227	}
228
229	if (sisr & CCSR_SSI_SISR_RFS) {
230		ssi_private->stats.rfs++;
231		ret = IRQ_HANDLED;
232	}
233
234	if (sisr & CCSR_SSI_SISR_TLS) {
235		ssi_private->stats.tls++;
236		ret = IRQ_HANDLED;
237	}
238
239	if (sisr & CCSR_SSI_SISR_RLS) {
240		ssi_private->stats.rls++;
241		ret = IRQ_HANDLED;
242	}
243
244	if (sisr & CCSR_SSI_SISR_RFF1) {
245		ssi_private->stats.rff1++;
246		ret = IRQ_HANDLED;
247	}
248
249	if (sisr & CCSR_SSI_SISR_RFF0) {
250		ssi_private->stats.rff0++;
251		ret = IRQ_HANDLED;
252	}
253
254	if (sisr & CCSR_SSI_SISR_TFE1) {
255		ssi_private->stats.tfe1++;
256		ret = IRQ_HANDLED;
257	}
258
259	if (sisr & CCSR_SSI_SISR_TFE0) {
260		ssi_private->stats.tfe0++;
261		ret = IRQ_HANDLED;
262	}
263
264	/* Clear the bits that we set */
265	if (sisr2)
266		out_be32(&ssi->sisr, sisr2);
267
268	return ret;
269}
270
271/**
272 * fsl_ssi_startup: create a new substream
273 *
274 * This is the first function called when a stream is opened.
275 *
276 * If this is the first stream open, then grab the IRQ and program most of
277 * the SSI registers.
278 */
279static int fsl_ssi_startup(struct snd_pcm_substream *substream,
280			   struct snd_soc_dai *dai)
281{
282	struct snd_soc_pcm_runtime *rtd = substream->private_data;
283	struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
284
285	/*
286	 * If this is the first stream opened, then request the IRQ
287	 * and initialize the SSI registers.
288	 */
289	if (!ssi_private->playback && !ssi_private->capture) {
290		struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
291		int ret;
292
293		ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
294				  ssi_private->name, ssi_private);
295		if (ret < 0) {
296			dev_err(substream->pcm->card->dev,
297				"could not claim irq %u\n", ssi_private->irq);
298			return ret;
299		}
300
301		/*
302		 * Section 16.5 of the MPC8610 reference manual says that the
303		 * SSI needs to be disabled before updating the registers we set
304		 * here.
305		 */
306		clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
307
308		clrsetbits_be32(&ssi->scr,
309			CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
310			CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
311			| (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN));
312
313		out_be32(&ssi->stcr,
314			 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
315			 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
316			 CCSR_SSI_STCR_TSCKP);
317
318		out_be32(&ssi->srcr,
319			 CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
320			 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
321			 CCSR_SSI_SRCR_RSCKP);
322
323		/*
324		 * The DC and PM bits are only used if the SSI is the clock
325		 * master.
326		 */
327
328		/* 4. Enable the interrupts and DMA requests */
329		out_be32(&ssi->sier, SIER_FLAGS);
330
331		/*
332		 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
333		 * don't use FIFO 1.  Since the SSI only supports stereo, the
334		 * watermark should never be an odd number.
335		 */
336		out_be32(&ssi->sfcsr,
337			 CCSR_SSI_SFCSR_TFWM0(6) | CCSR_SSI_SFCSR_RFWM0(2));
338
339		/*
340		 * We keep the SSI disabled because if we enable it, then the
341		 * DMA controller will start.  It's not supposed to start until
342		 * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
343		 * DMA controller will transfer one "BWC" of data (i.e. the
344		 * amount of data that the MR.BWC bits are set to).  The reason
345		 * this is bad is because at this point, the PCM driver has not
346		 * finished initializing the DMA controller.
347		 */
348	}
349
350	if (!ssi_private->first_stream)
351		ssi_private->first_stream = substream;
352	else {
353		struct snd_pcm_runtime *first_runtime =
354			ssi_private->first_stream->runtime;
355
356		if (!first_runtime->sample_bits) {
357			dev_err(substream->pcm->card->dev,
358				"set sample size in %s stream first\n",
359				substream->stream == SNDRV_PCM_STREAM_PLAYBACK
360				? "capture" : "playback");
361			return -EAGAIN;
362		}
363
364		/* If we're in synchronous mode, then we need to constrain
365		 * the sample size as well.  We don't support independent sample
366		 * rates in asynchronous mode.
367		 */
368		if (!ssi_private->asynchronous)
369			snd_pcm_hw_constraint_minmax(substream->runtime,
370				SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
371				first_runtime->sample_bits,
372				first_runtime->sample_bits);
373
374		ssi_private->second_stream = substream;
375	}
376
377	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
378		ssi_private->playback++;
379
380	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
381		ssi_private->capture++;
382
383	return 0;
384}
385
386/**
387 * fsl_ssi_hw_params - program the sample size
388 *
389 * Most of the SSI registers have been programmed in the startup function,
390 * but the word length must be programmed here.  Unfortunately, programming
391 * the SxCCR.WL bits requires the SSI to be temporarily disabled.  This can
392 * cause a problem with supporting simultaneous playback and capture.  If
393 * the SSI is already playing a stream, then that stream may be temporarily
394 * stopped when you start capture.
395 *
396 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
397 * clock master.
398 */
399static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
400	struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
401{
402	struct fsl_ssi_private *ssi_private = cpu_dai->private_data;
403
404	if (substream == ssi_private->first_stream) {
405		struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
406		unsigned int sample_size =
407			snd_pcm_format_width(params_format(hw_params));
408		u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
409
410		/* The SSI should always be disabled at this points (SSIEN=0) */
411
412		/* In synchronous mode, the SSI uses STCCR for capture */
413		if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
414		    !ssi_private->asynchronous)
415			clrsetbits_be32(&ssi->stccr,
416					CCSR_SSI_SxCCR_WL_MASK, wl);
417		else
418			clrsetbits_be32(&ssi->srccr,
419					CCSR_SSI_SxCCR_WL_MASK, wl);
420	}
421
422	return 0;
423}
424
425/**
426 * fsl_ssi_trigger: start and stop the DMA transfer.
427 *
428 * This function is called by ALSA to start, stop, pause, and resume the DMA
429 * transfer of data.
430 *
431 * The DMA channel is in external master start and pause mode, which
432 * means the SSI completely controls the flow of data.
433 */
434static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
435			   struct snd_soc_dai *dai)
436{
437	struct snd_soc_pcm_runtime *rtd = substream->private_data;
438	struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
439	struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
440
441	switch (cmd) {
442	case SNDRV_PCM_TRIGGER_START:
443		clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
444	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
445		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
446			setbits32(&ssi->scr,
447				CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
448		else
449			setbits32(&ssi->scr,
450				CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
451		break;
452
453	case SNDRV_PCM_TRIGGER_STOP:
454	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
455		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
456			clrbits32(&ssi->scr, CCSR_SSI_SCR_TE);
457		else
458			clrbits32(&ssi->scr, CCSR_SSI_SCR_RE);
459		break;
460
461	default:
462		return -EINVAL;
463	}
464
465	return 0;
466}
467
468/**
469 * fsl_ssi_shutdown: shutdown the SSI
470 *
471 * Shutdown the SSI if there are no other substreams open.
472 */
473static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
474			     struct snd_soc_dai *dai)
475{
476	struct snd_soc_pcm_runtime *rtd = substream->private_data;
477	struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
478
479	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
480		ssi_private->playback--;
481
482	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
483		ssi_private->capture--;
484
485	if (ssi_private->first_stream == substream)
486		ssi_private->first_stream = ssi_private->second_stream;
487
488	ssi_private->second_stream = NULL;
489
490	/*
491	 * If this is the last active substream, disable the SSI and release
492	 * the IRQ.
493	 */
494	if (!ssi_private->playback && !ssi_private->capture) {
495		struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
496
497		clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
498
499		free_irq(ssi_private->irq, ssi_private);
500	}
501}
502
503/**
504 * fsl_ssi_set_sysclk: set the clock frequency and direction
505 *
506 * This function is called by the machine driver to tell us what the clock
507 * frequency and direction are.
508 *
509 * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
510 * and we don't care about the frequency.  Return an error if the direction
511 * is not SND_SOC_CLOCK_IN.
512 *
513 * @clk_id: reserved, should be zero
514 * @freq: the frequency of the given clock ID, currently ignored
515 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
516 */
517static int fsl_ssi_set_sysclk(struct snd_soc_dai *cpu_dai,
518			      int clk_id, unsigned int freq, int dir)
519{
520
521	return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
522}
523
524/**
525 * fsl_ssi_set_fmt: set the serial format.
526 *
527 * This function is called by the machine driver to tell us what serial
528 * format to use.
529 *
530 * Currently, we only support I2S mode.  Return an error if the format is
531 * not SND_SOC_DAIFMT_I2S.
532 *
533 * @format: one of SND_SOC_DAIFMT_xxx
534 */
535static int fsl_ssi_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
536{
537	return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
538}
539
540/**
541 * fsl_ssi_dai_template: template CPU DAI for the SSI
542 */
543static struct snd_soc_dai_ops fsl_ssi_dai_ops = {
544	.startup	= fsl_ssi_startup,
545	.hw_params	= fsl_ssi_hw_params,
546	.shutdown	= fsl_ssi_shutdown,
547	.trigger	= fsl_ssi_trigger,
548	.set_sysclk	= fsl_ssi_set_sysclk,
549	.set_fmt	= fsl_ssi_set_fmt,
550};
551
552static struct snd_soc_dai fsl_ssi_dai_template = {
553	.playback = {
554		/* The SSI does not support monaural audio. */
555		.channels_min = 2,
556		.channels_max = 2,
557		.rates = FSLSSI_I2S_RATES,
558		.formats = FSLSSI_I2S_FORMATS,
559	},
560	.capture = {
561		.channels_min = 2,
562		.channels_max = 2,
563		.rates = FSLSSI_I2S_RATES,
564		.formats = FSLSSI_I2S_FORMATS,
565	},
566	.ops = &fsl_ssi_dai_ops,
567};
568
569/* Show the statistics of a flag only if its interrupt is enabled.  The
570 * compiler will optimze this code to a no-op if the interrupt is not
571 * enabled.
572 */
573#define SIER_SHOW(flag, name) \
574	do { \
575		if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
576			length += sprintf(buf + length, #name "=%u\n", \
577				ssi_private->stats.name); \
578	} while (0)
579
580
581/**
582 * fsl_sysfs_ssi_show: display SSI statistics
583 *
584 * Display the statistics for the current SSI device.  To avoid confusion,
585 * we only show those counts that are enabled.
586 */
587static ssize_t fsl_sysfs_ssi_show(struct device *dev,
588	struct device_attribute *attr, char *buf)
589{
590	struct fsl_ssi_private *ssi_private =
591		container_of(attr, struct fsl_ssi_private, dev_attr);
592	ssize_t length = 0;
593
594	SIER_SHOW(RFRC_EN, rfrc);
595	SIER_SHOW(TFRC_EN, tfrc);
596	SIER_SHOW(CMDAU_EN, cmdau);
597	SIER_SHOW(CMDDU_EN, cmddu);
598	SIER_SHOW(RXT_EN, rxt);
599	SIER_SHOW(RDR1_EN, rdr1);
600	SIER_SHOW(RDR0_EN, rdr0);
601	SIER_SHOW(TDE1_EN, tde1);
602	SIER_SHOW(TDE0_EN, tde0);
603	SIER_SHOW(ROE1_EN, roe1);
604	SIER_SHOW(ROE0_EN, roe0);
605	SIER_SHOW(TUE1_EN, tue1);
606	SIER_SHOW(TUE0_EN, tue0);
607	SIER_SHOW(TFS_EN, tfs);
608	SIER_SHOW(RFS_EN, rfs);
609	SIER_SHOW(TLS_EN, tls);
610	SIER_SHOW(RLS_EN, rls);
611	SIER_SHOW(RFF1_EN, rff1);
612	SIER_SHOW(RFF0_EN, rff0);
613	SIER_SHOW(TFE1_EN, tfe1);
614	SIER_SHOW(TFE0_EN, tfe0);
615
616	return length;
617}
618
619/**
620 * fsl_ssi_create_dai: create a snd_soc_dai structure
621 *
622 * This function is called by the machine driver to create a snd_soc_dai
623 * structure.  The function creates an ssi_private object, which contains
624 * the snd_soc_dai.  It also creates the sysfs statistics device.
625 */
626struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
627{
628	struct snd_soc_dai *fsl_ssi_dai;
629	struct fsl_ssi_private *ssi_private;
630	int ret = 0;
631	struct device_attribute *dev_attr;
632
633	ssi_private = kzalloc(sizeof(struct fsl_ssi_private), GFP_KERNEL);
634	if (!ssi_private) {
635		dev_err(ssi_info->dev, "could not allocate DAI object\n");
636		return NULL;
637	}
638	memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template,
639	       sizeof(struct snd_soc_dai));
640
641	fsl_ssi_dai = &ssi_private->cpu_dai;
642	dev_attr = &ssi_private->dev_attr;
643
644	sprintf(ssi_private->name, "ssi%u", (u8) ssi_info->id);
645	ssi_private->ssi = ssi_info->ssi;
646	ssi_private->ssi_phys = ssi_info->ssi_phys;
647	ssi_private->irq = ssi_info->irq;
648	ssi_private->dev = ssi_info->dev;
649	ssi_private->asynchronous = ssi_info->asynchronous;
650
651	dev_set_drvdata(ssi_private->dev, fsl_ssi_dai);
652
653	/* Initialize the the device_attribute structure */
654	dev_attr->attr.name = "ssi-stats";
655	dev_attr->attr.mode = S_IRUGO;
656	dev_attr->show = fsl_sysfs_ssi_show;
657
658	ret = device_create_file(ssi_private->dev, dev_attr);
659	if (ret) {
660		dev_err(ssi_info->dev, "could not create sysfs %s file\n",
661			ssi_private->dev_attr.attr.name);
662		kfree(fsl_ssi_dai);
663		return NULL;
664	}
665
666	fsl_ssi_dai->private_data = ssi_private;
667	fsl_ssi_dai->name = ssi_private->name;
668	fsl_ssi_dai->id = ssi_info->id;
669	fsl_ssi_dai->dev = ssi_info->dev;
670	fsl_ssi_dai->symmetric_rates = 1;
671
672	ret = snd_soc_register_dai(fsl_ssi_dai);
673	if (ret != 0) {
674		dev_err(ssi_info->dev, "failed to register DAI: %d\n", ret);
675		kfree(fsl_ssi_dai);
676		return NULL;
677	}
678
679	return fsl_ssi_dai;
680}
681EXPORT_SYMBOL_GPL(fsl_ssi_create_dai);
682
683/**
684 * fsl_ssi_destroy_dai: destroy the snd_soc_dai object
685 *
686 * This function undoes the operations of fsl_ssi_create_dai()
687 */
688void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
689{
690	struct fsl_ssi_private *ssi_private =
691	container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai);
692
693	device_remove_file(ssi_private->dev, &ssi_private->dev_attr);
694
695	snd_soc_unregister_dai(&ssi_private->cpu_dai);
696
697	kfree(ssi_private);
698}
699EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
700
701static int __init fsl_ssi_init(void)
702{
703	printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n");
704
705	return 0;
706}
707module_init(fsl_ssi_init);
708
709MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
710MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
711MODULE_LICENSE("GPL");
712