• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/sound/soc/pxa/
1/*
2 * pxa-ssp.c  --  ALSA Soc Audio Layer
3 *
4 * Copyright 2005,2008 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 *         Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *  This program is free software; you can redistribute  it and/or modify it
9 *  under  the terms of  the GNU General  Public License as published by the
10 *  Free Software Foundation;  either version 2 of the  License, or (at your
11 *  option) any later version.
12 *
13 * TODO:
14 *  o Test network mode for > 16bit sample size
15 */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/platform_device.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23
24#include <asm/irq.h>
25
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/initval.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/pxa2xx-lib.h>
32
33#include <mach/hardware.h>
34#include <mach/dma.h>
35#include <mach/audio.h>
36#include <plat/ssp.h>
37
38#include "pxa2xx-pcm.h"
39#include "pxa-ssp.h"
40
41/*
42 * SSP audio private data
43 */
44struct ssp_priv {
45	struct ssp_device *ssp;
46	unsigned int sysclk;
47	int dai_fmt;
48#ifdef CONFIG_PM
49	uint32_t	cr0;
50	uint32_t	cr1;
51	uint32_t	to;
52	uint32_t	psp;
53#endif
54};
55
56static void dump_registers(struct ssp_device *ssp)
57{
58	dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
59		 pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
60		 pxa_ssp_read_reg(ssp, SSTO));
61
62	dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
63		 pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
64		 pxa_ssp_read_reg(ssp, SSACD));
65}
66
67static void pxa_ssp_enable(struct ssp_device *ssp)
68{
69	uint32_t sscr0;
70
71	sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE;
72	__raw_writel(sscr0, ssp->mmio_base + SSCR0);
73}
74
75static void pxa_ssp_disable(struct ssp_device *ssp)
76{
77	uint32_t sscr0;
78
79	sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE;
80	__raw_writel(sscr0, ssp->mmio_base + SSCR0);
81}
82
83struct pxa2xx_pcm_dma_data {
84	struct pxa2xx_pcm_dma_params params;
85	char name[20];
86};
87
88static struct pxa2xx_pcm_dma_params *
89pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
90{
91	struct pxa2xx_pcm_dma_data *dma;
92
93	dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL);
94	if (dma == NULL)
95		return NULL;
96
97	snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id,
98			width4 ? "32-bit" : "16-bit", out ? "out" : "in");
99
100	dma->params.name = dma->name;
101	dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx);
102	dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) :
103				  (DCMD_INCTRGADDR | DCMD_FLOWSRC)) |
104			(width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16;
105	dma->params.dev_addr = ssp->phys_base + SSDR;
106
107	return &dma->params;
108}
109
110static int pxa_ssp_startup(struct snd_pcm_substream *substream,
111			   struct snd_soc_dai *dai)
112{
113	struct snd_soc_pcm_runtime *rtd = substream->private_data;
114	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
115	struct ssp_priv *priv = cpu_dai->private_data;
116	struct ssp_device *ssp = priv->ssp;
117	int ret = 0;
118
119	if (!cpu_dai->active) {
120		clk_enable(ssp->clk);
121		pxa_ssp_disable(ssp);
122	}
123
124	kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
125	snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
126
127	return ret;
128}
129
130static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
131			     struct snd_soc_dai *dai)
132{
133	struct snd_soc_pcm_runtime *rtd = substream->private_data;
134	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
135	struct ssp_priv *priv = cpu_dai->private_data;
136	struct ssp_device *ssp = priv->ssp;
137
138	if (!cpu_dai->active) {
139		pxa_ssp_disable(ssp);
140		clk_disable(ssp->clk);
141	}
142
143	kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
144	snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
145}
146
147#ifdef CONFIG_PM
148
149static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
150{
151	struct ssp_priv *priv = cpu_dai->private_data;
152	struct ssp_device *ssp = priv->ssp;
153
154	if (!cpu_dai->active)
155		clk_enable(ssp->clk);
156
157	priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
158	priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
159	priv->to  = __raw_readl(ssp->mmio_base + SSTO);
160	priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
161
162	pxa_ssp_disable(ssp);
163	clk_disable(ssp->clk);
164	return 0;
165}
166
167static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
168{
169	struct ssp_priv *priv = cpu_dai->private_data;
170	struct ssp_device *ssp = priv->ssp;
171	uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
172
173	clk_enable(ssp->clk);
174
175	__raw_writel(sssr, ssp->mmio_base + SSSR);
176	__raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
177	__raw_writel(priv->cr1, ssp->mmio_base + SSCR1);
178	__raw_writel(priv->to,  ssp->mmio_base + SSTO);
179	__raw_writel(priv->psp, ssp->mmio_base + SSPSP);
180
181	if (cpu_dai->active)
182		pxa_ssp_enable(ssp);
183	else
184		clk_disable(ssp->clk);
185
186	return 0;
187}
188
189#else
190#define pxa_ssp_suspend	NULL
191#define pxa_ssp_resume	NULL
192#endif
193
194/**
195 * ssp_set_clkdiv - set SSP clock divider
196 * @div: serial clock rate divider
197 */
198static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
199{
200	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
201
202	if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
203		sscr0 &= ~0x0000ff00;
204		sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
205	} else {
206		sscr0 &= ~0x000fff00;
207		sscr0 |= (div - 1) << 8;     /* 1..4096 */
208	}
209	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
210}
211
212/**
213 * pxa_ssp_get_clkdiv - get SSP clock divider
214 */
215static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
216{
217	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
218	u32 div;
219
220	if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
221		div = ((sscr0 >> 8) & 0xff) * 2 + 2;
222	else
223		div = ((sscr0 >> 8) & 0xfff) + 1;
224	return div;
225}
226
227/*
228 * Set the SSP ports SYSCLK.
229 */
230static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
231	int clk_id, unsigned int freq, int dir)
232{
233	struct ssp_priv *priv = cpu_dai->private_data;
234	struct ssp_device *ssp = priv->ssp;
235	int val;
236
237	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
238		~(SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
239
240	dev_dbg(&ssp->pdev->dev,
241		"pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
242		cpu_dai->id, clk_id, freq);
243
244	switch (clk_id) {
245	case PXA_SSP_CLK_NET_PLL:
246		sscr0 |= SSCR0_MOD;
247		break;
248	case PXA_SSP_CLK_PLL:
249		/* Internal PLL is fixed */
250		if (cpu_is_pxa25x())
251			priv->sysclk = 1843200;
252		else
253			priv->sysclk = 13000000;
254		break;
255	case PXA_SSP_CLK_EXT:
256		priv->sysclk = freq;
257		sscr0 |= SSCR0_ECS;
258		break;
259	case PXA_SSP_CLK_NET:
260		priv->sysclk = freq;
261		sscr0 |= SSCR0_NCS | SSCR0_MOD;
262		break;
263	case PXA_SSP_CLK_AUDIO:
264		priv->sysclk = 0;
265		pxa_ssp_set_scr(ssp, 1);
266		sscr0 |= SSCR0_ACS;
267		break;
268	default:
269		return -ENODEV;
270	}
271
272	/* The SSP clock must be disabled when changing SSP clock mode
273	 * on PXA2xx.  On PXA3xx it must be enabled when doing so. */
274	if (!cpu_is_pxa3xx())
275		clk_disable(ssp->clk);
276	val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
277	pxa_ssp_write_reg(ssp, SSCR0, val);
278	if (!cpu_is_pxa3xx())
279		clk_enable(ssp->clk);
280
281	return 0;
282}
283
284/*
285 * Set the SSP clock dividers.
286 */
287static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
288	int div_id, int div)
289{
290	struct ssp_priv *priv = cpu_dai->private_data;
291	struct ssp_device *ssp = priv->ssp;
292	int val;
293
294	switch (div_id) {
295	case PXA_SSP_AUDIO_DIV_ACDS:
296		val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
297		pxa_ssp_write_reg(ssp, SSACD, val);
298		break;
299	case PXA_SSP_AUDIO_DIV_SCDB:
300		val = pxa_ssp_read_reg(ssp, SSACD);
301		val &= ~SSACD_SCDB;
302#if defined(CONFIG_PXA3xx)
303		if (cpu_is_pxa3xx())
304			val &= ~SSACD_SCDX8;
305#endif
306		switch (div) {
307		case PXA_SSP_CLK_SCDB_1:
308			val |= SSACD_SCDB;
309			break;
310		case PXA_SSP_CLK_SCDB_4:
311			break;
312#if defined(CONFIG_PXA3xx)
313		case PXA_SSP_CLK_SCDB_8:
314			if (cpu_is_pxa3xx())
315				val |= SSACD_SCDX8;
316			else
317				return -EINVAL;
318			break;
319#endif
320		default:
321			return -EINVAL;
322		}
323		pxa_ssp_write_reg(ssp, SSACD, val);
324		break;
325	case PXA_SSP_DIV_SCR:
326		pxa_ssp_set_scr(ssp, div);
327		break;
328	default:
329		return -ENODEV;
330	}
331
332	return 0;
333}
334
335/*
336 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
337 */
338static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
339	int source, unsigned int freq_in, unsigned int freq_out)
340{
341	struct ssp_priv *priv = cpu_dai->private_data;
342	struct ssp_device *ssp = priv->ssp;
343	u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
344
345#if defined(CONFIG_PXA3xx)
346	if (cpu_is_pxa3xx())
347		pxa_ssp_write_reg(ssp, SSACDD, 0);
348#endif
349
350	switch (freq_out) {
351	case 5622000:
352		break;
353	case 11345000:
354		ssacd |= (0x1 << 4);
355		break;
356	case 12235000:
357		ssacd |= (0x2 << 4);
358		break;
359	case 14857000:
360		ssacd |= (0x3 << 4);
361		break;
362	case 32842000:
363		ssacd |= (0x4 << 4);
364		break;
365	case 48000000:
366		ssacd |= (0x5 << 4);
367		break;
368	case 0:
369		/* Disable */
370		break;
371
372	default:
373#ifdef CONFIG_PXA3xx
374		/* PXA3xx has a clock ditherer which can be used to generate
375		 * a wider range of frequencies - calculate a value for it.
376		 */
377		if (cpu_is_pxa3xx()) {
378			u32 val;
379			u64 tmp = 19968;
380			tmp *= 1000000;
381			do_div(tmp, freq_out);
382			val = tmp;
383
384			val = (val << 16) | 64;
385			pxa_ssp_write_reg(ssp, SSACDD, val);
386
387			ssacd |= (0x6 << 4);
388
389			dev_dbg(&ssp->pdev->dev,
390				"Using SSACDD %x to supply %uHz\n",
391				val, freq_out);
392			break;
393		}
394#endif
395
396		return -EINVAL;
397	}
398
399	pxa_ssp_write_reg(ssp, SSACD, ssacd);
400
401	return 0;
402}
403
404/*
405 * Set the active slots in TDM/Network mode
406 */
407static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
408	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
409{
410	struct ssp_priv *priv = cpu_dai->private_data;
411	struct ssp_device *ssp = priv->ssp;
412	u32 sscr0;
413
414	sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
415	sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
416
417	/* set slot width */
418	if (slot_width > 16)
419		sscr0 |= SSCR0_EDSS | SSCR0_DataSize(slot_width - 16);
420	else
421		sscr0 |= SSCR0_DataSize(slot_width);
422
423	if (slots > 1) {
424		/* enable network mode */
425		sscr0 |= SSCR0_MOD;
426
427		/* set number of active slots */
428		sscr0 |= SSCR0_SlotsPerFrm(slots);
429
430		/* set active slot mask */
431		pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
432		pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
433	}
434	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
435
436	return 0;
437}
438
439/*
440 * Tristate the SSP DAI lines
441 */
442static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
443	int tristate)
444{
445	struct ssp_priv *priv = cpu_dai->private_data;
446	struct ssp_device *ssp = priv->ssp;
447	u32 sscr1;
448
449	sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
450	if (tristate)
451		sscr1 &= ~SSCR1_TTE;
452	else
453		sscr1 |= SSCR1_TTE;
454	pxa_ssp_write_reg(ssp, SSCR1, sscr1);
455
456	return 0;
457}
458
459/*
460 * Set up the SSP DAI format.
461 * The SSP Port must be inactive before calling this function as the
462 * physical interface format is changed.
463 */
464static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
465		unsigned int fmt)
466{
467	struct ssp_priv *priv = cpu_dai->private_data;
468	struct ssp_device *ssp = priv->ssp;
469	u32 sscr0;
470	u32 sscr1;
471	u32 sspsp;
472
473	/* check if we need to change anything at all */
474	if (priv->dai_fmt == fmt)
475		return 0;
476
477	/* we can only change the settings if the port is not in use */
478	if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
479		dev_err(&ssp->pdev->dev,
480			"can't change hardware dai format: stream is in use");
481		return -EINVAL;
482	}
483
484	/* reset port settings */
485	sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
486		(SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
487	sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
488	sspsp = 0;
489
490	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
491	case SND_SOC_DAIFMT_CBM_CFM:
492		sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
493		break;
494	case SND_SOC_DAIFMT_CBM_CFS:
495		sscr1 |= SSCR1_SCLKDIR;
496		break;
497	case SND_SOC_DAIFMT_CBS_CFS:
498		break;
499	default:
500		return -EINVAL;
501	}
502
503	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
504	case SND_SOC_DAIFMT_NB_NF:
505		sspsp |= SSPSP_SFRMP;
506		break;
507	case SND_SOC_DAIFMT_NB_IF:
508		break;
509	case SND_SOC_DAIFMT_IB_IF:
510		sspsp |= SSPSP_SCMODE(2);
511		break;
512	case SND_SOC_DAIFMT_IB_NF:
513		sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
514		break;
515	default:
516		return -EINVAL;
517	}
518
519	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
520	case SND_SOC_DAIFMT_I2S:
521		sscr0 |= SSCR0_PSP;
522		sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
523		/* See hw_params() */
524		break;
525
526	case SND_SOC_DAIFMT_DSP_A:
527		sspsp |= SSPSP_FSRT;
528	case SND_SOC_DAIFMT_DSP_B:
529		sscr0 |= SSCR0_MOD | SSCR0_PSP;
530		sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
531		break;
532
533	default:
534		return -EINVAL;
535	}
536
537	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
538	pxa_ssp_write_reg(ssp, SSCR1, sscr1);
539	pxa_ssp_write_reg(ssp, SSPSP, sspsp);
540
541	dump_registers(ssp);
542
543	/* Since we are configuring the timings for the format by hand
544	 * we have to defer some things until hw_params() where we
545	 * know parameters like the sample size.
546	 */
547	priv->dai_fmt = fmt;
548
549	return 0;
550}
551
552/*
553 * Set the SSP audio DMA parameters and sample size.
554 * Can be called multiple times by oss emulation.
555 */
556static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
557				struct snd_pcm_hw_params *params,
558				struct snd_soc_dai *dai)
559{
560	struct snd_soc_pcm_runtime *rtd = substream->private_data;
561	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
562	struct ssp_priv *priv = cpu_dai->private_data;
563	struct ssp_device *ssp = priv->ssp;
564	int chn = params_channels(params);
565	u32 sscr0;
566	u32 sspsp;
567	int width = snd_pcm_format_physical_width(params_format(params));
568	int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
569	struct pxa2xx_pcm_dma_params *dma_data;
570
571	dma_data = snd_soc_dai_get_dma_data(dai, substream);
572
573	/* generate correct DMA params */
574	kfree(dma_data);
575
576	/* Network mode with one active slot (ttsa == 1) can be used
577	 * to force 16-bit frame width on the wire (for S16_LE), even
578	 * with two channels. Use 16-bit DMA transfers for this case.
579	 */
580	dma_data = pxa_ssp_get_dma_params(ssp,
581			((chn == 2) && (ttsa != 1)) || (width == 32),
582			substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
583
584	snd_soc_dai_set_dma_data(dai, substream, dma_data);
585
586	/* we can only change the settings if the port is not in use */
587	if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
588		return 0;
589
590	/* clear selected SSP bits */
591	sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
592	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
593
594	/* bit size */
595	sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
596	switch (params_format(params)) {
597	case SNDRV_PCM_FORMAT_S16_LE:
598#ifdef CONFIG_PXA3xx
599		if (cpu_is_pxa3xx())
600			sscr0 |= SSCR0_FPCKE;
601#endif
602		sscr0 |= SSCR0_DataSize(16);
603		break;
604	case SNDRV_PCM_FORMAT_S24_LE:
605		sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
606		break;
607	case SNDRV_PCM_FORMAT_S32_LE:
608		sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
609		break;
610	}
611	pxa_ssp_write_reg(ssp, SSCR0, sscr0);
612
613	switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
614	case SND_SOC_DAIFMT_I2S:
615	       sspsp = pxa_ssp_read_reg(ssp, SSPSP);
616
617		if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
618			/* This is a special case where the bitclk is 64fs
619			* and we're not dealing with 2*32 bits of audio
620			* samples.
621			*
622			* The SSP values used for that are all found out by
623			* trying and failing a lot; some of the registers
624			* needed for that mode are only available on PXA3xx.
625			*/
626
627#ifdef CONFIG_PXA3xx
628			if (!cpu_is_pxa3xx())
629				return -EINVAL;
630
631			sspsp |= SSPSP_SFRMWDTH(width * 2);
632			sspsp |= SSPSP_SFRMDLY(width * 4);
633			sspsp |= SSPSP_EDMYSTOP(3);
634			sspsp |= SSPSP_DMYSTOP(3);
635			sspsp |= SSPSP_DMYSTRT(1);
636#else
637			return -EINVAL;
638#endif
639		} else {
640			/* The frame width is the width the LRCLK is
641			 * asserted for; the delay is expressed in
642			 * half cycle units.  We need the extra cycle
643			 * because the data starts clocking out one BCLK
644			 * after LRCLK changes polarity.
645			 */
646			sspsp |= SSPSP_SFRMWDTH(width + 1);
647			sspsp |= SSPSP_SFRMDLY((width + 1) * 2);
648			sspsp |= SSPSP_DMYSTRT(1);
649		}
650
651		pxa_ssp_write_reg(ssp, SSPSP, sspsp);
652		break;
653	default:
654		break;
655	}
656
657	/* When we use a network mode, we always require TDM slots
658	 * - complain loudly and fail if they've not been set up yet.
659	 */
660	if ((sscr0 & SSCR0_MOD) && !ttsa) {
661		dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
662		return -EINVAL;
663	}
664
665	dump_registers(ssp);
666
667	return 0;
668}
669
670static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
671			   struct snd_soc_dai *dai)
672{
673	struct snd_soc_pcm_runtime *rtd = substream->private_data;
674	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
675	int ret = 0;
676	struct ssp_priv *priv = cpu_dai->private_data;
677	struct ssp_device *ssp = priv->ssp;
678	int val;
679
680	switch (cmd) {
681	case SNDRV_PCM_TRIGGER_RESUME:
682		pxa_ssp_enable(ssp);
683		break;
684	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
685		val = pxa_ssp_read_reg(ssp, SSCR1);
686		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
687			val |= SSCR1_TSRE;
688		else
689			val |= SSCR1_RSRE;
690		pxa_ssp_write_reg(ssp, SSCR1, val);
691		val = pxa_ssp_read_reg(ssp, SSSR);
692		pxa_ssp_write_reg(ssp, SSSR, val);
693		break;
694	case SNDRV_PCM_TRIGGER_START:
695		val = pxa_ssp_read_reg(ssp, SSCR1);
696		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
697			val |= SSCR1_TSRE;
698		else
699			val |= SSCR1_RSRE;
700		pxa_ssp_write_reg(ssp, SSCR1, val);
701		pxa_ssp_enable(ssp);
702		break;
703	case SNDRV_PCM_TRIGGER_STOP:
704		val = pxa_ssp_read_reg(ssp, SSCR1);
705		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
706			val &= ~SSCR1_TSRE;
707		else
708			val &= ~SSCR1_RSRE;
709		pxa_ssp_write_reg(ssp, SSCR1, val);
710		break;
711	case SNDRV_PCM_TRIGGER_SUSPEND:
712		pxa_ssp_disable(ssp);
713		break;
714	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
715		val = pxa_ssp_read_reg(ssp, SSCR1);
716		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
717			val &= ~SSCR1_TSRE;
718		else
719			val &= ~SSCR1_RSRE;
720		pxa_ssp_write_reg(ssp, SSCR1, val);
721		break;
722
723	default:
724		ret = -EINVAL;
725	}
726
727	dump_registers(ssp);
728
729	return ret;
730}
731
732static int pxa_ssp_probe(struct platform_device *pdev,
733			    struct snd_soc_dai *dai)
734{
735	struct ssp_priv *priv;
736	int ret;
737
738	priv = kzalloc(sizeof(struct ssp_priv), GFP_KERNEL);
739	if (!priv)
740		return -ENOMEM;
741
742	priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
743	if (priv->ssp == NULL) {
744		ret = -ENODEV;
745		goto err_priv;
746	}
747
748	priv->dai_fmt = (unsigned int) -1;
749	dai->private_data = priv;
750
751	return 0;
752
753err_priv:
754	kfree(priv);
755	return ret;
756}
757
758static void pxa_ssp_remove(struct platform_device *pdev,
759			      struct snd_soc_dai *dai)
760{
761	struct ssp_priv *priv = dai->private_data;
762	pxa_ssp_free(priv->ssp);
763}
764
765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
766			  SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |	\
767			  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |	\
768			  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
769
770#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
771			    SNDRV_PCM_FMTBIT_S24_LE |	\
772			    SNDRV_PCM_FMTBIT_S32_LE)
773
774static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
775	.startup	= pxa_ssp_startup,
776	.shutdown	= pxa_ssp_shutdown,
777	.trigger	= pxa_ssp_trigger,
778	.hw_params	= pxa_ssp_hw_params,
779	.set_sysclk	= pxa_ssp_set_dai_sysclk,
780	.set_clkdiv	= pxa_ssp_set_dai_clkdiv,
781	.set_pll	= pxa_ssp_set_dai_pll,
782	.set_fmt	= pxa_ssp_set_dai_fmt,
783	.set_tdm_slot	= pxa_ssp_set_dai_tdm_slot,
784	.set_tristate	= pxa_ssp_set_dai_tristate,
785};
786
787struct snd_soc_dai pxa_ssp_dai[] = {
788	{
789		.name = "pxa2xx-ssp1",
790		.id = 0,
791		.probe = pxa_ssp_probe,
792		.remove = pxa_ssp_remove,
793		.suspend = pxa_ssp_suspend,
794		.resume = pxa_ssp_resume,
795		.playback = {
796			.channels_min = 1,
797			.channels_max = 8,
798			.rates = PXA_SSP_RATES,
799			.formats = PXA_SSP_FORMATS,
800		},
801		.capture = {
802			 .channels_min = 1,
803			 .channels_max = 8,
804			.rates = PXA_SSP_RATES,
805			.formats = PXA_SSP_FORMATS,
806		 },
807		.ops = &pxa_ssp_dai_ops,
808	},
809	{	.name = "pxa2xx-ssp2",
810		.id = 1,
811		.probe = pxa_ssp_probe,
812		.remove = pxa_ssp_remove,
813		.suspend = pxa_ssp_suspend,
814		.resume = pxa_ssp_resume,
815		.playback = {
816			.channels_min = 1,
817			.channels_max = 8,
818			.rates = PXA_SSP_RATES,
819			.formats = PXA_SSP_FORMATS,
820		},
821		.capture = {
822			.channels_min = 1,
823			.channels_max = 8,
824			.rates = PXA_SSP_RATES,
825			.formats = PXA_SSP_FORMATS,
826		 },
827		.ops = &pxa_ssp_dai_ops,
828	},
829	{
830		.name = "pxa2xx-ssp3",
831		.id = 2,
832		.probe = pxa_ssp_probe,
833		.remove = pxa_ssp_remove,
834		.suspend = pxa_ssp_suspend,
835		.resume = pxa_ssp_resume,
836		.playback = {
837			.channels_min = 1,
838			.channels_max = 8,
839			.rates = PXA_SSP_RATES,
840			.formats = PXA_SSP_FORMATS,
841		},
842		.capture = {
843			.channels_min = 1,
844			.channels_max = 8,
845			.rates = PXA_SSP_RATES,
846			.formats = PXA_SSP_FORMATS,
847		 },
848		.ops = &pxa_ssp_dai_ops,
849	},
850	{
851		.name = "pxa2xx-ssp4",
852		.id = 3,
853		.probe = pxa_ssp_probe,
854		.remove = pxa_ssp_remove,
855		.suspend = pxa_ssp_suspend,
856		.resume = pxa_ssp_resume,
857		.playback = {
858			.channels_min = 1,
859			.channels_max = 8,
860			.rates = PXA_SSP_RATES,
861			.formats = PXA_SSP_FORMATS,
862		},
863		.capture = {
864			.channels_min = 1,
865			.channels_max = 8,
866			.rates = PXA_SSP_RATES,
867			.formats = PXA_SSP_FORMATS,
868		 },
869		.ops = &pxa_ssp_dai_ops,
870	},
871};
872EXPORT_SYMBOL_GPL(pxa_ssp_dai);
873
874static int __init pxa_ssp_init(void)
875{
876	return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
877}
878module_init(pxa_ssp_init);
879
880static void __exit pxa_ssp_exit(void)
881{
882	snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
883}
884module_exit(pxa_ssp_exit);
885
886/* Module information */
887MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
888MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
889MODULE_LICENSE("GPL");
890