diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-06-10 01:26:18 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-10 01:26:18 -0400 |
commit | ba252af8d60f543a2a2c03f5574f64007ae9c2f3 (patch) | |
tree | a37b2723f0c4ea10447600f321f4df261e45bde6 /sound/soc/omap | |
parent | 07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff) | |
parent | 74b8f955a73d20b1e22403fd1ef85834fbf38d98 (diff) |
Merge branch 'topic/asoc' into for-linus
* topic/asoc: (135 commits)
ASoC: Apostrophe patrol
ASoC: codec tlv320aic23 fix bogus divide by 0 message
ASoC: fix NULL pointer dereference in soc_suspend()
ASoC: Fix build error in twl4030.c
ASoC: SSM2602: assign last substream to the master when shutting down
ASoC: Blackfin: document how anomaly 05000250 is handled
ASoC: Blackfin: set the transfer size according the ac97_frame size
ASoC: SSM2602: remove unsupported sample rates
ASoC: TWL4030: Check the interface format for 4 channel mode
ASoC: TWL4030: Use reg_cache in twl4030_init_chip
ASoC: Initialise dev for the dummy S/PDIF DAI
ASoC: Add dummy S/PDIF codec support
ASoC: correct print specifiers for unsigneds
ASoC: Modify mpc5200 AC97 driver to use V9 of spin_event_timeout()
ASoC: Switch FSL SSI DAI over to symmetric_rates
ASoC: Mark MPC5200 AC97 as BROKEN until PowerPC merge issues are resolved
ASoC: Fabric bindings for STAC9766 on the Efika
ASoC: Support for AC97 on Phytec pmc030 base board.
ASoC: AC97 driver for mpc5200
ASoC: Main rewite of the mpc5200 audio DMA code
...
Diffstat (limited to 'sound/soc/omap')
-rw-r--r-- | sound/soc/omap/Kconfig | 8 | ||||
-rw-r--r-- | sound/soc/omap/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/omap/n810.c | 7 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcbsp.c | 43 | ||||
-rw-r--r-- | sound/soc/omap/omap-pcm.c | 9 | ||||
-rw-r--r-- | sound/soc/omap/omap2evm.c | 2 | ||||
-rw-r--r-- | sound/soc/omap/omap3beagle.c | 28 | ||||
-rw-r--r-- | sound/soc/omap/omap3evm.c | 147 | ||||
-rw-r--r-- | sound/soc/omap/omap3pandora.c | 4 | ||||
-rw-r--r-- | sound/soc/omap/overo.c | 2 | ||||
-rw-r--r-- | sound/soc/omap/sdp3430.c | 94 |
11 files changed, 304 insertions, 42 deletions
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 675732e724d5..b771238662b6 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig | |||
@@ -39,6 +39,14 @@ config SND_OMAP_SOC_OMAP2EVM | |||
39 | help | 39 | help |
40 | Say Y if you want to add support for SoC audio on the omap2evm board. | 40 | Say Y if you want to add support for SoC audio on the omap2evm board. |
41 | 41 | ||
42 | config SND_OMAP_SOC_OMAP3EVM | ||
43 | tristate "SoC Audio support for OMAP3EVM board" | ||
44 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM | ||
45 | select SND_OMAP_SOC_MCBSP | ||
46 | select SND_SOC_TWL4030 | ||
47 | help | ||
48 | Say Y if you want to add support for SoC audio on the omap3evm board. | ||
49 | |||
42 | config SND_OMAP_SOC_SDP3430 | 50 | config SND_OMAP_SOC_SDP3430 |
43 | tristate "SoC Audio support for Texas Instruments SDP3430" | 51 | tristate "SoC Audio support for Texas Instruments SDP3430" |
44 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP | 52 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP |
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 0c9e4ac37660..a37f49862389 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile | |||
@@ -10,6 +10,7 @@ snd-soc-n810-objs := n810.o | |||
10 | snd-soc-osk5912-objs := osk5912.o | 10 | snd-soc-osk5912-objs := osk5912.o |
11 | snd-soc-overo-objs := overo.o | 11 | snd-soc-overo-objs := overo.o |
12 | snd-soc-omap2evm-objs := omap2evm.o | 12 | snd-soc-omap2evm-objs := omap2evm.o |
13 | snd-soc-omap3evm-objs := omap3evm.o | ||
13 | snd-soc-sdp3430-objs := sdp3430.o | 14 | snd-soc-sdp3430-objs := sdp3430.o |
14 | snd-soc-omap3pandora-objs := omap3pandora.o | 15 | snd-soc-omap3pandora-objs := omap3pandora.o |
15 | snd-soc-omap3beagle-objs := omap3beagle.o | 16 | snd-soc-omap3beagle-objs := omap3beagle.o |
@@ -18,6 +19,7 @@ obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o | |||
18 | obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o | 19 | obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o |
19 | obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o | 20 | obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o |
20 | obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o | 21 | obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o |
22 | obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.o | ||
21 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o | 23 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o |
22 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o | 24 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o |
23 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o | 25 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o |
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 91ef17992de5..b60b1dfbc435 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c | |||
@@ -383,10 +383,9 @@ static int __init n810_soc_init(void) | |||
383 | clk_set_parent(sys_clkout2_src, func96m_clk); | 383 | clk_set_parent(sys_clkout2_src, func96m_clk); |
384 | clk_set_rate(sys_clkout2, 12000000); | 384 | clk_set_rate(sys_clkout2, 12000000); |
385 | 385 | ||
386 | if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) | 386 | BUG_ON((gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) || |
387 | BUG(); | 387 | (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0)); |
388 | if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0) | 388 | |
389 | BUG(); | ||
390 | gpio_direction_output(N810_HEADSET_AMP_GPIO, 0); | 389 | gpio_direction_output(N810_HEADSET_AMP_GPIO, 0); |
391 | gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); | 390 | gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); |
392 | 391 | ||
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 912614283848..a5d46a7b196a 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -215,8 +215,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
215 | struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); | 215 | struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); |
216 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; | 216 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; |
217 | int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; | 217 | int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; |
218 | int wlen, channels; | 218 | int wlen, channels, wpf; |
219 | unsigned long port; | 219 | unsigned long port; |
220 | unsigned int format; | ||
220 | 221 | ||
221 | if (cpu_class_is_omap1()) { | 222 | if (cpu_class_is_omap1()) { |
222 | dma = omap1_dma_reqs[bus_id][substream->stream]; | 223 | dma = omap1_dma_reqs[bus_id][substream->stream]; |
@@ -244,18 +245,24 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
244 | return 0; | 245 | return 0; |
245 | } | 246 | } |
246 | 247 | ||
247 | channels = params_channels(params); | 248 | format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; |
249 | wpf = channels = params_channels(params); | ||
248 | switch (channels) { | 250 | switch (channels) { |
249 | case 2: | 251 | case 2: |
250 | /* Use dual-phase frames */ | 252 | if (format == SND_SOC_DAIFMT_I2S) { |
251 | regs->rcr2 |= RPHASE; | 253 | /* Use dual-phase frames */ |
252 | regs->xcr2 |= XPHASE; | 254 | regs->rcr2 |= RPHASE; |
255 | regs->xcr2 |= XPHASE; | ||
256 | /* Set 1 word per (McBSP) frame for phase1 and phase2 */ | ||
257 | wpf--; | ||
258 | regs->rcr2 |= RFRLEN2(wpf - 1); | ||
259 | regs->xcr2 |= XFRLEN2(wpf - 1); | ||
260 | } | ||
253 | case 1: | 261 | case 1: |
254 | /* Set 1 word per (McBSP) frame */ | 262 | case 4: |
255 | regs->rcr2 |= RFRLEN2(1 - 1); | 263 | /* Set word per (McBSP) frame for phase1 */ |
256 | regs->rcr1 |= RFRLEN1(1 - 1); | 264 | regs->rcr1 |= RFRLEN1(wpf - 1); |
257 | regs->xcr2 |= XFRLEN2(1 - 1); | 265 | regs->xcr1 |= XFRLEN1(wpf - 1); |
258 | regs->xcr1 |= XFRLEN1(1 - 1); | ||
259 | break; | 266 | break; |
260 | default: | 267 | default: |
261 | /* Unsupported number of channels */ | 268 | /* Unsupported number of channels */ |
@@ -277,11 +284,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
277 | } | 284 | } |
278 | 285 | ||
279 | /* Set FS period and length in terms of bit clock periods */ | 286 | /* Set FS period and length in terms of bit clock periods */ |
280 | switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 287 | switch (format) { |
281 | case SND_SOC_DAIFMT_I2S: | 288 | case SND_SOC_DAIFMT_I2S: |
282 | regs->srgr2 |= FPER(wlen * 2 - 1); | 289 | regs->srgr2 |= FPER(wlen * channels - 1); |
283 | regs->srgr1 |= FWID(wlen - 1); | 290 | regs->srgr1 |= FWID(wlen - 1); |
284 | break; | 291 | break; |
292 | case SND_SOC_DAIFMT_DSP_A: | ||
285 | case SND_SOC_DAIFMT_DSP_B: | 293 | case SND_SOC_DAIFMT_DSP_B: |
286 | regs->srgr2 |= FPER(wlen * channels - 1); | 294 | regs->srgr2 |= FPER(wlen * channels - 1); |
287 | regs->srgr1 |= FWID(0); | 295 | regs->srgr1 |= FWID(0); |
@@ -326,6 +334,13 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
326 | regs->rcr2 |= RDATDLY(1); | 334 | regs->rcr2 |= RDATDLY(1); |
327 | regs->xcr2 |= XDATDLY(1); | 335 | regs->xcr2 |= XDATDLY(1); |
328 | break; | 336 | break; |
337 | case SND_SOC_DAIFMT_DSP_A: | ||
338 | /* 1-bit data delay */ | ||
339 | regs->rcr2 |= RDATDLY(1); | ||
340 | regs->xcr2 |= XDATDLY(1); | ||
341 | /* Invert FS polarity configuration */ | ||
342 | temp_fmt ^= SND_SOC_DAIFMT_NB_IF; | ||
343 | break; | ||
329 | case SND_SOC_DAIFMT_DSP_B: | 344 | case SND_SOC_DAIFMT_DSP_B: |
330 | /* 0-bit data delay */ | 345 | /* 0-bit data delay */ |
331 | regs->rcr2 |= RDATDLY(0); | 346 | regs->rcr2 |= RDATDLY(0); |
@@ -492,13 +507,13 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = { | |||
492 | .id = (link_id), \ | 507 | .id = (link_id), \ |
493 | .playback = { \ | 508 | .playback = { \ |
494 | .channels_min = 1, \ | 509 | .channels_min = 1, \ |
495 | .channels_max = 2, \ | 510 | .channels_max = 4, \ |
496 | .rates = OMAP_MCBSP_RATES, \ | 511 | .rates = OMAP_MCBSP_RATES, \ |
497 | .formats = SNDRV_PCM_FMTBIT_S16_LE, \ | 512 | .formats = SNDRV_PCM_FMTBIT_S16_LE, \ |
498 | }, \ | 513 | }, \ |
499 | .capture = { \ | 514 | .capture = { \ |
500 | .channels_min = 1, \ | 515 | .channels_min = 1, \ |
501 | .channels_max = 2, \ | 516 | .channels_max = 4, \ |
502 | .rates = OMAP_MCBSP_RATES, \ | 517 | .rates = OMAP_MCBSP_RATES, \ |
503 | .formats = SNDRV_PCM_FMTBIT_S16_LE, \ | 518 | .formats = SNDRV_PCM_FMTBIT_S16_LE, \ |
504 | }, \ | 519 | }, \ |
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 07cf7f46b584..6454e15f7d28 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -87,8 +87,10 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, | |||
87 | struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; | 87 | struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; |
88 | int err = 0; | 88 | int err = 0; |
89 | 89 | ||
90 | /* return if this is a bufferless transfer e.g. | ||
91 | * codec <--> BT codec or GSM modem -- lg FIXME */ | ||
90 | if (!dma_data) | 92 | if (!dma_data) |
91 | return -ENODEV; | 93 | return 0; |
92 | 94 | ||
93 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 95 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
94 | runtime->dma_bytes = params_buffer_bytes(params); | 96 | runtime->dma_bytes = params_buffer_bytes(params); |
@@ -134,6 +136,11 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
134 | struct omap_pcm_dma_data *dma_data = prtd->dma_data; | 136 | struct omap_pcm_dma_data *dma_data = prtd->dma_data; |
135 | struct omap_dma_channel_params dma_params; | 137 | struct omap_dma_channel_params dma_params; |
136 | 138 | ||
139 | /* return if this is a bufferless transfer e.g. | ||
140 | * codec <--> BT codec or GSM modem -- lg FIXME */ | ||
141 | if (!prtd->dma_data) | ||
142 | return 0; | ||
143 | |||
137 | memset(&dma_params, 0, sizeof(dma_params)); | 144 | memset(&dma_params, 0, sizeof(dma_params)); |
138 | /* | 145 | /* |
139 | * Note: Regardless of interface data formats supported by OMAP McBSP | 146 | * Note: Regardless of interface data formats supported by OMAP McBSP |
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c index 0c2322dcf02a..027e1a40f8a1 100644 --- a/sound/soc/omap/omap2evm.c +++ b/sound/soc/omap/omap2evm.c | |||
@@ -86,7 +86,7 @@ static struct snd_soc_dai_link omap2evm_dai = { | |||
86 | .name = "TWL4030", | 86 | .name = "TWL4030", |
87 | .stream_name = "TWL4030", | 87 | .stream_name = "TWL4030", |
88 | .cpu_dai = &omap_mcbsp_dai[0], | 88 | .cpu_dai = &omap_mcbsp_dai[0], |
89 | .codec_dai = &twl4030_dai, | 89 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], |
90 | .ops = &omap2evm_ops, | 90 | .ops = &omap2evm_ops, |
91 | }; | 91 | }; |
92 | 92 | ||
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c index fd24a4acd2f5..b0cff9f33b7e 100644 --- a/sound/soc/omap/omap3beagle.c +++ b/sound/soc/omap/omap3beagle.c | |||
@@ -41,23 +41,33 @@ static int omap3beagle_hw_params(struct snd_pcm_substream *substream, | |||
41 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 41 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
42 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | 42 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; |
43 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 43 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
44 | unsigned int fmt; | ||
44 | int ret; | 45 | int ret; |
45 | 46 | ||
47 | switch (params_channels(params)) { | ||
48 | case 2: /* Stereo I2S mode */ | ||
49 | fmt = SND_SOC_DAIFMT_I2S | | ||
50 | SND_SOC_DAIFMT_NB_NF | | ||
51 | SND_SOC_DAIFMT_CBM_CFM; | ||
52 | break; | ||
53 | case 4: /* Four channel TDM mode */ | ||
54 | fmt = SND_SOC_DAIFMT_DSP_A | | ||
55 | SND_SOC_DAIFMT_IB_NF | | ||
56 | SND_SOC_DAIFMT_CBM_CFM; | ||
57 | break; | ||
58 | default: | ||
59 | return -EINVAL; | ||
60 | } | ||
61 | |||
46 | /* Set codec DAI configuration */ | 62 | /* Set codec DAI configuration */ |
47 | ret = snd_soc_dai_set_fmt(codec_dai, | 63 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); |
48 | SND_SOC_DAIFMT_I2S | | ||
49 | SND_SOC_DAIFMT_NB_NF | | ||
50 | SND_SOC_DAIFMT_CBM_CFM); | ||
51 | if (ret < 0) { | 64 | if (ret < 0) { |
52 | printk(KERN_ERR "can't set codec DAI configuration\n"); | 65 | printk(KERN_ERR "can't set codec DAI configuration\n"); |
53 | return ret; | 66 | return ret; |
54 | } | 67 | } |
55 | 68 | ||
56 | /* Set cpu DAI configuration */ | 69 | /* Set cpu DAI configuration */ |
57 | ret = snd_soc_dai_set_fmt(cpu_dai, | 70 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); |
58 | SND_SOC_DAIFMT_I2S | | ||
59 | SND_SOC_DAIFMT_NB_NF | | ||
60 | SND_SOC_DAIFMT_CBM_CFM); | ||
61 | if (ret < 0) { | 71 | if (ret < 0) { |
62 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | 72 | printk(KERN_ERR "can't set cpu DAI configuration\n"); |
63 | return ret; | 73 | return ret; |
@@ -83,7 +93,7 @@ static struct snd_soc_dai_link omap3beagle_dai = { | |||
83 | .name = "TWL4030", | 93 | .name = "TWL4030", |
84 | .stream_name = "TWL4030", | 94 | .stream_name = "TWL4030", |
85 | .cpu_dai = &omap_mcbsp_dai[0], | 95 | .cpu_dai = &omap_mcbsp_dai[0], |
86 | .codec_dai = &twl4030_dai, | 96 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], |
87 | .ops = &omap3beagle_ops, | 97 | .ops = &omap3beagle_ops, |
88 | }; | 98 | }; |
89 | 99 | ||
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c new file mode 100644 index 000000000000..9114c263077b --- /dev/null +++ b/sound/soc/omap/omap3evm.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* | ||
2 | * omap3evm.c -- ALSA SoC support for OMAP3 EVM | ||
3 | * | ||
4 | * Author: Anuj Aggarwal <anuj.aggarwal@ti.com> | ||
5 | * | ||
6 | * Based on sound/soc/omap/beagle.c by Steve Sakoman | ||
7 | * | ||
8 | * Copyright (C) 2008 Texas Instruments, Incorporated | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation version 2. | ||
13 | * | ||
14 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
15 | * whether express or implied; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <sound/soc-dapm.h> | ||
26 | |||
27 | #include <asm/mach-types.h> | ||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/gpio.h> | ||
30 | #include <mach/mcbsp.h> | ||
31 | |||
32 | #include "omap-mcbsp.h" | ||
33 | #include "omap-pcm.h" | ||
34 | #include "../codecs/twl4030.h" | ||
35 | |||
36 | static int omap3evm_hw_params(struct snd_pcm_substream *substream, | ||
37 | struct snd_pcm_hw_params *params) | ||
38 | { | ||
39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
40 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | ||
41 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | ||
42 | int ret; | ||
43 | |||
44 | /* Set codec DAI configuration */ | ||
45 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
46 | SND_SOC_DAIFMT_I2S | | ||
47 | SND_SOC_DAIFMT_NB_NF | | ||
48 | SND_SOC_DAIFMT_CBM_CFM); | ||
49 | if (ret < 0) { | ||
50 | printk(KERN_ERR "Can't set codec DAI configuration\n"); | ||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | /* Set cpu DAI configuration */ | ||
55 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
56 | SND_SOC_DAIFMT_I2S | | ||
57 | SND_SOC_DAIFMT_NB_NF | | ||
58 | SND_SOC_DAIFMT_CBM_CFM); | ||
59 | if (ret < 0) { | ||
60 | printk(KERN_ERR "Can't set cpu DAI configuration\n"); | ||
61 | return ret; | ||
62 | } | ||
63 | |||
64 | /* Set the codec system clock for DAC and ADC */ | ||
65 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
66 | SND_SOC_CLOCK_IN); | ||
67 | if (ret < 0) { | ||
68 | printk(KERN_ERR "Can't set codec system clock\n"); | ||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static struct snd_soc_ops omap3evm_ops = { | ||
76 | .hw_params = omap3evm_hw_params, | ||
77 | }; | ||
78 | |||
79 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
80 | static struct snd_soc_dai_link omap3evm_dai = { | ||
81 | .name = "TWL4030", | ||
82 | .stream_name = "TWL4030", | ||
83 | .cpu_dai = &omap_mcbsp_dai[0], | ||
84 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], | ||
85 | .ops = &omap3evm_ops, | ||
86 | }; | ||
87 | |||
88 | /* Audio machine driver */ | ||
89 | static struct snd_soc_card snd_soc_omap3evm = { | ||
90 | .name = "omap3evm", | ||
91 | .platform = &omap_soc_platform, | ||
92 | .dai_link = &omap3evm_dai, | ||
93 | .num_links = 1, | ||
94 | }; | ||
95 | |||
96 | /* Audio subsystem */ | ||
97 | static struct snd_soc_device omap3evm_snd_devdata = { | ||
98 | .card = &snd_soc_omap3evm, | ||
99 | .codec_dev = &soc_codec_dev_twl4030, | ||
100 | }; | ||
101 | |||
102 | static struct platform_device *omap3evm_snd_device; | ||
103 | |||
104 | static int __init omap3evm_soc_init(void) | ||
105 | { | ||
106 | int ret; | ||
107 | |||
108 | if (!machine_is_omap3evm()) { | ||
109 | pr_err("Not OMAP3 EVM!\n"); | ||
110 | return -ENODEV; | ||
111 | } | ||
112 | pr_info("OMAP3 EVM SoC init\n"); | ||
113 | |||
114 | omap3evm_snd_device = platform_device_alloc("soc-audio", -1); | ||
115 | if (!omap3evm_snd_device) { | ||
116 | printk(KERN_ERR "Platform device allocation failed\n"); | ||
117 | return -ENOMEM; | ||
118 | } | ||
119 | |||
120 | platform_set_drvdata(omap3evm_snd_device, &omap3evm_snd_devdata); | ||
121 | omap3evm_snd_devdata.dev = &omap3evm_snd_device->dev; | ||
122 | *(unsigned int *)omap3evm_dai.cpu_dai->private_data = 1; | ||
123 | |||
124 | ret = platform_device_add(omap3evm_snd_device); | ||
125 | if (ret) | ||
126 | goto err1; | ||
127 | |||
128 | return 0; | ||
129 | |||
130 | err1: | ||
131 | printk(KERN_ERR "Unable to add platform device\n"); | ||
132 | platform_device_put(omap3evm_snd_device); | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static void __exit omap3evm_soc_exit(void) | ||
138 | { | ||
139 | platform_device_unregister(omap3evm_snd_device); | ||
140 | } | ||
141 | |||
142 | module_init(omap3evm_soc_init); | ||
143 | module_exit(omap3evm_soc_exit); | ||
144 | |||
145 | MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>"); | ||
146 | MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM"); | ||
147 | MODULE_LICENSE("GPLv2"); | ||
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index fe282d4ef422..ad219aaf7cb8 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c | |||
@@ -228,14 +228,14 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { | |||
228 | .name = "PCM1773", | 228 | .name = "PCM1773", |
229 | .stream_name = "HiFi Out", | 229 | .stream_name = "HiFi Out", |
230 | .cpu_dai = &omap_mcbsp_dai[0], | 230 | .cpu_dai = &omap_mcbsp_dai[0], |
231 | .codec_dai = &twl4030_dai, | 231 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], |
232 | .ops = &omap3pandora_out_ops, | 232 | .ops = &omap3pandora_out_ops, |
233 | .init = omap3pandora_out_init, | 233 | .init = omap3pandora_out_init, |
234 | }, { | 234 | }, { |
235 | .name = "TWL4030", | 235 | .name = "TWL4030", |
236 | .stream_name = "Line/Mic In", | 236 | .stream_name = "Line/Mic In", |
237 | .cpu_dai = &omap_mcbsp_dai[1], | 237 | .cpu_dai = &omap_mcbsp_dai[1], |
238 | .codec_dai = &twl4030_dai, | 238 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], |
239 | .ops = &omap3pandora_in_ops, | 239 | .ops = &omap3pandora_in_ops, |
240 | .init = omap3pandora_in_init, | 240 | .init = omap3pandora_in_init, |
241 | } | 241 | } |
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c index a72dc4e159e5..ec4f8fd8b3a2 100644 --- a/sound/soc/omap/overo.c +++ b/sound/soc/omap/overo.c | |||
@@ -83,7 +83,7 @@ static struct snd_soc_dai_link overo_dai = { | |||
83 | .name = "TWL4030", | 83 | .name = "TWL4030", |
84 | .stream_name = "TWL4030", | 84 | .stream_name = "TWL4030", |
85 | .cpu_dai = &omap_mcbsp_dai[0], | 85 | .cpu_dai = &omap_mcbsp_dai[0], |
86 | .codec_dai = &twl4030_dai, | 86 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], |
87 | .ops = &overo_ops, | 87 | .ops = &overo_ops, |
88 | }; | 88 | }; |
89 | 89 | ||
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index 10f1c867f11d..b719e5db4f57 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c | |||
@@ -84,6 +84,49 @@ static struct snd_soc_ops sdp3430_ops = { | |||
84 | .hw_params = sdp3430_hw_params, | 84 | .hw_params = sdp3430_hw_params, |
85 | }; | 85 | }; |
86 | 86 | ||
87 | static int sdp3430_hw_voice_params(struct snd_pcm_substream *substream, | ||
88 | struct snd_pcm_hw_params *params) | ||
89 | { | ||
90 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
91 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | ||
92 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | ||
93 | int ret; | ||
94 | |||
95 | /* Set codec DAI configuration */ | ||
96 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
97 | SND_SOC_DAIFMT_DSP_A | | ||
98 | SND_SOC_DAIFMT_IB_NF | | ||
99 | SND_SOC_DAIFMT_CBS_CFM); | ||
100 | if (ret) { | ||
101 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | /* Set cpu DAI configuration */ | ||
106 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
107 | SND_SOC_DAIFMT_DSP_A | | ||
108 | SND_SOC_DAIFMT_IB_NF | | ||
109 | SND_SOC_DAIFMT_CBM_CFM); | ||
110 | if (ret < 0) { | ||
111 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | /* Set the codec system clock for DAC and ADC */ | ||
116 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
117 | SND_SOC_CLOCK_IN); | ||
118 | if (ret < 0) { | ||
119 | printk(KERN_ERR "can't set codec system clock\n"); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static struct snd_soc_ops sdp3430_voice_ops = { | ||
127 | .hw_params = sdp3430_hw_voice_params, | ||
128 | }; | ||
129 | |||
87 | /* Headset jack */ | 130 | /* Headset jack */ |
88 | static struct snd_soc_jack hs_jack; | 131 | static struct snd_soc_jack hs_jack; |
89 | 132 | ||
@@ -192,28 +235,58 @@ static int sdp3430_twl4030_init(struct snd_soc_codec *codec) | |||
192 | return ret; | 235 | return ret; |
193 | } | 236 | } |
194 | 237 | ||
238 | static int sdp3430_twl4030_voice_init(struct snd_soc_codec *codec) | ||
239 | { | ||
240 | unsigned short reg; | ||
241 | |||
242 | /* Enable voice interface */ | ||
243 | reg = codec->read(codec, TWL4030_REG_VOICE_IF); | ||
244 | reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN; | ||
245 | codec->write(codec, TWL4030_REG_VOICE_IF, reg); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | |||
195 | /* Digital audio interface glue - connects codec <--> CPU */ | 251 | /* Digital audio interface glue - connects codec <--> CPU */ |
196 | static struct snd_soc_dai_link sdp3430_dai = { | 252 | static struct snd_soc_dai_link sdp3430_dai[] = { |
197 | .name = "TWL4030", | 253 | { |
198 | .stream_name = "TWL4030", | 254 | .name = "TWL4030 I2S", |
199 | .cpu_dai = &omap_mcbsp_dai[0], | 255 | .stream_name = "TWL4030 Audio", |
200 | .codec_dai = &twl4030_dai, | 256 | .cpu_dai = &omap_mcbsp_dai[0], |
201 | .init = sdp3430_twl4030_init, | 257 | .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], |
202 | .ops = &sdp3430_ops, | 258 | .init = sdp3430_twl4030_init, |
259 | .ops = &sdp3430_ops, | ||
260 | }, | ||
261 | { | ||
262 | .name = "TWL4030 PCM", | ||
263 | .stream_name = "TWL4030 Voice", | ||
264 | .cpu_dai = &omap_mcbsp_dai[1], | ||
265 | .codec_dai = &twl4030_dai[TWL4030_DAI_VOICE], | ||
266 | .init = sdp3430_twl4030_voice_init, | ||
267 | .ops = &sdp3430_voice_ops, | ||
268 | }, | ||
203 | }; | 269 | }; |
204 | 270 | ||
205 | /* Audio machine driver */ | 271 | /* Audio machine driver */ |
206 | static struct snd_soc_card snd_soc_sdp3430 = { | 272 | static struct snd_soc_card snd_soc_sdp3430 = { |
207 | .name = "SDP3430", | 273 | .name = "SDP3430", |
208 | .platform = &omap_soc_platform, | 274 | .platform = &omap_soc_platform, |
209 | .dai_link = &sdp3430_dai, | 275 | .dai_link = sdp3430_dai, |
210 | .num_links = 1, | 276 | .num_links = ARRAY_SIZE(sdp3430_dai), |
277 | }; | ||
278 | |||
279 | /* twl4030 setup */ | ||
280 | static struct twl4030_setup_data twl4030_setup = { | ||
281 | .ramp_delay_value = 3, | ||
282 | .sysclk = 26000, | ||
211 | }; | 283 | }; |
212 | 284 | ||
213 | /* Audio subsystem */ | 285 | /* Audio subsystem */ |
214 | static struct snd_soc_device sdp3430_snd_devdata = { | 286 | static struct snd_soc_device sdp3430_snd_devdata = { |
215 | .card = &snd_soc_sdp3430, | 287 | .card = &snd_soc_sdp3430, |
216 | .codec_dev = &soc_codec_dev_twl4030, | 288 | .codec_dev = &soc_codec_dev_twl4030, |
289 | .codec_data = &twl4030_setup, | ||
217 | }; | 290 | }; |
218 | 291 | ||
219 | static struct platform_device *sdp3430_snd_device; | 292 | static struct platform_device *sdp3430_snd_device; |
@@ -236,7 +309,8 @@ static int __init sdp3430_soc_init(void) | |||
236 | 309 | ||
237 | platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata); | 310 | platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata); |
238 | sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev; | 311 | sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev; |
239 | *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */ | 312 | *(unsigned int *)sdp3430_dai[0].cpu_dai->private_data = 1; /* McBSP2 */ |
313 | *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */ | ||
240 | 314 | ||
241 | ret = platform_device_add(sdp3430_snd_device); | 315 | ret = platform_device_add(sdp3430_snd_device); |
242 | if (ret) | 316 | if (ret) |