Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/soc/samsung/i2s.c
10817 views
1
/* sound/soc/samsung/i2s.c
2
*
3
* ALSA SoC Audio Layer - Samsung I2S Controller driver
4
*
5
* Copyright (c) 2010 Samsung Electronics Co. Ltd.
6
* Jaswinder Singh <[email protected]>
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
11
*/
12
13
#include <linux/delay.h>
14
#include <linux/slab.h>
15
#include <linux/clk.h>
16
#include <linux/io.h>
17
18
#include <sound/soc.h>
19
#include <sound/pcm_params.h>
20
21
#include <plat/audio.h>
22
23
#include "dma.h"
24
#include "i2s.h"
25
26
#define I2SCON 0x0
27
#define I2SMOD 0x4
28
#define I2SFIC 0x8
29
#define I2SPSR 0xc
30
#define I2STXD 0x10
31
#define I2SRXD 0x14
32
#define I2SFICS 0x18
33
#define I2STXDS 0x1c
34
35
#define CON_RSTCLR (1 << 31)
36
#define CON_FRXOFSTATUS (1 << 26)
37
#define CON_FRXORINTEN (1 << 25)
38
#define CON_FTXSURSTAT (1 << 24)
39
#define CON_FTXSURINTEN (1 << 23)
40
#define CON_TXSDMA_PAUSE (1 << 20)
41
#define CON_TXSDMA_ACTIVE (1 << 18)
42
43
#define CON_FTXURSTATUS (1 << 17)
44
#define CON_FTXURINTEN (1 << 16)
45
#define CON_TXFIFO2_EMPTY (1 << 15)
46
#define CON_TXFIFO1_EMPTY (1 << 14)
47
#define CON_TXFIFO2_FULL (1 << 13)
48
#define CON_TXFIFO1_FULL (1 << 12)
49
50
#define CON_LRINDEX (1 << 11)
51
#define CON_TXFIFO_EMPTY (1 << 10)
52
#define CON_RXFIFO_EMPTY (1 << 9)
53
#define CON_TXFIFO_FULL (1 << 8)
54
#define CON_RXFIFO_FULL (1 << 7)
55
#define CON_TXDMA_PAUSE (1 << 6)
56
#define CON_RXDMA_PAUSE (1 << 5)
57
#define CON_TXCH_PAUSE (1 << 4)
58
#define CON_RXCH_PAUSE (1 << 3)
59
#define CON_TXDMA_ACTIVE (1 << 2)
60
#define CON_RXDMA_ACTIVE (1 << 1)
61
#define CON_ACTIVE (1 << 0)
62
63
#define MOD_OPCLK_CDCLK_OUT (0 << 30)
64
#define MOD_OPCLK_CDCLK_IN (1 << 30)
65
#define MOD_OPCLK_BCLK_OUT (2 << 30)
66
#define MOD_OPCLK_PCLK (3 << 30)
67
#define MOD_OPCLK_MASK (3 << 30)
68
#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
69
70
#define MOD_BLCS_SHIFT 26
71
#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT)
72
#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT)
73
#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT)
74
#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT)
75
#define MOD_BLCP_SHIFT 24
76
#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT)
77
#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT)
78
#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT)
79
#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT)
80
81
#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
82
#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
83
#define MOD_C1DD_HHALF (1 << 19)
84
#define MOD_C1DD_LHALF (1 << 18)
85
#define MOD_DC2_EN (1 << 17)
86
#define MOD_DC1_EN (1 << 16)
87
#define MOD_BLC_16BIT (0 << 13)
88
#define MOD_BLC_8BIT (1 << 13)
89
#define MOD_BLC_24BIT (2 << 13)
90
#define MOD_BLC_MASK (3 << 13)
91
92
#define MOD_IMS_SYSMUX (1 << 10)
93
#define MOD_SLAVE (1 << 11)
94
#define MOD_TXONLY (0 << 8)
95
#define MOD_RXONLY (1 << 8)
96
#define MOD_TXRX (2 << 8)
97
#define MOD_MASK (3 << 8)
98
#define MOD_LR_LLOW (0 << 7)
99
#define MOD_LR_RLOW (1 << 7)
100
#define MOD_SDF_IIS (0 << 5)
101
#define MOD_SDF_MSB (1 << 5)
102
#define MOD_SDF_LSB (2 << 5)
103
#define MOD_SDF_MASK (3 << 5)
104
#define MOD_RCLK_256FS (0 << 3)
105
#define MOD_RCLK_512FS (1 << 3)
106
#define MOD_RCLK_384FS (2 << 3)
107
#define MOD_RCLK_768FS (3 << 3)
108
#define MOD_RCLK_MASK (3 << 3)
109
#define MOD_BCLK_32FS (0 << 1)
110
#define MOD_BCLK_48FS (1 << 1)
111
#define MOD_BCLK_16FS (2 << 1)
112
#define MOD_BCLK_24FS (3 << 1)
113
#define MOD_BCLK_MASK (3 << 1)
114
#define MOD_8BIT (1 << 0)
115
116
#define MOD_CDCLKCON (1 << 12)
117
118
#define PSR_PSREN (1 << 15)
119
120
#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
121
#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
122
123
#define FIC_TXFLUSH (1 << 15)
124
#define FIC_RXFLUSH (1 << 7)
125
#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf)
126
#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf)
127
#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
128
129
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
130
131
struct i2s_dai {
132
/* Platform device for this DAI */
133
struct platform_device *pdev;
134
/* IOREMAP'd SFRs */
135
void __iomem *addr;
136
/* Physical base address of SFRs */
137
u32 base;
138
/* Rate of RCLK source clock */
139
unsigned long rclk_srcrate;
140
/* Frame Clock */
141
unsigned frmclk;
142
/*
143
* Specifically requested RCLK,BCLK by MACHINE Driver.
144
* 0 indicates CPU driver is free to choose any value.
145
*/
146
unsigned rfs, bfs;
147
/* I2S Controller's core clock */
148
struct clk *clk;
149
/* Clock for generating I2S signals */
150
struct clk *op_clk;
151
/* Array of clock names for op_clk */
152
const char **src_clk;
153
/* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
154
struct i2s_dai *pri_dai;
155
/* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
156
struct i2s_dai *sec_dai;
157
#define DAI_OPENED (1 << 0) /* Dai is opened */
158
#define DAI_MANAGER (1 << 1) /* Dai is the manager */
159
unsigned mode;
160
/* Driver for this DAI */
161
struct snd_soc_dai_driver i2s_dai_drv;
162
/* DMA parameters */
163
struct s3c_dma_params dma_playback;
164
struct s3c_dma_params dma_capture;
165
u32 quirks;
166
u32 suspend_i2smod;
167
u32 suspend_i2scon;
168
u32 suspend_i2spsr;
169
};
170
171
/* Lock for cross i/f checks */
172
static DEFINE_SPINLOCK(lock);
173
174
/* If this is the 'overlay' stereo DAI */
175
static inline bool is_secondary(struct i2s_dai *i2s)
176
{
177
return i2s->pri_dai ? true : false;
178
}
179
180
/* If operating in SoC-Slave mode */
181
static inline bool is_slave(struct i2s_dai *i2s)
182
{
183
return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false;
184
}
185
186
/* If this interface of the controller is transmitting data */
187
static inline bool tx_active(struct i2s_dai *i2s)
188
{
189
u32 active;
190
191
if (!i2s)
192
return false;
193
194
active = readl(i2s->addr + I2SCON);
195
196
if (is_secondary(i2s))
197
active &= CON_TXSDMA_ACTIVE;
198
else
199
active &= CON_TXDMA_ACTIVE;
200
201
return active ? true : false;
202
}
203
204
/* If the other interface of the controller is transmitting data */
205
static inline bool other_tx_active(struct i2s_dai *i2s)
206
{
207
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
208
209
return tx_active(other);
210
}
211
212
/* If any interface of the controller is transmitting data */
213
static inline bool any_tx_active(struct i2s_dai *i2s)
214
{
215
return tx_active(i2s) || other_tx_active(i2s);
216
}
217
218
/* If this interface of the controller is receiving data */
219
static inline bool rx_active(struct i2s_dai *i2s)
220
{
221
u32 active;
222
223
if (!i2s)
224
return false;
225
226
active = readl(i2s->addr + I2SCON) & CON_RXDMA_ACTIVE;
227
228
return active ? true : false;
229
}
230
231
/* If the other interface of the controller is receiving data */
232
static inline bool other_rx_active(struct i2s_dai *i2s)
233
{
234
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
235
236
return rx_active(other);
237
}
238
239
/* If any interface of the controller is receiving data */
240
static inline bool any_rx_active(struct i2s_dai *i2s)
241
{
242
return rx_active(i2s) || other_rx_active(i2s);
243
}
244
245
/* If the other DAI is transmitting or receiving data */
246
static inline bool other_active(struct i2s_dai *i2s)
247
{
248
return other_rx_active(i2s) || other_tx_active(i2s);
249
}
250
251
/* If this DAI is transmitting or receiving data */
252
static inline bool this_active(struct i2s_dai *i2s)
253
{
254
return tx_active(i2s) || rx_active(i2s);
255
}
256
257
/* If the controller is active anyway */
258
static inline bool any_active(struct i2s_dai *i2s)
259
{
260
return this_active(i2s) || other_active(i2s);
261
}
262
263
static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
264
{
265
return snd_soc_dai_get_drvdata(dai);
266
}
267
268
static inline bool is_opened(struct i2s_dai *i2s)
269
{
270
if (i2s && (i2s->mode & DAI_OPENED))
271
return true;
272
else
273
return false;
274
}
275
276
static inline bool is_manager(struct i2s_dai *i2s)
277
{
278
if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
279
return true;
280
else
281
return false;
282
}
283
284
/* Read RCLK of I2S (in multiples of LRCLK) */
285
static inline unsigned get_rfs(struct i2s_dai *i2s)
286
{
287
u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3;
288
289
switch (rfs) {
290
case 3: return 768;
291
case 2: return 384;
292
case 1: return 512;
293
default: return 256;
294
}
295
}
296
297
/* Write RCLK of I2S (in multiples of LRCLK) */
298
static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
299
{
300
u32 mod = readl(i2s->addr + I2SMOD);
301
302
mod &= ~MOD_RCLK_MASK;
303
304
switch (rfs) {
305
case 768:
306
mod |= MOD_RCLK_768FS;
307
break;
308
case 512:
309
mod |= MOD_RCLK_512FS;
310
break;
311
case 384:
312
mod |= MOD_RCLK_384FS;
313
break;
314
default:
315
mod |= MOD_RCLK_256FS;
316
break;
317
}
318
319
writel(mod, i2s->addr + I2SMOD);
320
}
321
322
/* Read Bit-Clock of I2S (in multiples of LRCLK) */
323
static inline unsigned get_bfs(struct i2s_dai *i2s)
324
{
325
u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3;
326
327
switch (bfs) {
328
case 3: return 24;
329
case 2: return 16;
330
case 1: return 48;
331
default: return 32;
332
}
333
}
334
335
/* Write Bit-Clock of I2S (in multiples of LRCLK) */
336
static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
337
{
338
u32 mod = readl(i2s->addr + I2SMOD);
339
340
mod &= ~MOD_BCLK_MASK;
341
342
switch (bfs) {
343
case 48:
344
mod |= MOD_BCLK_48FS;
345
break;
346
case 32:
347
mod |= MOD_BCLK_32FS;
348
break;
349
case 24:
350
mod |= MOD_BCLK_24FS;
351
break;
352
case 16:
353
mod |= MOD_BCLK_16FS;
354
break;
355
default:
356
dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
357
return;
358
}
359
360
writel(mod, i2s->addr + I2SMOD);
361
}
362
363
/* Sample-Size */
364
static inline int get_blc(struct i2s_dai *i2s)
365
{
366
int blc = readl(i2s->addr + I2SMOD);
367
368
blc = (blc >> 13) & 0x3;
369
370
switch (blc) {
371
case 2: return 24;
372
case 1: return 8;
373
default: return 16;
374
}
375
}
376
377
/* TX Channel Control */
378
static void i2s_txctrl(struct i2s_dai *i2s, int on)
379
{
380
void __iomem *addr = i2s->addr;
381
u32 con = readl(addr + I2SCON);
382
u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
383
384
if (on) {
385
con |= CON_ACTIVE;
386
con &= ~CON_TXCH_PAUSE;
387
388
if (is_secondary(i2s)) {
389
con |= CON_TXSDMA_ACTIVE;
390
con &= ~CON_TXSDMA_PAUSE;
391
} else {
392
con |= CON_TXDMA_ACTIVE;
393
con &= ~CON_TXDMA_PAUSE;
394
}
395
396
if (any_rx_active(i2s))
397
mod |= MOD_TXRX;
398
else
399
mod |= MOD_TXONLY;
400
} else {
401
if (is_secondary(i2s)) {
402
con |= CON_TXSDMA_PAUSE;
403
con &= ~CON_TXSDMA_ACTIVE;
404
} else {
405
con |= CON_TXDMA_PAUSE;
406
con &= ~CON_TXDMA_ACTIVE;
407
}
408
409
if (other_tx_active(i2s)) {
410
writel(con, addr + I2SCON);
411
return;
412
}
413
414
con |= CON_TXCH_PAUSE;
415
416
if (any_rx_active(i2s))
417
mod |= MOD_RXONLY;
418
else
419
con &= ~CON_ACTIVE;
420
}
421
422
writel(mod, addr + I2SMOD);
423
writel(con, addr + I2SCON);
424
}
425
426
/* RX Channel Control */
427
static void i2s_rxctrl(struct i2s_dai *i2s, int on)
428
{
429
void __iomem *addr = i2s->addr;
430
u32 con = readl(addr + I2SCON);
431
u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
432
433
if (on) {
434
con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
435
con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
436
437
if (any_tx_active(i2s))
438
mod |= MOD_TXRX;
439
else
440
mod |= MOD_RXONLY;
441
} else {
442
con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
443
con &= ~CON_RXDMA_ACTIVE;
444
445
if (any_tx_active(i2s))
446
mod |= MOD_TXONLY;
447
else
448
con &= ~CON_ACTIVE;
449
}
450
451
writel(mod, addr + I2SMOD);
452
writel(con, addr + I2SCON);
453
}
454
455
/* Flush FIFO of an interface */
456
static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
457
{
458
void __iomem *fic;
459
u32 val;
460
461
if (!i2s)
462
return;
463
464
if (is_secondary(i2s))
465
fic = i2s->addr + I2SFICS;
466
else
467
fic = i2s->addr + I2SFIC;
468
469
/* Flush the FIFO */
470
writel(readl(fic) | flush, fic);
471
472
/* Be patient */
473
val = msecs_to_loops(1) / 1000; /* 1 usec */
474
while (--val)
475
cpu_relax();
476
477
writel(readl(fic) & ~flush, fic);
478
}
479
480
static int i2s_set_sysclk(struct snd_soc_dai *dai,
481
int clk_id, unsigned int rfs, int dir)
482
{
483
struct i2s_dai *i2s = to_info(dai);
484
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
485
u32 mod = readl(i2s->addr + I2SMOD);
486
487
switch (clk_id) {
488
case SAMSUNG_I2S_CDCLK:
489
/* Shouldn't matter in GATING(CLOCK_IN) mode */
490
if (dir == SND_SOC_CLOCK_IN)
491
rfs = 0;
492
493
if ((rfs && other->rfs && (other->rfs != rfs)) ||
494
(any_active(i2s) &&
495
(((dir == SND_SOC_CLOCK_IN)
496
&& !(mod & MOD_CDCLKCON)) ||
497
((dir == SND_SOC_CLOCK_OUT)
498
&& (mod & MOD_CDCLKCON))))) {
499
dev_err(&i2s->pdev->dev,
500
"%s:%d Other DAI busy\n", __func__, __LINE__);
501
return -EAGAIN;
502
}
503
504
if (dir == SND_SOC_CLOCK_IN)
505
mod |= MOD_CDCLKCON;
506
else
507
mod &= ~MOD_CDCLKCON;
508
509
i2s->rfs = rfs;
510
break;
511
512
case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
513
case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
514
if ((i2s->quirks & QUIRK_NO_MUXPSR)
515
|| (clk_id == SAMSUNG_I2S_RCLKSRC_0))
516
clk_id = 0;
517
else
518
clk_id = 1;
519
520
if (!any_active(i2s)) {
521
if (i2s->op_clk) {
522
if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
523
(!clk_id && (mod & MOD_IMS_SYSMUX))) {
524
clk_disable(i2s->op_clk);
525
clk_put(i2s->op_clk);
526
} else {
527
i2s->rclk_srcrate =
528
clk_get_rate(i2s->op_clk);
529
return 0;
530
}
531
}
532
533
i2s->op_clk = clk_get(&i2s->pdev->dev,
534
i2s->src_clk[clk_id]);
535
clk_enable(i2s->op_clk);
536
i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
537
538
/* Over-ride the other's */
539
if (other) {
540
other->op_clk = i2s->op_clk;
541
other->rclk_srcrate = i2s->rclk_srcrate;
542
}
543
} else if ((!clk_id && (mod & MOD_IMS_SYSMUX))
544
|| (clk_id && !(mod & MOD_IMS_SYSMUX))) {
545
dev_err(&i2s->pdev->dev,
546
"%s:%d Other DAI busy\n", __func__, __LINE__);
547
return -EAGAIN;
548
} else {
549
/* Call can't be on the active DAI */
550
i2s->op_clk = other->op_clk;
551
i2s->rclk_srcrate = other->rclk_srcrate;
552
return 0;
553
}
554
555
if (clk_id == 0)
556
mod &= ~MOD_IMS_SYSMUX;
557
else
558
mod |= MOD_IMS_SYSMUX;
559
break;
560
561
default:
562
dev_err(&i2s->pdev->dev, "We don't serve that!\n");
563
return -EINVAL;
564
}
565
566
writel(mod, i2s->addr + I2SMOD);
567
568
return 0;
569
}
570
571
static int i2s_set_fmt(struct snd_soc_dai *dai,
572
unsigned int fmt)
573
{
574
struct i2s_dai *i2s = to_info(dai);
575
u32 mod = readl(i2s->addr + I2SMOD);
576
u32 tmp = 0;
577
578
/* Format is priority */
579
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
580
case SND_SOC_DAIFMT_RIGHT_J:
581
tmp |= MOD_LR_RLOW;
582
tmp |= MOD_SDF_MSB;
583
break;
584
case SND_SOC_DAIFMT_LEFT_J:
585
tmp |= MOD_LR_RLOW;
586
tmp |= MOD_SDF_LSB;
587
break;
588
case SND_SOC_DAIFMT_I2S:
589
tmp |= MOD_SDF_IIS;
590
break;
591
default:
592
dev_err(&i2s->pdev->dev, "Format not supported\n");
593
return -EINVAL;
594
}
595
596
/*
597
* INV flag is relative to the FORMAT flag - if set it simply
598
* flips the polarity specified by the Standard
599
*/
600
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
601
case SND_SOC_DAIFMT_NB_NF:
602
break;
603
case SND_SOC_DAIFMT_NB_IF:
604
if (tmp & MOD_LR_RLOW)
605
tmp &= ~MOD_LR_RLOW;
606
else
607
tmp |= MOD_LR_RLOW;
608
break;
609
default:
610
dev_err(&i2s->pdev->dev, "Polarity not supported\n");
611
return -EINVAL;
612
}
613
614
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
615
case SND_SOC_DAIFMT_CBM_CFM:
616
tmp |= MOD_SLAVE;
617
break;
618
case SND_SOC_DAIFMT_CBS_CFS:
619
/* Set default source clock in Master mode */
620
if (i2s->rclk_srcrate == 0)
621
i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
622
0, SND_SOC_CLOCK_IN);
623
break;
624
default:
625
dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
626
return -EINVAL;
627
}
628
629
if (any_active(i2s) &&
630
((mod & (MOD_SDF_MASK | MOD_LR_RLOW
631
| MOD_SLAVE)) != tmp)) {
632
dev_err(&i2s->pdev->dev,
633
"%s:%d Other DAI busy\n", __func__, __LINE__);
634
return -EAGAIN;
635
}
636
637
mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
638
mod |= tmp;
639
writel(mod, i2s->addr + I2SMOD);
640
641
return 0;
642
}
643
644
static int i2s_hw_params(struct snd_pcm_substream *substream,
645
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
646
{
647
struct i2s_dai *i2s = to_info(dai);
648
u32 mod = readl(i2s->addr + I2SMOD);
649
650
if (!is_secondary(i2s))
651
mod &= ~(MOD_DC2_EN | MOD_DC1_EN);
652
653
switch (params_channels(params)) {
654
case 6:
655
mod |= MOD_DC2_EN;
656
case 4:
657
mod |= MOD_DC1_EN;
658
break;
659
case 2:
660
break;
661
default:
662
dev_err(&i2s->pdev->dev, "%d channels not supported\n",
663
params_channels(params));
664
return -EINVAL;
665
}
666
667
if (is_secondary(i2s))
668
mod &= ~MOD_BLCS_MASK;
669
else
670
mod &= ~MOD_BLCP_MASK;
671
672
if (is_manager(i2s))
673
mod &= ~MOD_BLC_MASK;
674
675
switch (params_format(params)) {
676
case SNDRV_PCM_FORMAT_S8:
677
if (is_secondary(i2s))
678
mod |= MOD_BLCS_8BIT;
679
else
680
mod |= MOD_BLCP_8BIT;
681
if (is_manager(i2s))
682
mod |= MOD_BLC_8BIT;
683
break;
684
case SNDRV_PCM_FORMAT_S16_LE:
685
if (is_secondary(i2s))
686
mod |= MOD_BLCS_16BIT;
687
else
688
mod |= MOD_BLCP_16BIT;
689
if (is_manager(i2s))
690
mod |= MOD_BLC_16BIT;
691
break;
692
case SNDRV_PCM_FORMAT_S24_LE:
693
if (is_secondary(i2s))
694
mod |= MOD_BLCS_24BIT;
695
else
696
mod |= MOD_BLCP_24BIT;
697
if (is_manager(i2s))
698
mod |= MOD_BLC_24BIT;
699
break;
700
default:
701
dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
702
params_format(params));
703
return -EINVAL;
704
}
705
writel(mod, i2s->addr + I2SMOD);
706
707
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
708
snd_soc_dai_set_dma_data(dai, substream,
709
(void *)&i2s->dma_playback);
710
else
711
snd_soc_dai_set_dma_data(dai, substream,
712
(void *)&i2s->dma_capture);
713
714
i2s->frmclk = params_rate(params);
715
716
return 0;
717
}
718
719
/* We set constraints on the substream acc to the version of I2S */
720
static int i2s_startup(struct snd_pcm_substream *substream,
721
struct snd_soc_dai *dai)
722
{
723
struct i2s_dai *i2s = to_info(dai);
724
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
725
unsigned long flags;
726
727
spin_lock_irqsave(&lock, flags);
728
729
i2s->mode |= DAI_OPENED;
730
731
if (is_manager(other))
732
i2s->mode &= ~DAI_MANAGER;
733
else
734
i2s->mode |= DAI_MANAGER;
735
736
/* Enforce set_sysclk in Master mode */
737
i2s->rclk_srcrate = 0;
738
739
spin_unlock_irqrestore(&lock, flags);
740
741
return 0;
742
}
743
744
static void i2s_shutdown(struct snd_pcm_substream *substream,
745
struct snd_soc_dai *dai)
746
{
747
struct i2s_dai *i2s = to_info(dai);
748
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
749
unsigned long flags;
750
751
spin_lock_irqsave(&lock, flags);
752
753
i2s->mode &= ~DAI_OPENED;
754
i2s->mode &= ~DAI_MANAGER;
755
756
if (is_opened(other))
757
other->mode |= DAI_MANAGER;
758
759
/* Reset any constraint on RFS and BFS */
760
i2s->rfs = 0;
761
i2s->bfs = 0;
762
763
spin_unlock_irqrestore(&lock, flags);
764
765
/* Gate CDCLK by default */
766
if (!is_opened(other))
767
i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
768
0, SND_SOC_CLOCK_IN);
769
}
770
771
static int config_setup(struct i2s_dai *i2s)
772
{
773
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
774
unsigned rfs, bfs, blc;
775
u32 psr;
776
777
blc = get_blc(i2s);
778
779
bfs = i2s->bfs;
780
781
if (!bfs && other)
782
bfs = other->bfs;
783
784
/* Select least possible multiple(2) if no constraint set */
785
if (!bfs)
786
bfs = blc * 2;
787
788
rfs = i2s->rfs;
789
790
if (!rfs && other)
791
rfs = other->rfs;
792
793
if ((rfs == 256 || rfs == 512) && (blc == 24)) {
794
dev_err(&i2s->pdev->dev,
795
"%d-RFS not supported for 24-blc\n", rfs);
796
return -EINVAL;
797
}
798
799
if (!rfs) {
800
if (bfs == 16 || bfs == 32)
801
rfs = 256;
802
else
803
rfs = 384;
804
}
805
806
/* If already setup and running */
807
if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
808
dev_err(&i2s->pdev->dev,
809
"%s:%d Other DAI busy\n", __func__, __LINE__);
810
return -EAGAIN;
811
}
812
813
/* Don't bother RFS, BFS & PSR in Slave mode */
814
if (is_slave(i2s))
815
return 0;
816
817
set_bfs(i2s, bfs);
818
set_rfs(i2s, rfs);
819
820
if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
821
psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
822
writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
823
dev_dbg(&i2s->pdev->dev,
824
"RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
825
i2s->rclk_srcrate, psr, rfs, bfs);
826
}
827
828
return 0;
829
}
830
831
static int i2s_trigger(struct snd_pcm_substream *substream,
832
int cmd, struct snd_soc_dai *dai)
833
{
834
int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
835
struct snd_soc_pcm_runtime *rtd = substream->private_data;
836
struct i2s_dai *i2s = to_info(rtd->cpu_dai);
837
unsigned long flags;
838
839
switch (cmd) {
840
case SNDRV_PCM_TRIGGER_START:
841
case SNDRV_PCM_TRIGGER_RESUME:
842
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
843
local_irq_save(flags);
844
845
if (config_setup(i2s)) {
846
local_irq_restore(flags);
847
return -EINVAL;
848
}
849
850
if (capture)
851
i2s_rxctrl(i2s, 1);
852
else
853
i2s_txctrl(i2s, 1);
854
855
local_irq_restore(flags);
856
break;
857
case SNDRV_PCM_TRIGGER_STOP:
858
case SNDRV_PCM_TRIGGER_SUSPEND:
859
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
860
local_irq_save(flags);
861
862
if (capture)
863
i2s_rxctrl(i2s, 0);
864
else
865
i2s_txctrl(i2s, 0);
866
867
if (capture)
868
i2s_fifo(i2s, FIC_RXFLUSH);
869
else
870
i2s_fifo(i2s, FIC_TXFLUSH);
871
872
local_irq_restore(flags);
873
break;
874
}
875
876
return 0;
877
}
878
879
static int i2s_set_clkdiv(struct snd_soc_dai *dai,
880
int div_id, int div)
881
{
882
struct i2s_dai *i2s = to_info(dai);
883
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
884
885
switch (div_id) {
886
case SAMSUNG_I2S_DIV_BCLK:
887
if ((any_active(i2s) && div && (get_bfs(i2s) != div))
888
|| (other && other->bfs && (other->bfs != div))) {
889
dev_err(&i2s->pdev->dev,
890
"%s:%d Other DAI busy\n", __func__, __LINE__);
891
return -EAGAIN;
892
}
893
i2s->bfs = div;
894
break;
895
default:
896
dev_err(&i2s->pdev->dev,
897
"Invalid clock divider(%d)\n", div_id);
898
return -EINVAL;
899
}
900
901
return 0;
902
}
903
904
static snd_pcm_sframes_t
905
i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
906
{
907
struct i2s_dai *i2s = to_info(dai);
908
u32 reg = readl(i2s->addr + I2SFIC);
909
snd_pcm_sframes_t delay;
910
911
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
912
delay = FIC_RXCOUNT(reg);
913
else if (is_secondary(i2s))
914
delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
915
else
916
delay = FIC_TXCOUNT(reg);
917
918
return delay;
919
}
920
921
#ifdef CONFIG_PM
922
static int i2s_suspend(struct snd_soc_dai *dai)
923
{
924
struct i2s_dai *i2s = to_info(dai);
925
926
if (dai->active) {
927
i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
928
i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
929
i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
930
}
931
932
return 0;
933
}
934
935
static int i2s_resume(struct snd_soc_dai *dai)
936
{
937
struct i2s_dai *i2s = to_info(dai);
938
939
if (dai->active) {
940
writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
941
writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
942
writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
943
}
944
945
return 0;
946
}
947
#else
948
#define i2s_suspend NULL
949
#define i2s_resume NULL
950
#endif
951
952
static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
953
{
954
struct i2s_dai *i2s = to_info(dai);
955
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
956
957
if (other && other->clk) /* If this is probe on secondary */
958
goto probe_exit;
959
960
i2s->addr = ioremap(i2s->base, 0x100);
961
if (i2s->addr == NULL) {
962
dev_err(&i2s->pdev->dev, "cannot ioremap registers\n");
963
return -ENXIO;
964
}
965
966
i2s->clk = clk_get(&i2s->pdev->dev, "iis");
967
if (IS_ERR(i2s->clk)) {
968
dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
969
iounmap(i2s->addr);
970
return -ENOENT;
971
}
972
clk_enable(i2s->clk);
973
974
if (other) {
975
other->addr = i2s->addr;
976
other->clk = i2s->clk;
977
}
978
979
if (i2s->quirks & QUIRK_NEED_RSTCLR)
980
writel(CON_RSTCLR, i2s->addr + I2SCON);
981
982
probe_exit:
983
/* Reset any constraint on RFS and BFS */
984
i2s->rfs = 0;
985
i2s->bfs = 0;
986
i2s_txctrl(i2s, 0);
987
i2s_rxctrl(i2s, 0);
988
i2s_fifo(i2s, FIC_TXFLUSH);
989
i2s_fifo(other, FIC_TXFLUSH);
990
i2s_fifo(i2s, FIC_RXFLUSH);
991
992
/* Gate CDCLK by default */
993
if (!is_opened(other))
994
i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
995
0, SND_SOC_CLOCK_IN);
996
997
return 0;
998
}
999
1000
static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
1001
{
1002
struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
1003
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
1004
1005
if (!other || !other->clk) {
1006
1007
if (i2s->quirks & QUIRK_NEED_RSTCLR)
1008
writel(0, i2s->addr + I2SCON);
1009
1010
clk_disable(i2s->clk);
1011
clk_put(i2s->clk);
1012
1013
iounmap(i2s->addr);
1014
}
1015
1016
i2s->clk = NULL;
1017
1018
return 0;
1019
}
1020
1021
static struct snd_soc_dai_ops samsung_i2s_dai_ops = {
1022
.trigger = i2s_trigger,
1023
.hw_params = i2s_hw_params,
1024
.set_fmt = i2s_set_fmt,
1025
.set_clkdiv = i2s_set_clkdiv,
1026
.set_sysclk = i2s_set_sysclk,
1027
.startup = i2s_startup,
1028
.shutdown = i2s_shutdown,
1029
.delay = i2s_delay,
1030
};
1031
1032
#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000
1033
1034
#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
1035
SNDRV_PCM_FMTBIT_S16_LE | \
1036
SNDRV_PCM_FMTBIT_S24_LE)
1037
1038
static __devinit
1039
struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1040
{
1041
struct i2s_dai *i2s;
1042
1043
i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL);
1044
if (i2s == NULL)
1045
return NULL;
1046
1047
i2s->pdev = pdev;
1048
i2s->pri_dai = NULL;
1049
i2s->sec_dai = NULL;
1050
i2s->i2s_dai_drv.symmetric_rates = 1;
1051
i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
1052
i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
1053
i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
1054
i2s->i2s_dai_drv.suspend = i2s_suspend;
1055
i2s->i2s_dai_drv.resume = i2s_resume;
1056
i2s->i2s_dai_drv.playback.channels_min = 2;
1057
i2s->i2s_dai_drv.playback.channels_max = 2;
1058
i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
1059
i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
1060
1061
if (!sec) {
1062
i2s->i2s_dai_drv.capture.channels_min = 2;
1063
i2s->i2s_dai_drv.capture.channels_max = 2;
1064
i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
1065
i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
1066
} else { /* Create a new platform_device for Secondary */
1067
i2s->pdev = platform_device_register_resndata(NULL,
1068
pdev->name, pdev->id + SAMSUNG_I2S_SECOFF,
1069
NULL, 0, NULL, 0);
1070
if (IS_ERR(i2s->pdev)) {
1071
kfree(i2s);
1072
return NULL;
1073
}
1074
}
1075
1076
/* Pre-assign snd_soc_dai_set_drvdata */
1077
dev_set_drvdata(&i2s->pdev->dev, i2s);
1078
1079
return i2s;
1080
}
1081
1082
static __devinit int samsung_i2s_probe(struct platform_device *pdev)
1083
{
1084
u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
1085
struct i2s_dai *pri_dai, *sec_dai = NULL;
1086
struct s3c_audio_pdata *i2s_pdata;
1087
struct samsung_i2s *i2s_cfg;
1088
struct resource *res;
1089
u32 regs_base, quirks;
1090
int ret = 0;
1091
1092
/* Call during Seconday interface registration */
1093
if (pdev->id >= SAMSUNG_I2S_SECOFF) {
1094
sec_dai = dev_get_drvdata(&pdev->dev);
1095
snd_soc_register_dai(&sec_dai->pdev->dev,
1096
&sec_dai->i2s_dai_drv);
1097
return 0;
1098
}
1099
1100
i2s_pdata = pdev->dev.platform_data;
1101
if (i2s_pdata == NULL) {
1102
dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
1103
return -EINVAL;
1104
}
1105
1106
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1107
if (!res) {
1108
dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
1109
return -ENXIO;
1110
}
1111
dma_pl_chan = res->start;
1112
1113
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1114
if (!res) {
1115
dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
1116
return -ENXIO;
1117
}
1118
dma_cp_chan = res->start;
1119
1120
res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
1121
if (res)
1122
dma_pl_sec_chan = res->start;
1123
else
1124
dma_pl_sec_chan = 0;
1125
1126
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1127
if (!res) {
1128
dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
1129
return -ENXIO;
1130
}
1131
1132
if (!request_mem_region(res->start, resource_size(res),
1133
"samsung-i2s")) {
1134
dev_err(&pdev->dev, "Unable to request SFR region\n");
1135
return -EBUSY;
1136
}
1137
regs_base = res->start;
1138
1139
i2s_cfg = &i2s_pdata->type.i2s;
1140
quirks = i2s_cfg->quirks;
1141
1142
pri_dai = i2s_alloc_dai(pdev, false);
1143
if (!pri_dai) {
1144
dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
1145
ret = -ENOMEM;
1146
goto err1;
1147
}
1148
1149
pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
1150
pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
1151
pri_dai->dma_playback.client =
1152
(struct s3c2410_dma_client *)&pri_dai->dma_playback;
1153
pri_dai->dma_capture.client =
1154
(struct s3c2410_dma_client *)&pri_dai->dma_capture;
1155
pri_dai->dma_playback.channel = dma_pl_chan;
1156
pri_dai->dma_capture.channel = dma_cp_chan;
1157
pri_dai->src_clk = i2s_cfg->src_clk;
1158
pri_dai->dma_playback.dma_size = 4;
1159
pri_dai->dma_capture.dma_size = 4;
1160
pri_dai->base = regs_base;
1161
pri_dai->quirks = quirks;
1162
1163
if (quirks & QUIRK_PRI_6CHAN)
1164
pri_dai->i2s_dai_drv.playback.channels_max = 6;
1165
1166
if (quirks & QUIRK_SEC_DAI) {
1167
sec_dai = i2s_alloc_dai(pdev, true);
1168
if (!sec_dai) {
1169
dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
1170
ret = -ENOMEM;
1171
goto err2;
1172
}
1173
sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
1174
sec_dai->dma_playback.client =
1175
(struct s3c2410_dma_client *)&sec_dai->dma_playback;
1176
/* Use iDMA always if SysDMA not provided */
1177
sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1;
1178
sec_dai->src_clk = i2s_cfg->src_clk;
1179
sec_dai->dma_playback.dma_size = 4;
1180
sec_dai->base = regs_base;
1181
sec_dai->quirks = quirks;
1182
sec_dai->pri_dai = pri_dai;
1183
pri_dai->sec_dai = sec_dai;
1184
}
1185
1186
if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
1187
dev_err(&pdev->dev, "Unable to configure gpio\n");
1188
ret = -EINVAL;
1189
goto err3;
1190
}
1191
1192
snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
1193
1194
return 0;
1195
err3:
1196
kfree(sec_dai);
1197
err2:
1198
kfree(pri_dai);
1199
err1:
1200
release_mem_region(regs_base, resource_size(res));
1201
1202
return ret;
1203
}
1204
1205
static __devexit int samsung_i2s_remove(struct platform_device *pdev)
1206
{
1207
struct i2s_dai *i2s, *other;
1208
1209
i2s = dev_get_drvdata(&pdev->dev);
1210
other = i2s->pri_dai ? : i2s->sec_dai;
1211
1212
if (other) {
1213
other->pri_dai = NULL;
1214
other->sec_dai = NULL;
1215
} else {
1216
struct resource *res;
1217
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1218
if (res)
1219
release_mem_region(res->start, resource_size(res));
1220
}
1221
1222
i2s->pri_dai = NULL;
1223
i2s->sec_dai = NULL;
1224
1225
kfree(i2s);
1226
1227
snd_soc_unregister_dai(&pdev->dev);
1228
1229
return 0;
1230
}
1231
1232
static struct platform_driver samsung_i2s_driver = {
1233
.probe = samsung_i2s_probe,
1234
.remove = samsung_i2s_remove,
1235
.driver = {
1236
.name = "samsung-i2s",
1237
.owner = THIS_MODULE,
1238
},
1239
};
1240
1241
static int __init samsung_i2s_init(void)
1242
{
1243
return platform_driver_register(&samsung_i2s_driver);
1244
}
1245
module_init(samsung_i2s_init);
1246
1247
static void __exit samsung_i2s_exit(void)
1248
{
1249
platform_driver_unregister(&samsung_i2s_driver);
1250
}
1251
module_exit(samsung_i2s_exit);
1252
1253
/* Module information */
1254
MODULE_AUTHOR("Jaswinder Singh, <[email protected]>");
1255
MODULE_DESCRIPTION("Samsung I2S Interface");
1256
MODULE_ALIAS("platform:samsung-i2s");
1257
MODULE_LICENSE("GPL");
1258
1259