2 * ALSA SoC Synopsys I2S Audio Layer
4 * sound/soc/dwc/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_read_reg(dev
->i2s_base
, TOR(i
));
105 for (i
= 0; i
< 4; i
++)
106 i2s_read_reg(dev
->i2s_base
, ROR(i
));
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
:
214 case SIX_CHANNEL_SUPPORT
:
217 case FOUR_CHANNEL_SUPPORT
:
220 case TWO_CHANNEL_SUPPORT
:
224 dev_err(dev
->dev
, "channel not supported\n");
228 i2s_disable_channels(dev
, substream
->stream
);
230 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
231 i2s_write_reg(dev
->i2s_base
, TCR(ch_reg
), xfer_resolution
);
232 i2s_write_reg(dev
->i2s_base
, TFCR(ch_reg
), 0x02);
233 irq
= i2s_read_reg(dev
->i2s_base
, IMR(ch_reg
));
234 i2s_write_reg(dev
->i2s_base
, IMR(ch_reg
), irq
& ~0x30);
235 i2s_write_reg(dev
->i2s_base
, TER(ch_reg
), 1);
237 i2s_write_reg(dev
->i2s_base
, RCR(ch_reg
), xfer_resolution
);
238 i2s_write_reg(dev
->i2s_base
, RFCR(ch_reg
), 0x07);
239 irq
= i2s_read_reg(dev
->i2s_base
, IMR(ch_reg
));
240 i2s_write_reg(dev
->i2s_base
, IMR(ch_reg
), irq
& ~0x03);
241 i2s_write_reg(dev
->i2s_base
, RER(ch_reg
), 1);
244 i2s_write_reg(dev
->i2s_base
, CCR
, ccr
);
246 config
->sample_rate
= params_rate(params
);
248 if (!dev
->i2s_clk_cfg
)
251 ret
= dev
->i2s_clk_cfg(config
);
253 dev_err(dev
->dev
, "runtime audio clk config fail\n");
260 static void dw_i2s_shutdown(struct snd_pcm_substream
*substream
,
261 struct snd_soc_dai
*dai
)
263 snd_soc_dai_set_dma_data(dai
, substream
, NULL
);
266 static int dw_i2s_prepare(struct snd_pcm_substream
*substream
,
267 struct snd_soc_dai
*dai
)
269 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
271 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
272 i2s_write_reg(dev
->i2s_base
, TXFFR
, 1);
274 i2s_write_reg(dev
->i2s_base
, RXFFR
, 1);
279 static int dw_i2s_trigger(struct snd_pcm_substream
*substream
,
280 int cmd
, struct snd_soc_dai
*dai
)
282 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
286 case SNDRV_PCM_TRIGGER_START
:
287 case SNDRV_PCM_TRIGGER_RESUME
:
288 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
290 i2s_start(dev
, substream
);
293 case SNDRV_PCM_TRIGGER_STOP
:
294 case SNDRV_PCM_TRIGGER_SUSPEND
:
295 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
297 i2s_stop(dev
, substream
);
306 static struct snd_soc_dai_ops dw_i2s_dai_ops
= {
307 .startup
= dw_i2s_startup
,
308 .shutdown
= dw_i2s_shutdown
,
309 .hw_params
= dw_i2s_hw_params
,
310 .prepare
= dw_i2s_prepare
,
311 .trigger
= dw_i2s_trigger
,
314 static const struct snd_soc_component_driver dw_i2s_component
= {
320 static int dw_i2s_suspend(struct snd_soc_dai
*dai
)
322 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
324 clk_disable(dev
->clk
);
328 static int dw_i2s_resume(struct snd_soc_dai
*dai
)
330 struct dw_i2s_dev
*dev
= snd_soc_dai_get_drvdata(dai
);
332 clk_enable(dev
->clk
);
337 #define dw_i2s_suspend NULL
338 #define dw_i2s_resume NULL
341 static int dw_i2s_probe(struct platform_device
*pdev
)
343 const struct i2s_platform_data
*pdata
= pdev
->dev
.platform_data
;
344 struct dw_i2s_dev
*dev
;
345 struct resource
*res
;
348 struct snd_soc_dai_driver
*dw_i2s_dai
;
351 dev_err(&pdev
->dev
, "Invalid platform data\n");
355 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
357 dev_err(&pdev
->dev
, "no i2s resource defined\n");
361 if (!devm_request_mem_region(&pdev
->dev
, res
->start
,
362 resource_size(res
), pdev
->name
)) {
363 dev_err(&pdev
->dev
, "i2s region already claimed\n");
367 dev
= devm_kzalloc(&pdev
->dev
, sizeof(*dev
), GFP_KERNEL
);
369 dev_warn(&pdev
->dev
, "kzalloc fail\n");
373 dev
->i2s_base
= devm_ioremap(&pdev
->dev
, res
->start
,
375 if (!dev
->i2s_base
) {
376 dev_err(&pdev
->dev
, "ioremap fail for i2s_region\n");
381 dev
->capability
= cap
;
382 dev
->i2s_clk_cfg
= pdata
->i2s_clk_cfg
;
384 /* Set DMA slaves info */
386 dev
->play_dma_data
.data
= pdata
->play_dma_data
;
387 dev
->capture_dma_data
.data
= pdata
->capture_dma_data
;
388 dev
->play_dma_data
.addr
= res
->start
+ I2S_TXDMA
;
389 dev
->capture_dma_data
.addr
= res
->start
+ I2S_RXDMA
;
390 dev
->play_dma_data
.max_burst
= 16;
391 dev
->capture_dma_data
.max_burst
= 16;
392 dev
->play_dma_data
.addr_width
= DMA_SLAVE_BUSWIDTH_2_BYTES
;
393 dev
->capture_dma_data
.addr_width
= DMA_SLAVE_BUSWIDTH_2_BYTES
;
394 dev
->play_dma_data
.filter
= pdata
->filter
;
395 dev
->capture_dma_data
.filter
= pdata
->filter
;
397 dev
->clk
= clk_get(&pdev
->dev
, NULL
);
398 if (IS_ERR(dev
->clk
))
399 return PTR_ERR(dev
->clk
);
401 ret
= clk_enable(dev
->clk
);
405 dw_i2s_dai
= devm_kzalloc(&pdev
->dev
, sizeof(*dw_i2s_dai
), GFP_KERNEL
);
407 dev_err(&pdev
->dev
, "mem allocation failed for dai driver\n");
409 goto err_clk_disable
;
412 if (cap
& DWC_I2S_PLAY
) {
413 dev_dbg(&pdev
->dev
, " designware: play supported\n");
414 dw_i2s_dai
->playback
.channels_min
= MIN_CHANNEL_NUM
;
415 dw_i2s_dai
->playback
.channels_max
= pdata
->channel
;
416 dw_i2s_dai
->playback
.formats
= pdata
->snd_fmts
;
417 dw_i2s_dai
->playback
.rates
= pdata
->snd_rates
;
420 if (cap
& DWC_I2S_RECORD
) {
421 dev_dbg(&pdev
->dev
, "designware: record supported\n");
422 dw_i2s_dai
->capture
.channels_min
= MIN_CHANNEL_NUM
;
423 dw_i2s_dai
->capture
.channels_max
= pdata
->channel
;
424 dw_i2s_dai
->capture
.formats
= pdata
->snd_fmts
;
425 dw_i2s_dai
->capture
.rates
= pdata
->snd_rates
;
428 dw_i2s_dai
->ops
= &dw_i2s_dai_ops
;
429 dw_i2s_dai
->suspend
= dw_i2s_suspend
;
430 dw_i2s_dai
->resume
= dw_i2s_resume
;
432 dev
->dev
= &pdev
->dev
;
433 dev_set_drvdata(&pdev
->dev
, dev
);
434 ret
= snd_soc_register_component(&pdev
->dev
, &dw_i2s_component
,
437 dev_err(&pdev
->dev
, "not able to register dai\n");
438 goto err_clk_disable
;
444 clk_disable(dev
->clk
);
450 static int dw_i2s_remove(struct platform_device
*pdev
)
452 struct dw_i2s_dev
*dev
= dev_get_drvdata(&pdev
->dev
);
454 snd_soc_unregister_component(&pdev
->dev
);
461 static struct platform_driver dw_i2s_driver
= {
462 .probe
= dw_i2s_probe
,
463 .remove
= dw_i2s_remove
,
465 .name
= "designware-i2s",
466 .owner
= THIS_MODULE
,
470 module_platform_driver(dw_i2s_driver
);
472 MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
473 MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
474 MODULE_LICENSE("GPL");
475 MODULE_ALIAS("platform:designware_i2s");