1
/* sound/soc/samsung/s3c-i2c-v2.c
3
* ALSA Soc Audio Layer - I2S core for newer Samsung SoCs.
5
* Copyright (c) 2006 Wolfson Microelectronics PLC.
6
* Graeme Gregory graeme.gregory@wolfsonmicro.com
7
* linux@wolfsonmicro.com
9
* Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics
10
* http://armlinux.simtec.co.uk/
11
* Ben Dooks <ben@simtec.co.uk>
13
* This program is free software; you can redistribute it and/or modify it
14
* under the terms of the GNU General Public License as published by the
15
* Free Software Foundation; either version 2 of the License, or (at your
16
* option) any later version.
19
#include <linux/module.h>
20
#include <linux/delay.h>
21
#include <linux/clk.h>
24
#include <sound/soc.h>
25
#include <sound/pcm_params.h>
29
#include "regs-i2s-v2.h"
30
#include "s3c-i2s-v2.h"
33
#undef S3C_IIS_V2_SUPPORTED
35
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \
36
|| defined(CONFIG_CPU_S5PV210)
37
#define S3C_IIS_V2_SUPPORTED
40
#ifdef CONFIG_PLAT_S3C64XX
41
#define S3C_IIS_V2_SUPPORTED
44
#ifndef S3C_IIS_V2_SUPPORTED
45
#error Unsupported CPU model
48
#define S3C2412_I2S_DEBUG_CON 0
50
static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
52
return snd_soc_dai_get_drvdata(cpu_dai);
55
#define bit_set(v, b) (((v) & (b)) ? 1 : 0)
57
#if S3C2412_I2S_DEBUG_CON
58
static void dbg_showcon(const char *fn, u32 con)
60
printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn,
61
bit_set(con, S3C2412_IISCON_LRINDEX),
62
bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY),
63
bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY),
64
bit_set(con, S3C2412_IISCON_TXFIFO_FULL),
65
bit_set(con, S3C2412_IISCON_RXFIFO_FULL));
67
printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n",
69
bit_set(con, S3C2412_IISCON_TXDMA_PAUSE),
70
bit_set(con, S3C2412_IISCON_RXDMA_PAUSE),
71
bit_set(con, S3C2412_IISCON_TXCH_PAUSE),
72
bit_set(con, S3C2412_IISCON_RXCH_PAUSE));
73
printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn,
74
bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE),
75
bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE),
76
bit_set(con, S3C2412_IISCON_IIS_ACTIVE));
79
static inline void dbg_showcon(const char *fn, u32 con)
85
/* Turn on or off the transmission path. */
86
static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
88
void __iomem *regs = i2s->regs;
91
pr_debug("%s(%d)\n", __func__, on);
93
fic = readl(regs + S3C2412_IISFIC);
94
con = readl(regs + S3C2412_IISCON);
95
mod = readl(regs + S3C2412_IISMOD);
97
pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
100
con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
101
con &= ~S3C2412_IISCON_TXDMA_PAUSE;
102
con &= ~S3C2412_IISCON_TXCH_PAUSE;
104
switch (mod & S3C2412_IISMOD_MODE_MASK) {
105
case S3C2412_IISMOD_MODE_TXONLY:
106
case S3C2412_IISMOD_MODE_TXRX:
107
/* do nothing, we are in the right mode */
110
case S3C2412_IISMOD_MODE_RXONLY:
111
mod &= ~S3C2412_IISMOD_MODE_MASK;
112
mod |= S3C2412_IISMOD_MODE_TXRX;
116
dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n",
117
mod & S3C2412_IISMOD_MODE_MASK);
121
writel(con, regs + S3C2412_IISCON);
122
writel(mod, regs + S3C2412_IISMOD);
124
/* Note, we do not have any indication that the FIFO problems
125
* tha the S3C2410/2440 had apply here, so we should be able
126
* to disable the DMA and TX without resetting the FIFOS.
129
con |= S3C2412_IISCON_TXDMA_PAUSE;
130
con |= S3C2412_IISCON_TXCH_PAUSE;
131
con &= ~S3C2412_IISCON_TXDMA_ACTIVE;
133
switch (mod & S3C2412_IISMOD_MODE_MASK) {
134
case S3C2412_IISMOD_MODE_TXRX:
135
mod &= ~S3C2412_IISMOD_MODE_MASK;
136
mod |= S3C2412_IISMOD_MODE_RXONLY;
139
case S3C2412_IISMOD_MODE_TXONLY:
140
mod &= ~S3C2412_IISMOD_MODE_MASK;
141
con &= ~S3C2412_IISCON_IIS_ACTIVE;
145
dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n",
146
mod & S3C2412_IISMOD_MODE_MASK);
150
writel(mod, regs + S3C2412_IISMOD);
151
writel(con, regs + S3C2412_IISCON);
154
fic = readl(regs + S3C2412_IISFIC);
155
dbg_showcon(__func__, con);
156
pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
159
static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
161
void __iomem *regs = i2s->regs;
164
pr_debug("%s(%d)\n", __func__, on);
166
fic = readl(regs + S3C2412_IISFIC);
167
con = readl(regs + S3C2412_IISCON);
168
mod = readl(regs + S3C2412_IISMOD);
170
pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
173
con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE;
174
con &= ~S3C2412_IISCON_RXDMA_PAUSE;
175
con &= ~S3C2412_IISCON_RXCH_PAUSE;
177
switch (mod & S3C2412_IISMOD_MODE_MASK) {
178
case S3C2412_IISMOD_MODE_TXRX:
179
case S3C2412_IISMOD_MODE_RXONLY:
180
/* do nothing, we are in the right mode */
183
case S3C2412_IISMOD_MODE_TXONLY:
184
mod &= ~S3C2412_IISMOD_MODE_MASK;
185
mod |= S3C2412_IISMOD_MODE_TXRX;
189
dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n",
190
mod & S3C2412_IISMOD_MODE_MASK);
193
writel(mod, regs + S3C2412_IISMOD);
194
writel(con, regs + S3C2412_IISCON);
196
/* See txctrl notes on FIFOs. */
198
con &= ~S3C2412_IISCON_RXDMA_ACTIVE;
199
con |= S3C2412_IISCON_RXDMA_PAUSE;
200
con |= S3C2412_IISCON_RXCH_PAUSE;
202
switch (mod & S3C2412_IISMOD_MODE_MASK) {
203
case S3C2412_IISMOD_MODE_RXONLY:
204
con &= ~S3C2412_IISCON_IIS_ACTIVE;
205
mod &= ~S3C2412_IISMOD_MODE_MASK;
208
case S3C2412_IISMOD_MODE_TXRX:
209
mod &= ~S3C2412_IISMOD_MODE_MASK;
210
mod |= S3C2412_IISMOD_MODE_TXONLY;
214
dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n",
215
mod & S3C2412_IISMOD_MODE_MASK);
218
writel(con, regs + S3C2412_IISCON);
219
writel(mod, regs + S3C2412_IISMOD);
222
fic = readl(regs + S3C2412_IISFIC);
223
pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
226
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
229
* Wait for the LR signal to allow synchronisation to the L/R clock
230
* from the codec. May only be needed for slave mode.
232
static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s)
235
unsigned long loops = msecs_to_loops(5);
237
pr_debug("Entered %s\n", __func__);
240
iiscon = readl(i2s->regs + S3C2412_IISCON);
241
if (iiscon & S3C2412_IISCON_LRINDEX)
248
printk(KERN_ERR "%s: timeout\n", __func__);
256
* Set S3C2412 I2S DAI format
258
static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
261
struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
264
pr_debug("Entered %s\n", __func__);
266
iismod = readl(i2s->regs + S3C2412_IISMOD);
267
pr_debug("hw_params r: IISMOD: %x \n", iismod);
269
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
270
case SND_SOC_DAIFMT_CBM_CFM:
272
iismod |= S3C2412_IISMOD_SLAVE;
274
case SND_SOC_DAIFMT_CBS_CFS:
276
iismod &= ~S3C2412_IISMOD_SLAVE;
279
pr_err("unknwon master/slave format\n");
283
iismod &= ~S3C2412_IISMOD_SDF_MASK;
285
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
286
case SND_SOC_DAIFMT_RIGHT_J:
287
iismod |= S3C2412_IISMOD_LR_RLOW;
288
iismod |= S3C2412_IISMOD_SDF_MSB;
290
case SND_SOC_DAIFMT_LEFT_J:
291
iismod |= S3C2412_IISMOD_LR_RLOW;
292
iismod |= S3C2412_IISMOD_SDF_LSB;
294
case SND_SOC_DAIFMT_I2S:
295
iismod &= ~S3C2412_IISMOD_LR_RLOW;
296
iismod |= S3C2412_IISMOD_SDF_IIS;
299
pr_err("Unknown data format\n");
303
writel(iismod, i2s->regs + S3C2412_IISMOD);
304
pr_debug("hw_params w: IISMOD: %x \n", iismod);
308
static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
309
struct snd_pcm_hw_params *params,
310
struct snd_soc_dai *dai)
312
struct s3c_i2sv2_info *i2s = to_info(dai);
313
struct s3c_dma_params *dma_data;
316
pr_debug("Entered %s\n", __func__);
318
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
319
dma_data = i2s->dma_playback;
321
dma_data = i2s->dma_capture;
323
snd_soc_dai_set_dma_data(dai, substream, dma_data);
325
/* Working copies of register */
326
iismod = readl(i2s->regs + S3C2412_IISMOD);
327
pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
329
iismod &= ~S3C64XX_IISMOD_BLC_MASK;
331
switch (params_format(params)) {
332
case SNDRV_PCM_FORMAT_S8:
333
iismod |= S3C64XX_IISMOD_BLC_8BIT;
335
case SNDRV_PCM_FORMAT_S16_LE:
337
case SNDRV_PCM_FORMAT_S24_LE:
338
iismod |= S3C64XX_IISMOD_BLC_24BIT;
342
writel(iismod, i2s->regs + S3C2412_IISMOD);
343
pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
348
static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai,
349
int clk_id, unsigned int freq, int dir)
351
struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
352
u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
354
pr_debug("Entered %s\n", __func__);
355
pr_debug("%s r: IISMOD: %x\n", __func__, iismod);
358
case S3C_I2SV2_CLKSRC_PCLK:
359
iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
362
case S3C_I2SV2_CLKSRC_AUDIOBUS:
363
iismod |= S3C2412_IISMOD_IMS_SYSMUX;
366
case S3C_I2SV2_CLKSRC_CDCLK:
367
/* Error if controller doesn't have the CDCLKCON bit */
368
if (!(i2s->feature & S3C_FEATURE_CDCLKCON))
372
case SND_SOC_CLOCK_IN:
373
iismod |= S3C64XX_IISMOD_CDCLKCON;
375
case SND_SOC_CLOCK_OUT:
376
iismod &= ~S3C64XX_IISMOD_CDCLKCON;
387
writel(iismod, i2s->regs + S3C2412_IISMOD);
388
pr_debug("%s w: IISMOD: %x\n", __func__, iismod);
393
static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
394
struct snd_soc_dai *dai)
396
struct snd_soc_pcm_runtime *rtd = substream->private_data;
397
struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai);
398
int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
401
struct s3c_dma_params *dma_data =
402
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
404
pr_debug("Entered %s\n", __func__);
407
case SNDRV_PCM_TRIGGER_START:
408
/* On start, ensure that the FIFOs are cleared and reset. */
410
writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH,
411
i2s->regs + S3C2412_IISFIC);
413
/* clear again, just in case */
414
writel(0x0, i2s->regs + S3C2412_IISFIC);
416
case SNDRV_PCM_TRIGGER_RESUME:
417
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
419
ret = s3c2412_snd_lrsync(i2s);
424
local_irq_save(irqs);
427
s3c2412_snd_rxctrl(i2s, 1);
429
s3c2412_snd_txctrl(i2s, 1);
431
local_irq_restore(irqs);
434
* Load the next buffer to DMA to meet the reqirement
435
* of the auto reload mechanism of S3C24XX.
436
* This call won't bother S3C64XX.
438
s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
442
case SNDRV_PCM_TRIGGER_STOP:
443
case SNDRV_PCM_TRIGGER_SUSPEND:
444
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
445
local_irq_save(irqs);
448
s3c2412_snd_rxctrl(i2s, 0);
450
s3c2412_snd_txctrl(i2s, 0);
452
local_irq_restore(irqs);
464
* Set S3C2412 Clock dividers
466
static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
469
struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
472
pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div);
475
case S3C_I2SV2_DIV_BCLK:
478
div = S3C2412_IISMOD_BCLK_16FS;
482
div = S3C2412_IISMOD_BCLK_32FS;
486
div = S3C2412_IISMOD_BCLK_24FS;
490
div = S3C2412_IISMOD_BCLK_48FS;
497
reg = readl(i2s->regs + S3C2412_IISMOD);
498
reg &= ~S3C2412_IISMOD_BCLK_MASK;
499
writel(reg | div, i2s->regs + S3C2412_IISMOD);
501
pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
504
case S3C_I2SV2_DIV_RCLK:
507
div = S3C2412_IISMOD_RCLK_256FS;
511
div = S3C2412_IISMOD_RCLK_384FS;
515
div = S3C2412_IISMOD_RCLK_512FS;
519
div = S3C2412_IISMOD_RCLK_768FS;
526
reg = readl(i2s->regs + S3C2412_IISMOD);
527
reg &= ~S3C2412_IISMOD_RCLK_MASK;
528
writel(reg | div, i2s->regs + S3C2412_IISMOD);
529
pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD));
532
case S3C_I2SV2_DIV_PRESCALER:
534
writel((div << 8) | S3C2412_IISPSR_PSREN,
535
i2s->regs + S3C2412_IISPSR);
537
writel(0x0, i2s->regs + S3C2412_IISPSR);
539
pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR));
549
static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream,
550
struct snd_soc_dai *dai)
552
struct s3c_i2sv2_info *i2s = to_info(dai);
553
u32 reg = readl(i2s->regs + S3C2412_IISFIC);
554
snd_pcm_sframes_t delay;
556
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
557
delay = S3C2412_IISFIC_TXCOUNT(reg);
559
delay = S3C2412_IISFIC_RXCOUNT(reg);
564
struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai)
566
struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
567
u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
569
if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
570
return i2s->iis_cclk;
572
return i2s->iis_pclk;
574
EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock);
576
/* default table of all avaialable root fs divisors */
577
static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 };
579
int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
581
unsigned int rate, struct clk *clk)
583
unsigned long clkrate = clk_get_rate(clk);
589
signed int deviation = 0;
590
unsigned int best_fs = 0;
591
unsigned int best_div = 0;
592
unsigned int best_rate = 0;
593
unsigned int best_deviation = INT_MAX;
595
pr_debug("Input clock rate %ldHz\n", clkrate);
600
for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) {
601
fsdiv = iis_fs_tab[fs];
603
fsclk = clkrate / fsdiv;
606
if ((fsclk % rate) > (rate / 2))
612
actual = clkrate / (fsdiv * div);
613
deviation = actual - rate;
615
printk(KERN_DEBUG "%ufs: div %u => result %u, deviation %d\n",
616
fsdiv, div, actual, deviation);
618
deviation = abs(deviation);
620
if (deviation < best_deviation) {
624
best_deviation = deviation;
631
printk(KERN_DEBUG "best: fs=%u, div=%u, rate=%u\n",
632
best_fs, best_div, best_rate);
634
info->fs_div = best_fs;
635
info->clk_div = best_div;
639
EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate);
641
int s3c_i2sv2_probe(struct snd_soc_dai *dai,
642
struct s3c_i2sv2_info *i2s,
645
struct device *dev = dai->dev;
650
/* record our i2s structure for later use in the callbacks */
651
snd_soc_dai_set_drvdata(dai, i2s);
653
i2s->regs = ioremap(base, 0x100);
654
if (i2s->regs == NULL) {
655
dev_err(dev, "cannot ioremap registers\n");
659
i2s->iis_pclk = clk_get(dev, "iis");
660
if (IS_ERR(i2s->iis_pclk)) {
661
dev_err(dev, "failed to get iis_clock\n");
666
clk_enable(i2s->iis_pclk);
668
/* Mark ourselves as in TXRX mode so we can run through our cleanup
669
* process without warnings. */
670
iismod = readl(i2s->regs + S3C2412_IISMOD);
671
iismod |= S3C2412_IISMOD_MODE_TXRX;
672
writel(iismod, i2s->regs + S3C2412_IISMOD);
673
s3c2412_snd_txctrl(i2s, 0);
674
s3c2412_snd_rxctrl(i2s, 0);
678
EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
681
static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
683
struct s3c_i2sv2_info *i2s = to_info(dai);
687
i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
688
i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
689
i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
691
/* some basic suspend checks */
693
iismod = readl(i2s->regs + S3C2412_IISMOD);
695
if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
696
pr_warning("%s: RXDMA active?\n", __func__);
698
if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
699
pr_warning("%s: TXDMA active?\n", __func__);
701
if (iismod & S3C2412_IISCON_IIS_ACTIVE)
702
pr_warning("%s: IIS active\n", __func__);
708
static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
710
struct s3c_i2sv2_info *i2s = to_info(dai);
712
pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
713
dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
716
writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
717
writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
718
writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
720
writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
721
i2s->regs + S3C2412_IISFIC);
724
writel(0x0, i2s->regs + S3C2412_IISFIC);
730
#define s3c2412_i2s_suspend NULL
731
#define s3c2412_i2s_resume NULL
734
int s3c_i2sv2_register_dai(struct device *dev, int id,
735
struct snd_soc_dai_driver *drv)
737
struct snd_soc_dai_ops *ops = drv->ops;
739
ops->trigger = s3c2412_i2s_trigger;
741
ops->hw_params = s3c_i2sv2_hw_params;
742
ops->set_fmt = s3c2412_i2s_set_fmt;
743
ops->set_clkdiv = s3c2412_i2s_set_clkdiv;
744
ops->set_sysclk = s3c_i2sv2_set_sysclk;
746
/* Allow overriding by (for example) IISv4 */
748
ops->delay = s3c2412_i2s_delay;
750
drv->suspend = s3c2412_i2s_suspend;
751
drv->resume = s3c2412_i2s_resume;
753
return snd_soc_register_dai(dev, drv);
755
EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai);
757
MODULE_LICENSE("GPL");