aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/sdp3430.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/omap/sdp3430.c')
-rw-r--r--sound/soc/omap/sdp3430.c103
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
42static struct snd_soc_card snd_soc_sdp3430; 46static struct snd_soc_card snd_soc_sdp3430;
43 47
44static int sdp3430_hw_params(struct snd_pcm_substream *substream, 48static 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
91static 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
130static struct snd_soc_ops sdp3430_voice_ops = {
131 .hw_params = sdp3430_hw_voice_params,
132};
133
87/* Headset jack */ 134/* Headset jack */
88static struct snd_soc_jack hs_jack; 135static 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
242static 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 */
196static struct snd_soc_dai_link sdp3430_dai = { 256static 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 */
206static struct snd_soc_card snd_soc_sdp3430 = { 276static 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 */
284static 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 */
214static struct snd_soc_device sdp3430_snd_devdata = { 291static 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
219static struct platform_device *sdp3430_snd_device; 297static 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)