2 * ALSA SoC Synopsys I2S Audio Layer
4 * sound/soc/spear/designware_i2s.c
6 * Copyright (C) 2010 ST Microelectronics
7 * Rajeev Kumar <rajeev-dlh.kumar@st.com>
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
14 #include <linux/clk.h>
15 #include <linux/device.h>
16 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/module.h>
20 #include <linux/slab.h>
21 #include <sound/designware_i2s.h>
22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h>
24 #include <sound/soc.h>
26 /* common register for all channel */
35 /* I2STxRxRegisters for all channels */
36 #define LRBR_LTHR(x) (0x40 * x + 0x020)
37 #define RRBR_RTHR(x) (0x40 * x + 0x024)
38 #define RER(x) (0x40 * x + 0x028)
39 #define TER(x) (0x40 * x + 0x02C)
40 #define RCR(x) (0x40 * x + 0x030)
41 #define TCR(x) (0x40 * x + 0x034)
42 #define ISR(x) (0x40 * x + 0x038)
43 #define IMR(x) (0x40 * x + 0x03C)
44 #define ROR(x) (0x40 * x + 0x040)
45 #define TOR(x) (0x40 * x + 0x044)
46 #define RFCR(x) (0x40 * x + 0x048)
47 #define TFCR(x) (0x40 * x + 0x04C)
48 #define RFF(x) (0x40 * x + 0x050)
49 #define TFF(x) (0x40 * x + 0x054)
51 /* I2SCOMPRegisters */
52 #define I2S_COMP_PARAM_2 0x01F0
53 #define I2S_COMP_PARAM_1 0x01F4
54 #define I2S_COMP_VERSION 0x01F8
55 #define I2S_COMP_TYPE 0x01FC
57 #define MAX_CHANNEL_NUM 8
58 #define MIN_CHANNEL_NUM 2
61 void __iomem
*i2s_base
;
64 unsigned int capability
;
67 /* data related to DMA transfers b/w i2s and DMAC */
68 struct i2s_dma_data play_dma_data
;
69 struct i2s_dma_data capture_dma_data
;
70 struct i2s_clk_config_data config
;
71 int (*i2s_clk_cfg
)(struct i2s_clk_config_data
*config
);
74 static inline void i2s_write_reg(void __iomem
*io_base
, int reg
, u32 val
)
76 writel(val
, io_base
+ reg
);
79 static inline u32
i2s_read_reg(void __iomem
*io_base
, int reg
)
81 return readl(io_base
+ reg
);
84 static inline void i2s_disable_channels(struct dw_i2s_dev
*dev
, u32 stream
)
88 if (stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
89 for (i
= 0; i
< 4; i
++)
90 i2s_write_reg(dev
->i2s_base
, TER(i
), 0);
92 for (i
= 0; i
< 4; i
++)
93 i2s_write_reg(dev
->i2s_base
, RER(i
), 0);
97 static inline void i2s_clear_irqs(struct dw_i2s_dev
*dev
, u32 stream
)
101 if (stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
102 for (i
= 0; i
< 4; i
++)
103 i2s_write_reg(dev
->i2s_base
, TOR(i
), 0);
105 for (i
= 0; i
< 4; i
++)
106 i2s_write_reg(dev
->i2s_base
, ROR(i
), 0);
110 static void i2s_start(struct dw_i2s_dev
*dev
,
111 struct snd_pcm_substream
*substream
)
114 i2s_write_reg(dev
->i2s_base
, IER
, 1);
116 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
117 i2s_write_reg(dev
->i2s_base
, ITER
, 1);
119 i2s_write_reg(dev
->i2s_base
, IRER
, 1);
121 i2s_write_reg(dev
->i2s_base
, CER
, 1);
124 static void i2s_stop(struct dw_i2s_dev
*dev
,
125 struct snd_pcm_substream
*substream
)
129 i2s_clear_irqs(dev
, substream
->stream
);
130 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
131 i2s_write_reg(dev
->i2s_base
, ITER
, 0);
133 for (i
= 0; i
< 4; i
++) {
134 irq
= i2s_read_reg(dev
->i2s_base
, IMR(i
));
135 i2s_write_reg(dev
->i2s_base
, IMR(i
), irq
| 0x30);
138 i2s_write_reg(dev
->i2s_base
, IRER
, 0);
140 for (i
= 0; i
< 4; i
++) {
141 irq
= i2s_read_reg(dev
->i2s_base
, IMR(i
));
142 i2s_write_reg(dev
->i2s_base
, IMR(i
), irq
| 0x03);
147 i2s_write_reg(dev
->i2s_base
, CER
, 0);
148 i2s_write_reg(dev
->i2s_base
, IER
, 0);
152 static int dw_i2s_startup(struct snd_pcm_substream
*substream
,
153 struct snd_soc_dai
*cpu_dai
)
155 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(cpu_dai
);
156 struct i2s_dma_data
*dma_data
= NULL
;
158 if (!(dev
->capability
& DWC_I2S_RECORD
) &&
159 (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
))
162 if (!(dev
->capability
& DWC_I2S_PLAY
) &&
163 (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
))
166 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
167 dma_data
= &dev
->play_dma_data
;
168 else if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
169 dma_data
= &dev
->capture_dma_data
;
171 snd_soc_dai_set_dma_data(cpu_dai
, substream
, (void *)dma_data
);
176 static int dw_i2s_hw_params(struct snd_pcm_substream
*substream
,
177 struct snd_pcm_hw_params
*params
, struct snd_soc_dai
*dai
)
179 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
180 struct i2s_clk_config_data
*config
= &dev
->config
;
181 u32 ccr
, xfer_resolution
, ch_reg
, irq
;
184 switch (params_format(params
)) {
185 case SNDRV_PCM_FORMAT_S16_LE
:
186 config
->data_width
= 16;
188 xfer_resolution
= 0x02;
191 case SNDRV_PCM_FORMAT_S24_LE
:
192 config
->data_width
= 24;
194 xfer_resolution
= 0x04;
197 case SNDRV_PCM_FORMAT_S32_LE
:
198 config
->data_width
= 32;
200 xfer_resolution
= 0x05;
204 dev_err(dev
->dev
, "designware-i2s: unsuppted PCM fmt");
208 config
->chan_nr
= params_channels(params
);
210 switch (config
->chan_nr
) {
211 case EIGHT_CHANNEL_SUPPORT
:
213 case SIX_CHANNEL_SUPPORT
:
215 case FOUR_CHANNEL_SUPPORT
:
217 case TWO_CHANNEL_SUPPORT
:
221 dev_err(dev
->dev
, "channel not supported\n");
224 i2s_disable_channels(dev
, substream
->stream
);
226 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
227 i2s_write_reg(dev
->i2s_base
, TCR(ch_reg
), xfer_resolution
);
228 i2s_write_reg(dev
->i2s_base
, TFCR(ch_reg
), 0x02);
229 irq
= i2s_read_reg(dev
->i2s_base
, IMR(ch_reg
));
230 i2s_write_reg(dev
->i2s_base
, IMR(ch_reg
), irq
& ~0x30);
231 i2s_write_reg(dev
->i2s_base
, TER(ch_reg
), 1);
233 i2s_write_reg(dev
->i2s_base
, RCR(ch_reg
), xfer_resolution
);
234 i2s_write_reg(dev
->i2s_base
, RFCR(ch_reg
), 0x07);
235 irq
= i2s_read_reg(dev
->i2s_base
, IMR(ch_reg
));
236 i2s_write_reg(dev
->i2s_base
, IMR(ch_reg
), irq
& ~0x03);
237 i2s_write_reg(dev
->i2s_base
, RER(ch_reg
), 1);
240 i2s_write_reg(dev
->i2s_base
, CCR
, ccr
);
242 config
->sample_rate
= params_rate(params
);
244 if (!dev
->i2s_clk_cfg
)
247 ret
= dev
->i2s_clk_cfg(config
);
249 dev_err(dev
->dev
, "runtime audio clk config fail\n");
256 static void dw_i2s_shutdown(struct snd_pcm_substream
*substream
,
257 struct snd_soc_dai
*dai
)
259 snd_soc_dai_set_dma_data(dai
, substream
, NULL
);
262 static int dw_i2s_trigger(struct snd_pcm_substream
*substream
,
263 int cmd
, struct snd_soc_dai
*dai
)
265 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
269 case SNDRV_PCM_TRIGGER_START
:
270 case SNDRV_PCM_TRIGGER_RESUME
:
271 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
273 i2s_start(dev
, substream
);
276 case SNDRV_PCM_TRIGGER_STOP
:
277 case SNDRV_PCM_TRIGGER_SUSPEND
:
278 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
280 i2s_stop(dev
, substream
);
289 static struct snd_soc_dai_ops dw_i2s_dai_ops
= {
290 .startup
= dw_i2s_startup
,
291 .shutdown
= dw_i2s_shutdown
,
292 .hw_params
= dw_i2s_hw_params
,
293 .trigger
= dw_i2s_trigger
,
298 static int dw_i2s_suspend(struct snd_soc_dai
*dai
)
300 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
302 clk_disable(dev
->clk
);
306 static int dw_i2s_resume(struct snd_soc_dai
*dai
)
308 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
310 clk_enable(dev
->clk
);
315 #define dw_i2s_suspend NULL
316 #define dw_i2s_resume NULL
319 static int dw_i2s_probe(struct platform_device
*pdev
)
321 const struct i2s_platform_data
*pdata
= pdev
->dev
.platform_data
;
322 struct dw_i2s_dev
*dev
;
323 struct resource
*res
;
326 struct snd_soc_dai_driver
*dw_i2s_dai
;
329 dev_err(&pdev
->dev
, "Invalid platform data\n");
333 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
335 dev_err(&pdev
->dev
, "no i2s resource defined\n");
339 if (!devm_request_mem_region(&pdev
->dev
, res
->start
,
340 resource_size(res
), pdev
->name
)) {
341 dev_err(&pdev
->dev
, "i2s region already claimed\n");
345 dev
= devm_kzalloc(&pdev
->dev
, sizeof(*dev
), GFP_KERNEL
);
347 dev_warn(&pdev
->dev
, "kzalloc fail\n");
351 dev
->i2s_base
= devm_ioremap(&pdev
->dev
, res
->start
,
353 if (!dev
->i2s_base
) {
354 dev_err(&pdev
->dev
, "ioremap fail for i2s_region\n");
359 dev
->capability
= cap
;
360 dev
->i2s_clk_cfg
= pdata
->i2s_clk_cfg
;
362 /* Set DMA slaves info */
364 dev
->play_dma_data
.data
= pdata
->play_dma_data
;
365 dev
->capture_dma_data
.data
= pdata
->capture_dma_data
;
366 dev
->play_dma_data
.addr
= res
->start
+ I2S_TXDMA
;
367 dev
->capture_dma_data
.addr
= res
->start
+ I2S_RXDMA
;
368 dev
->play_dma_data
.max_burst
= 16;
369 dev
->capture_dma_data
.max_burst
= 16;
370 dev
->play_dma_data
.addr_width
= DMA_SLAVE_BUSWIDTH_2_BYTES
;
371 dev
->capture_dma_data
.addr_width
= DMA_SLAVE_BUSWIDTH_2_BYTES
;
372 dev
->play_dma_data
.filter
= pdata
->filter
;
373 dev
->capture_dma_data
.filter
= pdata
->filter
;
375 dev
->clk
= clk_get(&pdev
->dev
, NULL
);
376 if (IS_ERR(dev
->clk
))
377 return PTR_ERR(dev
->clk
);
379 ret
= clk_enable(dev
->clk
);
383 dw_i2s_dai
= devm_kzalloc(&pdev
->dev
, sizeof(*dw_i2s_dai
), GFP_KERNEL
);
385 dev_err(&pdev
->dev
, "mem allocation failed for dai driver\n");
387 goto err_clk_disable
;
390 if (cap
& DWC_I2S_PLAY
) {
391 dev_dbg(&pdev
->dev
, " SPEAr: play supported\n");
392 dw_i2s_dai
->playback
.channels_min
= MIN_CHANNEL_NUM
;
393 dw_i2s_dai
->playback
.channels_max
= pdata
->channel
;
394 dw_i2s_dai
->playback
.formats
= pdata
->snd_fmts
;
395 dw_i2s_dai
->playback
.rates
= pdata
->snd_rates
;
398 if (cap
& DWC_I2S_RECORD
) {
399 dev_dbg(&pdev
->dev
, "SPEAr: record supported\n");
400 dw_i2s_dai
->capture
.channels_min
= MIN_CHANNEL_NUM
;
401 dw_i2s_dai
->capture
.channels_max
= pdata
->channel
;
402 dw_i2s_dai
->capture
.formats
= pdata
->snd_fmts
;
403 dw_i2s_dai
->capture
.rates
= pdata
->snd_rates
;
406 dw_i2s_dai
->ops
= &dw_i2s_dai_ops
;
407 dw_i2s_dai
->suspend
= dw_i2s_suspend
;
408 dw_i2s_dai
->resume
= dw_i2s_resume
;
410 dev
->dev
= &pdev
->dev
;
411 dev_set_drvdata(&pdev
->dev
, dev
);
412 ret
= snd_soc_register_dai(&pdev
->dev
, dw_i2s_dai
);
414 dev_err(&pdev
->dev
, "not able to register dai\n");
415 goto err_set_drvdata
;
421 dev_set_drvdata(&pdev
->dev
, NULL
);
423 clk_disable(dev
->clk
);
429 static int dw_i2s_remove(struct platform_device
*pdev
)
431 struct dw_i2s_dev
*dev
= dev_get_drvdata(&pdev
->dev
);
433 snd_soc_unregister_dai(&pdev
->dev
);
434 dev_set_drvdata(&pdev
->dev
, NULL
);
441 static struct platform_driver dw_i2s_driver
= {
442 .probe
= dw_i2s_probe
,
443 .remove
= dw_i2s_remove
,
445 .name
= "designware-i2s",
446 .owner
= THIS_MODULE
,
450 module_platform_driver(dw_i2s_driver
);
452 MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
453 MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
454 MODULE_LICENSE("GPL");
455 MODULE_ALIAS("platform:designware_i2s");