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