aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r--sound/soc/davinci/Kconfig33
-rw-r--r--sound/soc/davinci/Makefile5
-rw-r--r--sound/soc/davinci/davinci-evm.c140
-rw-r--r--sound/soc/davinci/davinci-i2s.c340
-rw-r--r--sound/soc/davinci/davinci-mcasp.c973
-rw-r--r--sound/soc/davinci/davinci-mcasp.h60
-rw-r--r--sound/soc/davinci/davinci-pcm.c10
-rw-r--r--sound/soc/davinci/davinci-pcm.h19
8 files changed, 1373 insertions, 207 deletions
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 411a710be660..4dfd4ad9d90e 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
@@ -28,3 +41,23 @@ config SND_DAVINCI_SOC_SFFSDR
28 help 41 help
29 Say Y if you want to add support for SoC audio on 42 Say Y if you want to add support for SoC audio on
30 Lyrtech SFFSDR board. 43 Lyrtech SFFSDR board.
44
45config SND_DA830_SOC_EVM
46 tristate "SoC Audio support for DA830/OMAP-L137 EVM"
47 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM
48 select SND_DAVINCI_SOC_MCASP
49 select SND_SOC_TLV320AIC3X
50
51 help
52 Say Y if you want to add support for SoC audio on TI
53 DA830/OMAP-L137 EVM
54
55config SND_DA850_SOC_EVM
56 tristate "SoC Audio support for DA850/OMAP-L138 EVM"
57 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM
58 select SND_DAVINCI_SOC_MCASP
59 select SND_SOC_TLV320AIC3X
60 help
61 Say Y if you want to add support for SoC audio on TI
62 DA850/OMAP-L138 EVM
63
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index ca8bae1fc3f6..a6939d71b988 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -1,13 +1,18 @@
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
16obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o
17obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o
13obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o 18obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 58fd1cbedd88..67414f659405 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -14,6 +14,7 @@
14#include <linux/timer.h> 14#include <linux/timer.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/i2c.h>
17#include <sound/core.h> 18#include <sound/core.h>
18#include <sound/pcm.h> 19#include <sound/pcm.h>
19#include <sound/soc.h> 20#include <sound/soc.h>
@@ -27,9 +28,10 @@
27#include <mach/mux.h> 28#include <mach/mux.h>
28 29
29#include "../codecs/tlv320aic3x.h" 30#include "../codecs/tlv320aic3x.h"
31#include "../codecs/spdif_transciever.h"
30#include "davinci-pcm.h" 32#include "davinci-pcm.h"
31#include "davinci-i2s.h" 33#include "davinci-i2s.h"
32 34#include "davinci-mcasp.h"
33 35
34#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ 36#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
35 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) 37 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
@@ -43,7 +45,7 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
43 unsigned sysclk; 45 unsigned sysclk;
44 46
45 /* ASP1 on DM355 EVM is clocked by an external oscillator */ 47 /* ASP1 on DM355 EVM is clocked by an external oscillator */
46 if (machine_is_davinci_dm355_evm()) 48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm())
47 sysclk = 27000000; 49 sysclk = 27000000;
48 50
49 /* ASP0 in DM6446 EVM is clocked by U55, as configured by 51 /* ASP0 in DM6446 EVM is clocked by U55, as configured by
@@ -53,6 +55,10 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
53 else if (machine_is_davinci_evm()) 55 else if (machine_is_davinci_evm())
54 sysclk = 12288000; 56 sysclk = 12288000;
55 57
58 else if (machine_is_davinci_da830_evm() ||
59 machine_is_davinci_da850_evm())
60 sysclk = 24576000;
61
56 else 62 else
57 return -EINVAL; 63 return -EINVAL;
58 64
@@ -144,6 +150,32 @@ static struct snd_soc_dai_link evm_dai = {
144 .ops = &evm_ops, 150 .ops = &evm_ops,
145}; 151};
146 152
153static struct snd_soc_dai_link dm6467_evm_dai[] = {
154 {
155 .name = "TLV320AIC3X",
156 .stream_name = "AIC3X",
157 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_I2S_DAI],
158 .codec_dai = &aic3x_dai,
159 .init = evm_aic3x_init,
160 .ops = &evm_ops,
161 },
162 {
163 .name = "McASP",
164 .stream_name = "spdif",
165 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_DIT_DAI],
166 .codec_dai = &dit_stub_dai,
167 .ops = &evm_ops,
168 },
169};
170static struct snd_soc_dai_link da8xx_evm_dai = {
171 .name = "TLV320AIC3X",
172 .stream_name = "AIC3X",
173 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_I2S_DAI],
174 .codec_dai = &aic3x_dai,
175 .init = evm_aic3x_init,
176 .ops = &evm_ops,
177};
178
147/* davinci-evm audio machine driver */ 179/* davinci-evm audio machine driver */
148static struct snd_soc_card snd_soc_card_evm = { 180static struct snd_soc_card snd_soc_card_evm = {
149 .name = "DaVinci EVM", 181 .name = "DaVinci EVM",
@@ -152,73 +184,80 @@ static struct snd_soc_card snd_soc_card_evm = {
152 .num_links = 1, 184 .num_links = 1,
153}; 185};
154 186
155/* evm audio private data */ 187/* davinci dm6467 evm audio machine driver */
156static struct aic3x_setup_data evm_aic3x_setup = { 188static struct snd_soc_card dm6467_snd_soc_card_evm = {
157 .i2c_bus = 1, 189 .name = "DaVinci DM6467 EVM",
158 .i2c_address = 0x1b, 190 .platform = &davinci_soc_platform,
191 .dai_link = dm6467_evm_dai,
192 .num_links = ARRAY_SIZE(dm6467_evm_dai),
159}; 193};
160 194
195static struct snd_soc_card da830_snd_soc_card = {
196 .name = "DA830/OMAP-L137 EVM",
197 .dai_link = &da8xx_evm_dai,
198 .platform = &davinci_soc_platform,
199 .num_links = 1,
200};
201
202static struct snd_soc_card da850_snd_soc_card = {
203 .name = "DA850/OMAP-L138 EVM",
204 .dai_link = &da8xx_evm_dai,
205 .platform = &davinci_soc_platform,
206 .num_links = 1,
207};
208
209static struct aic3x_setup_data aic3x_setup;
210
161/* evm audio subsystem */ 211/* evm audio subsystem */
162static struct snd_soc_device evm_snd_devdata = { 212static struct snd_soc_device evm_snd_devdata = {
163 .card = &snd_soc_card_evm, 213 .card = &snd_soc_card_evm,
164 .codec_dev = &soc_codec_dev_aic3x, 214 .codec_dev = &soc_codec_dev_aic3x,
165 .codec_data = &evm_aic3x_setup, 215 .codec_data = &aic3x_setup,
166};
167
168/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
169static struct resource evm_snd_resources[] = {
170 {
171 .start = DAVINCI_ASP0_BASE,
172 .end = DAVINCI_ASP0_BASE + SZ_8K - 1,
173 .flags = IORESOURCE_MEM,
174 },
175}; 216};
176 217
177static struct evm_snd_platform_data evm_snd_data = { 218/* evm audio subsystem */
178 .tx_dma_ch = DAVINCI_DMA_ASP0_TX, 219static struct snd_soc_device dm6467_evm_snd_devdata = {
179 .rx_dma_ch = DAVINCI_DMA_ASP0_RX, 220 .card = &dm6467_snd_soc_card_evm,
221 .codec_dev = &soc_codec_dev_aic3x,
222 .codec_data = &aic3x_setup,
180}; 223};
181 224
182/* DM335 EVM uses ASP1; line-out is a stereo mini-jack */ 225/* evm audio subsystem */
183static struct resource dm335evm_snd_resources[] = { 226static struct snd_soc_device da830_evm_snd_devdata = {
184 { 227 .card = &da830_snd_soc_card,
185 .start = DAVINCI_ASP1_BASE, 228 .codec_dev = &soc_codec_dev_aic3x,
186 .end = DAVINCI_ASP1_BASE + SZ_8K - 1, 229 .codec_data = &aic3x_setup,
187 .flags = IORESOURCE_MEM,
188 },
189}; 230};
190 231
191static struct evm_snd_platform_data dm335evm_snd_data = { 232static struct snd_soc_device da850_evm_snd_devdata = {
192 .tx_dma_ch = DAVINCI_DMA_ASP1_TX, 233 .card = &da850_snd_soc_card,
193 .rx_dma_ch = DAVINCI_DMA_ASP1_RX, 234 .codec_dev = &soc_codec_dev_aic3x,
235 .codec_data = &aic3x_setup,
194}; 236};
195 237
196static struct platform_device *evm_snd_device; 238static struct platform_device *evm_snd_device;
197 239
198static int __init evm_init(void) 240static int __init evm_init(void)
199{ 241{
200 struct resource *resources; 242 struct snd_soc_device *evm_snd_dev_data;
201 unsigned num_resources;
202 struct evm_snd_platform_data *data;
203 int index; 243 int index;
204 int ret; 244 int ret;
205 245
206 if (machine_is_davinci_evm()) { 246 if (machine_is_davinci_evm()) {
207 davinci_cfg_reg(DM644X_MCBSP); 247 evm_snd_dev_data = &evm_snd_devdata;
208
209 resources = evm_snd_resources;
210 num_resources = ARRAY_SIZE(evm_snd_resources);
211 data = &evm_snd_data;
212 index = 0; 248 index = 0;
213 } else if (machine_is_davinci_dm355_evm()) { 249 } else if (machine_is_davinci_dm355_evm()) {
214 /* we don't use ASP1 IRQs, or we'd need to mux them ... */ 250 evm_snd_dev_data = &evm_snd_devdata;
215 davinci_cfg_reg(DM355_EVT8_ASP1_TX); 251 index = 1;
216 davinci_cfg_reg(DM355_EVT9_ASP1_RX); 252 } else if (machine_is_davinci_dm6467_evm()) {
217 253 evm_snd_dev_data = &dm6467_evm_snd_devdata;
218 resources = dm335evm_snd_resources; 254 index = 0;
219 num_resources = ARRAY_SIZE(dm335evm_snd_resources); 255 } else if (machine_is_davinci_da830_evm()) {
220 data = &dm335evm_snd_data; 256 evm_snd_dev_data = &da830_evm_snd_devdata;
221 index = 1; 257 index = 1;
258 } else if (machine_is_davinci_da850_evm()) {
259 evm_snd_dev_data = &da850_evm_snd_devdata;
260 index = 0;
222 } else 261 } else
223 return -EINVAL; 262 return -EINVAL;
224 263
@@ -226,17 +265,8 @@ static int __init evm_init(void)
226 if (!evm_snd_device) 265 if (!evm_snd_device)
227 return -ENOMEM; 266 return -ENOMEM;
228 267
229 platform_set_drvdata(evm_snd_device, &evm_snd_devdata); 268 platform_set_drvdata(evm_snd_device, evm_snd_dev_data);
230 evm_snd_devdata.dev = &evm_snd_device->dev; 269 evm_snd_dev_data->dev = &evm_snd_device->dev;
231 platform_device_add_data(evm_snd_device, data, sizeof(*data));
232
233 ret = platform_device_add_resources(evm_snd_device, resources,
234 num_resources);
235 if (ret) {
236 platform_device_put(evm_snd_device);
237 return ret;
238 }
239
240 ret = platform_device_add(evm_snd_device); 270 ret = platform_device_add(evm_snd_device);
241 if (ret) 271 if (ret)
242 platform_device_put(evm_snd_device); 272 platform_device_put(evm_snd_device);
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index b1ea52fc83c7..12a6c549ee6e 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -22,6 +22,8 @@
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24 24
25#include <mach/asp.h>
26
25#include "davinci-pcm.h" 27#include "davinci-pcm.h"
26 28
27 29
@@ -63,6 +65,7 @@
63#define DAVINCI_MCBSP_RCR_RWDLEN1(v) ((v) << 5) 65#define DAVINCI_MCBSP_RCR_RWDLEN1(v) ((v) << 5)
64#define DAVINCI_MCBSP_RCR_RFRLEN1(v) ((v) << 8) 66#define DAVINCI_MCBSP_RCR_RFRLEN1(v) ((v) << 8)
65#define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16) 67#define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16)
68#define DAVINCI_MCBSP_RCR_RFIG (1 << 18)
66#define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21) 69#define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21)
67 70
68#define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5) 71#define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5)
@@ -85,14 +88,6 @@
85#define DAVINCI_MCBSP_PCR_FSRM (1 << 10) 88#define DAVINCI_MCBSP_PCR_FSRM (1 << 10)
86#define DAVINCI_MCBSP_PCR_FSXM (1 << 11) 89#define DAVINCI_MCBSP_PCR_FSXM (1 << 11)
87 90
88#define MOD_REG_BIT(val, mask, set) do { \
89 if (set) { \
90 val |= mask; \
91 } else { \
92 val &= ~mask; \
93 } \
94} while (0)
95
96enum { 91enum {
97 DAVINCI_MCBSP_WORD_8 = 0, 92 DAVINCI_MCBSP_WORD_8 = 0,
98 DAVINCI_MCBSP_WORD_12, 93 DAVINCI_MCBSP_WORD_12,
@@ -112,6 +107,10 @@ static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
112 107
113struct davinci_mcbsp_dev { 108struct davinci_mcbsp_dev {
114 void __iomem *base; 109 void __iomem *base;
110#define MOD_DSP_A 0
111#define MOD_DSP_B 1
112 int mode;
113 u32 pcr;
115 struct clk *clk; 114 struct clk *clk;
116 struct davinci_pcm_dma_params *dma_params[2]; 115 struct davinci_pcm_dma_params *dma_params[2];
117}; 116};
@@ -127,96 +126,100 @@ static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg)
127 return __raw_readl(dev->base + reg); 126 return __raw_readl(dev->base + reg);
128} 127}
129 128
130static void davinci_mcbsp_start(struct snd_pcm_substream *substream) 129static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
130{
131 u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP;
132 /* The clock needs to toggle to complete reset.
133 * So, fake it by toggling the clk polarity.
134 */
135 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m);
136 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr);
137}
138
139static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
140 struct snd_pcm_substream *substream)
131{ 141{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
134 struct snd_soc_device *socdev = rtd->socdev; 143 struct snd_soc_device *socdev = rtd->socdev;
135 struct snd_soc_platform *platform = socdev->card->platform; 144 struct snd_soc_platform *platform = socdev->card->platform;
136 u32 w; 145 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
137 int ret; 146 u32 spcr;
138 147 u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
139 /* Start the sample generator and enable transmitter/receiver */ 148 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
140 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 149 if (spcr & mask) {
141 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1); 150 /* start off disabled */
142 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 151 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
152 spcr & ~mask);
153 toggle_clock(dev, playback);
154 }
155 if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
156 DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
157 /* Start the sample generator */
158 spcr |= DAVINCI_MCBSP_SPCR_GRST;
159 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
160 }
143 161
144 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 162 if (playback) {
145 /* Stop the DMA to avoid data loss */ 163 /* Stop the DMA to avoid data loss */
146 /* while the transmitter is out of reset to handle XSYNCERR */ 164 /* while the transmitter is out of reset to handle XSYNCERR */
147 if (platform->pcm_ops->trigger) { 165 if (platform->pcm_ops->trigger) {
148 ret = platform->pcm_ops->trigger(substream, 166 int ret = platform->pcm_ops->trigger(substream,
149 SNDRV_PCM_TRIGGER_STOP); 167 SNDRV_PCM_TRIGGER_STOP);
150 if (ret < 0) 168 if (ret < 0)
151 printk(KERN_DEBUG "Playback DMA stop failed\n"); 169 printk(KERN_DEBUG "Playback DMA stop failed\n");
152 } 170 }
153 171
154 /* Enable the transmitter */ 172 /* Enable the transmitter */
155 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 173 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
156 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1); 174 spcr |= DAVINCI_MCBSP_SPCR_XRST;
157 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 175 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
158 176
159 /* wait for any unexpected frame sync error to occur */ 177 /* wait for any unexpected frame sync error to occur */
160 udelay(100); 178 udelay(100);
161 179
162 /* Disable the transmitter to clear any outstanding XSYNCERR */ 180 /* Disable the transmitter to clear any outstanding XSYNCERR */
163 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 181 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
164 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0); 182 spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
165 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 183 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
184 toggle_clock(dev, playback);
166 185
167 /* Restart the DMA */ 186 /* Restart the DMA */
168 if (platform->pcm_ops->trigger) { 187 if (platform->pcm_ops->trigger) {
169 ret = platform->pcm_ops->trigger(substream, 188 int ret = platform->pcm_ops->trigger(substream,
170 SNDRV_PCM_TRIGGER_START); 189 SNDRV_PCM_TRIGGER_START);
171 if (ret < 0) 190 if (ret < 0)
172 printk(KERN_DEBUG "Playback DMA start failed\n"); 191 printk(KERN_DEBUG "Playback DMA start failed\n");
173 } 192 }
174 /* Enable the transmitter */
175 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
176 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
177 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
178
179 } else {
180
181 /* Enable the reciever */
182 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
183 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1);
184 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
185 } 193 }
186 194
195 /* Enable transmitter or receiver */
196 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
197 spcr |= mask;
187 198
188 /* Start frame sync */ 199 if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM)) {
189 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 200 /* Start frame sync */
190 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_FRST, 1); 201 spcr |= DAVINCI_MCBSP_SPCR_FRST;
191 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 202 }
203 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
192} 204}
193 205
194static void davinci_mcbsp_stop(struct snd_pcm_substream *substream) 206static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
195{ 207{
196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 208 u32 spcr;
197 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
198 u32 w;
199 209
200 /* Reset transmitter/receiver and sample rate/frame sync generators */ 210 /* Reset transmitter/receiver and sample rate/frame sync generators */
201 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 211 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
202 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST | 212 spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
203 DAVINCI_MCBSP_SPCR_FRST, 0); 213 spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST;
204 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 214 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
205 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0); 215 toggle_clock(dev, playback);
206 else
207 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 0);
208 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
209} 216}
210 217
211static int davinci_i2s_startup(struct snd_pcm_substream *substream, 218static int davinci_i2s_startup(struct snd_pcm_substream *substream,
212 struct snd_soc_dai *dai) 219 struct snd_soc_dai *cpu_dai)
213{ 220{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 221 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
215 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
216 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
217
218 cpu_dai->dma_data = dev->dma_params[substream->stream]; 222 cpu_dai->dma_data = dev->dma_params[substream->stream];
219
220 return 0; 223 return 0;
221} 224}
222 225
@@ -228,12 +231,11 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
228 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 231 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
229 unsigned int pcr; 232 unsigned int pcr;
230 unsigned int srgr; 233 unsigned int srgr;
231 unsigned int rcr;
232 unsigned int xcr;
233 srgr = DAVINCI_MCBSP_SRGR_FSGM | 234 srgr = DAVINCI_MCBSP_SRGR_FSGM |
234 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | 235 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
235 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1); 236 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
236 237
238 /* set master/slave audio interface */
237 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 239 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
238 case SND_SOC_DAIFMT_CBS_CFS: 240 case SND_SOC_DAIFMT_CBS_CFS:
239 /* cpu is master */ 241 /* cpu is master */
@@ -258,11 +260,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
258 return -EINVAL; 260 return -EINVAL;
259 } 261 }
260 262
261 rcr = DAVINCI_MCBSP_RCR_RFRLEN1(1); 263 /* interface format */
262 xcr = DAVINCI_MCBSP_XCR_XFIG | DAVINCI_MCBSP_XCR_XFRLEN1(1);
263 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 264 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
264 case SND_SOC_DAIFMT_DSP_B:
265 break;
266 case SND_SOC_DAIFMT_I2S: 265 case SND_SOC_DAIFMT_I2S:
267 /* Davinci doesn't support TRUE I2S, but some codecs will have 266 /* Davinci doesn't support TRUE I2S, but some codecs will have
268 * the left and right channels contiguous. This allows 267 * the left and right channels contiguous. This allows
@@ -282,8 +281,10 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
282 */ 281 */
283 fmt ^= SND_SOC_DAIFMT_NB_IF; 282 fmt ^= SND_SOC_DAIFMT_NB_IF;
284 case SND_SOC_DAIFMT_DSP_A: 283 case SND_SOC_DAIFMT_DSP_A:
285 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1); 284 dev->mode = MOD_DSP_A;
286 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1); 285 break;
286 case SND_SOC_DAIFMT_DSP_B:
287 dev->mode = MOD_DSP_B;
287 break; 288 break;
288 default: 289 default:
289 printk(KERN_ERR "%s:bad format\n", __func__); 290 printk(KERN_ERR "%s:bad format\n", __func__);
@@ -343,9 +344,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
343 return -EINVAL; 344 return -EINVAL;
344 } 345 }
345 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); 346 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
347 dev->pcr = pcr;
346 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); 348 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
347 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
348 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
349 return 0; 349 return 0;
350} 350}
351 351
@@ -353,31 +353,40 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
353 struct snd_pcm_hw_params *params, 353 struct snd_pcm_hw_params *params,
354 struct snd_soc_dai *dai) 354 struct snd_soc_dai *dai)
355{ 355{
356 struct snd_soc_pcm_runtime *rtd = substream->private_data; 356 struct davinci_pcm_dma_params *dma_params = dai->dma_data;
357 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; 357 struct davinci_mcbsp_dev *dev = dai->private_data;
358 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
359 struct snd_interval *i = NULL; 358 struct snd_interval *i = NULL;
360 int mcbsp_word_length; 359 int mcbsp_word_length;
361 u32 w; 360 unsigned int rcr, xcr, srgr;
361 u32 spcr;
362 362
363 /* general line settings */ 363 /* general line settings */
364 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 364 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
365 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 365 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
366 w |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE; 366 spcr |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
367 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 367 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
368 } else { 368 } else {
369 w |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE; 369 spcr |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
370 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 370 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
371 } 371 }
372 372
373 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); 373 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
374 w = DAVINCI_MCBSP_SRGR_FSGM; 374 srgr = DAVINCI_MCBSP_SRGR_FSGM;
375 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1); 375 srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1);
376 376
377 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS); 377 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
378 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1); 378 srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1);
379 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w); 379 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
380 380
381 rcr = DAVINCI_MCBSP_RCR_RFIG;
382 xcr = DAVINCI_MCBSP_XCR_XFIG;
383 if (dev->mode == MOD_DSP_B) {
384 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(0);
385 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(0);
386 } else {
387 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
388 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
389 }
381 /* Determine xfer data type */ 390 /* Determine xfer data type */
382 switch (params_format(params)) { 391 switch (params_format(params)) {
383 case SNDRV_PCM_FORMAT_S8: 392 case SNDRV_PCM_FORMAT_S8:
@@ -397,18 +406,31 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
397 return -EINVAL; 406 return -EINVAL;
398 } 407 }
399 408
400 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 409 dma_params->acnt = dma_params->data_type;
401 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG); 410 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1);
402 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 411 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1);
403 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1);
404 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w);
405 412
406 } else { 413 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
407 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG); 414 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
408 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | 415 xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
409 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1); 416 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length);
410 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w);
411 417
418 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
419 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
420 else
421 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
422 return 0;
423}
424
425static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
426 struct snd_soc_dai *dai)
427{
428 struct davinci_mcbsp_dev *dev = dai->private_data;
429 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
430 davinci_mcbsp_stop(dev, playback);
431 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) {
432 /* codec is master */
433 davinci_mcbsp_start(dev, substream);
412 } 434 }
413 return 0; 435 return 0;
414} 436}
@@ -416,35 +438,72 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
416static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 438static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
417 struct snd_soc_dai *dai) 439 struct snd_soc_dai *dai)
418{ 440{
441 struct davinci_mcbsp_dev *dev = dai->private_data;
419 int ret = 0; 442 int ret = 0;
443 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
444 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0)
445 return 0; /* return if codec is master */
420 446
421 switch (cmd) { 447 switch (cmd) {
422 case SNDRV_PCM_TRIGGER_START: 448 case SNDRV_PCM_TRIGGER_START:
423 case SNDRV_PCM_TRIGGER_RESUME: 449 case SNDRV_PCM_TRIGGER_RESUME:
424 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 450 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
425 davinci_mcbsp_start(substream); 451 davinci_mcbsp_start(dev, substream);
426 break; 452 break;
427 case SNDRV_PCM_TRIGGER_STOP: 453 case SNDRV_PCM_TRIGGER_STOP:
428 case SNDRV_PCM_TRIGGER_SUSPEND: 454 case SNDRV_PCM_TRIGGER_SUSPEND:
429 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 455 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
430 davinci_mcbsp_stop(substream); 456 davinci_mcbsp_stop(dev, playback);
431 break; 457 break;
432 default: 458 default:
433 ret = -EINVAL; 459 ret = -EINVAL;
434 } 460 }
435
436 return ret; 461 return ret;
437} 462}
438 463
439static int davinci_i2s_probe(struct platform_device *pdev, 464static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
440 struct snd_soc_dai *dai) 465 struct snd_soc_dai *dai)
466{
467 struct davinci_mcbsp_dev *dev = dai->private_data;
468 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
469 davinci_mcbsp_stop(dev, playback);
470}
471
472#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
473
474static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
475 .startup = davinci_i2s_startup,
476 .shutdown = davinci_i2s_shutdown,
477 .prepare = davinci_i2s_prepare,
478 .trigger = davinci_i2s_trigger,
479 .hw_params = davinci_i2s_hw_params,
480 .set_fmt = davinci_i2s_set_dai_fmt,
481
482};
483
484struct snd_soc_dai davinci_i2s_dai = {
485 .name = "davinci-i2s",
486 .id = 0,
487 .playback = {
488 .channels_min = 2,
489 .channels_max = 2,
490 .rates = DAVINCI_I2S_RATES,
491 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
492 .capture = {
493 .channels_min = 2,
494 .channels_max = 2,
495 .rates = DAVINCI_I2S_RATES,
496 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
497 .ops = &davinci_i2s_dai_ops,
498
499};
500EXPORT_SYMBOL_GPL(davinci_i2s_dai);
501
502static int davinci_i2s_probe(struct platform_device *pdev)
441{ 503{
442 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 504 struct snd_platform_data *pdata = pdev->dev.platform_data;
443 struct snd_soc_card *card = socdev->card;
444 struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
445 struct davinci_mcbsp_dev *dev; 505 struct davinci_mcbsp_dev *dev;
446 struct resource *mem, *ioarea; 506 struct resource *mem, *ioarea, *res;
447 struct evm_snd_platform_data *pdata;
448 int ret; 507 int ret;
449 508
450 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 509 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -466,8 +525,6 @@ static int davinci_i2s_probe(struct platform_device *pdev,
466 goto err_release_region; 525 goto err_release_region;
467 } 526 }
468 527
469 cpu_dai->private_data = dev;
470
471 dev->clk = clk_get(&pdev->dev, NULL); 528 dev->clk = clk_get(&pdev->dev, NULL);
472 if (IS_ERR(dev->clk)) { 529 if (IS_ERR(dev->clk)) {
473 ret = -ENODEV; 530 ret = -ENODEV;
@@ -476,18 +533,37 @@ static int davinci_i2s_probe(struct platform_device *pdev,
476 clk_enable(dev->clk); 533 clk_enable(dev->clk);
477 534
478 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 535 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
479 pdata = pdev->dev.platform_data;
480 536
481 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out; 537 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out;
482 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = pdata->tx_dma_ch;
483 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr = 538 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
484 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); 539 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
485 540
486 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in; 541 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in;
487 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = pdata->rx_dma_ch;
488 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr = 542 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
489 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); 543 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
490 544
545 /* first TX, then RX */
546 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
547 if (!res) {
548 dev_err(&pdev->dev, "no DMA resource\n");
549 ret = -ENXIO;
550 goto err_free_mem;
551 }
552 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start;
553
554 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
555 if (!res) {
556 dev_err(&pdev->dev, "no DMA resource\n");
557 ret = -ENXIO;
558 goto err_free_mem;
559 }
560 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start;
561
562 davinci_i2s_dai.private_data = dev;
563 ret = snd_soc_register_dai(&davinci_i2s_dai);
564 if (ret != 0)
565 goto err_free_mem;
566
491 return 0; 567 return 0;
492 568
493err_free_mem: 569err_free_mem:
@@ -498,62 +574,40 @@ err_release_region:
498 return ret; 574 return ret;
499} 575}
500 576
501static void davinci_i2s_remove(struct platform_device *pdev, 577static int davinci_i2s_remove(struct platform_device *pdev)
502 struct snd_soc_dai *dai)
503{ 578{
504 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 579 struct davinci_mcbsp_dev *dev = davinci_i2s_dai.private_data;
505 struct snd_soc_card *card = socdev->card;
506 struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
507 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
508 struct resource *mem; 580 struct resource *mem;
509 581
582 snd_soc_unregister_dai(&davinci_i2s_dai);
510 clk_disable(dev->clk); 583 clk_disable(dev->clk);
511 clk_put(dev->clk); 584 clk_put(dev->clk);
512 dev->clk = NULL; 585 dev->clk = NULL;
513
514 kfree(dev); 586 kfree(dev);
515
516 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 587 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
517 release_mem_region(mem->start, (mem->end - mem->start) + 1); 588 release_mem_region(mem->start, (mem->end - mem->start) + 1);
518}
519 589
520#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 590 return 0;
521 591}
522static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
523 .startup = davinci_i2s_startup,
524 .trigger = davinci_i2s_trigger,
525 .hw_params = davinci_i2s_hw_params,
526 .set_fmt = davinci_i2s_set_dai_fmt,
527};
528 592
529struct snd_soc_dai davinci_i2s_dai = { 593static struct platform_driver davinci_mcbsp_driver = {
530 .name = "davinci-i2s", 594 .probe = davinci_i2s_probe,
531 .id = 0, 595 .remove = davinci_i2s_remove,
532 .probe = davinci_i2s_probe, 596 .driver = {
533 .remove = davinci_i2s_remove, 597 .name = "davinci-asp",
534 .playback = { 598 .owner = THIS_MODULE,
535 .channels_min = 2, 599 },
536 .channels_max = 2,
537 .rates = DAVINCI_I2S_RATES,
538 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
539 .capture = {
540 .channels_min = 2,
541 .channels_max = 2,
542 .rates = DAVINCI_I2S_RATES,
543 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
544 .ops = &davinci_i2s_dai_ops,
545}; 600};
546EXPORT_SYMBOL_GPL(davinci_i2s_dai);
547 601
548static int __init davinci_i2s_init(void) 602static int __init davinci_i2s_init(void)
549{ 603{
550 return snd_soc_register_dai(&davinci_i2s_dai); 604 return platform_driver_register(&davinci_mcbsp_driver);
551} 605}
552module_init(davinci_i2s_init); 606module_init(davinci_i2s_init);
553 607
554static void __exit davinci_i2s_exit(void) 608static void __exit davinci_i2s_exit(void)
555{ 609{
556 snd_soc_unregister_dai(&davinci_i2s_dai); 610 platform_driver_unregister(&davinci_mcbsp_driver);
557} 611}
558module_exit(davinci_i2s_exit); 612module_exit(davinci_i2s_exit);
559 613
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
new file mode 100644
index 000000000000..eca22d7829d2
--- /dev/null
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -0,0 +1,973 @@
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/* McASP FIFO Registers */
106#define DAVINCI_MCASP_WFIFOCTL (0x1010)
107#define DAVINCI_MCASP_WFIFOSTS (0x1014)
108#define DAVINCI_MCASP_RFIFOCTL (0x1018)
109#define DAVINCI_MCASP_RFIFOSTS (0x101C)
110
111/*
112 * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
113 * Register Bits
114 */
115#define MCASP_FREE BIT(0)
116#define MCASP_SOFT BIT(1)
117
118/*
119 * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits
120 */
121#define AXR(n) (1<<n)
122#define PFUNC_AMUTE BIT(25)
123#define ACLKX BIT(26)
124#define AHCLKX BIT(27)
125#define AFSX BIT(28)
126#define ACLKR BIT(29)
127#define AHCLKR BIT(30)
128#define AFSR BIT(31)
129
130/*
131 * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits
132 */
133#define AXR(n) (1<<n)
134#define PDIR_AMUTE BIT(25)
135#define ACLKX BIT(26)
136#define AHCLKX BIT(27)
137#define AFSX BIT(28)
138#define ACLKR BIT(29)
139#define AHCLKR BIT(30)
140#define AFSR BIT(31)
141
142/*
143 * DAVINCI_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits
144 */
145#define DITEN BIT(0) /* Transmit DIT mode enable/disable */
146#define VA BIT(2)
147#define VB BIT(3)
148
149/*
150 * DAVINCI_MCASP_TXFMT_REG - Transmit Bitstream Format Register Bits
151 */
152#define TXROT(val) (val)
153#define TXSEL BIT(3)
154#define TXSSZ(val) (val<<4)
155#define TXPBIT(val) (val<<8)
156#define TXPAD(val) (val<<13)
157#define TXORD BIT(15)
158#define FSXDLY(val) (val<<16)
159
160/*
161 * DAVINCI_MCASP_RXFMT_REG - Receive Bitstream Format Register Bits
162 */
163#define RXROT(val) (val)
164#define RXSEL BIT(3)
165#define RXSSZ(val) (val<<4)
166#define RXPBIT(val) (val<<8)
167#define RXPAD(val) (val<<13)
168#define RXORD BIT(15)
169#define FSRDLY(val) (val<<16)
170
171/*
172 * DAVINCI_MCASP_TXFMCTL_REG - Transmit Frame Control Register Bits
173 */
174#define FSXPOL BIT(0)
175#define AFSXE BIT(1)
176#define FSXDUR BIT(4)
177#define FSXMOD(val) (val<<7)
178
179/*
180 * DAVINCI_MCASP_RXFMCTL_REG - Receive Frame Control Register Bits
181 */
182#define FSRPOL BIT(0)
183#define AFSRE BIT(1)
184#define FSRDUR BIT(4)
185#define FSRMOD(val) (val<<7)
186
187/*
188 * DAVINCI_MCASP_ACLKXCTL_REG - Transmit Clock Control Register Bits
189 */
190#define ACLKXDIV(val) (val)
191#define ACLKXE BIT(5)
192#define TX_ASYNC BIT(6)
193#define ACLKXPOL BIT(7)
194
195/*
196 * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits
197 */
198#define ACLKRDIV(val) (val)
199#define ACLKRE BIT(5)
200#define RX_ASYNC BIT(6)
201#define ACLKRPOL BIT(7)
202
203/*
204 * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control
205 * Register Bits
206 */
207#define AHCLKXDIV(val) (val)
208#define AHCLKXPOL BIT(14)
209#define AHCLKXE BIT(15)
210
211/*
212 * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control
213 * Register Bits
214 */
215#define AHCLKRDIV(val) (val)
216#define AHCLKRPOL BIT(14)
217#define AHCLKRE BIT(15)
218
219/*
220 * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits
221 */
222#define MODE(val) (val)
223#define DISMOD (val)(val<<2)
224#define TXSTATE BIT(4)
225#define RXSTATE BIT(5)
226
227/*
228 * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits
229 */
230#define LBEN BIT(0)
231#define LBORD BIT(1)
232#define LBGENMODE(val) (val<<2)
233
234/*
235 * DAVINCI_MCASP_TXTDMSLOT_REG - Transmit TDM Slot Register configuration
236 */
237#define TXTDMS(n) (1<<n)
238
239/*
240 * DAVINCI_MCASP_RXTDMSLOT_REG - Receive TDM Slot Register configuration
241 */
242#define RXTDMS(n) (1<<n)
243
244/*
245 * DAVINCI_MCASP_GBLCTL_REG - Global Control Register Bits
246 */
247#define RXCLKRST BIT(0) /* Receiver Clock Divider Reset */
248#define RXHCLKRST BIT(1) /* Receiver High Frequency Clock Divider */
249#define RXSERCLR BIT(2) /* Receiver Serializer Clear */
250#define RXSMRST BIT(3) /* Receiver State Machine Reset */
251#define RXFSRST BIT(4) /* Frame Sync Generator Reset */
252#define TXCLKRST BIT(8) /* Transmitter Clock Divider Reset */
253#define TXHCLKRST BIT(9) /* Transmitter High Frequency Clock Divider*/
254#define TXSERCLR BIT(10) /* Transmit Serializer Clear */
255#define TXSMRST BIT(11) /* Transmitter State Machine Reset */
256#define TXFSRST BIT(12) /* Frame Sync Generator Reset */
257
258/*
259 * DAVINCI_MCASP_AMUTE_REG - Mute Control Register Bits
260 */
261#define MUTENA(val) (val)
262#define MUTEINPOL BIT(2)
263#define MUTEINENA BIT(3)
264#define MUTEIN BIT(4)
265#define MUTER BIT(5)
266#define MUTEX BIT(6)
267#define MUTEFSR BIT(7)
268#define MUTEFSX BIT(8)
269#define MUTEBADCLKR BIT(9)
270#define MUTEBADCLKX BIT(10)
271#define MUTERXDMAERR BIT(11)
272#define MUTETXDMAERR BIT(12)
273
274/*
275 * DAVINCI_MCASP_REVTCTL_REG - Receiver DMA Event Control Register bits
276 */
277#define RXDATADMADIS BIT(0)
278
279/*
280 * DAVINCI_MCASP_XEVTCTL_REG - Transmitter DMA Event Control Register bits
281 */
282#define TXDATADMADIS BIT(0)
283
284/*
285 * DAVINCI_MCASP_W[R]FIFOCTL - Write/Read FIFO Control Register bits
286 */
287#define FIFO_ENABLE BIT(16)
288#define NUMEVT_MASK (0xFF << 8)
289#define NUMDMA_MASK (0xFF)
290
291#define DAVINCI_MCASP_NUM_SERIALIZER 16
292
293static inline void mcasp_set_bits(void __iomem *reg, u32 val)
294{
295 __raw_writel(__raw_readl(reg) | val, reg);
296}
297
298static inline void mcasp_clr_bits(void __iomem *reg, u32 val)
299{
300 __raw_writel((__raw_readl(reg) & ~(val)), reg);
301}
302
303static inline void mcasp_mod_bits(void __iomem *reg, u32 val, u32 mask)
304{
305 __raw_writel((__raw_readl(reg) & ~mask) | val, reg);
306}
307
308static inline void mcasp_set_reg(void __iomem *reg, u32 val)
309{
310 __raw_writel(val, reg);
311}
312
313static inline u32 mcasp_get_reg(void __iomem *reg)
314{
315 return (unsigned int)__raw_readl(reg);
316}
317
318static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
319{
320 int i = 0;
321
322 mcasp_set_bits(regs, val);
323
324 /* programming GBLCTL needs to read back from GBLCTL and verfiy */
325 /* loop count is to avoid the lock-up */
326 for (i = 0; i < 1000; i++) {
327 if ((mcasp_get_reg(regs) & val) == val)
328 break;
329 }
330
331 if (i == 1000 && ((mcasp_get_reg(regs) & val) != val))
332 printk(KERN_ERR "GBLCTL write error\n");
333}
334
335static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
336 struct snd_soc_dai *cpu_dai)
337{
338 struct davinci_audio_dev *dev = cpu_dai->private_data;
339 cpu_dai->dma_data = dev->dma_params[substream->stream];
340 return 0;
341}
342
343static void mcasp_start_rx(struct davinci_audio_dev *dev)
344{
345 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
346 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST);
347 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR);
348 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
349
350 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
351 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
352 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
353
354 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
355 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
356}
357
358static void mcasp_start_tx(struct davinci_audio_dev *dev)
359{
360 u8 offset = 0, i;
361 u32 cnt;
362
363 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
364 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
365 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
366 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
367
368 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
369 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
370 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
371 for (i = 0; i < dev->num_serializer; i++) {
372 if (dev->serial_dir[i] == TX_MODE) {
373 offset = i;
374 break;
375 }
376 }
377
378 /* wait for TX ready */
379 cnt = 0;
380 while (!(mcasp_get_reg(dev->base + DAVINCI_MCASP_XRSRCTL_REG(offset)) &
381 TXSTATE) && (cnt < 100000))
382 cnt++;
383
384 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
385}
386
387static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
388{
389 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
390 mcasp_start_tx(dev);
391 else
392 mcasp_start_rx(dev);
393
394 /* enable FIFO */
395 if (dev->txnumevt)
396 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
397
398 if (dev->rxnumevt)
399 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
400}
401
402static void mcasp_stop_rx(struct davinci_audio_dev *dev)
403{
404 mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, 0);
405 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
406}
407
408static void mcasp_stop_tx(struct davinci_audio_dev *dev)
409{
410 mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, 0);
411 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
412}
413
414static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
415{
416 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
417 mcasp_stop_tx(dev);
418 else
419 mcasp_stop_rx(dev);
420
421 /* disable FIFO */
422 if (dev->txnumevt)
423 mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
424
425 if (dev->rxnumevt)
426 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
427}
428
429static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
430 unsigned int fmt)
431{
432 struct davinci_audio_dev *dev = cpu_dai->private_data;
433 void __iomem *base = dev->base;
434
435 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
436 case SND_SOC_DAIFMT_CBS_CFS:
437 /* codec is clock and frame slave */
438 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
439 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
440
441 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
442 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
443
444 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x7 << 26));
445 break;
446 case SND_SOC_DAIFMT_CBM_CFS:
447 /* codec is clock master and frame slave */
448 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
449 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
450
451 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
452 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
453
454 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x2d << 26));
455 break;
456 case SND_SOC_DAIFMT_CBM_CFM:
457 /* codec is clock and frame master */
458 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
459 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
460
461 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
462 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
463
464 mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, (0x3f << 26));
465 break;
466
467 default:
468 return -EINVAL;
469 }
470
471 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
472 case SND_SOC_DAIFMT_IB_NF:
473 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
474 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
475
476 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
477 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
478 break;
479
480 case SND_SOC_DAIFMT_NB_IF:
481 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
482 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
483
484 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
485 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
486 break;
487
488 case SND_SOC_DAIFMT_IB_IF:
489 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
490 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
491
492 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
493 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
494 break;
495
496 case SND_SOC_DAIFMT_NB_NF:
497 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
498 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
499
500 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
501 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
502 break;
503
504 default:
505 return -EINVAL;
506 }
507
508 return 0;
509}
510
511static int davinci_config_channel_size(struct davinci_audio_dev *dev,
512 int channel_size)
513{
514 u32 fmt = 0;
515
516 switch (channel_size) {
517 case DAVINCI_AUDIO_WORD_8:
518 fmt = 0x03;
519 break;
520
521 case DAVINCI_AUDIO_WORD_12:
522 fmt = 0x05;
523 break;
524
525 case DAVINCI_AUDIO_WORD_16:
526 fmt = 0x07;
527 break;
528
529 case DAVINCI_AUDIO_WORD_20:
530 fmt = 0x09;
531 break;
532
533 case DAVINCI_AUDIO_WORD_24:
534 fmt = 0x0B;
535 break;
536
537 case DAVINCI_AUDIO_WORD_28:
538 fmt = 0x0D;
539 break;
540
541 case DAVINCI_AUDIO_WORD_32:
542 fmt = 0x0F;
543 break;
544
545 default:
546 return -EINVAL;
547 }
548
549 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
550 RXSSZ(fmt), RXSSZ(0x0F));
551 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
552 TXSSZ(fmt), TXSSZ(0x0F));
553 return 0;
554}
555
556static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
557{
558 int i;
559 u8 tx_ser = 0;
560 u8 rx_ser = 0;
561
562 /* Default configuration */
563 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
564
565 /* All PINS as McASP */
566 mcasp_set_reg(dev->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000);
567
568 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
569 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
570 mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG,
571 TXDATADMADIS);
572 } else {
573 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
574 mcasp_clr_bits(dev->base + DAVINCI_MCASP_REVTCTL_REG,
575 RXDATADMADIS);
576 }
577
578 for (i = 0; i < dev->num_serializer; i++) {
579 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
580 dev->serial_dir[i]);
581 if (dev->serial_dir[i] == TX_MODE) {
582 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
583 AXR(i));
584 tx_ser++;
585 } else if (dev->serial_dir[i] == RX_MODE) {
586 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
587 AXR(i));
588 rx_ser++;
589 }
590 }
591
592 if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
593 if (dev->txnumevt * tx_ser > 64)
594 dev->txnumevt = 1;
595
596 mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, tx_ser,
597 NUMDMA_MASK);
598 mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
599 ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
600 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
601 }
602
603 if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
604 if (dev->rxnumevt * rx_ser > 64)
605 dev->rxnumevt = 1;
606
607 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, rx_ser,
608 NUMDMA_MASK);
609 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
610 ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
611 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
612 }
613}
614
615static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
616{
617 int i, active_slots;
618 u32 mask = 0;
619
620 active_slots = (dev->tdm_slots > 31) ? 32 : dev->tdm_slots;
621 for (i = 0; i < active_slots; i++)
622 mask |= (1 << i);
623
624 mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
625
626 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
627 /* bit stream is MSB first with no delay */
628 /* DSP_B mode */
629 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
630 AHCLKXE);
631 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
632 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
633
634 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32))
635 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
636 FSXMOD(dev->tdm_slots), FSXMOD(0x1FF));
637 else
638 printk(KERN_ERR "playback tdm slot %d not supported\n",
639 dev->tdm_slots);
640
641 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0xFFFFFFFF);
642 mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
643 } else {
644 /* bit stream is MSB first with no delay */
645 /* DSP_B mode */
646 mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD);
647 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
648 AHCLKRE);
649 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask);
650
651 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32))
652 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG,
653 FSRMOD(dev->tdm_slots), FSRMOD(0x1FF));
654 else
655 printk(KERN_ERR "capture tdm slot %d not supported\n",
656 dev->tdm_slots);
657
658 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, 0xFFFFFFFF);
659 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
660 }
661}
662
663/* S/PDIF */
664static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
665{
666 /* Set the PDIR for Serialiser as output */
667 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);
668
669 /* TXMASK for 24 bits */
670 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);
671
672 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
673 and LSB first */
674 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
675 TXROT(6) | TXSSZ(15));
676
677 /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
678 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
679 AFSXE | FSXMOD(0x180));
680
681 /* Set the TX tdm : for all the slots */
682 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);
683
684 /* Set the TX clock controls : div = 1 and internal */
685 mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
686 ACLKXE | TX_ASYNC);
687
688 mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
689
690 /* Only 44100 and 48000 are valid, both have the same setting */
691 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3));
692
693 /* Enable the DIT */
694 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXDITCTL_REG, DITEN);
695}
696
697static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
698 struct snd_pcm_hw_params *params,
699 struct snd_soc_dai *cpu_dai)
700{
701 struct davinci_audio_dev *dev = cpu_dai->private_data;
702 struct davinci_pcm_dma_params *dma_params =
703 dev->dma_params[substream->stream];
704 int word_length;
705 u8 numevt;
706
707 davinci_hw_common_param(dev, substream->stream);
708 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
709 numevt = dev->txnumevt;
710 else
711 numevt = dev->rxnumevt;
712
713 if (!numevt)
714 numevt = 1;
715
716 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
717 davinci_hw_dit_param(dev);
718 else
719 davinci_hw_param(dev, substream->stream);
720
721 switch (params_format(params)) {
722 case SNDRV_PCM_FORMAT_S8:
723 dma_params->data_type = 1;
724 word_length = DAVINCI_AUDIO_WORD_8;
725 break;
726
727 case SNDRV_PCM_FORMAT_S16_LE:
728 dma_params->data_type = 2;
729 word_length = DAVINCI_AUDIO_WORD_16;
730 break;
731
732 case SNDRV_PCM_FORMAT_S32_LE:
733 dma_params->data_type = 4;
734 word_length = DAVINCI_AUDIO_WORD_32;
735 break;
736
737 default:
738 printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
739 return -EINVAL;
740 }
741
742 if (dev->version == MCASP_VERSION_2) {
743 dma_params->data_type *= numevt;
744 dma_params->acnt = 4 * numevt;
745 } else
746 dma_params->acnt = dma_params->data_type;
747
748 davinci_config_channel_size(dev, word_length);
749
750 return 0;
751}
752
753static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
754 int cmd, struct snd_soc_dai *cpu_dai)
755{
756 struct snd_soc_pcm_runtime *rtd = substream->private_data;
757 struct davinci_audio_dev *dev = rtd->dai->cpu_dai->private_data;
758 int ret = 0;
759
760 switch (cmd) {
761 case SNDRV_PCM_TRIGGER_START:
762 case SNDRV_PCM_TRIGGER_RESUME:
763 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
764 davinci_mcasp_start(dev, substream->stream);
765 break;
766
767 case SNDRV_PCM_TRIGGER_STOP:
768 case SNDRV_PCM_TRIGGER_SUSPEND:
769 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
770 davinci_mcasp_stop(dev, substream->stream);
771 break;
772
773 default:
774 ret = -EINVAL;
775 }
776
777 return ret;
778}
779
780static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
781 .startup = davinci_mcasp_startup,
782 .trigger = davinci_mcasp_trigger,
783 .hw_params = davinci_mcasp_hw_params,
784 .set_fmt = davinci_mcasp_set_dai_fmt,
785
786};
787
788struct snd_soc_dai davinci_mcasp_dai[] = {
789 {
790 .name = "davinci-i2s",
791 .id = 0,
792 .playback = {
793 .channels_min = 2,
794 .channels_max = 2,
795 .rates = DAVINCI_MCASP_RATES,
796 .formats = SNDRV_PCM_FMTBIT_S8 |
797 SNDRV_PCM_FMTBIT_S16_LE |
798 SNDRV_PCM_FMTBIT_S32_LE,
799 },
800 .capture = {
801 .channels_min = 2,
802 .channels_max = 2,
803 .rates = DAVINCI_MCASP_RATES,
804 .formats = SNDRV_PCM_FMTBIT_S8 |
805 SNDRV_PCM_FMTBIT_S16_LE |
806 SNDRV_PCM_FMTBIT_S32_LE,
807 },
808 .ops = &davinci_mcasp_dai_ops,
809
810 },
811 {
812 .name = "davinci-dit",
813 .id = 1,
814 .playback = {
815 .channels_min = 1,
816 .channels_max = 384,
817 .rates = DAVINCI_MCASP_RATES,
818 .formats = SNDRV_PCM_FMTBIT_S16_LE,
819 },
820 .ops = &davinci_mcasp_dai_ops,
821 },
822
823};
824EXPORT_SYMBOL_GPL(davinci_mcasp_dai);
825
826static int davinci_mcasp_probe(struct platform_device *pdev)
827{
828 struct davinci_pcm_dma_params *dma_data;
829 struct resource *mem, *ioarea, *res;
830 struct snd_platform_data *pdata;
831 struct davinci_audio_dev *dev;
832 int count = 0;
833 int ret = 0;
834
835 dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
836 if (!dev)
837 return -ENOMEM;
838
839 dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
840 GFP_KERNEL);
841 if (!dma_data) {
842 ret = -ENOMEM;
843 goto err_release_dev;
844 }
845
846 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
847 if (!mem) {
848 dev_err(&pdev->dev, "no mem resource?\n");
849 ret = -ENODEV;
850 goto err_release_data;
851 }
852
853 ioarea = request_mem_region(mem->start,
854 (mem->end - mem->start) + 1, pdev->name);
855 if (!ioarea) {
856 dev_err(&pdev->dev, "Audio region already claimed\n");
857 ret = -EBUSY;
858 goto err_release_data;
859 }
860
861 pdata = pdev->dev.platform_data;
862 dev->clk = clk_get(&pdev->dev, NULL);
863 if (IS_ERR(dev->clk)) {
864 ret = -ENODEV;
865 goto err_release_region;
866 }
867
868 clk_enable(dev->clk);
869
870 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
871 dev->op_mode = pdata->op_mode;
872 dev->tdm_slots = pdata->tdm_slots;
873 dev->num_serializer = pdata->num_serializer;
874 dev->serial_dir = pdata->serial_dir;
875 dev->codec_fmt = pdata->codec_fmt;
876 dev->version = pdata->version;
877 dev->txnumevt = pdata->txnumevt;
878 dev->rxnumevt = pdata->rxnumevt;
879
880 dma_data[count].name = "I2S PCM Stereo out";
881 dma_data[count].eventq_no = pdata->eventq_no;
882 dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
883 io_v2p(dev->base));
884 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
885
886 /* first TX, then RX */
887 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
888 if (!res) {
889 dev_err(&pdev->dev, "no DMA resource\n");
890 goto err_release_region;
891 }
892
893 dma_data[count].channel = res->start;
894 count++;
895 dma_data[count].name = "I2S PCM Stereo in";
896 dma_data[count].eventq_no = pdata->eventq_no;
897 dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
898 io_v2p(dev->base));
899 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
900
901 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
902 if (!res) {
903 dev_err(&pdev->dev, "no DMA resource\n");
904 goto err_release_region;
905 }
906
907 dma_data[count].channel = res->start;
908 davinci_mcasp_dai[pdata->op_mode].private_data = dev;
909 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
910 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
911
912 if (ret != 0)
913 goto err_release_region;
914 return 0;
915
916err_release_region:
917 release_mem_region(mem->start, (mem->end - mem->start) + 1);
918err_release_data:
919 kfree(dma_data);
920err_release_dev:
921 kfree(dev);
922
923 return ret;
924}
925
926static int davinci_mcasp_remove(struct platform_device *pdev)
927{
928 struct snd_platform_data *pdata = pdev->dev.platform_data;
929 struct davinci_pcm_dma_params *dma_data;
930 struct davinci_audio_dev *dev;
931 struct resource *mem;
932
933 snd_soc_unregister_dai(&davinci_mcasp_dai[pdata->op_mode]);
934 dev = davinci_mcasp_dai[pdata->op_mode].private_data;
935 clk_disable(dev->clk);
936 clk_put(dev->clk);
937 dev->clk = NULL;
938
939 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
940 release_mem_region(mem->start, (mem->end - mem->start) + 1);
941
942 dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
943 kfree(dma_data);
944 kfree(dev);
945
946 return 0;
947}
948
949static struct platform_driver davinci_mcasp_driver = {
950 .probe = davinci_mcasp_probe,
951 .remove = davinci_mcasp_remove,
952 .driver = {
953 .name = "davinci-mcasp",
954 .owner = THIS_MODULE,
955 },
956};
957
958static int __init davinci_mcasp_init(void)
959{
960 return platform_driver_register(&davinci_mcasp_driver);
961}
962module_init(davinci_mcasp_init);
963
964static void __exit davinci_mcasp_exit(void)
965{
966 platform_driver_unregister(&davinci_mcasp_driver);
967}
968module_exit(davinci_mcasp_exit);
969
970MODULE_AUTHOR("Steve Chen");
971MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
972MODULE_LICENSE("GPL");
973
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
new file mode 100644
index 000000000000..554354c1cc2f
--- /dev/null
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -0,0 +1,60 @@
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 u8 version;
54
55 /* McASP FIFO related */
56 u8 txnumevt;
57 u8 rxnumevt;
58};
59
60#endif /* DAVINCI_MCASP_H */
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index a05996588489..091dacb78b4d 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -67,6 +67,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
67 dma_addr_t src, dst; 67 dma_addr_t src, dst;
68 unsigned short src_bidx, dst_bidx; 68 unsigned short src_bidx, dst_bidx;
69 unsigned int data_type; 69 unsigned int data_type;
70 unsigned short acnt;
70 unsigned int count; 71 unsigned int count;
71 72
72 period_size = snd_pcm_lib_period_bytes(substream); 73 period_size = snd_pcm_lib_period_bytes(substream);
@@ -91,11 +92,12 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
91 dst_bidx = data_type; 92 dst_bidx = data_type;
92 } 93 }
93 94
95 acnt = prtd->params->acnt;
94 edma_set_src(lch, src, INCR, W8BIT); 96 edma_set_src(lch, src, INCR, W8BIT);
95 edma_set_dest(lch, dst, INCR, W8BIT); 97 edma_set_dest(lch, dst, INCR, W8BIT);
96 edma_set_src_index(lch, src_bidx, 0); 98 edma_set_src_index(lch, src_bidx, 0);
97 edma_set_dest_index(lch, dst_bidx, 0); 99 edma_set_dest_index(lch, dst_bidx, 0);
98 edma_set_transfer_params(lch, data_type, count, 1, 0, ASYNC); 100 edma_set_transfer_params(lch, acnt, count, 1, 0, ASYNC);
99 101
100 prtd->period++; 102 prtd->period++;
101 if (unlikely(prtd->period >= runtime->periods)) 103 if (unlikely(prtd->period >= runtime->periods))
@@ -206,6 +208,7 @@ static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
206 /* Copy self-linked parameter RAM entry into master channel */ 208 /* Copy self-linked parameter RAM entry into master channel */
207 edma_read_slot(prtd->slave_lch, &temp); 209 edma_read_slot(prtd->slave_lch, &temp);
208 edma_write_slot(prtd->master_lch, &temp); 210 edma_write_slot(prtd->master_lch, &temp);
211 davinci_pcm_enqueue_dma(substream);
209 212
210 return 0; 213 return 0;
211} 214}
@@ -243,6 +246,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
243 int ret = 0; 246 int ret = 0;
244 247
245 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); 248 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
249 /* ensure that buffer size is a multiple of period size */
250 ret = snd_pcm_hw_constraint_integer(runtime,
251 SNDRV_PCM_HW_PARAM_PERIODS);
252 if (ret < 0)
253 return ret;
246 254
247 prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL); 255 prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL);
248 if (prtd == NULL) 256 if (prtd == NULL)
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 62cb4eb07e34..63d96253c73a 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -12,17 +12,20 @@
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 unsigned short acnt;
19 unsigned int data_type; /* xfer data type */ 23 dma_addr_t dma_addr; /* device physical address for DMA */
24 enum dma_event_q eventq_no; /* event queue number */
25 unsigned char data_type; /* xfer data type */
26 unsigned char convert_mono_stereo;
20}; 27};
21 28
22struct evm_snd_platform_data {
23 int tx_dma_ch;
24 int rx_dma_ch;
25};
26 29
27extern struct snd_soc_platform davinci_soc_platform; 30extern struct snd_soc_platform davinci_soc_platform;
28 31