diff options
Diffstat (limited to 'sound/soc/omap/sdp3430.c')
-rw-r--r-- | sound/soc/omap/sdp3430.c | 103 |
1 files changed, 93 insertions, 10 deletions
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index 10f1c867f11d..f7e5b7488c35 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/i2c/twl4030.h> | ||
27 | #include <sound/core.h> | 28 | #include <sound/core.h> |
28 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
29 | #include <sound/soc.h> | 30 | #include <sound/soc.h> |
@@ -39,6 +40,9 @@ | |||
39 | #include "omap-pcm.h" | 40 | #include "omap-pcm.h" |
40 | #include "../codecs/twl4030.h" | 41 | #include "../codecs/twl4030.h" |
41 | 42 | ||
43 | #define TWL4030_INTBR_PMBR1 0x0D | ||
44 | #define EXTMUTE(value) (value << 2) | ||
45 | |||
42 | static struct snd_soc_card snd_soc_sdp3430; | 46 | static struct snd_soc_card snd_soc_sdp3430; |
43 | 47 | ||
44 | static int sdp3430_hw_params(struct snd_pcm_substream *substream, | 48 | static int sdp3430_hw_params(struct snd_pcm_substream *substream, |
@@ -84,6 +88,49 @@ static struct snd_soc_ops sdp3430_ops = { | |||
84 | .hw_params = sdp3430_hw_params, | 88 | .hw_params = sdp3430_hw_params, |
85 | }; | 89 | }; |
86 | 90 | ||
91 | static int sdp3430_hw_voice_params(struct snd_pcm_substream *substream, | ||
92 | struct snd_pcm_hw_params *params) | ||
93 | { | ||
94 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
95 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | ||
96 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | ||
97 | int ret; | ||
98 | |||
99 | /* Set codec DAI configuration */ | ||
100 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
101 | SND_SOC_DAIFMT_DSP_A | | ||
102 | SND_SOC_DAIFMT_IB_NF | | ||
103 | SND_SOC_DAIFMT_CBM_CFM); | ||
104 | if (ret) { | ||
105 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | /* Set cpu DAI configuration */ | ||
110 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
111 | SND_SOC_DAIFMT_DSP_A | | ||
112 | SND_SOC_DAIFMT_IB_NF | | ||
113 | SND_SOC_DAIFMT_CBM_CFM); | ||
114 | if (ret < 0) { | ||
115 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | /* Set the codec system clock for DAC and ADC */ | ||
120 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
121 | SND_SOC_CLOCK_IN); | ||
122 | if (ret < 0) { | ||
123 | printk(KERN_ERR "can't set codec system clock\n"); | ||
124 | return ret; | ||
125 | } | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static struct snd_soc_ops sdp3430_voice_ops = { | ||
131 | .hw_params = sdp3430_hw_voice_params, | ||
132 | }; | ||
133 | |||
87 | /* Headset jack */ | 134 | /* Headset jack */ |
88 | static struct snd_soc_jack hs_jack; | 135 | static struct snd_soc_jack hs_jack; |
89 | 136 | ||
@@ -192,28 +239,59 @@ static int sdp3430_twl4030_init(struct snd_soc_codec *codec) | |||
192 | return ret; | 239 | return ret; |
193 | } | 240 | } |
194 | 241 | ||
242 | static int sdp3430_twl4030_voice_init(struct snd_soc_codec *codec) | ||
243 | { | ||
244 | unsigned short reg; | ||
245 | |||
246 | /* Enable voice interface */ | ||
247 | reg = codec->read(codec, TWL4030_REG_VOICE_IF); | ||
248 | reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN; | ||
249 | codec->write(codec, TWL4030_REG_VOICE_IF, reg); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | |||
195 | /* Digital audio interface glue - connects codec <--> CPU */ | 255 | /* Digital audio interface glue - connects codec <--> CPU */ |
196 | static struct snd_soc_dai_link sdp3430_dai = { | 256 | static struct snd_soc_dai_link sdp3430_dai[] = { |
197 | .name = "TWL4030", | 257 | { |
198 | .stream_name = "TWL4030", | 258 | .name = "TWL4030 I2S", |
199 | .cpu_dai = &omap_mcbsp_dai[0], | 259 | .stream_name = "TWL4030 Audio", |
200 | .codec_dai = &twl4030_dai, | 260 | .cpu_dai = &omap_mcbsp_dai[0], |
201 | .init = sdp3430_twl4030_init, | 261 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], |
202 | .ops = &sdp3430_ops, | 262 | .init = sdp3430_twl4030_init, |
263 | .ops = &sdp3430_ops, | ||
264 | }, | ||
265 | { | ||
266 | .name = "TWL4030 PCM", | ||
267 | .stream_name = "TWL4030 Voice", | ||
268 | .cpu_dai = &omap_mcbsp_dai[1], | ||
269 | .codec_dai = &twl4030_dai[TWL4030_DAI_VOICE], | ||
270 | .init = sdp3430_twl4030_voice_init, | ||
271 | .ops = &sdp3430_voice_ops, | ||
272 | }, | ||
203 | }; | 273 | }; |
204 | 274 | ||
205 | /* Audio machine driver */ | 275 | /* Audio machine driver */ |
206 | static struct snd_soc_card snd_soc_sdp3430 = { | 276 | static struct snd_soc_card snd_soc_sdp3430 = { |
207 | .name = "SDP3430", | 277 | .name = "SDP3430", |
208 | .platform = &omap_soc_platform, | 278 | .platform = &omap_soc_platform, |
209 | .dai_link = &sdp3430_dai, | 279 | .dai_link = sdp3430_dai, |
210 | .num_links = 1, | 280 | .num_links = ARRAY_SIZE(sdp3430_dai), |
281 | }; | ||
282 | |||
283 | /* twl4030 setup */ | ||
284 | static struct twl4030_setup_data twl4030_setup = { | ||
285 | .ramp_delay_value = 3, | ||
286 | .sysclk = 26000, | ||
287 | .hs_extmute = 1, | ||
211 | }; | 288 | }; |
212 | 289 | ||
213 | /* Audio subsystem */ | 290 | /* Audio subsystem */ |
214 | static struct snd_soc_device sdp3430_snd_devdata = { | 291 | static struct snd_soc_device sdp3430_snd_devdata = { |
215 | .card = &snd_soc_sdp3430, | 292 | .card = &snd_soc_sdp3430, |
216 | .codec_dev = &soc_codec_dev_twl4030, | 293 | .codec_dev = &soc_codec_dev_twl4030, |
294 | .codec_data = &twl4030_setup, | ||
217 | }; | 295 | }; |
218 | 296 | ||
219 | static struct platform_device *sdp3430_snd_device; | 297 | static struct platform_device *sdp3430_snd_device; |
@@ -236,7 +314,12 @@ static int __init sdp3430_soc_init(void) | |||
236 | 314 | ||
237 | platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata); | 315 | platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata); |
238 | sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev; | 316 | sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev; |
239 | *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */ | 317 | *(unsigned int *)sdp3430_dai[0].cpu_dai->private_data = 1; /* McBSP2 */ |
318 | *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */ | ||
319 | |||
320 | /* Set TWL4030 GPIO6 as EXTMUTE signal */ | ||
321 | twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, EXTMUTE(0x02), | ||
322 | TWL4030_MODULE_INTBR); | ||
240 | 323 | ||
241 | ret = platform_device_add(sdp3430_snd_device); | 324 | ret = platform_device_add(sdp3430_snd_device); |
242 | if (ret) | 325 | if (ret) |