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