aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-08 18:07:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-08 18:07:14 -0400
commitf5a246eab9a268f51ba8189ea5b098a1bfff200e (patch)
treea6ff7169e0bcaca498d9aec8b0624de1b74eaecb /sound/soc/omap
parentd5bbd43d5f450c3fca058f5b85f3dfb4e8cc88c9 (diff)
parent7ff34ad80b7080fafaac8efa9ef0061708eddd51 (diff)
Merge tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This contains pretty many small commits covering fairly large range of files in sound/ directory. Partly because of additional API support and partly because of constantly developed ASoC and ARM stuff. Some highlights: - Introduced the helper function and documentation for exposing the channel map via control API, as discussed in Plumbers; most of PCI drivers are covered, will follow more drivers later - Most of drivers have been replaced with the new PM callbacks (if the bus is supported) - HD-audio controller got the support of runtime PM and the support of D3 clock-stop. Also changing the power_save option in sysfs kicks off immediately to enable / disable the power-save mode. - Another significant code change in HD-audio is the rewrite of firmware loading code. Other than that, most of changes in HD-audio are continued cleanups and standardization for the generic auto parser and bug fixes (HBR, device-specific fixups), in addition to the support of channel-map API. - Addition of ASoC bindings for the compressed API, used by the mid-x86 drivers. - Lots of cleanups and API refreshes for ASoC codec drivers and DaVinci. - Conversion of OMAP to dmaengine. - New machine driver for Wolfson Microelectronics Bells. - New CODEC driver for Wolfson Microelectronics WM0010. - Enhancements to the ux500 and wm2000 drivers - A new driver for DA9055 and the support for regulator bypass mode." Fix up various arm soc header file reorg conflicts. * tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (339 commits) ALSA: hda - Add new codec ALC283 ALC290 support ALSA: hda - avoid unneccesary indices on "Headphone Jack" controls ALSA: hda - fix indices on boost volume on Conexant ALSA: aloop - add locking to timer access ALSA: hda - Fix hang caused by race during suspend. sound: Remove unnecessary semicolon ALSA: hda/realtek - Fix detection of ALC271X codec ALSA: hda - Add inverted internal mic quirk for Lenovo IdeaPad U310 ALSA: hda - make Realtek/Sigmatel/Conexant use the generic unsol event ALSA: hda - make a generic unsol event handler ASoC: codecs: Add DA9055 codec driver ASoC: eukrea-tlv320: Convert it to platform driver ALSA: ASoC: add DT bindings for CS4271 ASoC: wm_hubs: Ensure volume updates are handled during class W startup ASoC: wm5110: Adding missing volume update bits ASoC: wm5110: Add OUT3R support ASoC: wm5110: Add AEC loopback support ASoC: wm5110: Rename EPOUT to HPOUT3 ASoC: arizona: Add more clock rates ASoC: arizona: Add more DSP options for mixer input muxes ...
Diffstat (limited to 'sound/soc/omap')
-rw-r--r--sound/soc/omap/Kconfig51
-rw-r--r--sound/soc/omap/Makefile10
-rw-r--r--sound/soc/omap/am3517evm.c21
-rw-r--r--sound/soc/omap/igep0020.c120
-rw-r--r--sound/soc/omap/mcbsp.c54
-rw-r--r--sound/soc/omap/mcbsp.h3
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c145
-rw-r--r--sound/soc/omap/omap-dmic.c9
-rw-r--r--sound/soc/omap/omap-hdmi.c17
-rw-r--r--sound/soc/omap/omap-mcbsp.c230
-rw-r--r--sound/soc/omap/omap-mcbsp.h20
-rw-r--r--sound/soc/omap/omap-mcpdm.c92
-rw-r--r--sound/soc/omap/omap-pcm.c236
-rw-r--r--sound/soc/omap/omap-pcm.h4
-rw-r--r--sound/soc/omap/omap-twl4030.c188
-rw-r--r--sound/soc/omap/omap3beagle.c150
-rw-r--r--sound/soc/omap/omap3evm.c118
-rw-r--r--sound/soc/omap/overo.c122
-rw-r--r--sound/soc/omap/zoom2.c4
19 files changed, 579 insertions, 1015 deletions
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 57a2fa751085..7048137f9a33 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,6 +1,7 @@
1config SND_OMAP_SOC 1config SND_OMAP_SOC
2 tristate "SoC Audio for the Texas Instruments OMAP chips" 2 tristate "SoC Audio for the Texas Instruments OMAP chips"
3 depends on ARCH_OMAP 3 depends on ARCH_OMAP && DMA_OMAP
4 select SND_SOC_DMAENGINE_PCM
4 5
5config SND_OMAP_SOC_DMIC 6config SND_OMAP_SOC_DMIC
6 tristate 7 tristate
@@ -60,23 +61,6 @@ config SND_OMAP_SOC_OSK5912
60 help 61 help
61 Say Y if you want to add support for SoC audio on osk5912. 62 Say Y if you want to add support for SoC audio on osk5912.
62 63
63config SND_OMAP_SOC_OVERO
64 tristate "SoC Audio support for Gumstix Overo and CompuLab CM-T35"
65 depends on TWL4030_CORE && SND_OMAP_SOC && (MACH_OVERO || MACH_CM_T35)
66 select SND_OMAP_SOC_MCBSP
67 select SND_SOC_TWL4030
68 help
69 Say Y if you want to add support for SoC audio on the
70 Gumstix Overo or CompuLab CM-T35
71
72config SND_OMAP_SOC_OMAP3EVM
73 tristate "SoC Audio support for OMAP3EVM board"
74 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM
75 select SND_OMAP_SOC_MCBSP
76 select SND_SOC_TWL4030
77 help
78 Say Y if you want to add support for SoC audio on the omap3evm board.
79
80config SND_OMAP_SOC_AM3517EVM 64config SND_OMAP_SOC_AM3517EVM
81 tristate "SoC Audio support for OMAP3517 / AM3517 EVM" 65 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
82 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C 66 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
@@ -95,6 +79,19 @@ config SND_OMAP_SOC_SDP3430
95 Say Y if you want to add support for SoC audio on Texas Instruments 79 Say Y if you want to add support for SoC audio on Texas Instruments
96 SDP3430. 80 SDP3430.
97 81
82config SND_OMAP_SOC_OMAP_TWL4030
83 tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
84 depends on TWL4030_CORE && SND_OMAP_SOC
85 select SND_OMAP_SOC_MCBSP
86 select SND_SOC_TWL4030
87 help
88 Say Y if you want to add support for SoC audio on TI SoC based boards
89 using twl4030 as c codec. This driver currently supports:
90 - Beagleboard or Devkit8000
91 - Gumstix Overo or CompuLab CM-T35/CM-T3730
92 - IGEP v2
93 - OMAP3EVM
94
98config SND_OMAP_SOC_OMAP_ABE_TWL6040 95config SND_OMAP_SOC_OMAP_ABE_TWL6040
99 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" 96 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
100 depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 97 depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
@@ -127,16 +124,6 @@ config SND_OMAP_SOC_OMAP3_PANDORA
127 help 124 help
128 Say Y if you want to add support for SoC audio on the OMAP3 Pandora. 125 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
129 126
130config SND_OMAP_SOC_OMAP3_BEAGLE
131 tristate "SoC Audio support for OMAP3 Beagle and Devkit8000"
132 depends on TWL4030_CORE && SND_OMAP_SOC
133 depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000)
134 select SND_OMAP_SOC_MCBSP
135 select SND_SOC_TWL4030
136 help
137 Say Y if you want to add support for SoC audio on the Beagleboard or
138 the clone Devkit8000.
139
140config SND_OMAP_SOC_ZOOM2 127config SND_OMAP_SOC_ZOOM2
141 tristate "SoC Audio support for Zoom2" 128 tristate "SoC Audio support for Zoom2"
142 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2 129 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
@@ -144,11 +131,3 @@ config SND_OMAP_SOC_ZOOM2
144 select SND_SOC_TWL4030 131 select SND_SOC_TWL4030
145 help 132 help
146 Say Y if you want to add support for Soc audio on Zoom2 board. 133 Say Y if you want to add support for Soc audio on Zoom2 board.
147
148config SND_OMAP_SOC_IGEP0020
149 tristate "SoC Audio support for IGEP v2"
150 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_IGEP0020
151 select SND_OMAP_SOC_MCBSP
152 select SND_SOC_TWL4030
153 help
154 Say Y if you want to add support for Soc audio on IGEP v2 board.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 0e14dd322565..19637e55ea48 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -16,29 +16,23 @@ snd-soc-n810-objs := n810.o
16snd-soc-rx51-objs := rx51.o 16snd-soc-rx51-objs := rx51.o
17snd-soc-ams-delta-objs := ams-delta.o 17snd-soc-ams-delta-objs := ams-delta.o
18snd-soc-osk5912-objs := osk5912.o 18snd-soc-osk5912-objs := osk5912.o
19snd-soc-overo-objs := overo.o
20snd-soc-omap3evm-objs := omap3evm.o
21snd-soc-am3517evm-objs := am3517evm.o 19snd-soc-am3517evm-objs := am3517evm.o
22snd-soc-sdp3430-objs := sdp3430.o 20snd-soc-sdp3430-objs := sdp3430.o
23snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o 21snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
22snd-soc-omap-twl4030-objs := omap-twl4030.o
24snd-soc-omap3pandora-objs := omap3pandora.o 23snd-soc-omap3pandora-objs := omap3pandora.o
25snd-soc-omap3beagle-objs := omap3beagle.o
26snd-soc-zoom2-objs := zoom2.o 24snd-soc-zoom2-objs := zoom2.o
27snd-soc-igep0020-objs := igep0020.o
28snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o 25snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o
29 26
30obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 27obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
31obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o 28obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
32obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o 29obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
33obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 30obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
34obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
35obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o 31obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
36obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
37obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o 32obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
38obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 33obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
39obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o 34obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
35obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
40obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 36obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
41obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
42obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o 37obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
43obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o
44obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o 38obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index a52e87d28b6e..fad350682ca2 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -41,32 +41,15 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
41{ 41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *codec_dai = rtd->codec_dai; 43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
44 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
45 int ret; 44 int ret;
46 45
47 /* Set the codec system clock for DAC and ADC */ 46 /* Set the codec system clock for DAC and ADC */
48 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 47 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
49 CODEC_CLOCK, SND_SOC_CLOCK_IN); 48 CODEC_CLOCK, SND_SOC_CLOCK_IN);
50 if (ret < 0) { 49 if (ret < 0)
51 printk(KERN_ERR "can't set codec system clock\n"); 50 printk(KERN_ERR "can't set codec system clock\n");
52 return ret;
53 }
54
55 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
56 SND_SOC_CLOCK_IN);
57 if (ret < 0) {
58 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
59 return ret;
60 }
61 51
62 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0, 52 return ret;
63 SND_SOC_CLOCK_IN);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
66 return ret;
67 }
68
69 return 0;
70} 53}
71 54
72static struct snd_soc_ops am3517evm_ops = { 55static struct snd_soc_ops am3517evm_ops = {
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
deleted file mode 100644
index 5ed871676ed0..000000000000
--- a/sound/soc/omap/igep0020.c
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * igep0020.c -- SoC audio for IGEP v2
3 *
4 * Based on sound/soc/omap/overo.c by Steve Sakoman
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/module.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/soc.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <linux/platform_data/asoc-ti-mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36
37static int igep2_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 int ret;
43
44 /* Set the codec system clock for DAC and ADC */
45 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
46 SND_SOC_CLOCK_IN);
47 if (ret < 0) {
48 printk(KERN_ERR "can't set codec system clock\n");
49 return ret;
50 }
51
52 return 0;
53}
54
55static struct snd_soc_ops igep2_ops = {
56 .hw_params = igep2_hw_params,
57};
58
59/* Digital audio interface glue - connects codec <--> CPU */
60static struct snd_soc_dai_link igep2_dai = {
61 .name = "TWL4030",
62 .stream_name = "TWL4030",
63 .cpu_dai_name = "omap-mcbsp.2",
64 .codec_dai_name = "twl4030-hifi",
65 .platform_name = "omap-pcm-audio",
66 .codec_name = "twl4030-codec",
67 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
68 SND_SOC_DAIFMT_CBM_CFM,
69 .ops = &igep2_ops,
70};
71
72/* Audio machine driver */
73static struct snd_soc_card snd_soc_card_igep2 = {
74 .name = "igep2",
75 .owner = THIS_MODULE,
76 .dai_link = &igep2_dai,
77 .num_links = 1,
78};
79
80static struct platform_device *igep2_snd_device;
81
82static int __init igep2_soc_init(void)
83{
84 int ret;
85
86 if (!machine_is_igep0020())
87 return -ENODEV;
88 printk(KERN_INFO "IGEP v2 SoC init\n");
89
90 igep2_snd_device = platform_device_alloc("soc-audio", -1);
91 if (!igep2_snd_device) {
92 printk(KERN_ERR "Platform device allocation failed\n");
93 return -ENOMEM;
94 }
95
96 platform_set_drvdata(igep2_snd_device, &snd_soc_card_igep2);
97
98 ret = platform_device_add(igep2_snd_device);
99 if (ret)
100 goto err1;
101
102 return 0;
103
104err1:
105 printk(KERN_ERR "Unable to add platform device\n");
106 platform_device_put(igep2_snd_device);
107
108 return ret;
109}
110module_init(igep2_soc_init);
111
112static void __exit igep2_soc_exit(void)
113{
114 platform_device_unregister(igep2_snd_device);
115}
116module_exit(igep2_soc_exit);
117
118MODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>");
119MODULE_DESCRIPTION("ALSA SoC IGEP v2");
120MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index a681a9a8b846..afb8d4f1bedf 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -24,6 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/pm_runtime.h>
27 28
28#include <linux/platform_data/asoc-ti-mcbsp.h> 29#include <linux/platform_data/asoc-ti-mcbsp.h>
29 30
@@ -728,50 +729,39 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)
728 729
729int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) 730int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
730{ 731{
732 struct clk *fck_src;
731 const char *src; 733 const char *src;
734 int r;
732 735
733 if (fck_src_id == MCBSP_CLKS_PAD_SRC) 736 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
734 src = "clks_ext"; 737 src = "pad_fck";
735 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) 738 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
736 src = "clks_fclk"; 739 src = "prcm_fck";
737 else 740 else
738 return -EINVAL; 741 return -EINVAL;
739 742
740 if (mcbsp->pdata->set_clk_src) 743 fck_src = clk_get(mcbsp->dev, src);
741 return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src); 744 if (IS_ERR(fck_src)) {
742 else 745 dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src);
743 return -EINVAL; 746 return -EINVAL;
744} 747 }
745
746int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
747{
748 const char *signal, *src;
749 748
750 if (!mcbsp->pdata->mux_signal) 749 pm_runtime_put_sync(mcbsp->dev);
751 return -EINVAL;
752 750
753 switch (mux) { 751 r = clk_set_parent(mcbsp->fclk, fck_src);
754 case CLKR_SRC_CLKR: 752 if (r) {
755 signal = "clkr"; 753 dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n",
756 src = "clkr"; 754 src);
757 break; 755 clk_put(fck_src);
758 case CLKR_SRC_CLKX: 756 return r;
759 signal = "clkr";
760 src = "clkx";
761 break;
762 case FSR_SRC_FSR:
763 signal = "fsr";
764 src = "fsr";
765 break;
766 case FSR_SRC_FSX:
767 signal = "fsr";
768 src = "fsx";
769 break;
770 default:
771 return -EINVAL;
772 } 757 }
773 758
774 return mcbsp->pdata->mux_signal(mcbsp->dev, signal, src); 759 pm_runtime_get_sync(mcbsp->dev);
760
761 clk_put(fck_src);
762
763 return 0;
764
775} 765}
776 766
777#define max_thres(m) (mcbsp->pdata->buffer_size) 767#define max_thres(m) (mcbsp->pdata->buffer_size)
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
index 262a6152111f..49a67259ce5a 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/omap/mcbsp.h
@@ -334,9 +334,6 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx);
334/* McBSP functional clock source changing function */ 334/* McBSP functional clock source changing function */
335int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); 335int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id);
336 336
337/* McBSP signal muxing API */
338int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux);
339
340/* Sidetone specific API */ 337/* Sidetone specific API */
341int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); 338int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain);
342int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); 339int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain);
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 45909ca889fa..4a73ef3ae12f 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -25,6 +25,7 @@
25#include <linux/mfd/twl6040.h> 25#include <linux/mfd/twl6040.h>
26#include <linux/platform_data/omap-abe-twl6040.h> 26#include <linux/platform_data/omap-abe-twl6040.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/of.h>
28 29
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/pcm.h> 31#include <sound/pcm.h>
@@ -39,6 +40,8 @@
39struct abe_twl6040 { 40struct abe_twl6040 {
40 int jack_detection; /* board can detect jack events */ 41 int jack_detection; /* board can detect jack events */
41 int mclk_freq; /* MCLK frequency speed for twl6040 */ 42 int mclk_freq; /* MCLK frequency speed for twl6040 */
43
44 struct platform_device *dmic_codec_dev;
42}; 45};
43 46
44static int omap_abe_hw_params(struct snd_pcm_substream *substream, 47static int omap_abe_hw_params(struct snd_pcm_substream *substream,
@@ -181,17 +184,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
181 int hs_trim; 184 int hs_trim;
182 int ret = 0; 185 int ret = 0;
183 186
184 /* Disable not connected paths if not used */
185 twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
186 twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
187 twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
188 twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
189 twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
190 twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
191 twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
192 twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
193 twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
194
195 /* 187 /*
196 * Configure McPDM offset cancellation based on the HSOTRIM value from 188 * Configure McPDM offset cancellation based on the HSOTRIM value from
197 * twl6040. 189 * twl6040.
@@ -212,6 +204,24 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
212 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); 204 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
213 } 205 }
214 206
207 /*
208 * NULL pdata means we booted with DT. In this case the routing is
209 * provided and the card is fully routed, no need to mark pins.
210 */
211 if (!pdata)
212 return ret;
213
214 /* Disable not connected paths if not used */
215 twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
216 twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
217 twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
218 twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
219 twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
220 twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
221 twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
222 twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
223 twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
224
215 return ret; 225 return ret;
216} 226}
217 227
@@ -266,52 +276,116 @@ static struct snd_soc_card omap_abe_card = {
266static __devinit int omap_abe_probe(struct platform_device *pdev) 276static __devinit int omap_abe_probe(struct platform_device *pdev)
267{ 277{
268 struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); 278 struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
279 struct device_node *node = pdev->dev.of_node;
269 struct snd_soc_card *card = &omap_abe_card; 280 struct snd_soc_card *card = &omap_abe_card;
270 struct abe_twl6040 *priv; 281 struct abe_twl6040 *priv;
271 int num_links = 0; 282 int num_links = 0;
272 int ret; 283 int ret = 0;
273 284
274 card->dev = &pdev->dev; 285 card->dev = &pdev->dev;
275 286
276 if (!pdata) {
277 dev_err(&pdev->dev, "Missing pdata\n");
278 return -ENODEV;
279 }
280
281 priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); 287 priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL);
282 if (priv == NULL) 288 if (priv == NULL)
283 return -ENOMEM; 289 return -ENOMEM;
284 290
285 if (pdata->card_name) { 291 priv->dmic_codec_dev = ERR_PTR(-EINVAL);
286 card->name = pdata->card_name; 292
293 if (node) {
294 struct device_node *dai_node;
295
296 if (snd_soc_of_parse_card_name(card, "ti,model")) {
297 dev_err(&pdev->dev, "Card name is not provided\n");
298 return -ENODEV;
299 }
300
301 ret = snd_soc_of_parse_audio_routing(card,
302 "ti,audio-routing");
303 if (ret) {
304 dev_err(&pdev->dev,
305 "Error while parsing DAPM routing\n");
306 return ret;
307 }
308
309 dai_node = of_parse_phandle(node, "ti,mcpdm", 0);
310 if (!dai_node) {
311 dev_err(&pdev->dev, "McPDM node is not provided\n");
312 return -EINVAL;
313 }
314 abe_twl6040_dai_links[0].cpu_dai_name = NULL;
315 abe_twl6040_dai_links[0].cpu_of_node = dai_node;
316
317 dai_node = of_parse_phandle(node, "ti,dmic", 0);
318 if (dai_node) {
319 num_links = 2;
320 abe_twl6040_dai_links[1].cpu_dai_name = NULL;
321 abe_twl6040_dai_links[1].cpu_of_node = dai_node;
322
323 priv->dmic_codec_dev = platform_device_register_simple(
324 "dmic-codec", -1, NULL, 0);
325 if (IS_ERR(priv->dmic_codec_dev)) {
326 dev_err(&pdev->dev,
327 "Can't instantiate dmic-codec\n");
328 return PTR_ERR(priv->dmic_codec_dev);
329 }
330 } else {
331 num_links = 1;
332 }
333
334 of_property_read_u32(node, "ti,jack-detection",
335 &priv->jack_detection);
336 of_property_read_u32(node, "ti,mclk-freq",
337 &priv->mclk_freq);
338 if (!priv->mclk_freq) {
339 dev_err(&pdev->dev, "MCLK frequency not provided\n");
340 ret = -EINVAL;
341 goto err_unregister;
342 }
343
344 omap_abe_card.fully_routed = 1;
345 } else if (pdata) {
346 if (pdata->card_name) {
347 card->name = pdata->card_name;
348 } else {
349 dev_err(&pdev->dev, "Card name is not provided\n");
350 return -ENODEV;
351 }
352
353 if (pdata->has_dmic)
354 num_links = 2;
355 else
356 num_links = 1;
357
358 priv->jack_detection = pdata->jack_detection;
359 priv->mclk_freq = pdata->mclk_freq;
287 } else { 360 } else {
288 dev_err(&pdev->dev, "Card name is not provided\n"); 361 dev_err(&pdev->dev, "Missing pdata\n");
289 return -ENODEV; 362 return -ENODEV;
290 } 363 }
291 364
292 priv->jack_detection = pdata->jack_detection;
293 priv->mclk_freq = pdata->mclk_freq;
294
295 365
296 if (!priv->mclk_freq) { 366 if (!priv->mclk_freq) {
297 dev_err(&pdev->dev, "MCLK frequency missing\n"); 367 dev_err(&pdev->dev, "MCLK frequency missing\n");
298 return -ENODEV; 368 ret = -ENODEV;
369 goto err_unregister;
299 } 370 }
300 371
301 if (pdata->has_dmic)
302 num_links = 2;
303 else
304 num_links = 1;
305
306 card->dai_link = abe_twl6040_dai_links; 372 card->dai_link = abe_twl6040_dai_links;
307 card->num_links = num_links; 373 card->num_links = num_links;
308 374
309 snd_soc_card_set_drvdata(card, priv); 375 snd_soc_card_set_drvdata(card, priv);
310 376
311 ret = snd_soc_register_card(card); 377 ret = snd_soc_register_card(card);
312 if (ret) 378 if (ret) {
313 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 379 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
314 ret); 380 ret);
381 goto err_unregister;
382 }
383
384 return 0;
385
386err_unregister:
387 if (!IS_ERR(priv->dmic_codec_dev))
388 platform_device_unregister(priv->dmic_codec_dev);
315 389
316 return ret; 390 return ret;
317} 391}
@@ -319,17 +393,28 @@ static __devinit int omap_abe_probe(struct platform_device *pdev)
319static int __devexit omap_abe_remove(struct platform_device *pdev) 393static int __devexit omap_abe_remove(struct platform_device *pdev)
320{ 394{
321 struct snd_soc_card *card = platform_get_drvdata(pdev); 395 struct snd_soc_card *card = platform_get_drvdata(pdev);
396 struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
322 397
323 snd_soc_unregister_card(card); 398 snd_soc_unregister_card(card);
324 399
400 if (!IS_ERR(priv->dmic_codec_dev))
401 platform_device_unregister(priv->dmic_codec_dev);
402
325 return 0; 403 return 0;
326} 404}
327 405
406static const struct of_device_id omap_abe_of_match[] = {
407 {.compatible = "ti,abe-twl6040", },
408 { },
409};
410MODULE_DEVICE_TABLE(of, omap_abe_of_match);
411
328static struct platform_driver omap_abe_driver = { 412static struct platform_driver omap_abe_driver = {
329 .driver = { 413 .driver = {
330 .name = "omap-abe-twl6040", 414 .name = "omap-abe-twl6040",
331 .owner = THIS_MODULE, 415 .owner = THIS_MODULE,
332 .pm = &snd_soc_pm_ops, 416 .pm = &snd_soc_pm_ops,
417 .of_match_table = omap_abe_of_match,
333 }, 418 },
334 .probe = omap_abe_probe, 419 .probe = omap_abe_probe,
335 .remove = __devexit_p(omap_abe_remove), 420 .remove = __devexit_p(omap_abe_remove),
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 75f5dca0e8d2..68f2cd1a9206 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -33,7 +33,6 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/pm_runtime.h> 34#include <linux/pm_runtime.h>
35#include <linux/of_device.h> 35#include <linux/of_device.h>
36#include <plat/dma.h>
37 36
38#include <sound/core.h> 37#include <sound/core.h>
39#include <sound/pcm.h> 38#include <sound/pcm.h>
@@ -63,8 +62,6 @@ struct omap_dmic {
63 */ 62 */
64static struct omap_pcm_dma_data omap_dmic_dai_dma_params = { 63static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
65 .name = "DMIC capture", 64 .name = "DMIC capture",
66 .data_type = OMAP_DMA_DATA_TYPE_S32,
67 .sync_mode = OMAP_DMA_SYNC_PACKET,
68}; 65};
69 66
70static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) 67static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
@@ -121,6 +118,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
121 118
122 mutex_unlock(&dmic->mutex); 119 mutex_unlock(&dmic->mutex);
123 120
121 snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
124 return ret; 122 return ret;
125} 123}
126 124
@@ -205,6 +203,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
205 struct snd_soc_dai *dai) 203 struct snd_soc_dai *dai)
206{ 204{
207 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); 205 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
206 struct omap_pcm_dma_data *dma_data;
208 int channels; 207 int channels;
209 208
210 dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); 209 dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
@@ -230,8 +229,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
230 } 229 }
231 230
232 /* packet size is threshold * channels */ 231 /* packet size is threshold * channels */
233 omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels; 232 dma_data = snd_soc_dai_get_dma_data(dai, substream);
234 snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); 233 dma_data->packet_size = dmic->threshold * channels;
235 234
236 return 0; 235 return 0;
237} 236}
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index a08245d9203c..f59c69fb400e 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -34,7 +34,6 @@
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include <video/omapdss.h> 35#include <video/omapdss.h>
36 36
37#include <plat/dma.h>
38#include "omap-pcm.h" 37#include "omap-pcm.h"
39#include "omap-hdmi.h" 38#include "omap-hdmi.h"
40 39
@@ -68,6 +67,9 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
68 dev_err(dai->dev, "audio not supported\n"); 67 dev_err(dai->dev, "audio not supported\n");
69 return -ENODEV; 68 return -ENODEV;
70 } 69 }
70
71 snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params);
72
71 return 0; 73 return 0;
72} 74}
73 75
@@ -86,24 +88,24 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
86 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai); 88 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
87 struct snd_aes_iec958 *iec = &priv->iec; 89 struct snd_aes_iec958 *iec = &priv->iec;
88 struct snd_cea_861_aud_if *cea = &priv->cea; 90 struct snd_cea_861_aud_if *cea = &priv->cea;
91 struct omap_pcm_dma_data *dma_data;
89 int err = 0; 92 int err = 0;
90 93
94 dma_data = snd_soc_dai_get_dma_data(dai, substream);
95
91 switch (params_format(params)) { 96 switch (params_format(params)) {
92 case SNDRV_PCM_FORMAT_S16_LE: 97 case SNDRV_PCM_FORMAT_S16_LE:
93 priv->dma_params.packet_size = 16; 98 dma_data->packet_size = 16;
94 break; 99 break;
95 case SNDRV_PCM_FORMAT_S24_LE: 100 case SNDRV_PCM_FORMAT_S24_LE:
96 priv->dma_params.packet_size = 32; 101 dma_data->packet_size = 32;
97 break; 102 break;
98 default: 103 default:
99 dev_err(dai->dev, "format not supported!\n"); 104 dev_err(dai->dev, "format not supported!\n");
100 return -EINVAL; 105 return -EINVAL;
101 } 106 }
102 107
103 priv->dma_params.data_type = OMAP_DMA_DATA_TYPE_S32; 108 dma_data->data_type = 32;
104
105 snd_soc_dai_set_dma_data(dai, substream,
106 &priv->dma_params);
107 109
108 /* 110 /*
109 * fill the IEC-60958 channel status word 111 * fill the IEC-60958 channel status word
@@ -290,7 +292,6 @@ static __devinit int omap_hdmi_probe(struct platform_device *pdev)
290 292
291 hdmi_data->dma_params.dma_req = hdmi_rsrc->start; 293 hdmi_data->dma_params.dma_req = hdmi_rsrc->start;
292 hdmi_data->dma_params.name = "HDMI playback"; 294 hdmi_data->dma_params.name = "HDMI playback";
293 hdmi_data->dma_params.sync_mode = OMAP_DMA_SYNC_PACKET;
294 295
295 /* 296 /*
296 * TODO: We assume that there is only one DSS HDMI device. Future 297 * TODO: We assume that there is only one DSS HDMI device. Future
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 1b18627763ce..a6ee15747859 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -26,6 +26,8 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/of.h>
30#include <linux/of_device.h>
29#include <sound/core.h> 31#include <sound/core.h>
30#include <sound/pcm.h> 32#include <sound/pcm.h>
31#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
@@ -33,7 +35,6 @@
33#include <sound/soc.h> 35#include <sound/soc.h>
34 36
35#include <plat/cpu.h> 37#include <plat/cpu.h>
36#include <plat/dma.h>
37#include <linux/platform_data/asoc-ti-mcbsp.h> 38#include <linux/platform_data/asoc-ti-mcbsp.h>
38#include "mcbsp.h" 39#include "mcbsp.h"
39#include "omap-mcbsp.h" 40#include "omap-mcbsp.h"
@@ -80,9 +81,6 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
80 */ 81 */
81 if (dma_data->packet_size) 82 if (dma_data->packet_size)
82 words = dma_data->packet_size; 83 words = dma_data->packet_size;
83 else if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
84 words = snd_pcm_lib_period_bytes(substream) /
85 (mcbsp->wlen / 8);
86 else 84 else
87 words = 1; 85 words = 1;
88 86
@@ -154,6 +152,9 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
154 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); 152 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
155 } 153 }
156 154
155 snd_soc_dai_set_dma_data(cpu_dai, substream,
156 &mcbsp->dma_data[substream->stream]);
157
157 return err; 158 return err;
158} 159}
159 160
@@ -227,20 +228,18 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
227 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 228 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
228 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; 229 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
229 struct omap_pcm_dma_data *dma_data; 230 struct omap_pcm_dma_data *dma_data;
230 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; 231 int wlen, channels, wpf;
231 int pkt_size = 0; 232 int pkt_size = 0;
232 unsigned int format, div, framesize, master; 233 unsigned int format, div, framesize, master;
233 234
234 dma_data = &mcbsp->dma_data[substream->stream]; 235 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
235 channels = params_channels(params); 236 channels = params_channels(params);
236 237
237 switch (params_format(params)) { 238 switch (params_format(params)) {
238 case SNDRV_PCM_FORMAT_S16_LE: 239 case SNDRV_PCM_FORMAT_S16_LE:
239 dma_data->data_type = OMAP_DMA_DATA_TYPE_S16;
240 wlen = 16; 240 wlen = 16;
241 break; 241 break;
242 case SNDRV_PCM_FORMAT_S32_LE: 242 case SNDRV_PCM_FORMAT_S32_LE:
243 dma_data->data_type = OMAP_DMA_DATA_TYPE_S32;
244 wlen = 32; 243 wlen = 32;
245 break; 244 break;
246 default: 245 default:
@@ -250,6 +249,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
250 dma_data->set_threshold = omap_mcbsp_set_threshold; 249 dma_data->set_threshold = omap_mcbsp_set_threshold;
251 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { 250 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
252 int period_words, max_thrsh; 251 int period_words, max_thrsh;
252 int divider = 0;
253 253
254 period_words = params_period_bytes(params) / (wlen / 8); 254 period_words = params_period_bytes(params) / (wlen / 8);
255 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 255 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -257,46 +257,30 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
257 else 257 else
258 max_thrsh = mcbsp->max_rx_thres; 258 max_thrsh = mcbsp->max_rx_thres;
259 /* 259 /*
260 * If the period contains less or equal number of words, 260 * Use sDMA packet mode if McBSP is in threshold mode:
261 * we are using the original threshold mode setup: 261 * If period words less than the FIFO size the packet
262 * McBSP threshold = sDMA frame size = period_size 262 * size is set to the number of period words, otherwise
263 * Otherwise we switch to sDMA packet mode: 263 * Look for the biggest threshold value which divides
264 * McBSP threshold = sDMA packet size 264 * the period size evenly.
265 * sDMA frame size = period size
266 */ 265 */
267 if (period_words > max_thrsh) { 266 divider = period_words / max_thrsh;
268 int divider = 0; 267 if (period_words % max_thrsh)
269 268 divider++;
270 /* 269 while (period_words % divider &&
271 * Look for the biggest threshold value, which 270 divider < period_words)
272 * divides the period size evenly. 271 divider++;
273 */ 272 if (divider == period_words)
274 divider = period_words / max_thrsh; 273 return -EINVAL;
275 if (period_words % max_thrsh) 274
276 divider++; 275 pkt_size = period_words / divider;
277 while (period_words % divider &&
278 divider < period_words)
279 divider++;
280 if (divider == period_words)
281 return -EINVAL;
282
283 pkt_size = period_words / divider;
284 sync_mode = OMAP_DMA_SYNC_PACKET;
285 } else {
286 sync_mode = OMAP_DMA_SYNC_FRAME;
287 }
288 } else if (channels > 1) { 276 } else if (channels > 1) {
289 /* Use packet mode for non mono streams */ 277 /* Use packet mode for non mono streams */
290 pkt_size = channels; 278 pkt_size = channels;
291 sync_mode = OMAP_DMA_SYNC_PACKET;
292 } 279 }
293 } 280 }
294 281
295 dma_data->sync_mode = sync_mode;
296 dma_data->packet_size = pkt_size; 282 dma_data->packet_size = pkt_size;
297 283
298 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
299
300 if (mcbsp->configured) { 284 if (mcbsp->configured) {
301 /* McBSP already configured by another stream */ 285 /* McBSP already configured by another stream */
302 return 0; 286 return 0;
@@ -399,12 +383,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
399 /* Generic McBSP register settings */ 383 /* Generic McBSP register settings */
400 regs->spcr2 |= XINTM(3) | FREE; 384 regs->spcr2 |= XINTM(3) | FREE;
401 regs->spcr1 |= RINTM(3); 385 regs->spcr1 |= RINTM(3);
402 /* RFIG and XFIG are not defined in 34xx */ 386 /* RFIG and XFIG are not defined in 2430 and on OMAP3+ */
403 if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { 387 if (!mcbsp->pdata->has_ccr) {
404 regs->rcr2 |= RFIG; 388 regs->rcr2 |= RFIG;
405 regs->xcr2 |= XFIG; 389 regs->xcr2 |= XFIG;
406 } 390 }
407 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { 391
392 /* Configure XCCR/RCCR only for revisions which have ccr registers */
393 if (mcbsp->pdata->has_ccr) {
408 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; 394 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
409 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; 395 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
410 } 396 }
@@ -517,21 +503,9 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
517 return -EBUSY; 503 return -EBUSY;
518 } 504 }
519 505
520 if (clk_id == OMAP_MCBSP_SYSCLK_CLK || 506 mcbsp->in_freq = freq;
521 clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK || 507 regs->srgr2 &= ~CLKSM;
522 clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT || 508 regs->pcr0 &= ~SCLKME;
523 clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT ||
524 clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) {
525 mcbsp->in_freq = freq;
526 regs->srgr2 &= ~CLKSM;
527 regs->pcr0 &= ~SCLKME;
528 } else if (cpu_class_is_omap1()) {
529 /*
530 * McBSP CLKR/FSR signal muxing functions are only available on
531 * OMAP2 or newer versions
532 */
533 return -EINVAL;
534 }
535 509
536 switch (clk_id) { 510 switch (clk_id) {
537 case OMAP_MCBSP_SYSCLK_CLK: 511 case OMAP_MCBSP_SYSCLK_CLK:
@@ -559,20 +533,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
559 case OMAP_MCBSP_SYSCLK_CLKR_EXT: 533 case OMAP_MCBSP_SYSCLK_CLKR_EXT:
560 regs->pcr0 |= SCLKME; 534 regs->pcr0 |= SCLKME;
561 break; 535 break;
562
563
564 case OMAP_MCBSP_CLKR_SRC_CLKR:
565 err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR);
566 break;
567 case OMAP_MCBSP_CLKR_SRC_CLKX:
568 err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX);
569 break;
570 case OMAP_MCBSP_FSR_SRC_FSR:
571 err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR);
572 break;
573 case OMAP_MCBSP_FSR_SRC_FSX:
574 err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX);
575 break;
576 default: 536 default:
577 err = -ENODEV; 537 err = -ENODEV;
578 } 538 }
@@ -642,9 +602,9 @@ static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
642 return 0; 602 return 0;
643} 603}
644 604
645#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel) \ 605#define OMAP_MCBSP_ST_CHANNEL_VOLUME(channel) \
646static int \ 606static int \
647omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ 607omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
648 struct snd_ctl_elem_value *uc) \ 608 struct snd_ctl_elem_value *uc) \
649{ \ 609{ \
650 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ 610 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
@@ -660,11 +620,10 @@ omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
660 \ 620 \
661 /* OMAP McBSP implementation uses index values 0..4 */ \ 621 /* OMAP McBSP implementation uses index values 0..4 */ \
662 return omap_st_set_chgain(mcbsp, channel, val); \ 622 return omap_st_set_chgain(mcbsp, channel, val); \
663} 623} \
664 624 \
665#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel) \
666static int \ 625static int \
667omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ 626omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
668 struct snd_ctl_elem_value *uc) \ 627 struct snd_ctl_elem_value *uc) \
669{ \ 628{ \
670 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ 629 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
@@ -678,10 +637,8 @@ omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
678 return 0; \ 637 return 0; \
679} 638}
680 639
681OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0) 640OMAP_MCBSP_ST_CHANNEL_VOLUME(0)
682OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1) 641OMAP_MCBSP_ST_CHANNEL_VOLUME(1)
683OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0)
684OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1)
685 642
686static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, 643static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol) 644 struct snd_ctl_elem_value *ucontrol)
@@ -711,41 +668,34 @@ static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
711 return 0; 668 return 0;
712} 669}
713 670
714static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = { 671#define OMAP_MCBSP_ST_CONTROLS(port) \
715 SOC_SINGLE_EXT("McBSP2 Sidetone Switch", 1, 0, 1, 0, 672static const struct snd_kcontrol_new omap_mcbsp##port##_st_controls[] = { \
716 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), 673SOC_SINGLE_EXT("McBSP" #port " Sidetone Switch", 1, 0, 1, 0, \
717 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume", 674 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), \
718 -32768, 32767, 675OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 0 Volume", \
719 omap_mcbsp_get_st_ch0_volume, 676 -32768, 32767, \
720 omap_mcbsp_set_st_ch0_volume), 677 omap_mcbsp_get_st_ch0_volume, \
721 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume", 678 omap_mcbsp_set_st_ch0_volume), \
722 -32768, 32767, 679OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
723 omap_mcbsp_get_st_ch1_volume, 680 -32768, 32767, \
724 omap_mcbsp_set_st_ch1_volume), 681 omap_mcbsp_get_st_ch1_volume, \
725}; 682 omap_mcbsp_set_st_ch1_volume), \
683}
726 684
727static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = { 685OMAP_MCBSP_ST_CONTROLS(2);
728 SOC_SINGLE_EXT("McBSP3 Sidetone Switch", 2, 0, 1, 0, 686OMAP_MCBSP_ST_CONTROLS(3);
729 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
730 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
731 -32768, 32767,
732 omap_mcbsp_get_st_ch0_volume,
733 omap_mcbsp_set_st_ch0_volume),
734 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
735 -32768, 32767,
736 omap_mcbsp_get_st_ch1_volume,
737 omap_mcbsp_set_st_ch1_volume),
738};
739 687
740int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) 688int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
741{ 689{
742 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 690 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
743 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 691 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
744 692
745 if (!mcbsp->st_data) 693 if (!mcbsp->st_data) {
746 return -ENODEV; 694 dev_warn(mcbsp->dev, "No sidetone data for port\n");
695 return 0;
696 }
747 697
748 switch (cpu_dai->id) { 698 switch (mcbsp->id) {
749 case 2: /* McBSP 2 */ 699 case 2: /* McBSP 2 */
750 return snd_soc_add_dai_controls(cpu_dai, 700 return snd_soc_add_dai_controls(cpu_dai,
751 omap_mcbsp2_st_controls, 701 omap_mcbsp2_st_controls,
@@ -762,13 +712,74 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
762} 712}
763EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); 713EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
764 714
715static struct omap_mcbsp_platform_data omap2420_pdata = {
716 .reg_step = 4,
717 .reg_size = 2,
718};
719
720static struct omap_mcbsp_platform_data omap2430_pdata = {
721 .reg_step = 4,
722 .reg_size = 4,
723 .has_ccr = true,
724};
725
726static struct omap_mcbsp_platform_data omap3_pdata = {
727 .reg_step = 4,
728 .reg_size = 4,
729 .has_ccr = true,
730 .has_wakeup = true,
731};
732
733static struct omap_mcbsp_platform_data omap4_pdata = {
734 .reg_step = 4,
735 .reg_size = 4,
736 .has_ccr = true,
737 .has_wakeup = true,
738};
739
740static const struct of_device_id omap_mcbsp_of_match[] = {
741 {
742 .compatible = "ti,omap2420-mcbsp",
743 .data = &omap2420_pdata,
744 },
745 {
746 .compatible = "ti,omap2430-mcbsp",
747 .data = &omap2430_pdata,
748 },
749 {
750 .compatible = "ti,omap3-mcbsp",
751 .data = &omap3_pdata,
752 },
753 {
754 .compatible = "ti,omap4-mcbsp",
755 .data = &omap4_pdata,
756 },
757 { },
758};
759MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match);
760
765static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) 761static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
766{ 762{
767 struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); 763 struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
768 struct omap_mcbsp *mcbsp; 764 struct omap_mcbsp *mcbsp;
765 const struct of_device_id *match;
769 int ret; 766 int ret;
770 767
771 if (!pdata) { 768 match = of_match_device(omap_mcbsp_of_match, &pdev->dev);
769 if (match) {
770 struct device_node *node = pdev->dev.of_node;
771 int buffer_size;
772
773 pdata = devm_kzalloc(&pdev->dev,
774 sizeof(struct omap_mcbsp_platform_data),
775 GFP_KERNEL);
776 if (!pdata)
777 return -ENOMEM;
778
779 memcpy(pdata, match->data, sizeof(*pdata));
780 if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size))
781 pdata->buffer_size = buffer_size;
782 } else if (!pdata) {
772 dev_err(&pdev->dev, "missing platform data.\n"); 783 dev_err(&pdev->dev, "missing platform data.\n");
773 return -EINVAL; 784 return -EINVAL;
774 } 785 }
@@ -810,6 +821,7 @@ static struct platform_driver asoc_mcbsp_driver = {
810 .driver = { 821 .driver = {
811 .name = "omap-mcbsp", 822 .name = "omap-mcbsp",
812 .owner = THIS_MODULE, 823 .owner = THIS_MODULE,
824 .of_match_table = omap_mcbsp_of_match,
813 }, 825 },
814 826
815 .probe = asoc_mcbsp_probe, 827 .probe = asoc_mcbsp_probe,
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index f877b16f19c9..ba8386a0d8dc 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -32,10 +32,6 @@ enum omap_mcbsp_clksrg_clk {
32 OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */ 32 OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */
33 OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */ 33 OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */
34 OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */ 34 OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */
35 OMAP_MCBSP_CLKR_SRC_CLKR, /* CLKR from CLKR pin */
36 OMAP_MCBSP_CLKR_SRC_CLKX, /* CLKR from CLKX pin */
37 OMAP_MCBSP_FSR_SRC_FSR, /* FSR from FSR pin */
38 OMAP_MCBSP_FSR_SRC_FSX, /* FSR from FSX pin */
39}; 35};
40 36
41/* McBSP dividers */ 37/* McBSP dividers */
@@ -43,22 +39,6 @@ enum omap_mcbsp_div {
43 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ 39 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
44}; 40};
45 41
46#if defined(CONFIG_SOC_OMAP2420)
47#define NUM_LINKS 2
48#endif
49#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
50#undef NUM_LINKS
51#define NUM_LINKS 3
52#endif
53#if defined(CONFIG_ARCH_OMAP4)
54#undef NUM_LINKS
55#define NUM_LINKS 4
56#endif
57#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430)
58#undef NUM_LINKS
59#define NUM_LINKS 5
60#endif
61
62int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); 42int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
63 43
64#endif 44#endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index ea053c3d2ab1..c02b001ee4b5 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -40,7 +40,6 @@
40#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42 42
43#include <plat/dma.h>
44#include <plat/omap_hwmod.h> 43#include <plat/omap_hwmod.h>
45#include "omap-mcpdm.h" 44#include "omap-mcpdm.h"
46#include "omap-pcm.h" 45#include "omap-pcm.h"
@@ -73,17 +72,9 @@ struct omap_mcpdm {
73static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = { 72static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
74 { 73 {
75 .name = "Audio playback", 74 .name = "Audio playback",
76 .dma_req = OMAP44XX_DMA_MCPDM_DL,
77 .data_type = OMAP_DMA_DATA_TYPE_S32,
78 .sync_mode = OMAP_DMA_SYNC_PACKET,
79 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA,
80 }, 75 },
81 { 76 {
82 .name = "Audio capture", 77 .name = "Audio capture",
83 .dma_req = OMAP44XX_DMA_MCPDM_UP,
84 .data_type = OMAP_DMA_DATA_TYPE_S32,
85 .sync_mode = OMAP_DMA_SYNC_PACKET,
86 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA,
87 }, 78 },
88}; 79};
89 80
@@ -278,9 +269,11 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
278 } 269 }
279 omap_mcpdm_open_streams(mcpdm); 270 omap_mcpdm_open_streams(mcpdm);
280 } 271 }
281
282 mutex_unlock(&mcpdm->mutex); 272 mutex_unlock(&mcpdm->mutex);
283 273
274 snd_soc_dai_set_dma_data(dai, substream,
275 &omap_mcpdm_dai_dma_params[substream->stream]);
276
284 return 0; 277 return 0;
285} 278}
286 279
@@ -335,7 +328,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
335 return -EINVAL; 328 return -EINVAL;
336 } 329 }
337 330
338 dma_data = &omap_mcpdm_dai_dma_params[stream]; 331 dma_data = snd_soc_dai_get_dma_data(dai, substream);
339 332
340 /* Configure McPDM channels, and DMA packet size */ 333 /* Configure McPDM channels, and DMA packet size */
341 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 334 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -347,8 +340,6 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
347 dma_data->packet_size = mcpdm->up_threshold * channels; 340 dma_data->packet_size = mcpdm->up_threshold * channels;
348 } 341 }
349 342
350 snd_soc_dai_set_dma_data(dai, substream, dma_data);
351
352 return 0; 343 return 0;
353} 344}
354 345
@@ -447,9 +438,8 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
447{ 438{
448 struct omap_mcpdm *mcpdm; 439 struct omap_mcpdm *mcpdm;
449 struct resource *res; 440 struct resource *res;
450 int ret = 0;
451 441
452 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); 442 mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL);
453 if (!mcpdm) 443 if (!mcpdm)
454 return -ENOMEM; 444 return -ENOMEM;
455 445
@@ -457,56 +447,54 @@ static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
457 447
458 mutex_init(&mcpdm->mutex); 448 mutex_init(&mcpdm->mutex);
459 449
450 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
451 if (res == NULL)
452 return -ENOMEM;
453
454 omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA;
455 omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA;
456
460 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 457 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
461 if (res == NULL) { 458 if (res == NULL)
462 dev_err(&pdev->dev, "no resource\n"); 459 return -ENOMEM;
463 goto err_res;
464 }
465 460
466 if (!request_mem_region(res->start, resource_size(res), "McPDM")) { 461 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
467 ret = -EBUSY; 462 if (!res)
468 goto err_res; 463 return -ENODEV;
469 }
470 464
471 mcpdm->io_base = ioremap(res->start, resource_size(res)); 465 omap_mcpdm_dai_dma_params[0].dma_req = res->start;
472 if (!mcpdm->io_base) { 466
473 ret = -ENOMEM; 467 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
474 goto err_iomap; 468 if (!res)
475 } 469 return -ENODEV;
470
471 omap_mcpdm_dai_dma_params[1].dma_req = res->start;
472
473 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
474 if (res == NULL)
475 return -ENOMEM;
476
477 if (!devm_request_mem_region(&pdev->dev, res->start,
478 resource_size(res), "McPDM"))
479 return -EBUSY;
480
481 mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
482 resource_size(res));
483 if (!mcpdm->io_base)
484 return -ENOMEM;
476 485
477 mcpdm->irq = platform_get_irq(pdev, 0); 486 mcpdm->irq = platform_get_irq(pdev, 0);
478 if (mcpdm->irq < 0) { 487 if (mcpdm->irq < 0)
479 ret = mcpdm->irq; 488 return mcpdm->irq;
480 goto err_irq;
481 }
482 489
483 mcpdm->dev = &pdev->dev; 490 mcpdm->dev = &pdev->dev;
484 491
485 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); 492 return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
486 if (!ret)
487 return 0;
488
489err_irq:
490 iounmap(mcpdm->io_base);
491err_iomap:
492 release_mem_region(res->start, resource_size(res));
493err_res:
494 kfree(mcpdm);
495 return ret;
496} 493}
497 494
498static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) 495static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
499{ 496{
500 struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
501 struct resource *res;
502
503 snd_soc_unregister_dai(&pdev->dev); 497 snd_soc_unregister_dai(&pdev->dev);
504
505 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
506 iounmap(mcpdm->io_base);
507 release_mem_region(res->start, resource_size(res));
508
509 kfree(mcpdm);
510 return 0; 498 return 0;
511} 499}
512 500
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index b30994179885..340874ebf9ae 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -25,13 +25,14 @@
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/omap-dma.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
32#include <sound/dmaengine_pcm.h>
31#include <sound/soc.h> 33#include <sound/soc.h>
32 34
33#include <plat/cpu.h> 35#include <plat/cpu.h>
34#include <plat/dma.h>
35#include "omap-pcm.h" 36#include "omap-pcm.h"
36 37
37static const struct snd_pcm_hardware omap_pcm_hardware = { 38static const struct snd_pcm_hardware omap_pcm_hardware = {
@@ -50,61 +51,34 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
50 .buffer_bytes_max = 128 * 1024, 51 .buffer_bytes_max = 128 * 1024,
51}; 52};
52 53
53struct omap_runtime_data { 54static int omap_pcm_get_dma_buswidth(int num_bits)
54 spinlock_t lock;
55 struct omap_pcm_dma_data *dma_data;
56 int dma_ch;
57 int period_index;
58};
59
60static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
61{ 55{
62 struct snd_pcm_substream *substream = data; 56 int buswidth;
63 struct snd_pcm_runtime *runtime = substream->runtime;
64 struct omap_runtime_data *prtd = runtime->private_data;
65 unsigned long flags;
66
67 if ((cpu_is_omap1510())) {
68 /*
69 * OMAP1510 doesn't fully support DMA progress counter
70 * and there is no software emulation implemented yet,
71 * so have to maintain our own progress counters
72 * that can be used by omap_pcm_pointer() instead.
73 */
74 spin_lock_irqsave(&prtd->lock, flags);
75 if ((stat == OMAP_DMA_LAST_IRQ) &&
76 (prtd->period_index == runtime->periods - 1)) {
77 /* we are in sync, do nothing */
78 spin_unlock_irqrestore(&prtd->lock, flags);
79 return;
80 }
81 if (prtd->period_index >= 0) {
82 if (stat & OMAP_DMA_BLOCK_IRQ) {
83 /* end of buffer reached, loop back */
84 prtd->period_index = 0;
85 } else if (stat & OMAP_DMA_LAST_IRQ) {
86 /* update the counter for the last period */
87 prtd->period_index = runtime->periods - 1;
88 } else if (++prtd->period_index >= runtime->periods) {
89 /* end of buffer missed? loop back */
90 prtd->period_index = 0;
91 }
92 }
93 spin_unlock_irqrestore(&prtd->lock, flags);
94 }
95 57
96 snd_pcm_period_elapsed(substream); 58 switch (num_bits) {
59 case 16:
60 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
61 break;
62 case 32:
63 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
64 break;
65 default:
66 buswidth = -EINVAL;
67 break;
68 }
69 return buswidth;
97} 70}
98 71
72
99/* this may get called several times by oss emulation */ 73/* this may get called several times by oss emulation */
100static int omap_pcm_hw_params(struct snd_pcm_substream *substream, 74static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
101 struct snd_pcm_hw_params *params) 75 struct snd_pcm_hw_params *params)
102{ 76{
103 struct snd_pcm_runtime *runtime = substream->runtime; 77 struct snd_pcm_runtime *runtime = substream->runtime;
104 struct snd_soc_pcm_runtime *rtd = substream->private_data; 78 struct snd_soc_pcm_runtime *rtd = substream->private_data;
105 struct omap_runtime_data *prtd = runtime->private_data;
106 struct omap_pcm_dma_data *dma_data; 79 struct omap_pcm_dma_data *dma_data;
107 80 struct dma_slave_config config;
81 struct dma_chan *chan;
108 int err = 0; 82 int err = 0;
109 83
110 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 84 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
@@ -117,162 +91,78 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
117 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 91 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
118 runtime->dma_bytes = params_buffer_bytes(params); 92 runtime->dma_bytes = params_buffer_bytes(params);
119 93
120 if (prtd->dma_data) 94 chan = snd_dmaengine_pcm_get_chan(substream);
121 return 0; 95 if (!chan)
122 prtd->dma_data = dma_data; 96 return -EINVAL;
123 err = omap_request_dma(dma_data->dma_req, dma_data->name,
124 omap_pcm_dma_irq, substream, &prtd->dma_ch);
125 if (!err) {
126 /*
127 * Link channel with itself so DMA doesn't need any
128 * reprogramming while looping the buffer
129 */
130 omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch);
131 }
132 97
133 return err; 98 /* fills in addr_width and direction */
134} 99 err = snd_hwparams_to_dma_slave_config(substream, params, &config);
100 if (err)
101 return err;
135 102
136static int omap_pcm_hw_free(struct snd_pcm_substream *substream) 103 /* Override the *_dma addr_width if requested by the DAI driver */
137{ 104 if (dma_data->data_type) {
138 struct snd_pcm_runtime *runtime = substream->runtime; 105 int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type);
139 struct omap_runtime_data *prtd = runtime->private_data;
140 106
141 if (prtd->dma_data == NULL) 107 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
142 return 0; 108 config.dst_addr_width = buswidth;
143 109 else
144 omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch); 110 config.src_addr_width = buswidth;
145 omap_free_dma(prtd->dma_ch); 111 }
146 prtd->dma_data = NULL;
147 112
148 snd_pcm_set_runtime_buffer(substream, NULL); 113 config.src_addr = dma_data->port_addr;
114 config.dst_addr = dma_data->port_addr;
115 config.src_maxburst = dma_data->packet_size;
116 config.dst_maxburst = dma_data->packet_size;
149 117
150 return 0; 118 return dmaengine_slave_config(chan, &config);
151} 119}
152 120
153static int omap_pcm_prepare(struct snd_pcm_substream *substream) 121static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
154{ 122{
155 struct snd_pcm_runtime *runtime = substream->runtime; 123 snd_pcm_set_runtime_buffer(substream, NULL);
156 struct omap_runtime_data *prtd = runtime->private_data;
157 struct omap_pcm_dma_data *dma_data = prtd->dma_data;
158 struct omap_dma_channel_params dma_params;
159 int bytes;
160
161 /* return if this is a bufferless transfer e.g.
162 * codec <--> BT codec or GSM modem -- lg FIXME */
163 if (!prtd->dma_data)
164 return 0;
165
166 memset(&dma_params, 0, sizeof(dma_params));
167 dma_params.data_type = dma_data->data_type;
168 dma_params.trigger = dma_data->dma_req;
169 dma_params.sync_mode = dma_data->sync_mode;
170 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
171 dma_params.src_amode = OMAP_DMA_AMODE_POST_INC;
172 dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT;
173 dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC;
174 dma_params.src_start = runtime->dma_addr;
175 dma_params.dst_start = dma_data->port_addr;
176 dma_params.dst_port = OMAP_DMA_PORT_MPUI;
177 dma_params.dst_fi = dma_data->packet_size;
178 } else {
179 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
180 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
181 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
182 dma_params.src_start = dma_data->port_addr;
183 dma_params.dst_start = runtime->dma_addr;
184 dma_params.src_port = OMAP_DMA_PORT_MPUI;
185 dma_params.src_fi = dma_data->packet_size;
186 }
187 /*
188 * Set DMA transfer frame size equal to ALSA period size and frame
189 * count as no. of ALSA periods. Then with DMA frame interrupt enabled,
190 * we can transfer the whole ALSA buffer with single DMA transfer but
191 * still can get an interrupt at each period bounary
192 */
193 bytes = snd_pcm_lib_period_bytes(substream);
194 dma_params.elem_count = bytes >> dma_data->data_type;
195 dma_params.frame_count = runtime->periods;
196 omap_set_dma_params(prtd->dma_ch, &dma_params);
197
198 if ((cpu_is_omap1510()))
199 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
200 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
201 else if (!substream->runtime->no_period_wakeup)
202 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
203 else {
204 /*
205 * No period wakeup:
206 * we need to disable BLOCK_IRQ, which is enabled by the omap
207 * dma core at request dma time.
208 */
209 omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ);
210 }
211
212 if (!(cpu_class_is_omap1())) {
213 omap_set_dma_src_burst_mode(prtd->dma_ch,
214 OMAP_DMA_DATA_BURST_16);
215 omap_set_dma_dest_burst_mode(prtd->dma_ch,
216 OMAP_DMA_DATA_BURST_16);
217 }
218
219 return 0; 124 return 0;
220} 125}
221 126
222static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 127static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
223{ 128{
224 struct snd_pcm_runtime *runtime = substream->runtime; 129 struct snd_soc_pcm_runtime *rtd = substream->private_data;
225 struct omap_runtime_data *prtd = runtime->private_data; 130 struct omap_pcm_dma_data *dma_data;
226 struct omap_pcm_dma_data *dma_data = prtd->dma_data;
227 unsigned long flags;
228 int ret = 0; 131 int ret = 0;
229 132
230 spin_lock_irqsave(&prtd->lock, flags); 133 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
134
231 switch (cmd) { 135 switch (cmd) {
232 case SNDRV_PCM_TRIGGER_START: 136 case SNDRV_PCM_TRIGGER_START:
233 case SNDRV_PCM_TRIGGER_RESUME: 137 case SNDRV_PCM_TRIGGER_RESUME:
234 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 138 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
235 prtd->period_index = 0;
236 /* Configure McBSP internal buffer usage */ 139 /* Configure McBSP internal buffer usage */
237 if (dma_data->set_threshold) 140 if (dma_data->set_threshold)
238 dma_data->set_threshold(substream); 141 dma_data->set_threshold(substream);
239
240 omap_start_dma(prtd->dma_ch);
241 break; 142 break;
242 143
243 case SNDRV_PCM_TRIGGER_STOP: 144 case SNDRV_PCM_TRIGGER_STOP:
244 case SNDRV_PCM_TRIGGER_SUSPEND: 145 case SNDRV_PCM_TRIGGER_SUSPEND:
245 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 146 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
246 prtd->period_index = -1;
247 omap_stop_dma(prtd->dma_ch);
248 break; 147 break;
249 default: 148 default:
250 ret = -EINVAL; 149 ret = -EINVAL;
251 } 150 }
252 spin_unlock_irqrestore(&prtd->lock, flags); 151
152 if (ret == 0)
153 ret = snd_dmaengine_pcm_trigger(substream, cmd);
253 154
254 return ret; 155 return ret;
255} 156}
256 157
257static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) 158static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
258{ 159{
259 struct snd_pcm_runtime *runtime = substream->runtime;
260 struct omap_runtime_data *prtd = runtime->private_data;
261 dma_addr_t ptr;
262 snd_pcm_uframes_t offset; 160 snd_pcm_uframes_t offset;
263 161
264 if (cpu_is_omap1510()) { 162 if (cpu_is_omap1510())
265 offset = prtd->period_index * runtime->period_size; 163 offset = snd_dmaengine_pcm_pointer_no_residue(substream);
266 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 164 else
267 ptr = omap_get_dma_dst_pos(prtd->dma_ch); 165 offset = snd_dmaengine_pcm_pointer(substream);
268 offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
269 } else {
270 ptr = omap_get_dma_src_pos(prtd->dma_ch);
271 offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
272 }
273
274 if (offset >= runtime->buffer_size)
275 offset = 0;
276 166
277 return offset; 167 return offset;
278} 168}
@@ -280,7 +170,8 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
280static int omap_pcm_open(struct snd_pcm_substream *substream) 170static int omap_pcm_open(struct snd_pcm_substream *substream)
281{ 171{
282 struct snd_pcm_runtime *runtime = substream->runtime; 172 struct snd_pcm_runtime *runtime = substream->runtime;
283 struct omap_runtime_data *prtd; 173 struct snd_soc_pcm_runtime *rtd = substream->private_data;
174 struct omap_pcm_dma_data *dma_data;
284 int ret; 175 int ret;
285 176
286 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); 177 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
@@ -289,25 +180,17 @@ static int omap_pcm_open(struct snd_pcm_substream *substream)
289 ret = snd_pcm_hw_constraint_integer(runtime, 180 ret = snd_pcm_hw_constraint_integer(runtime,
290 SNDRV_PCM_HW_PARAM_PERIODS); 181 SNDRV_PCM_HW_PARAM_PERIODS);
291 if (ret < 0) 182 if (ret < 0)
292 goto out; 183 return ret;
293 184
294 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); 185 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
295 if (prtd == NULL) { 186 ret = snd_dmaengine_pcm_open(substream, omap_dma_filter_fn,
296 ret = -ENOMEM; 187 &dma_data->dma_req);
297 goto out;
298 }
299 spin_lock_init(&prtd->lock);
300 runtime->private_data = prtd;
301
302out:
303 return ret; 188 return ret;
304} 189}
305 190
306static int omap_pcm_close(struct snd_pcm_substream *substream) 191static int omap_pcm_close(struct snd_pcm_substream *substream)
307{ 192{
308 struct snd_pcm_runtime *runtime = substream->runtime; 193 snd_dmaengine_pcm_close(substream);
309
310 kfree(runtime->private_data);
311 return 0; 194 return 0;
312} 195}
313 196
@@ -328,7 +211,6 @@ static struct snd_pcm_ops omap_pcm_ops = {
328 .ioctl = snd_pcm_lib_ioctl, 211 .ioctl = snd_pcm_lib_ioctl,
329 .hw_params = omap_pcm_hw_params, 212 .hw_params = omap_pcm_hw_params,
330 .hw_free = omap_pcm_hw_free, 213 .hw_free = omap_pcm_hw_free,
331 .prepare = omap_pcm_prepare,
332 .trigger = omap_pcm_trigger, 214 .trigger = omap_pcm_trigger,
333 .pointer = omap_pcm_pointer, 215 .pointer = omap_pcm_pointer,
334 .mmap = omap_pcm_mmap, 216 .mmap = omap_pcm_mmap,
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index b92248cbd47a..cabe74c4068b 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -32,8 +32,8 @@ struct omap_pcm_dma_data {
32 int dma_req; /* DMA request line */ 32 int dma_req; /* DMA request line */
33 unsigned long port_addr; /* transmit/receive register */ 33 unsigned long port_addr; /* transmit/receive register */
34 void (*set_threshold)(struct snd_pcm_substream *substream); 34 void (*set_threshold)(struct snd_pcm_substream *substream);
35 int data_type; /* data type 8,16,32 */ 35 int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm
36 int sync_mode; /* DMA sync mode */ 36 * to decide the sDMA data type */
37 int packet_size; /* packet size only in PACKET mode */ 37 int packet_size; /* packet size only in PACKET mode */
38}; 38};
39 39
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
new file mode 100644
index 000000000000..3b97b87971f5
--- /dev/null
+++ b/sound/soc/omap/omap-twl4030.c
@@ -0,0 +1,188 @@
1/*
2 * omap-twl4030.c -- SoC audio for TI SoC based boards with twl4030 codec
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 * All rights reserved.
6 *
7 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
8 *
9 * This driver replaces the following machine drivers:
10 * omap3beagle (Author: Steve Sakoman <steve@sakoman.com>)
11 * omap3evm (Author: Anuj Aggarwal <anuj.aggarwal@ti.com>)
12 * overo (Author: Steve Sakoman <steve@sakoman.com>)
13 * igep0020 (Author: Enric Balletbo i Serra <eballetbo@iseebcn.com>)
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <linux/platform_device.h>
32#include <linux/platform_data/omap-twl4030.h>
33#include <linux/module.h>
34#include <linux/of.h>
35
36#include <sound/core.h>
37#include <sound/pcm.h>
38#include <sound/soc.h>
39
40#include "omap-mcbsp.h"
41#include "omap-pcm.h"
42
43static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
44 struct snd_pcm_hw_params *params)
45{
46 struct snd_soc_pcm_runtime *rtd = substream->private_data;
47 struct snd_soc_dai *codec_dai = rtd->codec_dai;
48 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
49 struct snd_soc_codec *codec = rtd->codec;
50 struct snd_soc_card *card = codec->card;
51 unsigned int fmt;
52 int ret;
53
54 switch (params_channels(params)) {
55 case 2: /* Stereo I2S mode */
56 fmt = SND_SOC_DAIFMT_I2S |
57 SND_SOC_DAIFMT_NB_NF |
58 SND_SOC_DAIFMT_CBM_CFM;
59 break;
60 case 4: /* Four channel TDM mode */
61 fmt = SND_SOC_DAIFMT_DSP_A |
62 SND_SOC_DAIFMT_IB_NF |
63 SND_SOC_DAIFMT_CBM_CFM;
64 break;
65 default:
66 return -EINVAL;
67 }
68
69 /* Set codec DAI configuration */
70 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
71 if (ret < 0) {
72 dev_err(card->dev, "can't set codec DAI configuration\n");
73 return ret;
74 }
75
76 /* Set cpu DAI configuration */
77 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
78 if (ret < 0) {
79 dev_err(card->dev, "can't set cpu DAI configuration\n");
80 return ret;
81 }
82
83 return 0;
84}
85
86static struct snd_soc_ops omap_twl4030_ops = {
87 .hw_params = omap_twl4030_hw_params,
88};
89
90/* Digital audio interface glue - connects codec <--> CPU */
91static struct snd_soc_dai_link omap_twl4030_dai_links[] = {
92 {
93 .name = "TWL4030",
94 .stream_name = "TWL4030",
95 .cpu_dai_name = "omap-mcbsp.2",
96 .codec_dai_name = "twl4030-hifi",
97 .platform_name = "omap-pcm-audio",
98 .codec_name = "twl4030-codec",
99 .ops = &omap_twl4030_ops,
100 },
101};
102
103/* Audio machine driver */
104static struct snd_soc_card omap_twl4030_card = {
105 .owner = THIS_MODULE,
106 .dai_link = omap_twl4030_dai_links,
107 .num_links = ARRAY_SIZE(omap_twl4030_dai_links),
108};
109
110static __devinit int omap_twl4030_probe(struct platform_device *pdev)
111{
112 struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev);
113 struct device_node *node = pdev->dev.of_node;
114 struct snd_soc_card *card = &omap_twl4030_card;
115 int ret = 0;
116
117 card->dev = &pdev->dev;
118
119 if (node) {
120 struct device_node *dai_node;
121
122 if (snd_soc_of_parse_card_name(card, "ti,model")) {
123 dev_err(&pdev->dev, "Card name is not provided\n");
124 return -ENODEV;
125 }
126
127 dai_node = of_parse_phandle(node, "ti,mcbsp", 0);
128 if (!dai_node) {
129 dev_err(&pdev->dev, "McBSP node is not provided\n");
130 return -EINVAL;
131 }
132 omap_twl4030_dai_links[0].cpu_dai_name = NULL;
133 omap_twl4030_dai_links[0].cpu_of_node = dai_node;
134
135 } else if (pdata) {
136 if (pdata->card_name) {
137 card->name = pdata->card_name;
138 } else {
139 dev_err(&pdev->dev, "Card name is not provided\n");
140 return -ENODEV;
141 }
142 } else {
143 dev_err(&pdev->dev, "Missing pdata\n");
144 return -ENODEV;
145 }
146
147 ret = snd_soc_register_card(card);
148 if (ret) {
149 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
150 ret);
151 return ret;
152 }
153
154 return 0;
155}
156
157static int __devexit omap_twl4030_remove(struct platform_device *pdev)
158{
159 struct snd_soc_card *card = platform_get_drvdata(pdev);
160
161 snd_soc_unregister_card(card);
162
163 return 0;
164}
165
166static const struct of_device_id omap_twl4030_of_match[] = {
167 {.compatible = "ti,omap-twl4030", },
168 { },
169};
170MODULE_DEVICE_TABLE(of, omap_twl4030_of_match);
171
172static struct platform_driver omap_twl4030_driver = {
173 .driver = {
174 .name = "omap-twl4030",
175 .owner = THIS_MODULE,
176 .pm = &snd_soc_pm_ops,
177 .of_match_table = omap_twl4030_of_match,
178 },
179 .probe = omap_twl4030_probe,
180 .remove = __devexit_p(omap_twl4030_remove),
181};
182
183module_platform_driver(omap_twl4030_driver);
184
185MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
186MODULE_DESCRIPTION("ALSA SoC for TI SoC based boards with twl4030 codec");
187MODULE_LICENSE("GPL");
188MODULE_ALIAS("platform:omap-twl4030");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
deleted file mode 100644
index e263188841b6..000000000000
--- a/sound/soc/omap/omap3beagle.c
+++ /dev/null
@@ -1,150 +0,0 @@
1/*
2 * omap3beagle.c -- SoC audio for OMAP3 Beagle
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/module.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/soc.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <linux/platform_data/asoc-ti-mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36
37static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 unsigned int fmt;
44 int ret;
45
46 switch (params_channels(params)) {
47 case 2: /* Stereo I2S mode */
48 fmt = SND_SOC_DAIFMT_I2S |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM;
51 break;
52 case 4: /* Four channel TDM mode */
53 fmt = SND_SOC_DAIFMT_DSP_A |
54 SND_SOC_DAIFMT_IB_NF |
55 SND_SOC_DAIFMT_CBM_CFM;
56 break;
57 default:
58 return -EINVAL;
59 }
60
61 /* Set codec DAI configuration */
62 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
63 if (ret < 0) {
64 printk(KERN_ERR "can't set codec DAI configuration\n");
65 return ret;
66 }
67
68 /* Set cpu DAI configuration */
69 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
70 if (ret < 0) {
71 printk(KERN_ERR "can't set cpu DAI configuration\n");
72 return ret;
73 }
74
75 /* Set the codec system clock for DAC and ADC */
76 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
77 SND_SOC_CLOCK_IN);
78 if (ret < 0) {
79 printk(KERN_ERR "can't set codec system clock\n");
80 return ret;
81 }
82
83 return 0;
84}
85
86static struct snd_soc_ops omap3beagle_ops = {
87 .hw_params = omap3beagle_hw_params,
88};
89
90/* Digital audio interface glue - connects codec <--> CPU */
91static struct snd_soc_dai_link omap3beagle_dai = {
92 .name = "TWL4030",
93 .stream_name = "TWL4030",
94 .cpu_dai_name = "omap-mcbsp.2",
95 .platform_name = "omap-pcm-audio",
96 .codec_dai_name = "twl4030-hifi",
97 .codec_name = "twl4030-codec",
98 .ops = &omap3beagle_ops,
99};
100
101/* Audio machine driver */
102static struct snd_soc_card snd_soc_omap3beagle = {
103 .name = "omap3beagle",
104 .owner = THIS_MODULE,
105 .dai_link = &omap3beagle_dai,
106 .num_links = 1,
107};
108
109static struct platform_device *omap3beagle_snd_device;
110
111static int __init omap3beagle_soc_init(void)
112{
113 int ret;
114
115 if (!(machine_is_omap3_beagle() || machine_is_devkit8000()))
116 return -ENODEV;
117 pr_info("OMAP3 Beagle/Devkit8000 SoC init\n");
118
119 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
120 if (!omap3beagle_snd_device) {
121 printk(KERN_ERR "Platform device allocation failed\n");
122 return -ENOMEM;
123 }
124
125 platform_set_drvdata(omap3beagle_snd_device, &snd_soc_omap3beagle);
126
127 ret = platform_device_add(omap3beagle_snd_device);
128 if (ret)
129 goto err1;
130
131 return 0;
132
133err1:
134 printk(KERN_ERR "Unable to add platform device\n");
135 platform_device_put(omap3beagle_snd_device);
136
137 return ret;
138}
139
140static void __exit omap3beagle_soc_exit(void)
141{
142 platform_device_unregister(omap3beagle_snd_device);
143}
144
145module_init(omap3beagle_soc_init);
146module_exit(omap3beagle_soc_exit);
147
148MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
149MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
150MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
deleted file mode 100644
index d632bfbb6983..000000000000
--- a/sound/soc/omap/omap3evm.c
+++ /dev/null
@@ -1,118 +0,0 @@
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 <linux/module.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include <mach/gpio.h>
30#include <linux/platform_data/asoc-ti-mcbsp.h>
31
32#include "omap-mcbsp.h"
33#include "omap-pcm.h"
34
35static int omap3evm_hw_params(struct snd_pcm_substream *substream,
36 struct snd_pcm_hw_params *params)
37{
38 struct snd_soc_pcm_runtime *rtd = substream->private_data;
39 struct snd_soc_dai *codec_dai = rtd->codec_dai;
40 int ret;
41
42 /* Set the codec system clock for DAC and ADC */
43 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
44 SND_SOC_CLOCK_IN);
45 if (ret < 0) {
46 printk(KERN_ERR "Can't set codec system clock\n");
47 return ret;
48 }
49
50 return 0;
51}
52
53static struct snd_soc_ops omap3evm_ops = {
54 .hw_params = omap3evm_hw_params,
55};
56
57/* Digital audio interface glue - connects codec <--> CPU */
58static struct snd_soc_dai_link omap3evm_dai = {
59 .name = "TWL4030",
60 .stream_name = "TWL4030",
61 .cpu_dai_name = "omap-mcbsp.2",
62 .codec_dai_name = "twl4030-hifi",
63 .platform_name = "omap-pcm-audio",
64 .codec_name = "twl4030-codec",
65 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
66 SND_SOC_DAIFMT_CBM_CFM,
67 .ops = &omap3evm_ops,
68};
69
70/* Audio machine driver */
71static struct snd_soc_card snd_soc_omap3evm = {
72 .name = "omap3evm",
73 .owner = THIS_MODULE,
74 .dai_link = &omap3evm_dai,
75 .num_links = 1,
76};
77
78static struct platform_device *omap3evm_snd_device;
79
80static int __init omap3evm_soc_init(void)
81{
82 int ret;
83
84 if (!machine_is_omap3evm())
85 return -ENODEV;
86 pr_info("OMAP3 EVM SoC init\n");
87
88 omap3evm_snd_device = platform_device_alloc("soc-audio", -1);
89 if (!omap3evm_snd_device) {
90 printk(KERN_ERR "Platform device allocation failed\n");
91 return -ENOMEM;
92 }
93
94 platform_set_drvdata(omap3evm_snd_device, &snd_soc_omap3evm);
95 ret = platform_device_add(omap3evm_snd_device);
96 if (ret)
97 goto err1;
98
99 return 0;
100
101err1:
102 printk(KERN_ERR "Unable to add platform device\n");
103 platform_device_put(omap3evm_snd_device);
104
105 return ret;
106}
107
108static void __exit omap3evm_soc_exit(void)
109{
110 platform_device_unregister(omap3evm_snd_device);
111}
112
113module_init(omap3evm_soc_init);
114module_exit(omap3evm_soc_exit);
115
116MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
117MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
118MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
deleted file mode 100644
index 502bce299885..000000000000
--- a/sound/soc/omap/overo.c
+++ /dev/null
@@ -1,122 +0,0 @@
1/*
2 * overo.c -- SoC audio for Gumstix Overo
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/module.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/soc.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <linux/platform_data/asoc-ti-mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36
37static int overo_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 int ret;
43
44 /* Set the codec system clock for DAC and ADC */
45 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
46 SND_SOC_CLOCK_IN);
47 if (ret < 0) {
48 printk(KERN_ERR "can't set codec system clock\n");
49 return ret;
50 }
51
52 return 0;
53}
54
55static struct snd_soc_ops overo_ops = {
56 .hw_params = overo_hw_params,
57};
58
59/* Digital audio interface glue - connects codec <--> CPU */
60static struct snd_soc_dai_link overo_dai = {
61 .name = "TWL4030",
62 .stream_name = "TWL4030",
63 .cpu_dai_name = "omap-mcbsp.2",
64 .codec_dai_name = "twl4030-hifi",
65 .platform_name = "omap-pcm-audio",
66 .codec_name = "twl4030-codec",
67 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
68 SND_SOC_DAIFMT_CBM_CFM,
69 .ops = &overo_ops,
70};
71
72/* Audio machine driver */
73static struct snd_soc_card snd_soc_card_overo = {
74 .name = "overo",
75 .owner = THIS_MODULE,
76 .dai_link = &overo_dai,
77 .num_links = 1,
78};
79
80static struct platform_device *overo_snd_device;
81
82static int __init overo_soc_init(void)
83{
84 int ret;
85
86 if (!(machine_is_overo() || machine_is_cm_t35())) {
87 pr_debug("Incomatible machine!\n");
88 return -ENODEV;
89 }
90 printk(KERN_INFO "overo SoC init\n");
91
92 overo_snd_device = platform_device_alloc("soc-audio", -1);
93 if (!overo_snd_device) {
94 printk(KERN_ERR "Platform device allocation failed\n");
95 return -ENOMEM;
96 }
97
98 platform_set_drvdata(overo_snd_device, &snd_soc_card_overo);
99
100 ret = platform_device_add(overo_snd_device);
101 if (ret)
102 goto err1;
103
104 return 0;
105
106err1:
107 printk(KERN_ERR "Unable to add platform device\n");
108 platform_device_put(overo_snd_device);
109
110 return ret;
111}
112module_init(overo_soc_init);
113
114static void __exit overo_soc_exit(void)
115{
116 platform_device_unregister(overo_snd_device);
117}
118module_exit(overo_soc_exit);
119
120MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
121MODULE_DESCRIPTION("ALSA SoC overo");
122MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 23de2b21d696..677b567935f8 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -191,9 +191,6 @@ static int __init zoom2_soc_init(void)
191 BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0); 191 BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0);
192 gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0); 192 gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0);
193 193
194 BUG_ON(gpio_request(ZOOM2_HEADSET_EXTMUTE_GPIO, "ext_mute") < 0);
195 gpio_direction_output(ZOOM2_HEADSET_EXTMUTE_GPIO, 0);
196
197 return 0; 194 return 0;
198 195
199err1: 196err1:
@@ -207,7 +204,6 @@ module_init(zoom2_soc_init);
207static void __exit zoom2_soc_exit(void) 204static void __exit zoom2_soc_exit(void)
208{ 205{
209 gpio_free(ZOOM2_HEADSET_MUX_GPIO); 206 gpio_free(ZOOM2_HEADSET_MUX_GPIO);
210 gpio_free(ZOOM2_HEADSET_EXTMUTE_GPIO);
211 207
212 platform_device_unregister(zoom2_snd_device); 208 platform_device_unregister(zoom2_snd_device);
213} 209}