aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChaithrika U S <chaithrika@ti.com>2009-06-05 06:28:40 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-06-07 15:10:01 -0400
commitb67f4487295560599f6cca55fb7e8773ff27f00a (patch)
tree52ab3ed13c0911a6c0aa0275a35c98630ed8a4e6
parent5204d49676dae3ae1f9dff5b60bf567d24680872 (diff)
ASoC: Add mcasp support for DM646x
Adds driver support for the two instances of McASP on TI's DM646x. The multichannel audio serial port (McASP) functions as a general-purpose audio serial port optimized for the needs of multichannel audio application. (http://www.ti.com/litv/pdf/spruer1b). There are two instances of McASP on DM646x. The McASP0 module includes up to 4 serializers that can be individually enabled to either transmit or receive in different modes. The McASP1 module is limited with only 1 pinned-out serializer that can be enabled to only transmit in DIT mode (neither receiving in any mode nor transmitting in either Burst or TDM mode is supported). McASP0 consists of transmit and receive sections that may operate synchronized, or completely independently with separate master clocks, bit clocks, and frame syncs, and using different transmit modes with different bit-stream formats. Signed-off-by: Steve Chen <schen@mvista.com> Signed-off-by: Pavel Kiryukhin <pkiryukhin@ru.mvista.com> Signed-off-by: Naresh Medisetty <naresh@ti.com> Signed-off-by: Chaithrika U S <chaithrika@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/davinci/Kconfig13
-rw-r--r--sound/soc/davinci/Makefile3
-rw-r--r--sound/soc/davinci/davinci-mcasp.c874
-rw-r--r--sound/soc/davinci/davinci-mcasp.h55
-rw-r--r--sound/soc/davinci/davinci-pcm.h18
5 files changed, 955 insertions, 8 deletions
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 411a710be660..6802dd5e4731 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -9,6 +9,9 @@ config SND_DAVINCI_SOC
9config SND_DAVINCI_SOC_I2S 9config SND_DAVINCI_SOC_I2S
10 tristate 10 tristate
11 11
12config SND_DAVINCI_SOC_MCASP
13 tristate
14
12config SND_DAVINCI_SOC_EVM 15config SND_DAVINCI_SOC_EVM
13 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM" 16 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM"
14 depends on SND_DAVINCI_SOC 17 depends on SND_DAVINCI_SOC
@@ -19,6 +22,16 @@ config SND_DAVINCI_SOC_EVM
19 Say Y if you want to add support for SoC audio on TI 22 Say Y if you want to add support for SoC audio on TI
20 DaVinci DM6446 or DM355 EVM platforms. 23 DaVinci DM6446 or DM355 EVM platforms.
21 24
25config SND_DM6467_SOC_EVM
26 tristate "SoC Audio support for DaVinci DM6467 EVM"
27 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM
28 select SND_DAVINCI_SOC_MCASP
29 select SND_SOC_TLV320AIC3X
30 select SND_SOC_SPDIF
31
32 help
33 Say Y if you want to add support for SoC audio on TI
34
22config SND_DAVINCI_SOC_SFFSDR 35config SND_DAVINCI_SOC_SFFSDR
23 tristate "SoC Audio support for SFFSDR" 36 tristate "SoC Audio support for SFFSDR"
24 depends on SND_DAVINCI_SOC && MACH_SFFSDR 37 depends on SND_DAVINCI_SOC && MACH_SFFSDR
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index ca8bae1fc3f6..67be54f3a3a5 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -1,13 +1,16 @@
1# DAVINCI Platform Support 1# DAVINCI Platform Support
2snd-soc-davinci-objs := davinci-pcm.o 2snd-soc-davinci-objs := davinci-pcm.o
3snd-soc-davinci-i2s-objs := davinci-i2s.o 3snd-soc-davinci-i2s-objs := davinci-i2s.o
4snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
4 5
5obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o 6obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
6obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o 7obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
8obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
7 9
8# DAVINCI Machine Support 10# DAVINCI Machine Support
9snd-soc-evm-objs := davinci-evm.o 11snd-soc-evm-objs := davinci-evm.o
10snd-soc-sffsdr-objs := davinci-sffsdr.o 12snd-soc-sffsdr-objs := davinci-sffsdr.o
11 13
12obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o 14obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
15obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o
13obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o 16obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
new file mode 100644
index 000000000000..b27aab60ece3
--- /dev/null
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -0,0 +1,874 @@
1/*
2 * ALSA SoC McASP Audio Layer for TI DAVINCI processor
3 *
4 * Multi-channel Audio Serial Port Driver
5 *
6 * Author: Nirmal Pandey <n-pandey@ti.com>,
7 * Suresh Rajashekara <suresh.r@ti.com>
8 * Steve Chen <schen@.mvista.com>
9 *
10 * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
11 * Copyright: (C) 2009 Texas Instruments, India
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/io.h>
23#include <linux/clk.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include "davinci-pcm.h"
32#include "davinci-mcasp.h"
33
34/*
35 * McASP register definitions
36 */
37#define DAVINCI_MCASP_PID_REG 0x00
38#define DAVINCI_MCASP_PWREMUMGT_REG 0x04
39
40#define DAVINCI_MCASP_PFUNC_REG 0x10
41#define DAVINCI_MCASP_PDIR_REG 0x14
42#define DAVINCI_MCASP_PDOUT_REG 0x18
43#define DAVINCI_MCASP_PDSET_REG 0x1c
44
45#define DAVINCI_MCASP_PDCLR_REG 0x20
46
47#define DAVINCI_MCASP_TLGC_REG 0x30
48#define DAVINCI_MCASP_TLMR_REG 0x34
49
50#define DAVINCI_MCASP_GBLCTL_REG 0x44
51#define DAVINCI_MCASP_AMUTE_REG 0x48
52#define DAVINCI_MCASP_LBCTL_REG 0x4c
53
54#define DAVINCI_MCASP_TXDITCTL_REG 0x50
55
56#define DAVINCI_MCASP_GBLCTLR_REG 0x60
57#define DAVINCI_MCASP_RXMASK_REG 0x64
58#define DAVINCI_MCASP_RXFMT_REG 0x68
59#define DAVINCI_MCASP_RXFMCTL_REG 0x6c
60
61#define DAVINCI_MCASP_ACLKRCTL_REG 0x70
62#define DAVINCI_MCASP_AHCLKRCTL_REG 0x74
63#define DAVINCI_MCASP_RXTDM_REG 0x78
64#define DAVINCI_MCASP_EVTCTLR_REG 0x7c
65
66#define DAVINCI_MCASP_RXSTAT_REG 0x80
67#define DAVINCI_MCASP_RXTDMSLOT_REG 0x84
68#define DAVINCI_MCASP_RXCLKCHK_REG 0x88
69#define DAVINCI_MCASP_REVTCTL_REG 0x8c
70
71#define DAVINCI_MCASP_GBLCTLX_REG 0xa0
72#define DAVINCI_MCASP_TXMASK_REG 0xa4
73#define DAVINCI_MCASP_TXFMT_REG 0xa8
74#define DAVINCI_MCASP_TXFMCTL_REG 0xac
75
76#define DAVINCI_MCASP_ACLKXCTL_REG 0xb0
77#define DAVINCI_MCASP_AHCLKXCTL_REG 0xb4
78#define DAVINCI_MCASP_TXTDM_REG 0xb8
79#define DAVINCI_MCASP_EVTCTLX_REG 0xbc
80
81#define DAVINCI_MCASP_TXSTAT_REG 0xc0
82#define DAVINCI_MCASP_TXTDMSLOT_REG 0xc4
83#define DAVINCI_MCASP_TXCLKCHK_REG 0xc8
84#define DAVINCI_MCASP_XEVTCTL_REG 0xcc
85
86/* Left(even TDM Slot) Channel Status Register File */
87#define DAVINCI_MCASP_DITCSRA_REG 0x100
88/* Right(odd TDM slot) Channel Status Register File */
89#define DAVINCI_MCASP_DITCSRB_REG 0x118
90/* Left(even TDM slot) User Data Register File */
91#define DAVINCI_MCASP_DITUDRA_REG 0x130
92/* Right(odd TDM Slot) User Data Register File */
93#define DAVINCI_MCASP_DITUDRB_REG 0x148
94
95/* Serializer n Control Register */
96#define DAVINCI_MCASP_XRSRCTL_BASE_REG 0x180
97#define DAVINCI_MCASP_XRSRCTL_REG(n) (DAVINCI_MCASP_XRSRCTL_BASE_REG + \
98 (n << 2))
99
100/* Transmit Buffer for Serializer n */
101#define DAVINCI_MCASP_TXBUF_REG 0x200
102/* Receive Buffer for Serializer n */
103#define DAVINCI_MCASP_RXBUF_REG 0x280
104
105
106/*
107 * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
108 * Register Bits
109 */
110#define MCASP_FREE BIT(0)
111#define MCASP_SOFT BIT(1)
112
113/*
114 * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits
115 */
116#define AXR(n) (1<<n)
117#define PFUNC_AMUTE BIT(25)
118#define ACLKX BIT(26)
119#define AHCLKX BIT(27)
120#define AFSX BIT(28)
121#define ACLKR BIT(29)
122#define AHCLKR BIT(30)
123#define AFSR BIT(31)
124
125/*
126 * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits
127 */
128#define AXR(n) (1<<n)
129#define PDIR_AMUTE BIT(25)
130#define ACLKX BIT(26)
131#define AHCLKX BIT(27)
132#define AFSX BIT(28)
133#define ACLKR BIT(29)
134#define AHCLKR BIT(30)
135#define AFSR BIT(31)
136
137/*
138 * DAVINCI_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits
139 */
140#define DITEN BIT(0) /* Transmit DIT mode enable/disable */
141#define VA BIT(2)
142#define VB BIT(3)
143
144/*
145 * DAVINCI_MCASP_TXFMT_REG - Transmit Bitstream Format Register Bits
146 */
147#define TXROT(val) (val)
148#define TXSEL BIT(3)
149#define TXSSZ(val) (val<<4)
150#define TXPBIT(val) (val<<8)
151#define TXPAD(val) (val<<13)
152#define TXORD BIT(15)
153#define FSXDLY(val) (val<<16)
154
155/*
156 * DAVINCI_MCASP_RXFMT_REG - Receive Bitstream Format Register Bits
157 */
158#define RXROT(val) (val)
159#define RXSEL BIT(3)
160#define RXSSZ(val) (val<<4)
161#define RXPBIT(val) (val<<8)
162#define RXPAD(val) (val<<13)
163#define RXORD BIT(15)
164#define FSRDLY(val) (val<<16)
165
166/*
167 * DAVINCI_MCASP_TXFMCTL_REG - Transmit Frame Control Register Bits
168 */
169#define FSXPOL BIT(0)
170#define AFSXE BIT(1)
171#define FSXDUR BIT(4)
172#define FSXMOD(val) (val<<7)
173
174/*
175 * DAVINCI_MCASP_RXFMCTL_REG - Receive Frame Control Register Bits
176 */
177#define FSRPOL BIT(0)
178#define AFSRE BIT(1)
179#define FSRDUR BIT(4)
180#define FSRMOD(val) (val<<7)
181
182/*
183 * DAVINCI_MCASP_ACLKXCTL_REG - Transmit Clock Control Register Bits
184 */
185#define ACLKXDIV(val) (val)
186#define ACLKXE BIT(5)
187#define TX_ASYNC BIT(6)
188#define ACLKXPOL BIT(7)
189
190/*
191 * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits
192 */
193#define ACLKRDIV(val) (val)
194#define ACLKRE BIT(5)
195#define RX_ASYNC BIT(6)
196#define ACLKRPOL BIT(7)
197
198/*
199 * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control
200 * Register Bits
201 */
202#define AHCLKXDIV(val) (val)
203#define AHCLKXPOL BIT(14)
204#define AHCLKXE BIT(15)
205
206/*
207 * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control
208 * Register Bits
209 */
210#define AHCLKRDIV(val) (val)
211#define AHCLKRPOL BIT(14)
212#define AHCLKRE BIT(15)
213
214/*
215 * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits
216 */
217#define MODE(val) (val)
218#define DISMOD (val)(val<<2)
219#define TXSTATE BIT(4)
220#define RXSTATE BIT(5)
221
222/*
223 * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits
224 */
225#define LBEN BIT(0)
226#define LBORD BIT(1)
227#define LBGENMODE(val) (val<<2)
228
229/*
230 * DAVINCI_MCASP_TXTDMSLOT_REG - Transmit TDM Slot Register configuration
231 */
232#define TXTDMS(n) (1<<n)
233
234/*
235 * DAVINCI_MCASP_RXTDMSLOT_REG - Receive TDM Slot Register configuration
236 */
237#define RXTDMS(n) (1<<n)
238
239/*
240 * DAVINCI_MCASP_GBLCTL_REG - Global Control Register Bits
241 */
242#define RXCLKRST BIT(0) /* Receiver Clock Divider Reset */
243#define RXHCLKRST BIT(1) /* Receiver High Frequency Clock Divider */
244#define RXSERCLR BIT(2) /* Receiver Serializer Clear */
245#define RXSMRST BIT(3) /* Receiver State Machine Reset */
246#define RXFSRST BIT(4) /* Frame Sync Generator Reset */
247#define TXCLKRST BIT(8) /* Transmitter Clock Divider Reset */
248#define TXHCLKRST BIT(9) /* Transmitter High Frequency Clock Divider*/
249#define TXSERCLR BIT(10) /* Transmit Serializer Clear */
250#define TXSMRST BIT(11) /* Transmitter State Machine Reset */
251#define TXFSRST BIT(12) /* Frame Sync Generator Reset */
252
253/*
254 * DAVINCI_MCASP_AMUTE_REG - Mute Control Register Bits
255 */
256#define MUTENA(val) (val)
257#define MUTEINPOL BIT(2)
258#define MUTEINENA BIT(3)
259#define MUTEIN BIT(4)
260#define MUTER BIT(5)
261#define MUTEX BIT(6)
262#define MUTEFSR BIT(7)
263#define MUTEFSX BIT(8)
264#define MUTEBADCLKR BIT(9)
265#define MUTEBADCLKX BIT(10)
266#define MUTERXDMAERR BIT(11)
267#define MUTETXDMAERR BIT(12)
268
269/*
270 * DAVINCI_MCASP_REVTCTL_REG - Receiver DMA Event Control Register bits
271 */
272#define RXDATADMADIS BIT(0)
273
274/*
275 * DAVINCI_MCASP_XEVTCTL_REG - Transmitter DMA Event Control Register bits
276 */
277#define TXDATADMADIS BIT(0)
278
279#define DAVINCI_MCASP_NUM_SERIALIZER 16
280
281static inline void mcasp_set_bits(void __iomem *reg, u32 val)
282{
283 __raw_writel(__raw_readl(reg) | val, reg);
284}
285
286static inline void mcasp_clr_bits(void __iomem *reg, u32 val)
287{
288 __raw_writel((__raw_readl(reg) & ~(val)), reg);
289}
290
291static inline void mcasp_mod_bits(void __iomem *reg, u32 val, u32 mask)
292{
293 __raw_writel((__raw_readl(reg) & ~mask) | val, reg);
294}
295
296static inline void mcasp_set_reg(void __iomem *reg, u32 val)
297{
298 __raw_writel(val, reg);
299}
300
301static inline u32 mcasp_get_reg(void __iomem *reg)
302{
303 return (unsigned int)__raw_readl(reg);
304}
305
306static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
307{
308 int i = 0;
309
310 mcasp_set_bits(regs, val);
311
312 /* programming GBLCTL needs to read back from GBLCTL and verfiy */
313 /* loop count is to avoid the lock-up */
314 for (i = 0; i < 1000; i++) {
315 if ((mcasp_get_reg(regs) & val) == val)
316 break;
317 }
318
319 if (i == 1000 && ((mcasp_get_reg(regs) & val) != val))
320 printk(KERN_ERR "GBLCTL write error\n");
321}
322
323static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
324 struct snd_soc_dai *cpu_dai)
325{
326 struct davinci_audio_dev *dev = cpu_dai->private_data;
327 cpu_dai->dma_data = dev->dma_params[substream->stream];
328 return 0;
329}
330
331static void mcasp_start_rx(struct davinci_audio_dev *dev)
332{
333 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
334 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST);
335 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR);
336 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
337
338 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
339 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
340 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
341
342 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
343 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
344}
345
346static void mcasp_start_tx(struct davinci_audio_dev *dev)
347{
348 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
349 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
350 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
351 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
352
353 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
354 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
355 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
356 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
357}
358
359static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
360{
361 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
362 mcasp_start_tx(dev);
363 else
364 mcasp_start_rx(dev);
365}
366
367static void mcasp_stop_rx(struct davinci_audio_dev *dev)
368{
369 mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, 0);
370 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
371}
372
373static void mcasp_stop_tx(struct davinci_audio_dev *dev)
374{
375 mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, 0);
376 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
377}
378
379static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
380{
381 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
382 mcasp_stop_tx(dev);
383 else
384 mcasp_stop_rx(dev);
385}
386
387static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
388 unsigned int fmt)
389{
390 struct davinci_audio_dev *dev = cpu_dai->private_data;
391 void __iomem *base = dev->base;
392
393 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
394 case SND_SOC_DAIFMT_CBS_CFS:
395 /* codec is clock and frame slave */
396 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
397 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
398
399 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
400 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
401
402 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x7 << 26));
403 break;
404
405 case SND_SOC_DAIFMT_CBM_CFM:
406 /* codec is clock and frame master */
407 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
408 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
409
410 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
411 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
412
413 mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, (0x3f << 26));
414 break;
415
416 default:
417 return -EINVAL;
418 }
419
420 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
421 case SND_SOC_DAIFMT_IB_NF:
422 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
423 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
424
425 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
426 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
427 break;
428
429 case SND_SOC_DAIFMT_NB_IF:
430 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
431 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
432
433 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
434 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
435 break;
436
437 case SND_SOC_DAIFMT_IB_IF:
438 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
439 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
440
441 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
442 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
443 break;
444
445 case SND_SOC_DAIFMT_NB_NF:
446 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
447 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
448
449 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
450 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
451 break;
452
453 default:
454 return -EINVAL;
455 }
456
457 return 0;
458}
459
460static int davinci_config_channel_size(struct davinci_audio_dev *dev,
461 int channel_size)
462{
463 u32 fmt = 0;
464
465 switch (channel_size) {
466 case DAVINCI_AUDIO_WORD_8:
467 fmt = 0x03;
468 break;
469
470 case DAVINCI_AUDIO_WORD_12:
471 fmt = 0x05;
472 break;
473
474 case DAVINCI_AUDIO_WORD_16:
475 fmt = 0x07;
476 break;
477
478 case DAVINCI_AUDIO_WORD_20:
479 fmt = 0x09;
480 break;
481
482 case DAVINCI_AUDIO_WORD_24:
483 fmt = 0x0B;
484 break;
485
486 case DAVINCI_AUDIO_WORD_28:
487 fmt = 0x0D;
488 break;
489
490 case DAVINCI_AUDIO_WORD_32:
491 fmt = 0x0F;
492 break;
493
494 default:
495 return -EINVAL;
496 }
497
498 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
499 RXSSZ(fmt), RXSSZ(0x0F));
500 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
501 TXSSZ(fmt), TXSSZ(0x0F));
502 return 0;
503}
504
505static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
506{
507 int i;
508
509 /* Default configuration */
510 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
511
512 /* All PINS as McASP */
513 mcasp_set_reg(dev->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000);
514
515 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
516 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
517 mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG,
518 TXDATADMADIS);
519 } else {
520 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
521 mcasp_clr_bits(dev->base + DAVINCI_MCASP_REVTCTL_REG,
522 RXDATADMADIS);
523 }
524
525 for (i = 0; i < dev->num_serializer; i++) {
526 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
527 dev->serial_dir[i]);
528 if (dev->serial_dir[i] == TX_MODE)
529 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
530 AXR(i));
531 else if (dev->serial_dir[i] == RX_MODE)
532 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
533 AXR(i));
534 }
535}
536
537static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
538{
539 int i, active_slots;
540 u32 mask = 0;
541
542 active_slots = (dev->tdm_slots > 31) ? 32 : dev->tdm_slots;
543 for (i = 0; i < active_slots; i++)
544 mask |= (1 << i);
545
546 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
547 /* bit stream is MSB first with no delay */
548 /* DSP_B mode */
549 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
550 AHCLKXE);
551 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
552 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
553
554 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32))
555 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
556 FSXMOD(dev->tdm_slots), FSXMOD(0x1FF));
557 else
558 printk(KERN_ERR "playback tdm slot %d not supported\n",
559 dev->tdm_slots);
560
561 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0xFFFFFFFF);
562 mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
563 } else {
564 /* bit stream is MSB first with no delay */
565 /* DSP_B mode */
566 mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD);
567 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
568 AHCLKRE);
569 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask);
570
571 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32))
572 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG,
573 FSRMOD(dev->tdm_slots), FSRMOD(0x1FF));
574 else
575 printk(KERN_ERR "capture tdm slot %d not supported\n",
576 dev->tdm_slots);
577
578 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, 0xFFFFFFFF);
579 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
580 }
581}
582
583/* S/PDIF */
584static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
585{
586 /* Set the PDIR for Serialiser as output */
587 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);
588
589 /* TXMASK for 24 bits */
590 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);
591
592 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
593 and LSB first */
594 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
595 TXROT(6) | TXSSZ(15));
596
597 /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
598 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
599 AFSXE | FSXMOD(0x180));
600
601 /* Set the TX tdm : for all the slots */
602 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);
603
604 /* Set the TX clock controls : div = 1 and internal */
605 mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
606 ACLKXE | TX_ASYNC);
607
608 mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
609
610 /* Only 44100 and 48000 are valid, both have the same setting */
611 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3));
612
613 /* Enable the DIT */
614 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXDITCTL_REG, DITEN);
615}
616
617static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
618 struct snd_pcm_hw_params *params,
619 struct snd_soc_dai *cpu_dai)
620{
621 struct davinci_audio_dev *dev = cpu_dai->private_data;
622 struct davinci_pcm_dma_params *dma_params =
623 dev->dma_params[substream->stream];
624 int word_length;
625
626 davinci_hw_common_param(dev, substream->stream);
627
628 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
629 davinci_hw_dit_param(dev);
630 else
631 davinci_hw_param(dev, substream->stream);
632
633 switch (params_format(params)) {
634 case SNDRV_PCM_FORMAT_S8:
635 dma_params->data_type = 1;
636 word_length = DAVINCI_AUDIO_WORD_8;
637 break;
638
639 case SNDRV_PCM_FORMAT_S16_LE:
640 dma_params->data_type = 2;
641 word_length = DAVINCI_AUDIO_WORD_16;
642 break;
643
644 case SNDRV_PCM_FORMAT_S32_LE:
645 dma_params->data_type = 4;
646 word_length = DAVINCI_AUDIO_WORD_32;
647 break;
648
649 default:
650 printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
651 return -EINVAL;
652 }
653 davinci_config_channel_size(dev, word_length);
654
655 return 0;
656}
657
658static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
659 int cmd, struct snd_soc_dai *cpu_dai)
660{
661 struct snd_soc_pcm_runtime *rtd = substream->private_data;
662 struct davinci_audio_dev *dev = rtd->dai->cpu_dai->private_data;
663 int ret = 0;
664
665 switch (cmd) {
666 case SNDRV_PCM_TRIGGER_START:
667 case SNDRV_PCM_TRIGGER_RESUME:
668 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
669 davinci_mcasp_start(dev, substream->stream);
670 break;
671
672 case SNDRV_PCM_TRIGGER_STOP:
673 case SNDRV_PCM_TRIGGER_SUSPEND:
674 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
675 davinci_mcasp_stop(dev, substream->stream);
676 break;
677
678 default:
679 ret = -EINVAL;
680 }
681
682 return ret;
683}
684
685static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
686 .startup = davinci_mcasp_startup,
687 .trigger = davinci_mcasp_trigger,
688 .hw_params = davinci_mcasp_hw_params,
689 .set_fmt = davinci_mcasp_set_dai_fmt,
690
691};
692
693struct snd_soc_dai davinci_mcasp_dai[] = {
694 {
695 .name = "davinci-i2s",
696 .id = 0,
697 .playback = {
698 .channels_min = 2,
699 .channels_max = 2,
700 .rates = DAVINCI_MCASP_RATES,
701 .formats = SNDRV_PCM_FMTBIT_S8 |
702 SNDRV_PCM_FMTBIT_S16_LE |
703 SNDRV_PCM_FMTBIT_S32_LE,
704 },
705 .capture = {
706 .channels_min = 2,
707 .channels_max = 2,
708 .rates = DAVINCI_MCASP_RATES,
709 .formats = SNDRV_PCM_FMTBIT_S8 |
710 SNDRV_PCM_FMTBIT_S16_LE |
711 SNDRV_PCM_FMTBIT_S32_LE,
712 },
713 .ops = &davinci_mcasp_dai_ops,
714
715 },
716 {
717 .name = "davinci-dit",
718 .id = 1,
719 .playback = {
720 .channels_min = 1,
721 .channels_max = 384,
722 .rates = DAVINCI_MCASP_RATES,
723 .formats = SNDRV_PCM_FMTBIT_S16_LE,
724 },
725 .ops = &davinci_mcasp_dai_ops,
726 },
727
728};
729EXPORT_SYMBOL_GPL(davinci_mcasp_dai);
730
731static int davinci_mcasp_probe(struct platform_device *pdev)
732{
733 struct davinci_pcm_dma_params *dma_data;
734 struct resource *mem, *ioarea, *res;
735 struct snd_platform_data *pdata;
736 struct davinci_audio_dev *dev;
737 int count = 0;
738 int ret = 0;
739
740 dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
741 if (!dev)
742 return -ENOMEM;
743
744 dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
745 GFP_KERNEL);
746 if (!dma_data) {
747 ret = -ENOMEM;
748 goto err_release_dev;
749 }
750
751 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
752 if (!mem) {
753 dev_err(&pdev->dev, "no mem resource?\n");
754 ret = -ENODEV;
755 goto err_release_data;
756 }
757
758 ioarea = request_mem_region(mem->start,
759 (mem->end - mem->start) + 1, pdev->name);
760 if (!ioarea) {
761 dev_err(&pdev->dev, "Audio region already claimed\n");
762 ret = -EBUSY;
763 goto err_release_data;
764 }
765
766 pdata = pdev->dev.platform_data;
767 dev->clk = clk_get(&pdev->dev, pdata->clk_name);
768 if (IS_ERR(dev->clk)) {
769 ret = -ENODEV;
770 goto err_release_region;
771 }
772
773 clk_enable(dev->clk);
774
775 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
776 dev->op_mode = pdata->op_mode;
777 dev->tdm_slots = pdata->tdm_slots;
778 dev->num_serializer = pdata->num_serializer;
779 dev->serial_dir = pdata->serial_dir;
780 dev->codec_fmt = pdata->codec_fmt;
781
782 dma_data[count].name = "I2S PCM Stereo out";
783 dma_data[count].eventq_no = pdata->eventq_no;
784 dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
785 io_v2p(dev->base));
786 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
787
788 /* first TX, then RX */
789 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
790 if (!res) {
791 dev_err(&pdev->dev, "no DMA resource\n");
792 goto err_release_region;
793 }
794
795 dma_data[count].channel = res->start;
796 count++;
797 dma_data[count].name = "I2S PCM Stereo in";
798 dma_data[count].eventq_no = pdata->eventq_no;
799 dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
800 io_v2p(dev->base));
801 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
802
803 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
804 if (!res) {
805 dev_err(&pdev->dev, "no DMA resource\n");
806 goto err_release_region;
807 }
808
809 dma_data[count].channel = res->start;
810 davinci_mcasp_dai[pdev->id].private_data = dev;
811 davinci_mcasp_dai[pdev->id].dev = &pdev->dev;
812 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdev->id]);
813
814 if (ret != 0)
815 goto err_release_region;
816 return 0;
817
818err_release_region:
819 release_mem_region(mem->start, (mem->end - mem->start) + 1);
820err_release_data:
821 kfree(dma_data);
822err_release_dev:
823 kfree(dev);
824
825 return ret;
826}
827
828static int davinci_mcasp_remove(struct platform_device *pdev)
829{
830 struct davinci_pcm_dma_params *dma_data;
831 struct davinci_audio_dev *dev;
832 struct resource *mem;
833
834 snd_soc_unregister_dai(&davinci_mcasp_dai[pdev->id]);
835 dev = davinci_mcasp_dai[pdev->id].private_data;
836 clk_disable(dev->clk);
837 clk_put(dev->clk);
838 dev->clk = NULL;
839
840 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
841 release_mem_region(mem->start, (mem->end - mem->start) + 1);
842
843 dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
844 kfree(dma_data);
845 kfree(dev);
846
847 return 0;
848}
849
850static struct platform_driver davinci_mcasp_driver = {
851 .probe = davinci_mcasp_probe,
852 .remove = davinci_mcasp_remove,
853 .driver = {
854 .name = "davinci-mcasp",
855 .owner = THIS_MODULE,
856 },
857};
858
859static int __init davinci_mcasp_init(void)
860{
861 return platform_driver_register(&davinci_mcasp_driver);
862}
863module_init(davinci_mcasp_init);
864
865static void __exit davinci_mcasp_exit(void)
866{
867 platform_driver_unregister(&davinci_mcasp_driver);
868}
869module_exit(davinci_mcasp_exit);
870
871MODULE_AUTHOR("Steve Chen");
872MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
873MODULE_LICENSE("GPL");
874
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
new file mode 100644
index 000000000000..36b71047a06c
--- /dev/null
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -0,0 +1,55 @@
1/*
2 * ALSA SoC McASP Audio Layer for TI DAVINCI processor
3 *
4 * MCASP related definitions
5 *
6 * Author: Nirmal Pandey <n-pandey@ti.com>,
7 * Suresh Rajashekara <suresh.r@ti.com>
8 * Steve Chen <schen@.mvista.com>
9 *
10 * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
11 * Copyright: (C) 2009 Texas Instruments, India
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#ifndef DAVINCI_MCASP_H
19#define DAVINCI_MCASP_H
20
21#include <linux/io.h>
22#include <mach/asp.h>
23#include "davinci-pcm.h"
24
25extern struct snd_soc_dai davinci_mcasp_dai[];
26
27#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000
28#define DAVINCI_MCASP_I2S_DAI 0
29#define DAVINCI_MCASP_DIT_DAI 1
30
31enum {
32 DAVINCI_AUDIO_WORD_8 = 0,
33 DAVINCI_AUDIO_WORD_12,
34 DAVINCI_AUDIO_WORD_16,
35 DAVINCI_AUDIO_WORD_20,
36 DAVINCI_AUDIO_WORD_24,
37 DAVINCI_AUDIO_WORD_32,
38 DAVINCI_AUDIO_WORD_28, /* This is only valid for McASP */
39};
40
41struct davinci_audio_dev {
42 void __iomem *base;
43 int sample_rate;
44 struct clk *clk;
45 struct davinci_pcm_dma_params *dma_params[2];
46 unsigned int codec_fmt;
47
48 /* McASP specific data */
49 int tdm_slots;
50 u8 op_mode;
51 u8 num_serializer;
52 u8 *serial_dir;
53};
54
55#endif /* DAVINCI_MCASP_H */
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 62cb4eb07e34..eb4287faa3d5 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -12,17 +12,19 @@
12#ifndef _DAVINCI_PCM_H 12#ifndef _DAVINCI_PCM_H
13#define _DAVINCI_PCM_H 13#define _DAVINCI_PCM_H
14 14
15#include <mach/edma.h>
16#include <mach/asp.h>
17
18
15struct davinci_pcm_dma_params { 19struct davinci_pcm_dma_params {
16 char *name; /* stream identifier */ 20 char *name; /* stream identifier */
17 int channel; /* sync dma channel ID */ 21 int channel; /* sync dma channel ID */
18 dma_addr_t dma_addr; /* device physical address for DMA */ 22 dma_addr_t dma_addr; /* device physical address for DMA */
19 unsigned int data_type; /* xfer data type */ 23 enum dma_event_q eventq_no; /* event queue number */
24 unsigned char data_type; /* xfer data type */
25 unsigned char convert_mono_stereo;
20}; 26};
21 27
22struct evm_snd_platform_data {
23 int tx_dma_ch;
24 int rx_dma_ch;
25};
26 28
27extern struct snd_soc_platform davinci_soc_platform; 29extern struct snd_soc_platform davinci_soc_platform;
28 30