aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r--sound/soc/pxa/Kconfig28
-rw-r--r--sound/soc/pxa/Makefile6
-rw-r--r--sound/soc/pxa/corgi.c85
-rw-r--r--sound/soc/pxa/e740_wm9705.c57
-rw-r--r--sound/soc/pxa/e750_wm9705.c54
-rw-r--r--sound/soc/pxa/e800_wm9712.c34
-rw-r--r--sound/soc/pxa/em-x270.c23
-rw-r--r--sound/soc/pxa/hx4700.c255
-rw-r--r--sound/soc/pxa/imote2.c20
-rw-r--r--sound/soc/pxa/magician.c75
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c51
-rw-r--r--sound/soc/pxa/palm27x.c61
-rw-r--r--sound/soc/pxa/poodle.c60
-rw-r--r--sound/soc/pxa/pxa-ssp.c176
-rw-r--r--sound/soc/pxa/pxa-ssp.h2
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c46
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.h2
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c91
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.h2
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c47
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.h19
-rw-r--r--sound/soc/pxa/raumfeld.c145
-rw-r--r--sound/soc/pxa/saarb.c200
-rw-r--r--sound/soc/pxa/spitz.c142
-rw-r--r--sound/soc/pxa/tavorevb3.c200
-rw-r--r--sound/soc/pxa/tosa.c74
-rw-r--r--sound/soc/pxa/z2.c48
-rw-r--r--sound/soc/pxa/zylonite.c61
28 files changed, 1333 insertions, 731 deletions
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index e30c8325f35e..33ebc46b45b5 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,6 +1,7 @@
1config SND_PXA2XX_SOC 1config SND_PXA2XX_SOC
2 tristate "SoC Audio for the Intel PXA2xx chip" 2 tristate "SoC Audio for the Intel PXA2xx chip"
3 depends on ARCH_PXA 3 depends on ARCH_PXA
4 select SND_ARM
4 select SND_PXA2XX_LIB 5 select SND_PXA2XX_LIB
5 help 6 help
6 Say Y or M if you want to add support for codecs attached to 7 Say Y or M if you want to add support for codecs attached to
@@ -117,6 +118,24 @@ config SND_PXA2XX_SOC_PALM27X
117 Say Y if you want to add support for SoC audio on 118 Say Y if you want to add support for SoC audio on
118 Palm T|X, T5, E2 or LifeDrive handheld computer. 119 Palm T|X, T5, E2 or LifeDrive handheld computer.
119 120
121config SND_SOC_SAARB
122 tristate "SoC Audio support for Marvell Saarb"
123 depends on SND_PXA2XX_SOC && MACH_SAARB
124 select SND_PXA_SOC_SSP
125 select SND_SOC_88PM860X
126 help
127 Say Y if you want to add support for SoC audio on the
128 Marvell Saarb reference platform.
129
130config SND_SOC_TAVOREVB3
131 tristate "SoC Audio support for Marvell Tavor EVB3"
132 depends on SND_PXA2XX_SOC && MACH_TAVOREVB3
133 select SND_PXA_SOC_SSP
134 select SND_SOC_88PM860X
135 help
136 Say Y if you want to add support for SoC audio on the
137 Marvell Saarb reference platform.
138
120config SND_SOC_ZYLONITE 139config SND_SOC_ZYLONITE
121 tristate "SoC Audio support for Marvell Zylonite" 140 tristate "SoC Audio support for Marvell Zylonite"
122 depends on SND_PXA2XX_SOC && MACH_ZYLONITE 141 depends on SND_PXA2XX_SOC && MACH_ZYLONITE
@@ -136,6 +155,15 @@ config SND_SOC_RAUMFELD
136 help 155 help
137 Say Y if you want to add support for SoC audio on Raumfeld devices 156 Say Y if you want to add support for SoC audio on Raumfeld devices
138 157
158config SND_PXA2XX_SOC_HX4700
159 tristate "SoC Audio support for HP iPAQ hx4700"
160 depends on SND_PXA2XX_SOC && MACH_H4700
161 select SND_PXA2XX_SOC_I2S
162 select SND_SOC_AK4641
163 help
164 Say Y if you want to add support for SoC audio on the
165 HP iPAQ hx4700.
166
139config SND_PXA2XX_SOC_MAGICIAN 167config SND_PXA2XX_SOC_MAGICIAN
140 tristate "SoC Audio support for HTC Magician" 168 tristate "SoC Audio support for HTC Magician"
141 depends on SND_PXA2XX_SOC && MACH_MAGICIAN 169 depends on SND_PXA2XX_SOC && MACH_MAGICIAN
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index caa03d8f4789..af357623be9d 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -19,7 +19,10 @@ snd-soc-e800-objs := e800_wm9712.o
19snd-soc-spitz-objs := spitz.o 19snd-soc-spitz-objs := spitz.o
20snd-soc-em-x270-objs := em-x270.o 20snd-soc-em-x270-objs := em-x270.o
21snd-soc-palm27x-objs := palm27x.o 21snd-soc-palm27x-objs := palm27x.o
22snd-soc-saarb-objs := saarb.o
23snd-soc-tavorevb3-objs := tavorevb3.o
22snd-soc-zylonite-objs := zylonite.o 24snd-soc-zylonite-objs := zylonite.o
25snd-soc-hx4700-objs := hx4700.o
23snd-soc-magician-objs := magician.o 26snd-soc-magician-objs := magician.o
24snd-soc-mioa701-objs := mioa701_wm9713.o 27snd-soc-mioa701-objs := mioa701_wm9713.o
25snd-soc-z2-objs := z2.o 28snd-soc-z2-objs := z2.o
@@ -35,9 +38,12 @@ obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
35obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 38obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
36obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o 39obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
37obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o 40obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
41obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o
38obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 42obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
39obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 43obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
40obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o 44obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
45obj-$(CONFIG_SND_SOC_SAARB) += snd-soc-saarb.o
46obj-$(CONFIG_SND_SOC_TAVOREVB3) += snd-soc-tavorevb3.o
41obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 47obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
42obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 48obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
43obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o 49obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index fefe1a57f31a..28757fb9df31 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -23,14 +23,12 @@
23#include <sound/core.h> 23#include <sound/core.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <mach/corgi.h> 28#include <mach/corgi.h>
30#include <mach/audio.h> 29#include <mach/audio.h>
31 30
32#include "../codecs/wm8731.h" 31#include "../codecs/wm8731.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-i2s.h" 32#include "pxa2xx-i2s.h"
35 33
36#define CORGI_HP 0 34#define CORGI_HP 0
@@ -49,60 +47,67 @@ static int corgi_spk_func;
49 47
50static void corgi_ext_control(struct snd_soc_codec *codec) 48static void corgi_ext_control(struct snd_soc_codec *codec)
51{ 49{
50 struct snd_soc_dapm_context *dapm = &codec->dapm;
51
52 /* set up jack connection */ 52 /* set up jack connection */
53 switch (corgi_jack_func) { 53 switch (corgi_jack_func) {
54 case CORGI_HP: 54 case CORGI_HP:
55 /* set = unmute headphone */ 55 /* set = unmute headphone */
56 gpio_set_value(CORGI_GPIO_MUTE_L, 1); 56 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
57 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 57 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
58 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 58 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
59 snd_soc_dapm_disable_pin(codec, "Line Jack"); 59 snd_soc_dapm_disable_pin(dapm, "Line Jack");
60 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 60 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
61 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 61 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
62 break; 62 break;
63 case CORGI_MIC: 63 case CORGI_MIC:
64 /* reset = mute headphone */ 64 /* reset = mute headphone */
65 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 65 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
66 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 66 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
67 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 67 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
68 snd_soc_dapm_disable_pin(codec, "Line Jack"); 68 snd_soc_dapm_disable_pin(dapm, "Line Jack");
69 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 69 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
70 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 70 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
71 break; 71 break;
72 case CORGI_LINE: 72 case CORGI_LINE:
73 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 73 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
74 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 74 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
75 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 75 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
76 snd_soc_dapm_enable_pin(codec, "Line Jack"); 76 snd_soc_dapm_enable_pin(dapm, "Line Jack");
77 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 77 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
78 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 78 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
79 break; 79 break;
80 case CORGI_HEADSET: 80 case CORGI_HEADSET:
81 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 81 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
82 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 82 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
83 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 83 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
84 snd_soc_dapm_disable_pin(codec, "Line Jack"); 84 snd_soc_dapm_disable_pin(dapm, "Line Jack");
85 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 85 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
86 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 86 snd_soc_dapm_enable_pin(dapm, "Headset Jack");
87 break; 87 break;
88 } 88 }
89 89
90 if (corgi_spk_func == CORGI_SPK_ON) 90 if (corgi_spk_func == CORGI_SPK_ON)
91 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 91 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
92 else 92 else
93 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 93 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
94 94
95 /* signal a DAPM event */ 95 /* signal a DAPM event */
96 snd_soc_dapm_sync(codec); 96 snd_soc_dapm_sync(dapm);
97} 97}
98 98
99static int corgi_startup(struct snd_pcm_substream *substream) 99static int corgi_startup(struct snd_pcm_substream *substream)
100{ 100{
101 struct snd_soc_pcm_runtime *rtd = substream->private_data; 101 struct snd_soc_pcm_runtime *rtd = substream->private_data;
102 struct snd_soc_codec *codec = rtd->socdev->card->codec; 102 struct snd_soc_codec *codec = rtd->codec;
103
104 mutex_lock(&codec->mutex);
103 105
104 /* check the jack status at stream startup */ 106 /* check the jack status at stream startup */
105 corgi_ext_control(codec); 107 corgi_ext_control(codec);
108
109 mutex_unlock(&codec->mutex);
110
106 return 0; 111 return 0;
107} 112}
108 113
@@ -118,8 +123,8 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
118 struct snd_pcm_hw_params *params) 123 struct snd_pcm_hw_params *params)
119{ 124{
120 struct snd_soc_pcm_runtime *rtd = substream->private_data; 125 struct snd_soc_pcm_runtime *rtd = substream->private_data;
121 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 126 struct snd_soc_dai *codec_dai = rtd->codec_dai;
122 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 127 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
123 unsigned int clk = 0; 128 unsigned int clk = 0;
124 int ret = 0; 129 int ret = 0;
125 130
@@ -150,7 +155,7 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
150 return ret; 155 return ret;
151 156
152 /* set the codec system clock for DAC and ADC */ 157 /* set the codec system clock for DAC and ADC */
153 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, clk, 158 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
154 SND_SOC_CLOCK_IN); 159 SND_SOC_CLOCK_IN);
155 if (ret < 0) 160 if (ret < 0)
156 return ret; 161 return ret;
@@ -272,12 +277,14 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
272/* 277/*
273 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device 278 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
274 */ 279 */
275static int corgi_wm8731_init(struct snd_soc_codec *codec) 280static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
276{ 281{
282 struct snd_soc_codec *codec = rtd->codec;
283 struct snd_soc_dapm_context *dapm = &codec->dapm;
277 int err; 284 int err;
278 285
279 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 286 snd_soc_dapm_nc_pin(dapm, "LLINEIN");
280 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 287 snd_soc_dapm_nc_pin(dapm, "RLINEIN");
281 288
282 /* Add corgi specific controls */ 289 /* Add corgi specific controls */
283 err = snd_soc_add_controls(codec, wm8731_corgi_controls, 290 err = snd_soc_add_controls(codec, wm8731_corgi_controls,
@@ -286,13 +293,13 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
286 return err; 293 return err;
287 294
288 /* Add corgi specific widgets */ 295 /* Add corgi specific widgets */
289 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, 296 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
290 ARRAY_SIZE(wm8731_dapm_widgets)); 297 ARRAY_SIZE(wm8731_dapm_widgets));
291 298
292 /* Set up corgi specific audio path audio_map */ 299 /* Set up corgi specific audio path audio_map */
293 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
294 301
295 snd_soc_dapm_sync(codec); 302 snd_soc_dapm_sync(dapm);
296 return 0; 303 return 0;
297} 304}
298 305
@@ -300,8 +307,10 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
300static struct snd_soc_dai_link corgi_dai = { 307static struct snd_soc_dai_link corgi_dai = {
301 .name = "WM8731", 308 .name = "WM8731",
302 .stream_name = "WM8731", 309 .stream_name = "WM8731",
303 .cpu_dai = &pxa_i2s_dai, 310 .cpu_dai_name = "pxa2xx-i2s",
304 .codec_dai = &wm8731_dai, 311 .codec_dai_name = "wm8731-hifi",
312 .platform_name = "pxa-pcm-audio",
313 .codec_name = "wm8731.0-001b",
305 .init = corgi_wm8731_init, 314 .init = corgi_wm8731_init,
306 .ops = &corgi_ops, 315 .ops = &corgi_ops,
307}; 316};
@@ -309,17 +318,10 @@ static struct snd_soc_dai_link corgi_dai = {
309/* corgi audio machine driver */ 318/* corgi audio machine driver */
310static struct snd_soc_card snd_soc_corgi = { 319static struct snd_soc_card snd_soc_corgi = {
311 .name = "Corgi", 320 .name = "Corgi",
312 .platform = &pxa2xx_soc_platform,
313 .dai_link = &corgi_dai, 321 .dai_link = &corgi_dai,
314 .num_links = 1, 322 .num_links = 1,
315}; 323};
316 324
317/* corgi audio subsystem */
318static struct snd_soc_device corgi_snd_devdata = {
319 .card = &snd_soc_corgi,
320 .codec_dev = &soc_codec_dev_wm8731,
321};
322
323static struct platform_device *corgi_snd_device; 325static struct platform_device *corgi_snd_device;
324 326
325static int __init corgi_init(void) 327static int __init corgi_init(void)
@@ -334,8 +336,7 @@ static int __init corgi_init(void)
334 if (!corgi_snd_device) 336 if (!corgi_snd_device)
335 return -ENOMEM; 337 return -ENOMEM;
336 338
337 platform_set_drvdata(corgi_snd_device, &corgi_snd_devdata); 339 platform_set_drvdata(corgi_snd_device, &snd_soc_corgi);
338 corgi_snd_devdata.dev = &corgi_snd_device->dev;
339 ret = platform_device_add(corgi_snd_device); 340 ret = platform_device_add(corgi_snd_device);
340 341
341 if (ret) 342 if (ret)
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index 7cd2f89d7b10..dc65650a6fa1 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -16,7 +16,6 @@
16#include <sound/core.h> 16#include <sound/core.h>
17#include <sound/pcm.h> 17#include <sound/pcm.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20 19
21#include <mach/audio.h> 20#include <mach/audio.h>
22#include <mach/eseries-gpio.h> 21#include <mach/eseries-gpio.h>
@@ -24,7 +23,6 @@
24#include <asm/mach-types.h> 23#include <asm/mach-types.h>
25 24
26#include "../codecs/wm9705.h" 25#include "../codecs/wm9705.h"
27#include "pxa2xx-pcm.h"
28#include "pxa2xx-ac97.h" 26#include "pxa2xx-ac97.h"
29 27
30 28
@@ -90,24 +88,27 @@ static const struct snd_soc_dapm_route audio_map[] = {
90 {"Mic Amp", NULL, "Mic (Internal)"}, 88 {"Mic Amp", NULL, "Mic (Internal)"},
91}; 89};
92 90
93static int e740_ac97_init(struct snd_soc_codec *codec) 91static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
94{ 92{
95 snd_soc_dapm_nc_pin(codec, "HPOUTL"); 93 struct snd_soc_codec *codec = rtd->codec;
96 snd_soc_dapm_nc_pin(codec, "HPOUTR"); 94 struct snd_soc_dapm_context *dapm = &codec->dapm;
97 snd_soc_dapm_nc_pin(codec, "PHONE"); 95
98 snd_soc_dapm_nc_pin(codec, "LINEINL"); 96 snd_soc_dapm_nc_pin(dapm, "HPOUTL");
99 snd_soc_dapm_nc_pin(codec, "LINEINR"); 97 snd_soc_dapm_nc_pin(dapm, "HPOUTR");
100 snd_soc_dapm_nc_pin(codec, "CDINL"); 98 snd_soc_dapm_nc_pin(dapm, "PHONE");
101 snd_soc_dapm_nc_pin(codec, "CDINR"); 99 snd_soc_dapm_nc_pin(dapm, "LINEINL");
102 snd_soc_dapm_nc_pin(codec, "PCBEEP"); 100 snd_soc_dapm_nc_pin(dapm, "LINEINR");
103 snd_soc_dapm_nc_pin(codec, "MIC2"); 101 snd_soc_dapm_nc_pin(dapm, "CDINL");
104 102 snd_soc_dapm_nc_pin(dapm, "CDINR");
105 snd_soc_dapm_new_controls(codec, e740_dapm_widgets, 103 snd_soc_dapm_nc_pin(dapm, "PCBEEP");
104 snd_soc_dapm_nc_pin(dapm, "MIC2");
105
106 snd_soc_dapm_new_controls(dapm, e740_dapm_widgets,
106 ARRAY_SIZE(e740_dapm_widgets)); 107 ARRAY_SIZE(e740_dapm_widgets));
107 108
108 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 109 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
109 110
110 snd_soc_dapm_sync(codec); 111 snd_soc_dapm_sync(dapm);
111 112
112 return 0; 113 return 0;
113} 114}
@@ -116,30 +117,28 @@ static struct snd_soc_dai_link e740_dai[] = {
116 { 117 {
117 .name = "AC97", 118 .name = "AC97",
118 .stream_name = "AC97 HiFi", 119 .stream_name = "AC97 HiFi",
119 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 120 .cpu_dai_name = "pxa2xx-ac97",
120 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], 121 .codec_dai_name = "wm9705-hifi",
122 .platform_name = "pxa-pcm-audio",
123 .codec_name = "wm9705-codec",
121 .init = e740_ac97_init, 124 .init = e740_ac97_init,
122 }, 125 },
123 { 126 {
124 .name = "AC97 Aux", 127 .name = "AC97 Aux",
125 .stream_name = "AC97 Aux", 128 .stream_name = "AC97 Aux",
126 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 129 .cpu_dai_name = "pxa2xx-ac97-aux",
127 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], 130 .codec_dai_name = "wm9705-aux",
131 .platform_name = "pxa-pcm-audio",
132 .codec_name = "wm9705-codec",
128 }, 133 },
129}; 134};
130 135
131static struct snd_soc_card e740 = { 136static struct snd_soc_card e740 = {
132 .name = "Toshiba e740", 137 .name = "Toshiba e740",
133 .platform = &pxa2xx_soc_platform,
134 .dai_link = e740_dai, 138 .dai_link = e740_dai,
135 .num_links = ARRAY_SIZE(e740_dai), 139 .num_links = ARRAY_SIZE(e740_dai),
136}; 140};
137 141
138static struct snd_soc_device e740_snd_devdata = {
139 .card = &e740,
140 .codec_dev = &soc_codec_dev_wm9705,
141};
142
143static struct platform_device *e740_snd_device; 142static struct platform_device *e740_snd_device;
144 143
145static int __init e740_init(void) 144static int __init e740_init(void)
@@ -178,8 +177,7 @@ static int __init e740_init(void)
178 goto free_apwr_gpio; 177 goto free_apwr_gpio;
179 } 178 }
180 179
181 platform_set_drvdata(e740_snd_device, &e740_snd_devdata); 180 platform_set_drvdata(e740_snd_device, &e740);
182 e740_snd_devdata.dev = &e740_snd_device->dev;
183 ret = platform_device_add(e740_snd_device); 181 ret = platform_device_add(e740_snd_device);
184 182
185 if (!ret) 183 if (!ret)
@@ -200,6 +198,9 @@ free_mic_amp_gpio:
200static void __exit e740_exit(void) 198static void __exit e740_exit(void)
201{ 199{
202 platform_device_unregister(e740_snd_device); 200 platform_device_unregister(e740_snd_device);
201 gpio_free(GPIO_E740_WM9705_nAVDD2);
202 gpio_free(GPIO_E740_AMP_ON);
203 gpio_free(GPIO_E740_MIC_ON);
203} 204}
204 205
205module_init(e740_init); 206module_init(e740_init);
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 8dceccc5e059..51897fcd911b 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -16,7 +16,6 @@
16#include <sound/core.h> 16#include <sound/core.h>
17#include <sound/pcm.h> 17#include <sound/pcm.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20 19
21#include <mach/audio.h> 20#include <mach/audio.h>
22#include <mach/eseries-gpio.h> 21#include <mach/eseries-gpio.h>
@@ -24,7 +23,6 @@
24#include <asm/mach-types.h> 23#include <asm/mach-types.h>
25 24
26#include "../codecs/wm9705.h" 25#include "../codecs/wm9705.h"
27#include "pxa2xx-pcm.h"
28#include "pxa2xx-ac97.h" 26#include "pxa2xx-ac97.h"
29 27
30static int e750_spk_amp_event(struct snd_soc_dapm_widget *w, 28static int e750_spk_amp_event(struct snd_soc_dapm_widget *w,
@@ -72,24 +70,27 @@ static const struct snd_soc_dapm_route audio_map[] = {
72 {"MIC1", NULL, "Mic (Internal)"}, 70 {"MIC1", NULL, "Mic (Internal)"},
73}; 71};
74 72
75static int e750_ac97_init(struct snd_soc_codec *codec) 73static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
76{ 74{
77 snd_soc_dapm_nc_pin(codec, "LOUT"); 75 struct snd_soc_codec *codec = rtd->codec;
78 snd_soc_dapm_nc_pin(codec, "ROUT"); 76 struct snd_soc_dapm_context *dapm = &codec->dapm;
79 snd_soc_dapm_nc_pin(codec, "PHONE"); 77
80 snd_soc_dapm_nc_pin(codec, "LINEINL"); 78 snd_soc_dapm_nc_pin(dapm, "LOUT");
81 snd_soc_dapm_nc_pin(codec, "LINEINR"); 79 snd_soc_dapm_nc_pin(dapm, "ROUT");
82 snd_soc_dapm_nc_pin(codec, "CDINL"); 80 snd_soc_dapm_nc_pin(dapm, "PHONE");
83 snd_soc_dapm_nc_pin(codec, "CDINR"); 81 snd_soc_dapm_nc_pin(dapm, "LINEINL");
84 snd_soc_dapm_nc_pin(codec, "PCBEEP"); 82 snd_soc_dapm_nc_pin(dapm, "LINEINR");
85 snd_soc_dapm_nc_pin(codec, "MIC2"); 83 snd_soc_dapm_nc_pin(dapm, "CDINL");
86 84 snd_soc_dapm_nc_pin(dapm, "CDINR");
87 snd_soc_dapm_new_controls(codec, e750_dapm_widgets, 85 snd_soc_dapm_nc_pin(dapm, "PCBEEP");
86 snd_soc_dapm_nc_pin(dapm, "MIC2");
87
88 snd_soc_dapm_new_controls(dapm, e750_dapm_widgets,
88 ARRAY_SIZE(e750_dapm_widgets)); 89 ARRAY_SIZE(e750_dapm_widgets));
89 90
90 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 91 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
91 92
92 snd_soc_dapm_sync(codec); 93 snd_soc_dapm_sync(dapm);
93 94
94 return 0; 95 return 0;
95} 96}
@@ -98,31 +99,29 @@ static struct snd_soc_dai_link e750_dai[] = {
98 { 99 {
99 .name = "AC97", 100 .name = "AC97",
100 .stream_name = "AC97 HiFi", 101 .stream_name = "AC97 HiFi",
101 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 102 .cpu_dai_name = "pxa2xx-ac97",
102 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], 103 .codec_dai_name = "wm9705-hifi",
104 .platform_name = "pxa-pcm-audio",
105 .codec_name = "wm9705-codec",
103 .init = e750_ac97_init, 106 .init = e750_ac97_init,
104 /* use ops to check startup state */ 107 /* use ops to check startup state */
105 }, 108 },
106 { 109 {
107 .name = "AC97 Aux", 110 .name = "AC97 Aux",
108 .stream_name = "AC97 Aux", 111 .stream_name = "AC97 Aux",
109 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 112 .cpu_dai_name = "pxa2xx-ac97-aux",
110 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], 113 .codec_dai_name ="wm9705-aux",
114 .platform_name = "pxa-pcm-audio",
115 .codec_name = "wm9705-codec",
111 }, 116 },
112}; 117};
113 118
114static struct snd_soc_card e750 = { 119static struct snd_soc_card e750 = {
115 .name = "Toshiba e750", 120 .name = "Toshiba e750",
116 .platform = &pxa2xx_soc_platform,
117 .dai_link = e750_dai, 121 .dai_link = e750_dai,
118 .num_links = ARRAY_SIZE(e750_dai), 122 .num_links = ARRAY_SIZE(e750_dai),
119}; 123};
120 124
121static struct snd_soc_device e750_snd_devdata = {
122 .card = &e750,
123 .codec_dev = &soc_codec_dev_wm9705,
124};
125
126static struct platform_device *e750_snd_device; 125static struct platform_device *e750_snd_device;
127 126
128static int __init e750_init(void) 127static int __init e750_init(void)
@@ -154,8 +153,7 @@ static int __init e750_init(void)
154 goto free_spk_amp_gpio; 153 goto free_spk_amp_gpio;
155 } 154 }
156 155
157 platform_set_drvdata(e750_snd_device, &e750_snd_devdata); 156 platform_set_drvdata(e750_snd_device, &e750);
158 e750_snd_devdata.dev = &e750_snd_device->dev;
159 ret = platform_device_add(e750_snd_device); 157 ret = platform_device_add(e750_snd_device);
160 158
161 if (!ret) 159 if (!ret)
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index bc019cdce429..053ed208e59f 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -16,14 +16,12 @@
16#include <sound/core.h> 16#include <sound/core.h>
17#include <sound/pcm.h> 17#include <sound/pcm.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20 19
21#include <asm/mach-types.h> 20#include <asm/mach-types.h>
22#include <mach/audio.h> 21#include <mach/audio.h>
23#include <mach/eseries-gpio.h> 22#include <mach/eseries-gpio.h>
24 23
25#include "../codecs/wm9712.h" 24#include "../codecs/wm9712.h"
26#include "pxa2xx-pcm.h"
27#include "pxa2xx-ac97.h" 25#include "pxa2xx-ac97.h"
28 26
29static int e800_spk_amp_event(struct snd_soc_dapm_widget *w, 27static int e800_spk_amp_event(struct snd_soc_dapm_widget *w,
@@ -73,13 +71,16 @@ static const struct snd_soc_dapm_route audio_map[] = {
73 {"MIC2", NULL, "Mic (Internal2)"}, 71 {"MIC2", NULL, "Mic (Internal2)"},
74}; 72};
75 73
76static int e800_ac97_init(struct snd_soc_codec *codec) 74static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
77{ 75{
78 snd_soc_dapm_new_controls(codec, e800_dapm_widgets, 76 struct snd_soc_codec *codec = rtd->codec;
77 struct snd_soc_dapm_context *dapm = &codec->dapm;
78
79 snd_soc_dapm_new_controls(dapm, e800_dapm_widgets,
79 ARRAY_SIZE(e800_dapm_widgets)); 80 ARRAY_SIZE(e800_dapm_widgets));
80 81
81 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 82 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
82 snd_soc_dapm_sync(codec); 83 snd_soc_dapm_sync(dapm);
83 84
84 return 0; 85 return 0;
85} 86}
@@ -88,30 +89,28 @@ static struct snd_soc_dai_link e800_dai[] = {
88 { 89 {
89 .name = "AC97", 90 .name = "AC97",
90 .stream_name = "AC97 HiFi", 91 .stream_name = "AC97 HiFi",
91 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 92 .cpu_dai_name = "pxa2xx-ac97",
92 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 93 .codec_dai_name = "wm9712-hifi",
94 .platform_name = "pxa-pcm-audio",
95 .codec_name = "wm9712-codec",
93 .init = e800_ac97_init, 96 .init = e800_ac97_init,
94 }, 97 },
95 { 98 {
96 .name = "AC97 Aux", 99 .name = "AC97 Aux",
97 .stream_name = "AC97 Aux", 100 .stream_name = "AC97 Aux",
98 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 101 .cpu_dai_name = "pxa2xx-ac97-aux",
99 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 102 .codec_dai_name ="wm9712-aux",
103 .platform_name = "pxa-pcm-audio",
104 .codec_name = "wm9712-codec",
100 }, 105 },
101}; 106};
102 107
103static struct snd_soc_card e800 = { 108static struct snd_soc_card e800 = {
104 .name = "Toshiba e800", 109 .name = "Toshiba e800",
105 .platform = &pxa2xx_soc_platform,
106 .dai_link = e800_dai, 110 .dai_link = e800_dai,
107 .num_links = ARRAY_SIZE(e800_dai), 111 .num_links = ARRAY_SIZE(e800_dai),
108}; 112};
109 113
110static struct snd_soc_device e800_snd_devdata = {
111 .card = &e800,
112 .codec_dev = &soc_codec_dev_wm9712,
113};
114
115static struct platform_device *e800_snd_device; 114static struct platform_device *e800_snd_device;
116 115
117static int __init e800_init(void) 116static int __init e800_init(void)
@@ -141,8 +140,7 @@ static int __init e800_init(void)
141 if (!e800_snd_device) 140 if (!e800_snd_device)
142 return -ENOMEM; 141 return -ENOMEM;
143 142
144 platform_set_drvdata(e800_snd_device, &e800_snd_devdata); 143 platform_set_drvdata(e800_snd_device, &e800);
145 e800_snd_devdata.dev = &e800_snd_device->dev;
146 ret = platform_device_add(e800_snd_device); 144 ret = platform_device_add(e800_snd_device);
147 145
148 if (!ret) 146 if (!ret)
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index f4756e4025fd..b13a4252812d 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -26,42 +26,38 @@
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <mach/audio.h> 31#include <mach/audio.h>
33 32
34#include "../codecs/wm9712.h" 33#include "../codecs/wm9712.h"
35#include "pxa2xx-pcm.h"
36#include "pxa2xx-ac97.h" 34#include "pxa2xx-ac97.h"
37 35
38static struct snd_soc_dai_link em_x270_dai[] = { 36static struct snd_soc_dai_link em_x270_dai[] = {
39 { 37 {
40 .name = "AC97", 38 .name = "AC97",
41 .stream_name = "AC97 HiFi", 39 .stream_name = "AC97 HiFi",
42 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 40 .cpu_dai_name = "pxa2xx-ac97",
43 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 41 .codec_dai_name = "wm9712-hifi",
42 .platform_name = "pxa-pcm-audio",
43 .codec_name = "wm9712-codec",
44 }, 44 },
45 { 45 {
46 .name = "AC97 Aux", 46 .name = "AC97 Aux",
47 .stream_name = "AC97 Aux", 47 .stream_name = "AC97 Aux",
48 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 48 .cpu_dai_name = "pxa2xx-ac97-aux",
49 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 49 .codec_dai_name ="wm9712-aux",
50 .platform_name = "pxa-pcm-audio",
51 .codec_name = "wm9712-codec",
50 }, 52 },
51}; 53};
52 54
53static struct snd_soc_card em_x270 = { 55static struct snd_soc_card em_x270 = {
54 .name = "EM-X270", 56 .name = "EM-X270",
55 .platform = &pxa2xx_soc_platform,
56 .dai_link = em_x270_dai, 57 .dai_link = em_x270_dai,
57 .num_links = ARRAY_SIZE(em_x270_dai), 58 .num_links = ARRAY_SIZE(em_x270_dai),
58}; 59};
59 60
60static struct snd_soc_device em_x270_snd_devdata = {
61 .card = &em_x270,
62 .codec_dev = &soc_codec_dev_wm9712,
63};
64
65static struct platform_device *em_x270_snd_device; 61static struct platform_device *em_x270_snd_device;
66 62
67static int __init em_x270_init(void) 63static int __init em_x270_init(void)
@@ -76,8 +72,7 @@ static int __init em_x270_init(void)
76 if (!em_x270_snd_device) 72 if (!em_x270_snd_device)
77 return -ENOMEM; 73 return -ENOMEM;
78 74
79 platform_set_drvdata(em_x270_snd_device, &em_x270_snd_devdata); 75 platform_set_drvdata(em_x270_snd_device, &em_x270);
80 em_x270_snd_devdata.dev = &em_x270_snd_device->dev;
81 ret = platform_device_add(em_x270_snd_device); 76 ret = platform_device_add(em_x270_snd_device);
82 77
83 if (ret) 78 if (ret)
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
new file mode 100644
index 000000000000..65c124831a00
--- /dev/null
+++ b/sound/soc/pxa/hx4700.c
@@ -0,0 +1,255 @@
1/*
2 * SoC audio for HP iPAQ hx4700
3 *
4 * Copyright (c) 2009 Philipp Zabel
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/timer.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/delay.h>
18#include <linux/gpio.h>
19
20#include <sound/core.h>
21#include <sound/jack.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25
26#include <mach/hx4700.h>
27#include <asm/mach-types.h>
28#include "pxa2xx-i2s.h"
29
30#include "../codecs/ak4641.h"
31
32static struct snd_soc_jack hs_jack;
33
34/* Headphones jack detection DAPM pin */
35static struct snd_soc_jack_pin hs_jack_pin[] = {
36 {
37 .pin = "Headphone Jack",
38 .mask = SND_JACK_HEADPHONE,
39 },
40 {
41 .pin = "Speaker",
42 /* disable speaker when hp jack is inserted */
43 .mask = SND_JACK_HEADPHONE,
44 .invert = 1,
45 },
46};
47
48/* Headphones jack detection GPIO */
49static struct snd_soc_jack_gpio hs_jack_gpio = {
50 .gpio = GPIO75_HX4700_EARPHONE_nDET,
51 .invert = true,
52 .name = "hp-gpio",
53 .report = SND_JACK_HEADPHONE,
54 .debounce_time = 200,
55};
56
57/*
58 * iPAQ hx4700 uses I2S for capture and playback.
59 */
60static int hx4700_hw_params(struct snd_pcm_substream *substream,
61 struct snd_pcm_hw_params *params)
62{
63 struct snd_soc_pcm_runtime *rtd = substream->private_data;
64 struct snd_soc_dai *codec_dai = rtd->codec_dai;
65 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
66 int ret = 0;
67
68 /* set codec DAI configuration */
69 ret = snd_soc_dai_set_fmt(codec_dai,
70 SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
71 SND_SOC_DAIFMT_CBS_CFS);
72 if (ret < 0)
73 return ret;
74
75 /* set cpu DAI configuration */
76 ret = snd_soc_dai_set_fmt(cpu_dai,
77 SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF |
78 SND_SOC_DAIFMT_CBS_CFS);
79 if (ret < 0)
80 return ret;
81
82 /* set the I2S system clock as output */
83 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
84 SND_SOC_CLOCK_OUT);
85 if (ret < 0)
86 return ret;
87
88 /* inform codec driver about clock freq *
89 * (PXA I2S always uses divider 256) */
90 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params),
91 SND_SOC_CLOCK_IN);
92 if (ret < 0)
93 return ret;
94
95 return 0;
96}
97
98static struct snd_soc_ops hx4700_ops = {
99 .hw_params = hx4700_hw_params,
100};
101
102static int hx4700_spk_power(struct snd_soc_dapm_widget *w,
103 struct snd_kcontrol *k, int event)
104{
105 gpio_set_value(GPIO107_HX4700_SPK_nSD, !!SND_SOC_DAPM_EVENT_ON(event));
106 return 0;
107}
108
109static int hx4700_hp_power(struct snd_soc_dapm_widget *w,
110 struct snd_kcontrol *k, int event)
111{
112 gpio_set_value(GPIO92_HX4700_HP_DRIVER, !!SND_SOC_DAPM_EVENT_ON(event));
113 return 0;
114}
115
116/* hx4700 machine dapm widgets */
117static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power),
119 SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power),
120 SND_SOC_DAPM_MIC("Built-in Microphone", NULL),
121};
122
123/* hx4700 machine audio_map */
124static const struct snd_soc_dapm_route hx4700_audio_map[] = {
125
126 /* Headphone connected to LOUT, ROUT */
127 {"Headphone Jack", NULL, "LOUT"},
128 {"Headphone Jack", NULL, "ROUT"},
129
130 /* Speaker connected to MOUT2 */
131 {"Speaker", NULL, "MOUT2"},
132
133 /* Microphone connected to MICIN */
134 {"MICIN", NULL, "Built-in Microphone"},
135 {"AIN", NULL, "MICOUT"},
136};
137
138/*
139 * Logic for a ak4641 as connected on a HP iPAQ hx4700
140 */
141static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
142{
143 struct snd_soc_codec *codec = rtd->codec;
144 struct snd_soc_dapm_context *dapm = &codec->dapm;
145 int err;
146
147 /* NC codec pins */
148 /* FIXME: is anything connected here? */
149 snd_soc_dapm_nc_pin(dapm, "MOUT1");
150 snd_soc_dapm_nc_pin(dapm, "MICEXT");
151 snd_soc_dapm_nc_pin(dapm, "AUX");
152
153 /* Jack detection API stuff */
154 err = snd_soc_jack_new(codec, "Headphone Jack",
155 SND_JACK_HEADPHONE, &hs_jack);
156 if (err)
157 return err;
158
159 err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin),
160 hs_jack_pin);
161 if (err)
162 return err;
163
164 err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio);
165
166 return err;
167}
168
169/* hx4700 digital audio interface glue - connects codec <--> CPU */
170static struct snd_soc_dai_link hx4700_dai = {
171 .name = "ak4641",
172 .stream_name = "AK4641",
173 .cpu_dai_name = "pxa2xx-i2s",
174 .codec_dai_name = "ak4641-hifi",
175 .platform_name = "pxa-pcm-audio",
176 .codec_name = "ak4641.0-0012",
177 .init = hx4700_ak4641_init,
178 .ops = &hx4700_ops,
179};
180
181/* hx4700 audio machine driver */
182static struct snd_soc_card snd_soc_card_hx4700 = {
183 .name = "iPAQ hx4700",
184 .dai_link = &hx4700_dai,
185 .num_links = 1,
186 .dapm_widgets = hx4700_dapm_widgets,
187 .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets),
188 .dapm_routes = hx4700_audio_map,
189 .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map),
190};
191
192static struct gpio hx4700_audio_gpios[] = {
193 { GPIO107_HX4700_SPK_nSD, GPIOF_OUT_INIT_HIGH, "SPK_POWER" },
194 { GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" },
195};
196
197static int __devinit hx4700_audio_probe(struct platform_device *pdev)
198{
199 int ret;
200
201 if (!machine_is_h4700())
202 return -ENODEV;
203
204 ret = gpio_request_array(hx4700_audio_gpios,
205 ARRAY_SIZE(hx4700_audio_gpios));
206 if (ret)
207 return ret;
208
209 snd_soc_card_hx4700.dev = &pdev->dev;
210 ret = snd_soc_register_card(&snd_soc_card_hx4700);
211 if (ret)
212 return ret;
213
214 return 0;
215}
216
217static int __devexit hx4700_audio_remove(struct platform_device *pdev)
218{
219 snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio);
220 snd_soc_unregister_card(&snd_soc_card_hx4700);
221
222 gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
223 gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
224
225 gpio_free_array(hx4700_audio_gpios, ARRAY_SIZE(hx4700_audio_gpios));
226 return 0;
227}
228
229static struct platform_driver hx4700_audio_driver = {
230 .driver = {
231 .name = "hx4700-audio",
232 .owner = THIS_MODULE,
233 .pm = &snd_soc_pm_ops,
234 },
235 .probe = hx4700_audio_probe,
236 .remove = __devexit_p(hx4700_audio_remove),
237};
238
239static int __init hx4700_modinit(void)
240{
241 return platform_driver_register(&hx4700_audio_driver);
242}
243module_init(hx4700_modinit);
244
245static void __exit hx4700_modexit(void)
246{
247 platform_driver_unregister(&hx4700_audio_driver);
248}
249
250module_exit(hx4700_modexit);
251
252MODULE_AUTHOR("Philipp Zabel");
253MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
254MODULE_LICENSE("GPL");
255MODULE_ALIAS("platform:hx4700-audio");
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 405587a01160..154fc6f23438 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -6,14 +6,13 @@
6 6
7#include "../codecs/wm8940.h" 7#include "../codecs/wm8940.h"
8#include "pxa2xx-i2s.h" 8#include "pxa2xx-i2s.h"
9#include "pxa2xx-pcm.h"
10 9
11static int imote2_asoc_hw_params(struct snd_pcm_substream *substream, 10static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
12 struct snd_pcm_hw_params *params) 11 struct snd_pcm_hw_params *params)
13{ 12{
14 struct snd_soc_pcm_runtime *rtd = substream->private_data; 13 struct snd_soc_pcm_runtime *rtd = substream->private_data;
15 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 14 struct snd_soc_dai *codec_dai = rtd->codec_dai;
16 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 15 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
17 unsigned int clk = 0; 16 unsigned int clk = 0;
18 int ret; 17 int ret;
19 18
@@ -64,23 +63,19 @@ static struct snd_soc_ops imote2_asoc_ops = {
64static struct snd_soc_dai_link imote2_dai = { 63static struct snd_soc_dai_link imote2_dai = {
65 .name = "WM8940", 64 .name = "WM8940",
66 .stream_name = "WM8940", 65 .stream_name = "WM8940",
67 .cpu_dai = &pxa_i2s_dai, 66 .cpu_dai_name = "pxa2xx-i2s",
68 .codec_dai = &wm8940_dai, 67 .codec_dai_name = "wm8940-hifi",
68 .platform_name = "pxa-pcm-audio",
69 .codec_name = "wm8940-codec.0-0034",
69 .ops = &imote2_asoc_ops, 70 .ops = &imote2_asoc_ops,
70}; 71};
71 72
72static struct snd_soc_card snd_soc_imote2 = { 73static struct snd_soc_card snd_soc_imote2 = {
73 .name = "Imote2", 74 .name = "Imote2",
74 .platform = &pxa2xx_soc_platform,
75 .dai_link = &imote2_dai, 75 .dai_link = &imote2_dai,
76 .num_links = 1, 76 .num_links = 1,
77}; 77};
78 78
79static struct snd_soc_device imote2_snd_devdata = {
80 .card = &snd_soc_imote2,
81 .codec_dev = &soc_codec_dev_wm8940,
82};
83
84static struct platform_device *imote2_snd_device; 79static struct platform_device *imote2_snd_device;
85 80
86static int __init imote2_asoc_init(void) 81static int __init imote2_asoc_init(void)
@@ -93,8 +88,7 @@ static int __init imote2_asoc_init(void)
93 if (!imote2_snd_device) 88 if (!imote2_snd_device)
94 return -ENOMEM; 89 return -ENOMEM;
95 90
96 platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata); 91 platform_set_drvdata(imote2_snd_device, &snd_soc_imote2);
97 imote2_snd_devdata.dev = &imote2_snd_device->dev;
98 ret = platform_device_add(imote2_snd_device); 92 ret = platform_device_add(imote2_snd_device);
99 if (ret) 93 if (ret)
100 platform_device_put(imote2_snd_device); 94 platform_device_put(imote2_snd_device);
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 4c8d99a8d386..67dcc36cd621 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -26,13 +26,11 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/uda1380.h> 29#include <sound/uda1380.h>
31 30
32#include <mach/magician.h> 31#include <mach/magician.h>
33#include <asm/mach-types.h> 32#include <asm/mach-types.h>
34#include "../codecs/uda1380.h" 33#include "../codecs/uda1380.h"
35#include "pxa2xx-pcm.h"
36#include "pxa2xx-i2s.h" 34#include "pxa2xx-i2s.h"
37#include "pxa-ssp.h" 35#include "pxa-ssp.h"
38 36
@@ -45,37 +43,43 @@ static int magician_in_sel = MAGICIAN_MIC;
45 43
46static void magician_ext_control(struct snd_soc_codec *codec) 44static void magician_ext_control(struct snd_soc_codec *codec)
47{ 45{
46 struct snd_soc_dapm_context *dapm = &codec->dapm;
47
48 if (magician_spk_switch) 48 if (magician_spk_switch)
49 snd_soc_dapm_enable_pin(codec, "Speaker"); 49 snd_soc_dapm_enable_pin(dapm, "Speaker");
50 else 50 else
51 snd_soc_dapm_disable_pin(codec, "Speaker"); 51 snd_soc_dapm_disable_pin(dapm, "Speaker");
52 if (magician_hp_switch) 52 if (magician_hp_switch)
53 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 53 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
54 else 54 else
55 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 55 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
56 56
57 switch (magician_in_sel) { 57 switch (magician_in_sel) {
58 case MAGICIAN_MIC: 58 case MAGICIAN_MIC:
59 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 59 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
60 snd_soc_dapm_enable_pin(codec, "Call Mic"); 60 snd_soc_dapm_enable_pin(dapm, "Call Mic");
61 break; 61 break;
62 case MAGICIAN_MIC_EXT: 62 case MAGICIAN_MIC_EXT:
63 snd_soc_dapm_disable_pin(codec, "Call Mic"); 63 snd_soc_dapm_disable_pin(dapm, "Call Mic");
64 snd_soc_dapm_enable_pin(codec, "Headset Mic"); 64 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
65 break; 65 break;
66 } 66 }
67 67
68 snd_soc_dapm_sync(codec); 68 snd_soc_dapm_sync(dapm);
69} 69}
70 70
71static int magician_startup(struct snd_pcm_substream *substream) 71static int magician_startup(struct snd_pcm_substream *substream)
72{ 72{
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 73 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_codec *codec = rtd->socdev->card->codec; 74 struct snd_soc_codec *codec = rtd->codec;
75
76 mutex_lock(&codec->mutex);
75 77
76 /* check the jack status at stream startup */ 78 /* check the jack status at stream startup */
77 magician_ext_control(codec); 79 magician_ext_control(codec);
78 80
81 mutex_unlock(&codec->mutex);
82
79 return 0; 83 return 0;
80} 84}
81 85
@@ -86,8 +90,8 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params) 90 struct snd_pcm_hw_params *params)
87{ 91{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data; 92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 93 struct snd_soc_dai *codec_dai = rtd->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 94 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 unsigned int acps, acds, width, rate; 95 unsigned int acps, acds, width, rate;
92 unsigned int div4 = PXA_SSP_CLK_SCDB_4; 96 unsigned int div4 = PXA_SSP_CLK_SCDB_4;
93 int ret = 0; 97 int ret = 0;
@@ -227,8 +231,8 @@ static int magician_capture_hw_params(struct snd_pcm_substream *substream,
227 struct snd_pcm_hw_params *params) 231 struct snd_pcm_hw_params *params)
228{ 232{
229 struct snd_soc_pcm_runtime *rtd = substream->private_data; 233 struct snd_soc_pcm_runtime *rtd = substream->private_data;
230 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 234 struct snd_soc_dai *codec_dai = rtd->codec_dai;
231 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 235 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
232 int ret = 0; 236 int ret = 0;
233 237
234 /* set codec DAI configuration */ 238 /* set codec DAI configuration */
@@ -393,17 +397,19 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = {
393/* 397/*
394 * Logic for a uda1380 as connected on a HTC Magician 398 * Logic for a uda1380 as connected on a HTC Magician
395 */ 399 */
396static int magician_uda1380_init(struct snd_soc_codec *codec) 400static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
397{ 401{
402 struct snd_soc_codec *codec = rtd->codec;
403 struct snd_soc_dapm_context *dapm = &codec->dapm;
398 int err; 404 int err;
399 405
400 /* NC codec pins */ 406 /* NC codec pins */
401 snd_soc_dapm_nc_pin(codec, "VOUTLHP"); 407 snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
402 snd_soc_dapm_nc_pin(codec, "VOUTRHP"); 408 snd_soc_dapm_nc_pin(dapm, "VOUTRHP");
403 409
404 /* FIXME: is anything connected here? */ 410 /* FIXME: is anything connected here? */
405 snd_soc_dapm_nc_pin(codec, "VINL"); 411 snd_soc_dapm_nc_pin(dapm, "VINL");
406 snd_soc_dapm_nc_pin(codec, "VINR"); 412 snd_soc_dapm_nc_pin(dapm, "VINR");
407 413
408 /* Add magician specific controls */ 414 /* Add magician specific controls */
409 err = snd_soc_add_controls(codec, uda1380_magician_controls, 415 err = snd_soc_add_controls(codec, uda1380_magician_controls,
@@ -412,13 +418,13 @@ static int magician_uda1380_init(struct snd_soc_codec *codec)
412 return err; 418 return err;
413 419
414 /* Add magician specific widgets */ 420 /* Add magician specific widgets */
415 snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, 421 snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
416 ARRAY_SIZE(uda1380_dapm_widgets)); 422 ARRAY_SIZE(uda1380_dapm_widgets));
417 423
418 /* Set up magician specific audio path interconnects */ 424 /* Set up magician specific audio path interconnects */
419 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 425 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
420 426
421 snd_soc_dapm_sync(codec); 427 snd_soc_dapm_sync(dapm);
422 return 0; 428 return 0;
423} 429}
424 430
@@ -427,16 +433,20 @@ static struct snd_soc_dai_link magician_dai[] = {
427{ 433{
428 .name = "uda1380", 434 .name = "uda1380",
429 .stream_name = "UDA1380 Playback", 435 .stream_name = "UDA1380 Playback",
430 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1], 436 .cpu_dai_name = "pxa-ssp-dai.0",
431 .codec_dai = &uda1380_dai[UDA1380_DAI_PLAYBACK], 437 .codec_dai_name = "uda1380-hifi-playback",
438 .platform_name = "pxa-pcm-audio",
439 .codec_name = "uda1380-codec.0-0018",
432 .init = magician_uda1380_init, 440 .init = magician_uda1380_init,
433 .ops = &magician_playback_ops, 441 .ops = &magician_playback_ops,
434}, 442},
435{ 443{
436 .name = "uda1380", 444 .name = "uda1380",
437 .stream_name = "UDA1380 Capture", 445 .stream_name = "UDA1380 Capture",
438 .cpu_dai = &pxa_i2s_dai, 446 .cpu_dai_name = "pxa2xx-i2s",
439 .codec_dai = &uda1380_dai[UDA1380_DAI_CAPTURE], 447 .codec_dai_name = "uda1380-hifi-capture",
448 .platform_name = "pxa-pcm-audio",
449 .codec_name = "uda1380-codec.0-0018",
440 .ops = &magician_capture_ops, 450 .ops = &magician_capture_ops,
441} 451}
442}; 452};
@@ -446,13 +456,7 @@ static struct snd_soc_card snd_soc_card_magician = {
446 .name = "Magician", 456 .name = "Magician",
447 .dai_link = magician_dai, 457 .dai_link = magician_dai,
448 .num_links = ARRAY_SIZE(magician_dai), 458 .num_links = ARRAY_SIZE(magician_dai),
449 .platform = &pxa2xx_soc_platform,
450};
451 459
452/* magician audio subsystem */
453static struct snd_soc_device magician_snd_devdata = {
454 .card = &snd_soc_card_magician,
455 .codec_dev = &soc_codec_dev_uda1380,
456}; 460};
457 461
458static struct platform_device *magician_snd_device; 462static struct platform_device *magician_snd_device;
@@ -514,8 +518,7 @@ static int __init magician_init(void)
514 goto err_pdev; 518 goto err_pdev;
515 } 519 }
516 520
517 platform_set_drvdata(magician_snd_device, &magician_snd_devdata); 521 platform_set_drvdata(magician_snd_device, &snd_soc_card_magician);
518 magician_snd_devdata.dev = &magician_snd_device->dev;
519 ret = platform_device_add(magician_snd_device); 522 ret = platform_device_add(magician_snd_device);
520 if (ret) { 523 if (ret) {
521 platform_device_put(magician_snd_device); 524 platform_device_put(magician_snd_device);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 19eda8bbfdaf..38ca6759907e 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -50,11 +50,9 @@
50#include <sound/core.h> 50#include <sound/core.h>
51#include <sound/pcm.h> 51#include <sound/pcm.h>
52#include <sound/soc.h> 52#include <sound/soc.h>
53#include <sound/soc-dapm.h>
54#include <sound/initval.h> 53#include <sound/initval.h>
55#include <sound/ac97_codec.h> 54#include <sound/ac97_codec.h>
56 55
57#include "pxa2xx-pcm.h"
58#include "pxa2xx-ac97.h" 56#include "pxa2xx-ac97.h"
59#include "../codecs/wm9713.h" 57#include "../codecs/wm9713.h"
60 58
@@ -128,30 +126,32 @@ static const struct snd_soc_dapm_route audio_map[] = {
128 {"Rear Speaker", NULL, "SPKR"}, 126 {"Rear Speaker", NULL, "SPKR"},
129}; 127};
130 128
131static int mioa701_wm9713_init(struct snd_soc_codec *codec) 129static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
132{ 130{
131 struct snd_soc_codec *codec = rtd->codec;
132 struct snd_soc_dapm_context *dapm = &codec->dapm;
133 unsigned short reg; 133 unsigned short reg;
134 134
135 /* Add mioa701 specific widgets */ 135 /* Add mioa701 specific widgets */
136 snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets)); 136 snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets));
137 137
138 /* Set up mioa701 specific audio path audio_mapnects */ 138 /* Set up mioa701 specific audio path audio_mapnects */
139 snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map)); 139 snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map));
140 140
141 /* Prepare GPIO8 for rear speaker amplifier */ 141 /* Prepare GPIO8 for rear speaker amplifier */
142 reg = codec->read(codec, AC97_GPIO_CFG); 142 reg = codec->driver->read(codec, AC97_GPIO_CFG);
143 codec->write(codec, AC97_GPIO_CFG, reg | 0x0100); 143 codec->driver->write(codec, AC97_GPIO_CFG, reg | 0x0100);
144 144
145 /* Prepare MIC input */ 145 /* Prepare MIC input */
146 reg = codec->read(codec, AC97_3D_CONTROL); 146 reg = codec->driver->read(codec, AC97_3D_CONTROL);
147 codec->write(codec, AC97_3D_CONTROL, reg | 0xc000); 147 codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000);
148 148
149 snd_soc_dapm_enable_pin(codec, "Front Speaker"); 149 snd_soc_dapm_enable_pin(dapm, "Front Speaker");
150 snd_soc_dapm_enable_pin(codec, "Rear Speaker"); 150 snd_soc_dapm_enable_pin(dapm, "Rear Speaker");
151 snd_soc_dapm_enable_pin(codec, "Front Mic"); 151 snd_soc_dapm_enable_pin(dapm, "Front Mic");
152 snd_soc_dapm_enable_pin(codec, "GSM Line In"); 152 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
153 snd_soc_dapm_enable_pin(codec, "GSM Line Out"); 153 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
154 snd_soc_dapm_sync(codec); 154 snd_soc_dapm_sync(dapm);
155 155
156 return 0; 156 return 0;
157} 157}
@@ -162,32 +162,30 @@ static struct snd_soc_dai_link mioa701_dai[] = {
162 { 162 {
163 .name = "AC97", 163 .name = "AC97",
164 .stream_name = "AC97 HiFi", 164 .stream_name = "AC97 HiFi",
165 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 165 .cpu_dai_name = "pxa2xx-ac97",
166 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI], 166 .codec_dai_name = "wm9713-hifi",
167 .codec_name = "wm9713-codec",
167 .init = mioa701_wm9713_init, 168 .init = mioa701_wm9713_init,
169 .platform_name = "pxa-pcm-audio",
168 .ops = &mioa701_ops, 170 .ops = &mioa701_ops,
169 }, 171 },
170 { 172 {
171 .name = "AC97 Aux", 173 .name = "AC97 Aux",
172 .stream_name = "AC97 Aux", 174 .stream_name = "AC97 Aux",
173 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 175 .cpu_dai_name = "pxa2xx-ac97-aux",
174 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX], 176 .codec_dai_name ="wm9713-aux",
177 .codec_name = "wm9713-codec",
178 .platform_name = "pxa-pcm-audio",
175 .ops = &mioa701_ops, 179 .ops = &mioa701_ops,
176 }, 180 },
177}; 181};
178 182
179static struct snd_soc_card mioa701 = { 183static struct snd_soc_card mioa701 = {
180 .name = "MioA701", 184 .name = "MioA701",
181 .platform = &pxa2xx_soc_platform,
182 .dai_link = mioa701_dai, 185 .dai_link = mioa701_dai,
183 .num_links = ARRAY_SIZE(mioa701_dai), 186 .num_links = ARRAY_SIZE(mioa701_dai),
184}; 187};
185 188
186static struct snd_soc_device mioa701_snd_devdata = {
187 .card = &mioa701,
188 .codec_dev = &soc_codec_dev_wm9713,
189};
190
191static struct platform_device *mioa701_snd_device; 189static struct platform_device *mioa701_snd_device;
192 190
193static int mioa701_wm9713_probe(struct platform_device *pdev) 191static int mioa701_wm9713_probe(struct platform_device *pdev)
@@ -205,8 +203,7 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
205 if (!mioa701_snd_device) 203 if (!mioa701_snd_device)
206 return -ENOMEM; 204 return -ENOMEM;
207 205
208 platform_set_drvdata(mioa701_snd_device, &mioa701_snd_devdata); 206 platform_set_drvdata(mioa701_snd_device, &mioa701);
209 mioa701_snd_devdata.dev = &mioa701_snd_device->dev;
210 207
211 ret = platform_device_add(mioa701_snd_device); 208 ret = platform_device_add(mioa701_snd_device);
212 if (!ret) 209 if (!ret)
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 1f96e3227be5..504e4004f004 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -21,7 +21,6 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/jack.h> 24#include <sound/jack.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
@@ -29,7 +28,6 @@
29#include <mach/palmasoc.h> 28#include <mach/palmasoc.h>
30 29
31#include "../codecs/wm9712.h" 30#include "../codecs/wm9712.h"
32#include "pxa2xx-pcm.h"
33#include "pxa2xx-ac97.h" 31#include "pxa2xx-ac97.h"
34 32
35static struct snd_soc_jack hs_jack; 33static struct snd_soc_jack hs_jack;
@@ -75,44 +73,46 @@ static const struct snd_soc_dapm_route audio_map[] = {
75 73
76static struct snd_soc_card palm27x_asoc; 74static struct snd_soc_card palm27x_asoc;
77 75
78static int palm27x_ac97_init(struct snd_soc_codec *codec) 76static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
79{ 77{
78 struct snd_soc_codec *codec = rtd->codec;
79 struct snd_soc_dapm_context *dapm = &codec->dapm;
80 int err; 80 int err;
81 81
82 /* add palm27x specific widgets */ 82 /* add palm27x specific widgets */
83 err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, 83 err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets,
84 ARRAY_SIZE(palm27x_dapm_widgets)); 84 ARRAY_SIZE(palm27x_dapm_widgets));
85 if (err) 85 if (err)
86 return err; 86 return err;
87 87
88 /* set up palm27x specific audio path audio_map */ 88 /* set up palm27x specific audio path audio_map */
89 err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 89 err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
90 if (err) 90 if (err)
91 return err; 91 return err;
92 92
93 /* connected pins */ 93 /* connected pins */
94 if (machine_is_palmld()) 94 if (machine_is_palmld())
95 snd_soc_dapm_enable_pin(codec, "MIC1"); 95 snd_soc_dapm_enable_pin(dapm, "MIC1");
96 snd_soc_dapm_enable_pin(codec, "HPOUTL"); 96 snd_soc_dapm_enable_pin(dapm, "HPOUTL");
97 snd_soc_dapm_enable_pin(codec, "HPOUTR"); 97 snd_soc_dapm_enable_pin(dapm, "HPOUTR");
98 snd_soc_dapm_enable_pin(codec, "LOUT2"); 98 snd_soc_dapm_enable_pin(dapm, "LOUT2");
99 snd_soc_dapm_enable_pin(codec, "ROUT2"); 99 snd_soc_dapm_enable_pin(dapm, "ROUT2");
100 100
101 /* not connected pins */ 101 /* not connected pins */
102 snd_soc_dapm_nc_pin(codec, "OUT3"); 102 snd_soc_dapm_nc_pin(dapm, "OUT3");
103 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 103 snd_soc_dapm_nc_pin(dapm, "MONOOUT");
104 snd_soc_dapm_nc_pin(codec, "LINEINL"); 104 snd_soc_dapm_nc_pin(dapm, "LINEINL");
105 snd_soc_dapm_nc_pin(codec, "LINEINR"); 105 snd_soc_dapm_nc_pin(dapm, "LINEINR");
106 snd_soc_dapm_nc_pin(codec, "PCBEEP"); 106 snd_soc_dapm_nc_pin(dapm, "PCBEEP");
107 snd_soc_dapm_nc_pin(codec, "PHONE"); 107 snd_soc_dapm_nc_pin(dapm, "PHONE");
108 snd_soc_dapm_nc_pin(codec, "MIC2"); 108 snd_soc_dapm_nc_pin(dapm, "MIC2");
109 109
110 err = snd_soc_dapm_sync(codec); 110 err = snd_soc_dapm_sync(dapm);
111 if (err) 111 if (err)
112 return err; 112 return err;
113 113
114 /* Jack detection API stuff */ 114 /* Jack detection API stuff */
115 err = snd_soc_jack_new(&palm27x_asoc, "Headphone Jack", 115 err = snd_soc_jack_new(codec, "Headphone Jack",
116 SND_JACK_HEADPHONE, &hs_jack); 116 SND_JACK_HEADPHONE, &hs_jack);
117 if (err) 117 if (err)
118 return err; 118 return err;
@@ -132,30 +132,28 @@ static struct snd_soc_dai_link palm27x_dai[] = {
132{ 132{
133 .name = "AC97 HiFi", 133 .name = "AC97 HiFi",
134 .stream_name = "AC97 HiFi", 134 .stream_name = "AC97 HiFi",
135 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 135 .cpu_dai_name = "pxa2xx-ac97",
136 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 136 .codec_dai_name = "wm9712-hifi",
137 .codec_name = "wm9712-codec",
138 .platform_name = "pxa-pcm-audio",
137 .init = palm27x_ac97_init, 139 .init = palm27x_ac97_init,
138}, 140},
139{ 141{
140 .name = "AC97 Aux", 142 .name = "AC97 Aux",
141 .stream_name = "AC97 Aux", 143 .stream_name = "AC97 Aux",
142 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 144 .cpu_dai_name = "pxa2xx-ac97-aux",
143 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 145 .codec_dai_name = "wm9712-aux",
146 .codec_name = "wm9712-codec",
147 .platform_name = "pxa-pcm-audio",
144}, 148},
145}; 149};
146 150
147static struct snd_soc_card palm27x_asoc = { 151static struct snd_soc_card palm27x_asoc = {
148 .name = "Palm/PXA27x", 152 .name = "Palm/PXA27x",
149 .platform = &pxa2xx_soc_platform,
150 .dai_link = palm27x_dai, 153 .dai_link = palm27x_dai,
151 .num_links = ARRAY_SIZE(palm27x_dai), 154 .num_links = ARRAY_SIZE(palm27x_dai),
152}; 155};
153 156
154static struct snd_soc_device palm27x_snd_devdata = {
155 .card = &palm27x_asoc,
156 .codec_dev = &soc_codec_dev_wm9712,
157};
158
159static struct platform_device *palm27x_snd_device; 157static struct platform_device *palm27x_snd_device;
160 158
161static int palm27x_asoc_probe(struct platform_device *pdev) 159static int palm27x_asoc_probe(struct platform_device *pdev)
@@ -178,8 +176,7 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
178 if (!palm27x_snd_device) 176 if (!palm27x_snd_device)
179 return -ENOMEM; 177 return -ENOMEM;
180 178
181 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata); 179 platform_set_drvdata(palm27x_snd_device, &palm27x_asoc);
182 palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
183 ret = platform_device_add(palm27x_snd_device); 180 ret = platform_device_add(palm27x_snd_device);
184 181
185 if (ret != 0) 182 if (ret != 0)
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index c5f36e0eab58..da3ae4316cf2 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -23,7 +23,6 @@
23#include <sound/core.h> 23#include <sound/core.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <asm/hardware/locomo.h> 28#include <asm/hardware/locomo.h>
@@ -31,7 +30,6 @@
31#include <mach/audio.h> 30#include <mach/audio.h>
32 31
33#include "../codecs/wm8731.h" 32#include "../codecs/wm8731.h"
34#include "pxa2xx-pcm.h"
35#include "pxa2xx-i2s.h" 33#include "pxa2xx-i2s.h"
36 34
37#define POODLE_HP 1 35#define POODLE_HP 1
@@ -47,6 +45,8 @@ static int poodle_spk_func;
47 45
48static void poodle_ext_control(struct snd_soc_codec *codec) 46static void poodle_ext_control(struct snd_soc_codec *codec)
49{ 47{
48 struct snd_soc_dapm_context *dapm = &codec->dapm;
49
50 /* set up jack connection */ 50 /* set up jack connection */
51 if (poodle_jack_func == POODLE_HP) { 51 if (poodle_jack_func == POODLE_HP) {
52 /* set = unmute headphone */ 52 /* set = unmute headphone */
@@ -54,32 +54,37 @@ static void poodle_ext_control(struct snd_soc_codec *codec)
54 POODLE_LOCOMO_GPIO_MUTE_L, 1); 54 POODLE_LOCOMO_GPIO_MUTE_L, 1);
55 locomo_gpio_write(&poodle_locomo_device.dev, 55 locomo_gpio_write(&poodle_locomo_device.dev,
56 POODLE_LOCOMO_GPIO_MUTE_R, 1); 56 POODLE_LOCOMO_GPIO_MUTE_R, 1);
57 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 57 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
58 } else { 58 } else {
59 locomo_gpio_write(&poodle_locomo_device.dev, 59 locomo_gpio_write(&poodle_locomo_device.dev,
60 POODLE_LOCOMO_GPIO_MUTE_L, 0); 60 POODLE_LOCOMO_GPIO_MUTE_L, 0);
61 locomo_gpio_write(&poodle_locomo_device.dev, 61 locomo_gpio_write(&poodle_locomo_device.dev,
62 POODLE_LOCOMO_GPIO_MUTE_R, 0); 62 POODLE_LOCOMO_GPIO_MUTE_R, 0);
63 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 63 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
64 } 64 }
65 65
66 /* set the enpoints to their new connetion states */ 66 /* set the enpoints to their new connetion states */
67 if (poodle_spk_func == POODLE_SPK_ON) 67 if (poodle_spk_func == POODLE_SPK_ON)
68 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 68 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
69 else 69 else
70 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 70 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
71 71
72 /* signal a DAPM event */ 72 /* signal a DAPM event */
73 snd_soc_dapm_sync(codec); 73 snd_soc_dapm_sync(dapm);
74} 74}
75 75
76static int poodle_startup(struct snd_pcm_substream *substream) 76static int poodle_startup(struct snd_pcm_substream *substream)
77{ 77{
78 struct snd_soc_pcm_runtime *rtd = substream->private_data; 78 struct snd_soc_pcm_runtime *rtd = substream->private_data;
79 struct snd_soc_codec *codec = rtd->socdev->card->codec; 79 struct snd_soc_codec *codec = rtd->codec;
80
81 mutex_lock(&codec->mutex);
80 82
81 /* check the jack status at stream startup */ 83 /* check the jack status at stream startup */
82 poodle_ext_control(codec); 84 poodle_ext_control(codec);
85
86 mutex_unlock(&codec->mutex);
87
83 return 0; 88 return 0;
84} 89}
85 90
@@ -97,8 +102,8 @@ static int poodle_hw_params(struct snd_pcm_substream *substream,
97 struct snd_pcm_hw_params *params) 102 struct snd_pcm_hw_params *params)
98{ 103{
99 struct snd_soc_pcm_runtime *rtd = substream->private_data; 104 struct snd_soc_pcm_runtime *rtd = substream->private_data;
100 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 105 struct snd_soc_dai *codec_dai = rtd->codec_dai;
101 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 106 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
102 unsigned int clk = 0; 107 unsigned int clk = 0;
103 int ret = 0; 108 int ret = 0;
104 109
@@ -129,7 +134,7 @@ static int poodle_hw_params(struct snd_pcm_substream *substream,
129 return ret; 134 return ret;
130 135
131 /* set the codec system clock for DAC and ADC */ 136 /* set the codec system clock for DAC and ADC */
132 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, clk, 137 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk,
133 SND_SOC_CLOCK_IN); 138 SND_SOC_CLOCK_IN);
134 if (ret < 0) 139 if (ret < 0)
135 return ret; 140 return ret;
@@ -237,13 +242,15 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
237/* 242/*
238 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device 243 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
239 */ 244 */
240static int poodle_wm8731_init(struct snd_soc_codec *codec) 245static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
241{ 246{
247 struct snd_soc_codec *codec = rtd->codec;
248 struct snd_soc_dapm_context *dapm = &codec->dapm;
242 int err; 249 int err;
243 250
244 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 251 snd_soc_dapm_nc_pin(dapm, "LLINEIN");
245 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 252 snd_soc_dapm_nc_pin(dapm, "RLINEIN");
246 snd_soc_dapm_enable_pin(codec, "MICIN"); 253 snd_soc_dapm_enable_pin(dapm, "MICIN");
247 254
248 /* Add poodle specific controls */ 255 /* Add poodle specific controls */
249 err = snd_soc_add_controls(codec, wm8731_poodle_controls, 256 err = snd_soc_add_controls(codec, wm8731_poodle_controls,
@@ -252,13 +259,13 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
252 return err; 259 return err;
253 260
254 /* Add poodle specific widgets */ 261 /* Add poodle specific widgets */
255 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, 262 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
256 ARRAY_SIZE(wm8731_dapm_widgets)); 263 ARRAY_SIZE(wm8731_dapm_widgets));
257 264
258 /* Set up poodle specific audio path audio_map */ 265 /* Set up poodle specific audio path audio_map */
259 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
260 267
261 snd_soc_dapm_sync(codec); 268 snd_soc_dapm_sync(dapm);
262 return 0; 269 return 0;
263} 270}
264 271
@@ -266,8 +273,10 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
266static struct snd_soc_dai_link poodle_dai = { 273static struct snd_soc_dai_link poodle_dai = {
267 .name = "WM8731", 274 .name = "WM8731",
268 .stream_name = "WM8731", 275 .stream_name = "WM8731",
269 .cpu_dai = &pxa_i2s_dai, 276 .cpu_dai_name = "pxa2xx-i2s",
270 .codec_dai = &wm8731_dai, 277 .codec_dai_name = "wm8731-hifi",
278 .platform_name = "pxa-pcm-audio",
279 .codec_name = "wm8731.0-001b",
271 .init = poodle_wm8731_init, 280 .init = poodle_wm8731_init,
272 .ops = &poodle_ops, 281 .ops = &poodle_ops,
273}; 282};
@@ -275,15 +284,9 @@ static struct snd_soc_dai_link poodle_dai = {
275/* poodle audio machine driver */ 284/* poodle audio machine driver */
276static struct snd_soc_card snd_soc_poodle = { 285static struct snd_soc_card snd_soc_poodle = {
277 .name = "Poodle", 286 .name = "Poodle",
278 .platform = &pxa2xx_soc_platform,
279 .dai_link = &poodle_dai, 287 .dai_link = &poodle_dai,
280 .num_links = 1, 288 .num_links = 1,
281}; 289 .owner = THIS_MODULE,
282
283/* poodle audio subsystem */
284static struct snd_soc_device poodle_snd_devdata = {
285 .card = &snd_soc_poodle,
286 .codec_dev = &soc_codec_dev_wm8731,
287}; 290};
288 291
289static struct platform_device *poodle_snd_device; 292static struct platform_device *poodle_snd_device;
@@ -307,8 +310,7 @@ static int __init poodle_init(void)
307 if (!poodle_snd_device) 310 if (!poodle_snd_device)
308 return -ENOMEM; 311 return -ENOMEM;
309 312
310 platform_set_drvdata(poodle_snd_device, &poodle_snd_devdata); 313 platform_set_drvdata(poodle_snd_device, &snd_soc_poodle);
311 poodle_snd_devdata.dev = &poodle_snd_device->dev;
312 ret = platform_device_add(poodle_snd_device); 314 ret = platform_device_add(poodle_snd_device);
313 315
314 if (ret) 316 if (ret)
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index a1fd23e0e3d0..8ad93ee2e92b 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/pxa2xx_ssp.h>
23 24
24#include <asm/irq.h> 25#include <asm/irq.h>
25 26
@@ -33,9 +34,8 @@
33#include <mach/hardware.h> 34#include <mach/hardware.h>
34#include <mach/dma.h> 35#include <mach/dma.h>
35#include <mach/audio.h> 36#include <mach/audio.h>
36#include <plat/ssp.h>
37 37
38#include "pxa2xx-pcm.h" 38#include "../../arm/pxa2xx-pcm.h"
39#include "pxa-ssp.h" 39#include "pxa-ssp.h"
40 40
41/* 41/*
@@ -108,11 +108,9 @@ pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
108} 108}
109 109
110static int pxa_ssp_startup(struct snd_pcm_substream *substream, 110static int pxa_ssp_startup(struct snd_pcm_substream *substream,
111 struct snd_soc_dai *dai) 111 struct snd_soc_dai *cpu_dai)
112{ 112{
113 struct snd_soc_pcm_runtime *rtd = substream->private_data; 113 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
114 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
115 struct ssp_priv *priv = cpu_dai->private_data;
116 struct ssp_device *ssp = priv->ssp; 114 struct ssp_device *ssp = priv->ssp;
117 int ret = 0; 115 int ret = 0;
118 116
@@ -128,11 +126,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
128} 126}
129 127
130static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, 128static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
131 struct snd_soc_dai *dai) 129 struct snd_soc_dai *cpu_dai)
132{ 130{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
134 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
135 struct ssp_priv *priv = cpu_dai->private_data;
136 struct ssp_device *ssp = priv->ssp; 132 struct ssp_device *ssp = priv->ssp;
137 133
138 if (!cpu_dai->active) { 134 if (!cpu_dai->active) {
@@ -148,7 +144,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
148 144
149static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) 145static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
150{ 146{
151 struct ssp_priv *priv = cpu_dai->private_data; 147 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
152 struct ssp_device *ssp = priv->ssp; 148 struct ssp_device *ssp = priv->ssp;
153 149
154 if (!cpu_dai->active) 150 if (!cpu_dai->active)
@@ -166,7 +162,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
166 162
167static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) 163static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
168{ 164{
169 struct ssp_priv *priv = cpu_dai->private_data; 165 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
170 struct ssp_device *ssp = priv->ssp; 166 struct ssp_device *ssp = priv->ssp;
171 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; 167 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
172 168
@@ -230,7 +226,7 @@ static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
230static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 226static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
231 int clk_id, unsigned int freq, int dir) 227 int clk_id, unsigned int freq, int dir)
232{ 228{
233 struct ssp_priv *priv = cpu_dai->private_data; 229 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
234 struct ssp_device *ssp = priv->ssp; 230 struct ssp_device *ssp = priv->ssp;
235 int val; 231 int val;
236 232
@@ -287,7 +283,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
287static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, 283static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
288 int div_id, int div) 284 int div_id, int div)
289{ 285{
290 struct ssp_priv *priv = cpu_dai->private_data; 286 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
291 struct ssp_device *ssp = priv->ssp; 287 struct ssp_device *ssp = priv->ssp;
292 int val; 288 int val;
293 289
@@ -338,7 +334,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
338static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, 334static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
339 int source, unsigned int freq_in, unsigned int freq_out) 335 int source, unsigned int freq_in, unsigned int freq_out)
340{ 336{
341 struct ssp_priv *priv = cpu_dai->private_data; 337 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
342 struct ssp_device *ssp = priv->ssp; 338 struct ssp_device *ssp = priv->ssp;
343 u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70; 339 u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
344 340
@@ -407,7 +403,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
407static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, 403static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
408 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 404 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
409{ 405{
410 struct ssp_priv *priv = cpu_dai->private_data; 406 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
411 struct ssp_device *ssp = priv->ssp; 407 struct ssp_device *ssp = priv->ssp;
412 u32 sscr0; 408 u32 sscr0;
413 409
@@ -442,7 +438,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
442static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai, 438static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
443 int tristate) 439 int tristate)
444{ 440{
445 struct ssp_priv *priv = cpu_dai->private_data; 441 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
446 struct ssp_device *ssp = priv->ssp; 442 struct ssp_device *ssp = priv->ssp;
447 u32 sscr1; 443 u32 sscr1;
448 444
@@ -464,11 +460,9 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
464static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, 460static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
465 unsigned int fmt) 461 unsigned int fmt)
466{ 462{
467 struct ssp_priv *priv = cpu_dai->private_data; 463 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
468 struct ssp_device *ssp = priv->ssp; 464 struct ssp_device *ssp = priv->ssp;
469 u32 sscr0; 465 u32 sscr0, sscr1, sspsp, scfr;
470 u32 sscr1;
471 u32 sspsp;
472 466
473 /* check if we need to change anything at all */ 467 /* check if we need to change anything at all */
474 if (priv->dai_fmt == fmt) 468 if (priv->dai_fmt == fmt)
@@ -483,16 +477,16 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
483 477
484 /* reset port settings */ 478 /* reset port settings */
485 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & 479 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
486 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 480 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
487 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); 481 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
488 sspsp = 0; 482 sspsp = 0;
489 483
490 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 484 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
491 case SND_SOC_DAIFMT_CBM_CFM: 485 case SND_SOC_DAIFMT_CBM_CFM:
492 sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR; 486 sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR | SSCR1_SCFR;
493 break; 487 break;
494 case SND_SOC_DAIFMT_CBM_CFS: 488 case SND_SOC_DAIFMT_CBM_CFS:
495 sscr1 |= SSCR1_SCLKDIR; 489 sscr1 |= SSCR1_SCLKDIR | SSCR1_SCFR;
496 break; 490 break;
497 case SND_SOC_DAIFMT_CBS_CFS: 491 case SND_SOC_DAIFMT_CBS_CFS:
498 break; 492 break;
@@ -538,6 +532,17 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
538 pxa_ssp_write_reg(ssp, SSCR1, sscr1); 532 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
539 pxa_ssp_write_reg(ssp, SSPSP, sspsp); 533 pxa_ssp_write_reg(ssp, SSPSP, sspsp);
540 534
535 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
536 case SND_SOC_DAIFMT_CBM_CFM:
537 case SND_SOC_DAIFMT_CBM_CFS:
538 scfr = pxa_ssp_read_reg(ssp, SSCR1) | SSCR1_SCFR;
539 pxa_ssp_write_reg(ssp, SSCR1, scfr);
540
541 while (pxa_ssp_read_reg(ssp, SSSR) & SSSR_BSY)
542 cpu_relax();
543 break;
544 }
545
541 dump_registers(ssp); 546 dump_registers(ssp);
542 547
543 /* Since we are configuring the timings for the format by hand 548 /* Since we are configuring the timings for the format by hand
@@ -555,11 +560,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
555 */ 560 */
556static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, 561static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
557 struct snd_pcm_hw_params *params, 562 struct snd_pcm_hw_params *params,
558 struct snd_soc_dai *dai) 563 struct snd_soc_dai *cpu_dai)
559{ 564{
560 struct snd_soc_pcm_runtime *rtd = substream->private_data; 565 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
561 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
562 struct ssp_priv *priv = cpu_dai->private_data;
563 struct ssp_device *ssp = priv->ssp; 566 struct ssp_device *ssp = priv->ssp;
564 int chn = params_channels(params); 567 int chn = params_channels(params);
565 u32 sscr0; 568 u32 sscr0;
@@ -568,7 +571,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
568 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf; 571 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
569 struct pxa2xx_pcm_dma_params *dma_data; 572 struct pxa2xx_pcm_dma_params *dma_data;
570 573
571 dma_data = snd_soc_dai_get_dma_data(dai, substream); 574 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
572 575
573 /* generate correct DMA params */ 576 /* generate correct DMA params */
574 kfree(dma_data); 577 kfree(dma_data);
@@ -581,7 +584,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
581 ((chn == 2) && (ttsa != 1)) || (width == 32), 584 ((chn == 2) && (ttsa != 1)) || (width == 32),
582 substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 585 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
583 586
584 snd_soc_dai_set_dma_data(dai, substream, dma_data); 587 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
585 588
586 /* we can only change the settings if the port is not in use */ 589 /* we can only change the settings if the port is not in use */
587 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 590 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
@@ -589,10 +592,8 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
589 592
590 /* clear selected SSP bits */ 593 /* clear selected SSP bits */
591 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); 594 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
592 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
593 595
594 /* bit size */ 596 /* bit size */
595 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
596 switch (params_format(params)) { 597 switch (params_format(params)) {
597 case SNDRV_PCM_FORMAT_S16_LE: 598 case SNDRV_PCM_FORMAT_S16_LE:
598#ifdef CONFIG_PXA3xx 599#ifdef CONFIG_PXA3xx
@@ -668,12 +669,10 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
668} 669}
669 670
670static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, 671static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
671 struct snd_soc_dai *dai) 672 struct snd_soc_dai *cpu_dai)
672{ 673{
673 struct snd_soc_pcm_runtime *rtd = substream->private_data;
674 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
675 int ret = 0; 674 int ret = 0;
676 struct ssp_priv *priv = cpu_dai->private_data; 675 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
677 struct ssp_device *ssp = priv->ssp; 676 struct ssp_device *ssp = priv->ssp;
678 int val; 677 int val;
679 678
@@ -729,8 +728,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
729 return ret; 728 return ret;
730} 729}
731 730
732static int pxa_ssp_probe(struct platform_device *pdev, 731static int pxa_ssp_probe(struct snd_soc_dai *dai)
733 struct snd_soc_dai *dai)
734{ 732{
735 struct ssp_priv *priv; 733 struct ssp_priv *priv;
736 int ret; 734 int ret;
@@ -746,7 +744,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
746 } 744 }
747 745
748 priv->dai_fmt = (unsigned int) -1; 746 priv->dai_fmt = (unsigned int) -1;
749 dai->private_data = priv; 747 snd_soc_dai_set_drvdata(dai, priv);
750 748
751 return 0; 749 return 0;
752 750
@@ -755,11 +753,13 @@ err_priv:
755 return ret; 753 return ret;
756} 754}
757 755
758static void pxa_ssp_remove(struct platform_device *pdev, 756static int pxa_ssp_remove(struct snd_soc_dai *dai)
759 struct snd_soc_dai *dai)
760{ 757{
761 struct ssp_priv *priv = dai->private_data; 758 struct ssp_priv *priv = snd_soc_dai_get_drvdata(dai);
759
762 pxa_ssp_free(priv->ssp); 760 pxa_ssp_free(priv->ssp);
761 kfree(priv);
762 return 0;
763} 763}
764 764
765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -784,10 +784,7 @@ static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
784 .set_tristate = pxa_ssp_set_dai_tristate, 784 .set_tristate = pxa_ssp_set_dai_tristate,
785}; 785};
786 786
787struct snd_soc_dai pxa_ssp_dai[] = { 787static struct snd_soc_dai_driver pxa_ssp_dai = {
788 {
789 .name = "pxa2xx-ssp1",
790 .id = 0,
791 .probe = pxa_ssp_probe, 788 .probe = pxa_ssp_probe,
792 .remove = pxa_ssp_remove, 789 .remove = pxa_ssp_remove,
793 .suspend = pxa_ssp_suspend, 790 .suspend = pxa_ssp_suspend,
@@ -805,81 +802,38 @@ struct snd_soc_dai pxa_ssp_dai[] = {
805 .formats = PXA_SSP_FORMATS, 802 .formats = PXA_SSP_FORMATS,
806 }, 803 },
807 .ops = &pxa_ssp_dai_ops, 804 .ops = &pxa_ssp_dai_ops,
805};
806
807static __devinit int asoc_ssp_probe(struct platform_device *pdev)
808{
809 return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai);
810}
811
812static int __devexit asoc_ssp_remove(struct platform_device *pdev)
813{
814 snd_soc_unregister_dai(&pdev->dev);
815 return 0;
816}
817
818static struct platform_driver asoc_ssp_driver = {
819 .driver = {
820 .name = "pxa-ssp-dai",
821 .owner = THIS_MODULE,
808 }, 822 },
809 { .name = "pxa2xx-ssp2", 823
810 .id = 1, 824 .probe = asoc_ssp_probe,
811 .probe = pxa_ssp_probe, 825 .remove = __devexit_p(asoc_ssp_remove),
812 .remove = pxa_ssp_remove,
813 .suspend = pxa_ssp_suspend,
814 .resume = pxa_ssp_resume,
815 .playback = {
816 .channels_min = 1,
817 .channels_max = 8,
818 .rates = PXA_SSP_RATES,
819 .formats = PXA_SSP_FORMATS,
820 },
821 .capture = {
822 .channels_min = 1,
823 .channels_max = 8,
824 .rates = PXA_SSP_RATES,
825 .formats = PXA_SSP_FORMATS,
826 },
827 .ops = &pxa_ssp_dai_ops,
828 },
829 {
830 .name = "pxa2xx-ssp3",
831 .id = 2,
832 .probe = pxa_ssp_probe,
833 .remove = pxa_ssp_remove,
834 .suspend = pxa_ssp_suspend,
835 .resume = pxa_ssp_resume,
836 .playback = {
837 .channels_min = 1,
838 .channels_max = 8,
839 .rates = PXA_SSP_RATES,
840 .formats = PXA_SSP_FORMATS,
841 },
842 .capture = {
843 .channels_min = 1,
844 .channels_max = 8,
845 .rates = PXA_SSP_RATES,
846 .formats = PXA_SSP_FORMATS,
847 },
848 .ops = &pxa_ssp_dai_ops,
849 },
850 {
851 .name = "pxa2xx-ssp4",
852 .id = 3,
853 .probe = pxa_ssp_probe,
854 .remove = pxa_ssp_remove,
855 .suspend = pxa_ssp_suspend,
856 .resume = pxa_ssp_resume,
857 .playback = {
858 .channels_min = 1,
859 .channels_max = 8,
860 .rates = PXA_SSP_RATES,
861 .formats = PXA_SSP_FORMATS,
862 },
863 .capture = {
864 .channels_min = 1,
865 .channels_max = 8,
866 .rates = PXA_SSP_RATES,
867 .formats = PXA_SSP_FORMATS,
868 },
869 .ops = &pxa_ssp_dai_ops,
870 },
871}; 826};
872EXPORT_SYMBOL_GPL(pxa_ssp_dai);
873 827
874static int __init pxa_ssp_init(void) 828static int __init pxa_ssp_init(void)
875{ 829{
876 return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai)); 830 return platform_driver_register(&asoc_ssp_driver);
877} 831}
878module_init(pxa_ssp_init); 832module_init(pxa_ssp_init);
879 833
880static void __exit pxa_ssp_exit(void) 834static void __exit pxa_ssp_exit(void)
881{ 835{
882 snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai)); 836 platform_driver_unregister(&asoc_ssp_driver);
883} 837}
884module_exit(pxa_ssp_exit); 838module_exit(pxa_ssp_exit);
885 839
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
index 91deadd55675..bc79da221c0d 100644
--- a/sound/soc/pxa/pxa-ssp.h
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -42,6 +42,4 @@
42 42
43#define PXA_SSP_PLL_OUT 0 43#define PXA_SSP_PLL_OUT 0
44 44
45extern struct snd_soc_dai pxa_ssp_dai[4];
46
47#endif 45#endif
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d314115e3dd7..ac51c6d25c42 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -24,7 +24,6 @@
24#include <mach/dma.h> 24#include <mach/dma.h>
25#include <mach/audio.h> 25#include <mach/audio.h>
26 26
27#include "pxa2xx-pcm.h"
28#include "pxa2xx-ac97.h" 27#include "pxa2xx-ac97.h"
29 28
30static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) 29static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
@@ -104,24 +103,21 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
104#define pxa2xx_ac97_resume NULL 103#define pxa2xx_ac97_resume NULL
105#endif 104#endif
106 105
107static int pxa2xx_ac97_probe(struct platform_device *pdev, 106static int pxa2xx_ac97_probe(struct snd_soc_dai *dai)
108 struct snd_soc_dai *dai)
109{ 107{
110 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); 108 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
111} 109}
112 110
113static void pxa2xx_ac97_remove(struct platform_device *pdev, 111static int pxa2xx_ac97_remove(struct snd_soc_dai *dai)
114 struct snd_soc_dai *dai)
115{ 112{
116 pxa2xx_ac97_hw_remove(to_platform_device(dai->dev)); 113 pxa2xx_ac97_hw_remove(to_platform_device(dai->dev));
114 return 0;
117} 115}
118 116
119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 117static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params, 118 struct snd_pcm_hw_params *params,
121 struct snd_soc_dai *dai) 119 struct snd_soc_dai *cpu_dai)
122{ 120{
123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
124 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
125 struct pxa2xx_pcm_dma_params *dma_data; 121 struct pxa2xx_pcm_dma_params *dma_data;
126 122
127 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 123 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -136,10 +132,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
136 132
137static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 133static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params, 134 struct snd_pcm_hw_params *params,
139 struct snd_soc_dai *dai) 135 struct snd_soc_dai *cpu_dai)
140{ 136{
141 struct snd_soc_pcm_runtime *rtd = substream->private_data;
142 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
143 struct pxa2xx_pcm_dma_params *dma_data; 137 struct pxa2xx_pcm_dma_params *dma_data;
144 138
145 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 139 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -154,11 +148,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
154 148
155static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 149static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
156 struct snd_pcm_hw_params *params, 150 struct snd_pcm_hw_params *params,
157 struct snd_soc_dai *dai) 151 struct snd_soc_dai *cpu_dai)
158{ 152{
159 struct snd_soc_pcm_runtime *rtd = substream->private_data;
160 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
161
162 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 153 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
163 return -ENODEV; 154 return -ENODEV;
164 else 155 else
@@ -188,10 +179,9 @@ static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
188 * There is only 1 physical AC97 interface for pxa2xx, but it 179 * There is only 1 physical AC97 interface for pxa2xx, but it
189 * has extra fifo's that can be used for aux DACs and ADCs. 180 * has extra fifo's that can be used for aux DACs and ADCs.
190 */ 181 */
191struct snd_soc_dai pxa_ac97_dai[] = { 182static struct snd_soc_dai_driver pxa_ac97_dai[] = {
192{ 183{
193 .name = "pxa2xx-ac97", 184 .name = "pxa2xx-ac97",
194 .id = 0,
195 .ac97_control = 1, 185 .ac97_control = 1,
196 .probe = pxa2xx_ac97_probe, 186 .probe = pxa2xx_ac97_probe,
197 .remove = pxa2xx_ac97_remove, 187 .remove = pxa2xx_ac97_remove,
@@ -213,7 +203,6 @@ struct snd_soc_dai pxa_ac97_dai[] = {
213}, 203},
214{ 204{
215 .name = "pxa2xx-ac97-aux", 205 .name = "pxa2xx-ac97-aux",
216 .id = 1,
217 .ac97_control = 1, 206 .ac97_control = 1,
218 .playback = { 207 .playback = {
219 .stream_name = "AC97 Aux Playback", 208 .stream_name = "AC97 Aux Playback",
@@ -231,7 +220,6 @@ struct snd_soc_dai pxa_ac97_dai[] = {
231}, 220},
232{ 221{
233 .name = "pxa2xx-ac97-mic", 222 .name = "pxa2xx-ac97-mic",
234 .id = 2,
235 .ac97_control = 1, 223 .ac97_control = 1,
236 .capture = { 224 .capture = {
237 .stream_name = "AC97 Mic Capture", 225 .stream_name = "AC97 Mic Capture",
@@ -243,36 +231,26 @@ struct snd_soc_dai pxa_ac97_dai[] = {
243}, 231},
244}; 232};
245 233
246EXPORT_SYMBOL_GPL(pxa_ac97_dai);
247EXPORT_SYMBOL_GPL(soc_ac97_ops); 234EXPORT_SYMBOL_GPL(soc_ac97_ops);
248 235
249static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev) 236static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
250{ 237{
251 int i; 238 if (pdev->id != -1) {
252 pxa2xx_audio_ops_t *pdata = pdev->dev.platform_data;
253
254 if (pdev->id >= 0) {
255 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n"); 239 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
256 return -ENXIO; 240 return -ENXIO;
257 } 241 }
258 242
259 for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) {
260 pxa_ac97_dai[i].dev = &pdev->dev;
261 if (pdata && pdata->codec_pdata[0])
262 pxa_ac97_dai[i].ac97_pdata = pdata->codec_pdata[0];
263 }
264
265 /* Punt most of the init to the SoC probe; we may need the machine 243 /* Punt most of the init to the SoC probe; we may need the machine
266 * driver to do interesting things with the clocking to get us up 244 * driver to do interesting things with the clocking to get us up
267 * and running. 245 * and running.
268 */ 246 */
269 return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); 247 return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai,
248 ARRAY_SIZE(pxa_ac97_dai));
270} 249}
271 250
272static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) 251static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
273{ 252{
274 snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); 253 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai));
275
276 return 0; 254 return 0;
277} 255}
278 256
diff --git a/sound/soc/pxa/pxa2xx-ac97.h b/sound/soc/pxa/pxa2xx-ac97.h
index e390de8edcd4..eda891e6f31b 100644
--- a/sound/soc/pxa/pxa2xx-ac97.h
+++ b/sound/soc/pxa/pxa2xx-ac97.h
@@ -14,8 +14,6 @@
14#define PXA2XX_DAI_AC97_AUX 1 14#define PXA2XX_DAI_AC97_AUX 1
15#define PXA2XX_DAI_AC97_MIC 2 15#define PXA2XX_DAI_AC97_MIC 2
16 16
17extern struct snd_soc_dai pxa_ac97_dai[3];
18
19/* platform data */ 17/* platform data */
20extern struct snd_ac97_bus_ops pxa2xx_ac97_ops; 18extern struct snd_ac97_bus_ops pxa2xx_ac97_ops;
21 19
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index c1a5275721e4..11be5952a506 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -27,7 +27,6 @@
27#include <mach/dma.h> 27#include <mach/dma.h>
28#include <mach/audio.h> 28#include <mach/audio.h>
29 29
30#include "pxa2xx-pcm.h"
31#include "pxa2xx-i2s.h" 30#include "pxa2xx-i2s.h"
32 31
33/* 32/*
@@ -80,6 +79,7 @@ struct pxa_i2s_port {
80}; 79};
81static struct pxa_i2s_port pxa_i2s; 80static struct pxa_i2s_port pxa_i2s;
82static struct clk *clk_i2s; 81static struct clk *clk_i2s;
82static int clk_ena = 0;
83 83
84static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { 84static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
85 .name = "I2S PCM Stereo out", 85 .name = "I2S PCM Stereo out",
@@ -101,7 +101,7 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
101 struct snd_soc_dai *dai) 101 struct snd_soc_dai *dai)
102{ 102{
103 struct snd_soc_pcm_runtime *rtd = substream->private_data; 103 struct snd_soc_pcm_runtime *rtd = substream->private_data;
104 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 104 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
105 105
106 if (IS_ERR(clk_i2s)) 106 if (IS_ERR(clk_i2s))
107 return PTR_ERR(clk_i2s); 107 return PTR_ERR(clk_i2s);
@@ -162,13 +162,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params, 162 struct snd_pcm_hw_params *params,
163 struct snd_soc_dai *dai) 163 struct snd_soc_dai *dai)
164{ 164{
165 struct snd_soc_pcm_runtime *rtd = substream->private_data;
166 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
167 struct pxa2xx_pcm_dma_params *dma_data; 165 struct pxa2xx_pcm_dma_params *dma_data;
168 166
169 BUG_ON(IS_ERR(clk_i2s)); 167 BUG_ON(IS_ERR(clk_i2s));
170 clk_enable(clk_i2s); 168 clk_enable(clk_i2s);
171 dai->private_data = dai; 169 clk_ena = 1;
172 pxa_i2s_wait(); 170 pxa_i2s_wait();
173 171
174 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 172 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -176,7 +174,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
176 else 174 else
177 dma_data = &pxa2xx_i2s_pcm_stereo_in; 175 dma_data = &pxa2xx_i2s_pcm_stereo_in;
178 176
179 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); 177 snd_soc_dai_set_dma_data(dai, substream, dma_data);
180 178
181 /* is port used by another stream */ 179 /* is port used by another stream */
182 if (!(SACR0 & SACR0_ENB)) { 180 if (!(SACR0 & SACR0_ENB)) {
@@ -259,9 +257,9 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
259 if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) { 257 if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
260 SACR0 &= ~SACR0_ENB; 258 SACR0 &= ~SACR0_ENB;
261 pxa_i2s_wait(); 259 pxa_i2s_wait();
262 if (dai->private_data != NULL) { 260 if (clk_ena) {
263 clk_disable(clk_i2s); 261 clk_disable(clk_i2s);
264 dai->private_data = NULL; 262 clk_ena = 0;
265 } 263 }
266 } 264 }
267} 265}
@@ -300,6 +298,35 @@ static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
300#define pxa2xx_i2s_resume NULL 298#define pxa2xx_i2s_resume NULL
301#endif 299#endif
302 300
301static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
302{
303 clk_i2s = clk_get(dai->dev, "I2SCLK");
304 if (IS_ERR(clk_i2s))
305 return PTR_ERR(clk_i2s);
306
307 /*
308 * PXA Developer's Manual:
309 * If SACR0[ENB] is toggled in the middle of a normal operation,
310 * the SACR0[RST] bit must also be set and cleared to reset all
311 * I2S controller registers.
312 */
313 SACR0 = SACR0_RST;
314 SACR0 = 0;
315 /* Make sure RPL and REC are disabled */
316 SACR1 = SACR1_DRPL | SACR1_DREC;
317 /* Along with FIFO servicing */
318 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
319
320 return 0;
321}
322
323static int pxa2xx_i2s_remove(struct snd_soc_dai *dai)
324{
325 clk_put(clk_i2s);
326 clk_i2s = ERR_PTR(-ENOENT);
327 return 0;
328}
329
303#define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 330#define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
304 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ 331 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
305 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) 332 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
@@ -313,9 +340,9 @@ static struct snd_soc_dai_ops pxa_i2s_dai_ops = {
313 .set_sysclk = pxa2xx_i2s_set_dai_sysclk, 340 .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
314}; 341};
315 342
316struct snd_soc_dai pxa_i2s_dai = { 343static struct snd_soc_dai_driver pxa_i2s_dai = {
317 .name = "pxa2xx-i2s", 344 .probe = pxa2xx_i2s_probe,
318 .id = 0, 345 .remove = pxa2xx_i2s_remove,
319 .suspend = pxa2xx_i2s_suspend, 346 .suspend = pxa2xx_i2s_suspend,
320 .resume = pxa2xx_i2s_resume, 347 .resume = pxa2xx_i2s_resume,
321 .playback = { 348 .playback = {
@@ -332,49 +359,20 @@ struct snd_soc_dai pxa_i2s_dai = {
332 .symmetric_rates = 1, 359 .symmetric_rates = 1,
333}; 360};
334 361
335EXPORT_SYMBOL_GPL(pxa_i2s_dai); 362static int pxa2xx_i2s_drv_probe(struct platform_device *pdev)
336
337static int pxa2xx_i2s_probe(struct platform_device *dev)
338{ 363{
339 int ret; 364 return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai);
340
341 clk_i2s = clk_get(&dev->dev, "I2SCLK");
342 if (IS_ERR(clk_i2s))
343 return PTR_ERR(clk_i2s);
344
345 pxa_i2s_dai.dev = &dev->dev;
346 pxa_i2s_dai.private_data = NULL;
347 ret = snd_soc_register_dai(&pxa_i2s_dai);
348 if (ret != 0)
349 clk_put(clk_i2s);
350
351 /*
352 * PXA Developer's Manual:
353 * If SACR0[ENB] is toggled in the middle of a normal operation,
354 * the SACR0[RST] bit must also be set and cleared to reset all
355 * I2S controller registers.
356 */
357 SACR0 = SACR0_RST;
358 SACR0 = 0;
359 /* Make sure RPL and REC are disabled */
360 SACR1 = SACR1_DRPL | SACR1_DREC;
361 /* Along with FIFO servicing */
362 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
363
364 return ret;
365} 365}
366 366
367static int __devexit pxa2xx_i2s_remove(struct platform_device *dev) 367static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev)
368{ 368{
369 snd_soc_unregister_dai(&pxa_i2s_dai); 369 snd_soc_unregister_dai(&pdev->dev);
370 clk_put(clk_i2s);
371 clk_i2s = ERR_PTR(-ENOENT);
372 return 0; 370 return 0;
373} 371}
374 372
375static struct platform_driver pxa2xx_i2s_driver = { 373static struct platform_driver pxa2xx_i2s_driver = {
376 .probe = pxa2xx_i2s_probe, 374 .probe = pxa2xx_i2s_drv_probe,
377 .remove = __devexit_p(pxa2xx_i2s_remove), 375 .remove = __devexit_p(pxa2xx_i2s_drv_remove),
378 376
379 .driver = { 377 .driver = {
380 .name = "pxa2xx-i2s", 378 .name = "pxa2xx-i2s",
@@ -400,3 +398,4 @@ module_exit(pxa2xx_i2s_exit);
400MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 398MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
401MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); 399MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");
402MODULE_LICENSE("GPL"); 400MODULE_LICENSE("GPL");
401MODULE_ALIAS("platform:pxa2xx-i2s");
diff --git a/sound/soc/pxa/pxa2xx-i2s.h b/sound/soc/pxa/pxa2xx-i2s.h
index e2def441153e..070f3c6059fe 100644
--- a/sound/soc/pxa/pxa2xx-i2s.h
+++ b/sound/soc/pxa/pxa2xx-i2s.h
@@ -15,6 +15,4 @@
15/* I2S clock */ 15/* I2S clock */
16#define PXA2XX_I2S_SYSCLK 0 16#define PXA2XX_I2S_SYSCLK 0
17 17
18extern struct snd_soc_dai pxa_i2s_dai;
19
20#endif 18#endif
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index adc7e6f15f93..fab20a54e863 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -16,7 +16,6 @@
16#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/pxa2xx-lib.h> 17#include <sound/pxa2xx-lib.h>
18 18
19#include "pxa2xx-pcm.h"
20#include "../../arm/pxa2xx-pcm.h" 19#include "../../arm/pxa2xx-pcm.h"
21 20
22static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 21static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -28,7 +27,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
28 struct pxa2xx_pcm_dma_params *dma; 27 struct pxa2xx_pcm_dma_params *dma;
29 int ret; 28 int ret;
30 29
31 dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 30 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
32 31
33 /* return if this is a bufferless transfer e.g. 32 /* return if this is a bufferless transfer e.g.
34 * codec <--> BT codec or GSM modem -- lg FIXME */ 33 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -66,6 +65,7 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
66 if (prtd->dma_ch >= 0) { 65 if (prtd->dma_ch >= 0) {
67 pxa_free_dma(prtd->dma_ch); 66 pxa_free_dma(prtd->dma_ch);
68 prtd->dma_ch = -1; 67 prtd->dma_ch = -1;
68 prtd->params = NULL;
69 } 69 }
70 70
71 return 0; 71 return 0;
@@ -95,14 +95,14 @@ static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
95 if (!card->dev->coherent_dma_mask) 95 if (!card->dev->coherent_dma_mask)
96 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 96 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
97 97
98 if (dai->playback.channels_min) { 98 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
99 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, 99 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
100 SNDRV_PCM_STREAM_PLAYBACK); 100 SNDRV_PCM_STREAM_PLAYBACK);
101 if (ret) 101 if (ret)
102 goto out; 102 goto out;
103 } 103 }
104 104
105 if (dai->capture.channels_min) { 105 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
106 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, 106 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
107 SNDRV_PCM_STREAM_CAPTURE); 107 SNDRV_PCM_STREAM_CAPTURE);
108 if (ret) 108 if (ret)
@@ -112,25 +112,44 @@ static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
112 return ret; 112 return ret;
113} 113}
114 114
115struct snd_soc_platform pxa2xx_soc_platform = { 115static struct snd_soc_platform_driver pxa2xx_soc_platform = {
116 .name = "pxa2xx-audio", 116 .ops = &pxa2xx_pcm_ops,
117 .pcm_ops = &pxa2xx_pcm_ops,
118 .pcm_new = pxa2xx_soc_pcm_new, 117 .pcm_new = pxa2xx_soc_pcm_new,
119 .pcm_free = pxa2xx_pcm_free_dma_buffers, 118 .pcm_free = pxa2xx_pcm_free_dma_buffers,
120}; 119};
121EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
122 120
123static int __init pxa2xx_soc_platform_init(void) 121static int __devinit pxa2xx_soc_platform_probe(struct platform_device *pdev)
124{ 122{
125 return snd_soc_register_platform(&pxa2xx_soc_platform); 123 return snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform);
126} 124}
127module_init(pxa2xx_soc_platform_init);
128 125
129static void __exit pxa2xx_soc_platform_exit(void) 126static int __devexit pxa2xx_soc_platform_remove(struct platform_device *pdev)
130{ 127{
131 snd_soc_unregister_platform(&pxa2xx_soc_platform); 128 snd_soc_unregister_platform(&pdev->dev);
129 return 0;
130}
131
132static struct platform_driver pxa_pcm_driver = {
133 .driver = {
134 .name = "pxa-pcm-audio",
135 .owner = THIS_MODULE,
136 },
137
138 .probe = pxa2xx_soc_platform_probe,
139 .remove = __devexit_p(pxa2xx_soc_platform_remove),
140};
141
142static int __init snd_pxa_pcm_init(void)
143{
144 return platform_driver_register(&pxa_pcm_driver);
145}
146module_init(snd_pxa_pcm_init);
147
148static void __exit snd_pxa_pcm_exit(void)
149{
150 platform_driver_unregister(&pxa_pcm_driver);
132} 151}
133module_exit(pxa2xx_soc_platform_exit); 152module_exit(snd_pxa_pcm_exit);
134 153
135MODULE_AUTHOR("Nicolas Pitre"); 154MODULE_AUTHOR("Nicolas Pitre");
136MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); 155MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
diff --git a/sound/soc/pxa/pxa2xx-pcm.h b/sound/soc/pxa/pxa2xx-pcm.h
deleted file mode 100644
index 60c3b20aeeb4..000000000000
--- a/sound/soc/pxa/pxa2xx-pcm.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip
3 *
4 * Author: Nicolas Pitre
5 * Created: Nov 30, 2004
6 * Copyright: MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _PXA2XX_PCM_H
14#define _PXA2XX_PCM_H
15
16/* platform data */
17extern struct snd_soc_platform pxa2xx_soc_platform;
18
19#endif
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 7e3f41696c41..1a591f1ebfbd 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -22,13 +22,9 @@
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
28 27
29#include "../codecs/cs4270.h"
30#include "../codecs/ak4104.h"
31#include "pxa2xx-pcm.h"
32#include "pxa-ssp.h" 28#include "pxa-ssp.h"
33 29
34#define GPIO_SPDIF_RESET (38) 30#define GPIO_SPDIF_RESET (38)
@@ -71,7 +67,7 @@ static void raumfeld_enable_audio(bool en)
71static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream) 67static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
72{ 68{
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 70 struct snd_soc_dai *codec_dai = rtd->codec_dai;
75 71
76 /* set freq to 0 to enable all possible codec sample rates */ 72 /* set freq to 0 to enable all possible codec sample rates */
77 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0); 73 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
@@ -80,7 +76,7 @@ static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
80static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream) 76static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
81{ 77{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data; 78 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 79 struct snd_soc_dai *codec_dai = rtd->codec_dai;
84 80
85 /* set freq to 0 to enable all possible codec sample rates */ 81 /* set freq to 0 to enable all possible codec sample rates */
86 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0); 82 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
@@ -90,8 +86,8 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
90 struct snd_pcm_hw_params *params) 86 struct snd_pcm_hw_params *params)
91{ 87{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data; 88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 89 struct snd_soc_dai *codec_dai = rtd->codec_dai;
94 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 90 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
95 unsigned int fmt, clk = 0; 91 unsigned int fmt, clk = 0;
96 int ret = 0; 92 int ret = 0;
97 93
@@ -155,44 +151,26 @@ static struct snd_soc_ops raumfeld_cs4270_ops = {
155 .hw_params = raumfeld_cs4270_hw_params, 151 .hw_params = raumfeld_cs4270_hw_params,
156}; 152};
157 153
158static int raumfeld_line_suspend(struct platform_device *pdev, pm_message_t state) 154static int raumfeld_analog_suspend(struct snd_soc_card *card)
159{ 155{
160 raumfeld_enable_audio(false); 156 raumfeld_enable_audio(false);
161 return 0; 157 return 0;
162} 158}
163 159
164static int raumfeld_line_resume(struct platform_device *pdev) 160static int raumfeld_analog_resume(struct snd_soc_card *card)
165{ 161{
166 raumfeld_enable_audio(true); 162 raumfeld_enable_audio(true);
167 return 0; 163 return 0;
168} 164}
169 165
170static struct snd_soc_dai_link raumfeld_line_dai = {
171 .name = "CS4270",
172 .stream_name = "CS4270",
173 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
174 .codec_dai = &cs4270_dai,
175 .ops = &raumfeld_cs4270_ops,
176};
177
178static struct snd_soc_card snd_soc_line_raumfeld = {
179 .name = "Raumfeld analog",
180 .platform = &pxa2xx_soc_platform,
181 .dai_link = &raumfeld_line_dai,
182 .suspend_post = raumfeld_line_suspend,
183 .resume_pre = raumfeld_line_resume,
184 .num_links = 1,
185};
186
187
188/* AK4104 */ 166/* AK4104 */
189 167
190static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream, 168static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
191 struct snd_pcm_hw_params *params) 169 struct snd_pcm_hw_params *params)
192{ 170{
193 struct snd_soc_pcm_runtime *rtd = substream->private_data; 171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
194 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 172 struct snd_soc_dai *codec_dai = rtd->codec_dai;
195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 173 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
196 int fmt, ret = 0, clk = 0; 174 int fmt, ret = 0, clk = 0;
197 175
198 switch (params_rate(params)) { 176 switch (params_rate(params)) {
@@ -247,34 +225,56 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
247 .hw_params = raumfeld_ak4104_hw_params, 225 .hw_params = raumfeld_ak4104_hw_params,
248}; 226};
249 227
250static struct snd_soc_dai_link raumfeld_spdif_dai = { 228#define DAI_LINK_CS4270 \
251 .name = "ak4104", 229{ \
252 .stream_name = "Playback", 230 .name = "CS4270", \
253 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP2], 231 .stream_name = "CS4270", \
254 .codec_dai = &ak4104_dai, 232 .cpu_dai_name = "pxa-ssp-dai.0", \
255 .ops = &raumfeld_ak4104_ops, 233 .platform_name = "pxa-pcm-audio", \
234 .codec_dai_name = "cs4270-hifi", \
235 .codec_name = "cs4270-codec.0-0048", \
236 .ops = &raumfeld_cs4270_ops, \
237}
238
239#define DAI_LINK_AK4104 \
240{ \
241 .name = "ak4104", \
242 .stream_name = "Playback", \
243 .cpu_dai_name = "pxa-ssp-dai.1", \
244 .codec_dai_name = "ak4104-hifi", \
245 .platform_name = "pxa-pcm-audio", \
246 .ops = &raumfeld_ak4104_ops, \
247 .codec_name = "spi0.0", \
248}
249
250static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] =
251{
252 DAI_LINK_CS4270,
253 DAI_LINK_AK4104,
256}; 254};
257 255
258static struct snd_soc_card snd_soc_spdif_raumfeld = { 256static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] =
259 .name = "Raumfeld S/PDIF", 257{
260 .platform = &pxa2xx_soc_platform, 258 DAI_LINK_CS4270,
261 .dai_link = &raumfeld_spdif_dai,
262 .num_links = 1
263}; 259};
264 260
265/* raumfeld_audio audio subsystem */ 261static struct snd_soc_card snd_soc_raumfeld_connector = {
266static struct snd_soc_device raumfeld_line_devdata = { 262 .name = "Raumfeld Connector",
267 .card = &snd_soc_line_raumfeld, 263 .dai_link = snd_soc_raumfeld_connector_dai,
268 .codec_dev = &soc_codec_device_cs4270, 264 .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai),
265 .suspend_post = raumfeld_analog_suspend,
266 .resume_pre = raumfeld_analog_resume,
269}; 267};
270 268
271static struct snd_soc_device raumfeld_spdif_devdata = { 269static struct snd_soc_card snd_soc_raumfeld_speaker = {
272 .card = &snd_soc_spdif_raumfeld, 270 .name = "Raumfeld Speaker",
273 .codec_dev = &soc_codec_device_ak4104, 271 .dai_link = snd_soc_raumfeld_speaker_dai,
272 .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai),
273 .suspend_post = raumfeld_analog_suspend,
274 .resume_pre = raumfeld_analog_resume,
274}; 275};
275 276
276static struct platform_device *raumfeld_audio_line_device; 277static struct platform_device *raumfeld_audio_device;
277static struct platform_device *raumfeld_audio_spdif_device;
278 278
279static int __init raumfeld_audio_init(void) 279static int __init raumfeld_audio_init(void)
280{ 280{
@@ -292,51 +292,32 @@ static int __init raumfeld_audio_init(void)
292 292
293 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 293 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
294 294
295 /* LINE */ 295 /* Register analog device */
296 raumfeld_audio_line_device = platform_device_alloc("soc-audio", 0); 296 raumfeld_audio_device = platform_device_alloc("soc-audio", 0);
297 if (!raumfeld_audio_line_device) 297 if (!raumfeld_audio_device)
298 return -ENOMEM; 298 return -ENOMEM;
299 299
300 platform_set_drvdata(raumfeld_audio_line_device,
301 &raumfeld_line_devdata);
302 raumfeld_line_devdata.dev = &raumfeld_audio_line_device->dev;
303 ret = platform_device_add(raumfeld_audio_line_device);
304 if (ret)
305 platform_device_put(raumfeld_audio_line_device);
306
307 /* no S/PDIF on Speakers */
308 if (machine_is_raumfeld_speaker()) 300 if (machine_is_raumfeld_speaker())
309 return ret; 301 platform_set_drvdata(raumfeld_audio_device,
302 &snd_soc_raumfeld_speaker);
310 303
311 /* S/PDIF */ 304 if (machine_is_raumfeld_connector())
312 raumfeld_audio_spdif_device = platform_device_alloc("soc-audio", 1); 305 platform_set_drvdata(raumfeld_audio_device,
313 if (!raumfeld_audio_spdif_device) { 306 &snd_soc_raumfeld_connector);
314 platform_device_put(raumfeld_audio_line_device);
315 return -ENOMEM;
316 }
317 307
318 platform_set_drvdata(raumfeld_audio_spdif_device, 308 ret = platform_device_add(raumfeld_audio_device);
319 &raumfeld_spdif_devdata); 309 if (ret < 0)
320 raumfeld_spdif_devdata.dev = &raumfeld_audio_spdif_device->dev; 310 return ret;
321 ret = platform_device_add(raumfeld_audio_spdif_device);
322 if (ret) {
323 platform_device_put(raumfeld_audio_line_device);
324 platform_device_put(raumfeld_audio_spdif_device);
325 }
326 311
327 raumfeld_enable_audio(true); 312 raumfeld_enable_audio(true);
328 313 return 0;
329 return ret;
330} 314}
331 315
332static void __exit raumfeld_audio_exit(void) 316static void __exit raumfeld_audio_exit(void)
333{ 317{
334 raumfeld_enable_audio(false); 318 raumfeld_enable_audio(false);
335 319
336 platform_device_unregister(raumfeld_audio_line_device); 320 platform_device_unregister(raumfeld_audio_device);
337
338 if (machine_is_raumfeld_connector())
339 platform_device_unregister(raumfeld_audio_spdif_device);
340 321
341 i2c_unregister_device(max9486_client); 322 i2c_unregister_device(max9486_client);
342 323
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
new file mode 100644
index 000000000000..9595189fc681
--- /dev/null
+++ b/sound/soc/pxa/saarb.c
@@ -0,0 +1,200 @@
1/*
2 * saarb.c -- SoC audio for saarb
3 *
4 * Copyright (C) 2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/device.h>
15#include <linux/clk.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22
23#include <asm/mach-types.h>
24
25#include "../codecs/88pm860x-codec.h"
26#include "pxa-ssp.h"
27
28static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd);
29
30static struct platform_device *saarb_snd_device;
31
32static struct snd_soc_jack hs_jack, mic_jack;
33
34static struct snd_soc_jack_pin hs_jack_pins[] = {
35 { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
36};
37
38static struct snd_soc_jack_pin mic_jack_pins[] = {
39 { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
40};
41
42/* saarb machine dapm widgets */
43static const struct snd_soc_dapm_widget saarb_dapm_widgets[] = {
44 SND_SOC_DAPM_HP("Headphone Stereophone", NULL),
45 SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
46 SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
47 SND_SOC_DAPM_SPK("Ext Speaker", NULL),
48 SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
49 SND_SOC_DAPM_MIC("Headset Mic", NULL),
50 SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
51};
52
53/* saarb machine audio map */
54static const struct snd_soc_dapm_route audio_map[] = {
55 {"Headset Stereophone", NULL, "HS1"},
56 {"Headset Stereophone", NULL, "HS2"},
57
58 {"Ext Speaker", NULL, "LSP"},
59 {"Ext Speaker", NULL, "LSN"},
60
61 {"Lineout Out 1", NULL, "LINEOUT1"},
62 {"Lineout Out 2", NULL, "LINEOUT2"},
63
64 {"MIC1P", NULL, "Mic1 Bias"},
65 {"MIC1N", NULL, "Mic1 Bias"},
66 {"Mic1 Bias", NULL, "Ext Mic 1"},
67
68 {"MIC2P", NULL, "Mic1 Bias"},
69 {"MIC2N", NULL, "Mic1 Bias"},
70 {"Mic1 Bias", NULL, "Headset Mic 2"},
71
72 {"MIC3P", NULL, "Mic3 Bias"},
73 {"MIC3N", NULL, "Mic3 Bias"},
74 {"Mic3 Bias", NULL, "Ext Mic 3"},
75};
76
77static int saarb_i2s_hw_params(struct snd_pcm_substream *substream,
78 struct snd_pcm_hw_params *params)
79{
80 struct snd_soc_pcm_runtime *rtd = substream->private_data;
81 struct snd_soc_dai *codec_dai = rtd->codec_dai;
82 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
83 int width = snd_pcm_format_physical_width(params_format(params));
84 int ret;
85
86 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
87 PM860X_CLK_DIR_OUT);
88 if (ret < 0)
89 return ret;
90
91 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
97 if (ret < 0)
98 return ret;
99 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
100 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
101 if (ret < 0)
102 return ret;
103
104 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
105
106 return ret;
107}
108
109static struct snd_soc_ops saarb_i2s_ops = {
110 .hw_params = saarb_i2s_hw_params,
111};
112
113static struct snd_soc_dai_link saarb_dai[] = {
114 {
115 .name = "88PM860x I2S",
116 .stream_name = "I2S Audio",
117 .cpu_dai_name = "pxa-ssp-dai.1",
118 .codec_dai_name = "88pm860x-i2s",
119 .platform_name = "pxa-pcm-audio",
120 .codec_name = "88pm860x-codec",
121 .init = saarb_pm860x_init,
122 .ops = &saarb_i2s_ops,
123 },
124};
125
126static struct snd_soc_card snd_soc_card_saarb = {
127 .name = "Saarb",
128 .dai_link = saarb_dai,
129 .num_links = ARRAY_SIZE(saarb_dai),
130};
131
132static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
133{
134 struct snd_soc_codec *codec = rtd->codec;
135 struct snd_soc_dapm_context *dapm = &codec->dapm;
136 int ret;
137
138 snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets,
139 ARRAY_SIZE(saarb_dapm_widgets));
140 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
141
142 /* connected pins */
143 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
144 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
145 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148
149 ret = snd_soc_dapm_sync(dapm);
150 if (ret)
151 return ret;
152
153 /* Headset jack detection */
154 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
155 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
156 &hs_jack);
157 snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
158 hs_jack_pins);
159 snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
160 &mic_jack);
161 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
162 mic_jack_pins);
163
164 /* headphone, microphone detection & headset short detection */
165 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
166 SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
167 pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
168 return 0;
169}
170
171static int __init saarb_init(void)
172{
173 int ret;
174
175 if (!machine_is_saarb())
176 return -ENODEV;
177 saarb_snd_device = platform_device_alloc("soc-audio", -1);
178 if (!saarb_snd_device)
179 return -ENOMEM;
180
181 platform_set_drvdata(saarb_snd_device, &snd_soc_card_saarb);
182
183 ret = platform_device_add(saarb_snd_device);
184 if (ret)
185 platform_device_put(saarb_snd_device);
186
187 return ret;
188}
189
190static void __exit saarb_exit(void)
191{
192 platform_device_unregister(saarb_snd_device);
193}
194
195module_init(saarb_init);
196module_exit(saarb_exit);
197
198MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
199MODULE_DESCRIPTION("ALSA SoC 88PM860x Saarb");
200MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index d256f5f313b5..b253d864868a 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -23,12 +23,10 @@
23#include <sound/core.h> 23#include <sound/core.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <mach/spitz.h> 28#include <mach/spitz.h>
30#include "../codecs/wm8750.h" 29#include "../codecs/wm8750.h"
31#include "pxa2xx-pcm.h"
32#include "pxa2xx-i2s.h" 30#include "pxa2xx-i2s.h"
33 31
34#define SPITZ_HP 0 32#define SPITZ_HP 0
@@ -44,73 +42,81 @@
44 42
45static int spitz_jack_func; 43static int spitz_jack_func;
46static int spitz_spk_func; 44static int spitz_spk_func;
45static int spitz_mic_gpio;
47 46
48static void spitz_ext_control(struct snd_soc_codec *codec) 47static void spitz_ext_control(struct snd_soc_codec *codec)
49{ 48{
49 struct snd_soc_dapm_context *dapm = &codec->dapm;
50
50 if (spitz_spk_func == SPITZ_SPK_ON) 51 if (spitz_spk_func == SPITZ_SPK_ON)
51 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 52 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
52 else 53 else
53 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 54 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
54 55
55 /* set up jack connection */ 56 /* set up jack connection */
56 switch (spitz_jack_func) { 57 switch (spitz_jack_func) {
57 case SPITZ_HP: 58 case SPITZ_HP:
58 /* enable and unmute hp jack, disable mic bias */ 59 /* enable and unmute hp jack, disable mic bias */
59 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 60 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
60 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 61 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
61 snd_soc_dapm_disable_pin(codec, "Line Jack"); 62 snd_soc_dapm_disable_pin(dapm, "Line Jack");
62 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 63 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
63 gpio_set_value(SPITZ_GPIO_MUTE_L, 1); 64 gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
64 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 65 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
65 break; 66 break;
66 case SPITZ_MIC: 67 case SPITZ_MIC:
67 /* enable mic jack and bias, mute hp */ 68 /* enable mic jack and bias, mute hp */
68 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 69 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
69 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 70 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
70 snd_soc_dapm_disable_pin(codec, "Line Jack"); 71 snd_soc_dapm_disable_pin(dapm, "Line Jack");
71 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 72 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
72 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 73 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
73 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 74 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
74 break; 75 break;
75 case SPITZ_LINE: 76 case SPITZ_LINE:
76 /* enable line jack, disable mic bias and mute hp */ 77 /* enable line jack, disable mic bias and mute hp */
77 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 78 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
78 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 79 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
79 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 80 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
80 snd_soc_dapm_enable_pin(codec, "Line Jack"); 81 snd_soc_dapm_enable_pin(dapm, "Line Jack");
81 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 82 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
82 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 83 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
83 break; 84 break;
84 case SPITZ_HEADSET: 85 case SPITZ_HEADSET:
85 /* enable and unmute headset jack enable mic bias, mute L hp */ 86 /* enable and unmute headset jack enable mic bias, mute L hp */
86 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 87 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
87 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 88 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
88 snd_soc_dapm_disable_pin(codec, "Line Jack"); 89 snd_soc_dapm_disable_pin(dapm, "Line Jack");
89 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 90 snd_soc_dapm_enable_pin(dapm, "Headset Jack");
90 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 91 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
91 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 92 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
92 break; 93 break;
93 case SPITZ_HP_OFF: 94 case SPITZ_HP_OFF:
94 95
95 /* jack removed, everything off */ 96 /* jack removed, everything off */
96 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 97 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
97 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 98 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
98 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 99 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
99 snd_soc_dapm_disable_pin(codec, "Line Jack"); 100 snd_soc_dapm_disable_pin(dapm, "Line Jack");
100 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 101 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
101 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 102 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
102 break; 103 break;
103 } 104 }
104 snd_soc_dapm_sync(codec); 105 snd_soc_dapm_sync(dapm);
105} 106}
106 107
107static int spitz_startup(struct snd_pcm_substream *substream) 108static int spitz_startup(struct snd_pcm_substream *substream)
108{ 109{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 110 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct snd_soc_codec *codec = rtd->socdev->card->codec; 111 struct snd_soc_codec *codec = rtd->codec;
112
113 mutex_lock(&codec->mutex);
111 114
112 /* check the jack status at stream startup */ 115 /* check the jack status at stream startup */
113 spitz_ext_control(codec); 116 spitz_ext_control(codec);
117
118 mutex_unlock(&codec->mutex);
119
114 return 0; 120 return 0;
115} 121}
116 122
@@ -118,8 +124,8 @@ static int spitz_hw_params(struct snd_pcm_substream *substream,
118 struct snd_pcm_hw_params *params) 124 struct snd_pcm_hw_params *params)
119{ 125{
120 struct snd_soc_pcm_runtime *rtd = substream->private_data; 126 struct snd_soc_pcm_runtime *rtd = substream->private_data;
121 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 127 struct snd_soc_dai *codec_dai = rtd->codec_dai;
122 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 128 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
123 unsigned int clk = 0; 129 unsigned int clk = 0;
124 int ret = 0; 130 int ret = 0;
125 131
@@ -212,14 +218,7 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
212static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 218static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
213 struct snd_kcontrol *k, int event) 219 struct snd_kcontrol *k, int event)
214{ 220{
215 if (machine_is_borzoi() || machine_is_spitz()) 221 gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event));
216 gpio_set_value(SPITZ_GPIO_MIC_BIAS,
217 SND_SOC_DAPM_EVENT_ON(event));
218
219 if (machine_is_akita())
220 gpio_set_value(AKITA_GPIO_MIC_BIAS,
221 SND_SOC_DAPM_EVENT_ON(event));
222
223 return 0; 222 return 0;
224} 223}
225 224
@@ -274,18 +273,20 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
274/* 273/*
275 * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device 274 * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device
276 */ 275 */
277static int spitz_wm8750_init(struct snd_soc_codec *codec) 276static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
278{ 277{
278 struct snd_soc_codec *codec = rtd->codec;
279 struct snd_soc_dapm_context *dapm = &codec->dapm;
279 int err; 280 int err;
280 281
281 /* NC codec pins */ 282 /* NC codec pins */
282 snd_soc_dapm_nc_pin(codec, "RINPUT1"); 283 snd_soc_dapm_nc_pin(dapm, "RINPUT1");
283 snd_soc_dapm_nc_pin(codec, "LINPUT2"); 284 snd_soc_dapm_nc_pin(dapm, "LINPUT2");
284 snd_soc_dapm_nc_pin(codec, "RINPUT2"); 285 snd_soc_dapm_nc_pin(dapm, "RINPUT2");
285 snd_soc_dapm_nc_pin(codec, "LINPUT3"); 286 snd_soc_dapm_nc_pin(dapm, "LINPUT3");
286 snd_soc_dapm_nc_pin(codec, "RINPUT3"); 287 snd_soc_dapm_nc_pin(dapm, "RINPUT3");
287 snd_soc_dapm_nc_pin(codec, "OUT3"); 288 snd_soc_dapm_nc_pin(dapm, "OUT3");
288 snd_soc_dapm_nc_pin(codec, "MONO1"); 289 snd_soc_dapm_nc_pin(dapm, "MONO1");
289 290
290 /* Add spitz specific controls */ 291 /* Add spitz specific controls */
291 err = snd_soc_add_controls(codec, wm8750_spitz_controls, 292 err = snd_soc_add_controls(codec, wm8750_spitz_controls,
@@ -294,13 +295,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
294 return err; 295 return err;
295 296
296 /* Add spitz specific widgets */ 297 /* Add spitz specific widgets */
297 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 298 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
298 ARRAY_SIZE(wm8750_dapm_widgets)); 299 ARRAY_SIZE(wm8750_dapm_widgets));
299 300
300 /* Set up spitz specific audio paths */ 301 /* Set up spitz specific audio paths */
301 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 302 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
302 303
303 snd_soc_dapm_sync(codec); 304 snd_soc_dapm_sync(dapm);
304 return 0; 305 return 0;
305} 306}
306 307
@@ -308,8 +309,10 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
308static struct snd_soc_dai_link spitz_dai = { 309static struct snd_soc_dai_link spitz_dai = {
309 .name = "wm8750", 310 .name = "wm8750",
310 .stream_name = "WM8750", 311 .stream_name = "WM8750",
311 .cpu_dai = &pxa_i2s_dai, 312 .cpu_dai_name = "pxa2xx-i2s",
312 .codec_dai = &wm8750_dai, 313 .codec_dai_name = "wm8750-hifi",
314 .platform_name = "pxa-pcm-audio",
315 .codec_name = "wm8750-codec.0-001b",
313 .init = spitz_wm8750_init, 316 .init = spitz_wm8750_init,
314 .ops = &spitz_ops, 317 .ops = &spitz_ops,
315}; 318};
@@ -317,17 +320,10 @@ static struct snd_soc_dai_link spitz_dai = {
317/* spitz audio machine driver */ 320/* spitz audio machine driver */
318static struct snd_soc_card snd_soc_spitz = { 321static struct snd_soc_card snd_soc_spitz = {
319 .name = "Spitz", 322 .name = "Spitz",
320 .platform = &pxa2xx_soc_platform,
321 .dai_link = &spitz_dai, 323 .dai_link = &spitz_dai,
322 .num_links = 1, 324 .num_links = 1,
323}; 325};
324 326
325/* spitz audio subsystem */
326static struct snd_soc_device spitz_snd_devdata = {
327 .card = &snd_soc_spitz,
328 .codec_dev = &soc_codec_dev_wm8750,
329};
330
331static struct platform_device *spitz_snd_device; 327static struct platform_device *spitz_snd_device;
332 328
333static int __init spitz_init(void) 329static int __init spitz_init(void)
@@ -337,23 +333,45 @@ static int __init spitz_init(void)
337 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 333 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
338 return -ENODEV; 334 return -ENODEV;
339 335
336 if (machine_is_borzoi() || machine_is_spitz())
337 spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS;
338 else
339 spitz_mic_gpio = AKITA_GPIO_MIC_BIAS;
340
341 ret = gpio_request(spitz_mic_gpio, "MIC GPIO");
342 if (ret)
343 goto err1;
344
345 ret = gpio_direction_output(spitz_mic_gpio, 0);
346 if (ret)
347 goto err2;
348
340 spitz_snd_device = platform_device_alloc("soc-audio", -1); 349 spitz_snd_device = platform_device_alloc("soc-audio", -1);
341 if (!spitz_snd_device) 350 if (!spitz_snd_device) {
342 return -ENOMEM; 351 ret = -ENOMEM;
352 goto err2;
353 }
343 354
344 platform_set_drvdata(spitz_snd_device, &spitz_snd_devdata); 355 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
345 spitz_snd_devdata.dev = &spitz_snd_device->dev;
346 ret = platform_device_add(spitz_snd_device);
347 356
357 ret = platform_device_add(spitz_snd_device);
348 if (ret) 358 if (ret)
349 platform_device_put(spitz_snd_device); 359 goto err3;
360
361 return 0;
350 362
363err3:
364 platform_device_put(spitz_snd_device);
365err2:
366 gpio_free(spitz_mic_gpio);
367err1:
351 return ret; 368 return ret;
352} 369}
353 370
354static void __exit spitz_exit(void) 371static void __exit spitz_exit(void)
355{ 372{
356 platform_device_unregister(spitz_snd_device); 373 platform_device_unregister(spitz_snd_device);
374 gpio_free(spitz_mic_gpio);
357} 375}
358 376
359module_init(spitz_init); 377module_init(spitz_init);
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
new file mode 100644
index 000000000000..f881f65ec172
--- /dev/null
+++ b/sound/soc/pxa/tavorevb3.c
@@ -0,0 +1,200 @@
1/*
2 * tavorevb3.c -- SoC audio for Tavor EVB3
3 *
4 * Copyright (C) 2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/device.h>
15#include <linux/clk.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22
23#include <asm/mach-types.h>
24
25#include "../codecs/88pm860x-codec.h"
26#include "pxa-ssp.h"
27
28static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd);
29
30static struct platform_device *evb3_snd_device;
31
32static struct snd_soc_jack hs_jack, mic_jack;
33
34static struct snd_soc_jack_pin hs_jack_pins[] = {
35 { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
36};
37
38static struct snd_soc_jack_pin mic_jack_pins[] = {
39 { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
40};
41
42/* tavorevb3 machine dapm widgets */
43static const struct snd_soc_dapm_widget evb3_dapm_widgets[] = {
44 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
45 SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
46 SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
47 SND_SOC_DAPM_SPK("Ext Speaker", NULL),
48 SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
49 SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
50 SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
51};
52
53/* tavorevb3 machine audio map */
54static const struct snd_soc_dapm_route audio_map[] = {
55 {"Headset Stereophone", NULL, "HS1"},
56 {"Headset Stereophone", NULL, "HS2"},
57
58 {"Ext Speaker", NULL, "LSP"},
59 {"Ext Speaker", NULL, "LSN"},
60
61 {"Lineout Out 1", NULL, "LINEOUT1"},
62 {"Lineout Out 2", NULL, "LINEOUT2"},
63
64 {"MIC1P", NULL, "Mic1 Bias"},
65 {"MIC1N", NULL, "Mic1 Bias"},
66 {"Mic1 Bias", NULL, "Ext Mic 1"},
67
68 {"MIC2P", NULL, "Mic1 Bias"},
69 {"MIC2N", NULL, "Mic1 Bias"},
70 {"Mic1 Bias", NULL, "Headset Mic 2"},
71
72 {"MIC3P", NULL, "Mic3 Bias"},
73 {"MIC3N", NULL, "Mic3 Bias"},
74 {"Mic3 Bias", NULL, "Ext Mic 3"},
75};
76
77static int evb3_i2s_hw_params(struct snd_pcm_substream *substream,
78 struct snd_pcm_hw_params *params)
79{
80 struct snd_soc_pcm_runtime *rtd = substream->private_data;
81 struct snd_soc_dai *codec_dai = rtd->codec_dai;
82 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
83 int width = snd_pcm_format_physical_width(params_format(params));
84 int ret;
85
86 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_NET_PLL, 0,
87 PM860X_CLK_DIR_OUT);
88 if (ret < 0)
89 return ret;
90
91 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, PM860X_CLK_DIR_OUT);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
97 if (ret < 0)
98 return ret;
99
100 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
102 if (ret < 0)
103 return ret;
104
105 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width);
106 return ret;
107}
108
109static struct snd_soc_ops evb3_i2s_ops = {
110 .hw_params = evb3_i2s_hw_params,
111};
112
113static struct snd_soc_dai_link evb3_dai[] = {
114 {
115 .name = "88PM860x I2S",
116 .stream_name = "I2S Audio",
117 .cpu_dai_name = "pxa-ssp-dai.1",
118 .codec_dai_name = "88pm860x-i2s",
119 .platform_name = "pxa-pcm-audio",
120 .codec_name = "88pm860x-codec",
121 .init = evb3_pm860x_init,
122 .ops = &evb3_i2s_ops,
123 },
124};
125
126static struct snd_soc_card snd_soc_card_evb3 = {
127 .name = "Tavor EVB3",
128 .dai_link = evb3_dai,
129 .num_links = ARRAY_SIZE(evb3_dai),
130};
131
132static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
133{
134 struct snd_soc_codec *codec = rtd->codec;
135 struct snd_soc_dapm_context *dapm = &codec->dapm;
136 int ret;
137
138 snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets,
139 ARRAY_SIZE(evb3_dapm_widgets));
140 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
141
142 /* connected pins */
143 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
144 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
145 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148
149 ret = snd_soc_dapm_sync(dapm);
150 if (ret)
151 return ret;
152
153 /* Headset jack detection */
154 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
155 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
156 &hs_jack);
157 snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
158 hs_jack_pins);
159 snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
160 &mic_jack);
161 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
162 mic_jack_pins);
163
164 /* headphone, microphone detection & headset short detection */
165 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
166 SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
167 pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
168 return 0;
169}
170
171static int __init tavorevb3_init(void)
172{
173 int ret;
174
175 if (!machine_is_tavorevb3())
176 return -ENODEV;
177 evb3_snd_device = platform_device_alloc("soc-audio", -1);
178 if (!evb3_snd_device)
179 return -ENOMEM;
180
181 platform_set_drvdata(evb3_snd_device, &snd_soc_card_evb3);
182
183 ret = platform_device_add(evb3_snd_device);
184 if (ret)
185 platform_device_put(evb3_snd_device);
186
187 return ret;
188}
189
190static void __exit tavorevb3_exit(void)
191{
192 platform_device_unregister(evb3_snd_device);
193}
194
195module_init(tavorevb3_init);
196module_exit(tavorevb3_exit);
197
198MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
199MODULE_DESCRIPTION("ALSA SoC 88PM860x Tavor EVB3");
200MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index dbbd3e9d1637..9a2351366957 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -26,14 +26,12 @@
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <mach/tosa.h> 31#include <mach/tosa.h>
33#include <mach/audio.h> 32#include <mach/audio.h>
34 33
35#include "../codecs/wm9712.h" 34#include "../codecs/wm9712.h"
36#include "pxa2xx-pcm.h"
37#include "pxa2xx-ac97.h" 35#include "pxa2xx-ac97.h"
38 36
39static struct snd_soc_card tosa; 37static struct snd_soc_card tosa;
@@ -50,40 +48,47 @@ static int tosa_spk_func;
50 48
51static void tosa_ext_control(struct snd_soc_codec *codec) 49static void tosa_ext_control(struct snd_soc_codec *codec)
52{ 50{
51 struct snd_soc_dapm_context *dapm = &codec->dapm;
52
53 /* set up jack connection */ 53 /* set up jack connection */
54 switch (tosa_jack_func) { 54 switch (tosa_jack_func) {
55 case TOSA_HP: 55 case TOSA_HP:
56 snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); 56 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
57 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 57 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
58 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 58 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
59 break; 59 break;
60 case TOSA_MIC_INT: 60 case TOSA_MIC_INT:
61 snd_soc_dapm_enable_pin(codec, "Mic (Internal)"); 61 snd_soc_dapm_enable_pin(dapm, "Mic (Internal)");
62 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 62 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
63 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 63 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
64 break; 64 break;
65 case TOSA_HEADSET: 65 case TOSA_HEADSET:
66 snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); 66 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
67 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 67 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
68 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 68 snd_soc_dapm_enable_pin(dapm, "Headset Jack");
69 break; 69 break;
70 } 70 }
71 71
72 if (tosa_spk_func == TOSA_SPK_ON) 72 if (tosa_spk_func == TOSA_SPK_ON)
73 snd_soc_dapm_enable_pin(codec, "Speaker"); 73 snd_soc_dapm_enable_pin(dapm, "Speaker");
74 else 74 else
75 snd_soc_dapm_disable_pin(codec, "Speaker"); 75 snd_soc_dapm_disable_pin(dapm, "Speaker");
76 76
77 snd_soc_dapm_sync(codec); 77 snd_soc_dapm_sync(dapm);
78} 78}
79 79
80static int tosa_startup(struct snd_pcm_substream *substream) 80static int tosa_startup(struct snd_pcm_substream *substream)
81{ 81{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data; 82 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_codec *codec = rtd->socdev->card->codec; 83 struct snd_soc_codec *codec = rtd->codec;
84
85 mutex_lock(&codec->mutex);
84 86
85 /* check the jack status at stream startup */ 87 /* check the jack status at stream startup */
86 tosa_ext_control(codec); 88 tosa_ext_control(codec);
89
90 mutex_unlock(&codec->mutex);
91
87 return 0; 92 return 0;
88} 93}
89 94
@@ -184,12 +189,14 @@ static const struct snd_kcontrol_new tosa_controls[] = {
184 tosa_set_spk), 189 tosa_set_spk),
185}; 190};
186 191
187static int tosa_ac97_init(struct snd_soc_codec *codec) 192static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
188{ 193{
194 struct snd_soc_codec *codec = rtd->codec;
195 struct snd_soc_dapm_context *dapm = &codec->dapm;
189 int err; 196 int err;
190 197
191 snd_soc_dapm_nc_pin(codec, "OUT3"); 198 snd_soc_dapm_nc_pin(dapm, "OUT3");
192 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 199 snd_soc_dapm_nc_pin(dapm, "MONOOUT");
193 200
194 /* add tosa specific controls */ 201 /* add tosa specific controls */
195 err = snd_soc_add_controls(codec, tosa_controls, 202 err = snd_soc_add_controls(codec, tosa_controls,
@@ -198,13 +205,13 @@ static int tosa_ac97_init(struct snd_soc_codec *codec)
198 return err; 205 return err;
199 206
200 /* add tosa specific widgets */ 207 /* add tosa specific widgets */
201 snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, 208 snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets,
202 ARRAY_SIZE(tosa_dapm_widgets)); 209 ARRAY_SIZE(tosa_dapm_widgets));
203 210
204 /* set up tosa specific audio path audio_map */ 211 /* set up tosa specific audio path audio_map */
205 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 212 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
206 213
207 snd_soc_dapm_sync(codec); 214 snd_soc_dapm_sync(dapm);
208 return 0; 215 return 0;
209} 216}
210 217
@@ -212,21 +219,25 @@ static struct snd_soc_dai_link tosa_dai[] = {
212{ 219{
213 .name = "AC97", 220 .name = "AC97",
214 .stream_name = "AC97 HiFi", 221 .stream_name = "AC97 HiFi",
215 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 222 .cpu_dai_name = "pxa2xx-ac97",
216 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 223 .codec_dai_name = "wm9712-hifi",
224 .platform_name = "pxa-pcm-audio",
225 .codec_name = "wm9712-codec",
217 .init = tosa_ac97_init, 226 .init = tosa_ac97_init,
218 .ops = &tosa_ops, 227 .ops = &tosa_ops,
219}, 228},
220{ 229{
221 .name = "AC97 Aux", 230 .name = "AC97 Aux",
222 .stream_name = "AC97 Aux", 231 .stream_name = "AC97 Aux",
223 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 232 .cpu_dai_name = "pxa2xx-ac97-aux",
224 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 233 .codec_dai_name = "wm9712-aux",
234 .platform_name = "pxa-pcm-audio",
235 .codec_name = "wm9712-codec",
225 .ops = &tosa_ops, 236 .ops = &tosa_ops,
226}, 237},
227}; 238};
228 239
229static int tosa_probe(struct platform_device *dev) 240static int tosa_probe(struct snd_soc_card *card)
230{ 241{
231 int ret; 242 int ret;
232 243
@@ -240,7 +251,7 @@ static int tosa_probe(struct platform_device *dev)
240 return ret; 251 return ret;
241} 252}
242 253
243static int tosa_remove(struct platform_device *dev) 254static int tosa_remove(struct snd_soc_card *card)
244{ 255{
245 gpio_free(TOSA_GPIO_L_MUTE); 256 gpio_free(TOSA_GPIO_L_MUTE);
246 return 0; 257 return 0;
@@ -248,18 +259,12 @@ static int tosa_remove(struct platform_device *dev)
248 259
249static struct snd_soc_card tosa = { 260static struct snd_soc_card tosa = {
250 .name = "Tosa", 261 .name = "Tosa",
251 .platform = &pxa2xx_soc_platform,
252 .dai_link = tosa_dai, 262 .dai_link = tosa_dai,
253 .num_links = ARRAY_SIZE(tosa_dai), 263 .num_links = ARRAY_SIZE(tosa_dai),
254 .probe = tosa_probe, 264 .probe = tosa_probe,
255 .remove = tosa_remove, 265 .remove = tosa_remove,
256}; 266};
257 267
258static struct snd_soc_device tosa_snd_devdata = {
259 .card = &tosa,
260 .codec_dev = &soc_codec_dev_wm9712,
261};
262
263static struct platform_device *tosa_snd_device; 268static struct platform_device *tosa_snd_device;
264 269
265static int __init tosa_init(void) 270static int __init tosa_init(void)
@@ -275,8 +280,7 @@ static int __init tosa_init(void)
275 goto err_alloc; 280 goto err_alloc;
276 } 281 }
277 282
278 platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata); 283 platform_set_drvdata(tosa_snd_device, &tosa);
279 tosa_snd_devdata.dev = &tosa_snd_device->dev;
280 ret = platform_device_add(tosa_snd_device); 284 ret = platform_device_add(tosa_snd_device);
281 285
282 if (!ret) 286 if (!ret)
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 4e4d2fa8ddc5..d69d9fc32233 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -21,7 +21,6 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/jack.h> 24#include <sound/jack.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
@@ -30,7 +29,6 @@
30#include <mach/z2.h> 29#include <mach/z2.h>
31 30
32#include "../codecs/wm8750.h" 31#include "../codecs/wm8750.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-i2s.h" 32#include "pxa2xx-i2s.h"
35 33
36static struct snd_soc_card snd_soc_z2; 34static struct snd_soc_card snd_soc_z2;
@@ -39,8 +37,8 @@ static int z2_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params) 37 struct snd_pcm_hw_params *params)
40{ 38{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 39 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 41 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 unsigned int clk = 0; 42 unsigned int clk = 0;
45 int ret = 0; 43 int ret = 0;
46 44
@@ -97,6 +95,11 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
97 .pin = "Headphone Jack", 95 .pin = "Headphone Jack",
98 .mask = SND_JACK_HEADPHONE, 96 .mask = SND_JACK_HEADPHONE,
99 }, 97 },
98 {
99 .pin = "Ext Spk",
100 .mask = SND_JACK_HEADPHONE,
101 .invert = 1
102 },
100}; 103};
101 104
102/* Headset jack detection gpios */ 105/* Headset jack detection gpios */
@@ -106,6 +109,7 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = {
106 .name = "hsdet-gpio", 109 .name = "hsdet-gpio",
107 .report = SND_JACK_HEADSET, 110 .report = SND_JACK_HEADSET,
108 .debounce_time = 200, 111 .debounce_time = 200,
112 .invert = 1,
109 }, 113 },
110}; 114};
111 115
@@ -138,29 +142,31 @@ static const struct snd_soc_dapm_route audio_map[] = {
138/* 142/*
139 * Logic for a wm8750 as connected on a Z2 Device 143 * Logic for a wm8750 as connected on a Z2 Device
140 */ 144 */
141static int z2_wm8750_init(struct snd_soc_codec *codec) 145static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
142{ 146{
147 struct snd_soc_codec *codec = rtd->codec;
148 struct snd_soc_dapm_context *dapm = &codec->dapm;
143 int ret; 149 int ret;
144 150
145 /* NC codec pins */ 151 /* NC codec pins */
146 snd_soc_dapm_disable_pin(codec, "LINPUT3"); 152 snd_soc_dapm_disable_pin(dapm, "LINPUT3");
147 snd_soc_dapm_disable_pin(codec, "RINPUT3"); 153 snd_soc_dapm_disable_pin(dapm, "RINPUT3");
148 snd_soc_dapm_disable_pin(codec, "OUT3"); 154 snd_soc_dapm_disable_pin(dapm, "OUT3");
149 snd_soc_dapm_disable_pin(codec, "MONO"); 155 snd_soc_dapm_disable_pin(dapm, "MONO1");
150 156
151 /* Add z2 specific widgets */ 157 /* Add z2 specific widgets */
152 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 158 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
153 ARRAY_SIZE(wm8750_dapm_widgets)); 159 ARRAY_SIZE(wm8750_dapm_widgets));
154 160
155 /* Set up z2 specific audio paths */ 161 /* Set up z2 specific audio paths */
156 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 162 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
157 163
158 ret = snd_soc_dapm_sync(codec); 164 ret = snd_soc_dapm_sync(dapm);
159 if (ret) 165 if (ret)
160 goto err; 166 goto err;
161 167
162 /* Jack detection API stuff */ 168 /* Jack detection API stuff */
163 ret = snd_soc_jack_new(&snd_soc_z2, "Headset Jack", SND_JACK_HEADSET, 169 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
164 &hs_jack); 170 &hs_jack);
165 if (ret) 171 if (ret)
166 goto err; 172 goto err;
@@ -189,8 +195,10 @@ static struct snd_soc_ops z2_ops = {
189static struct snd_soc_dai_link z2_dai = { 195static struct snd_soc_dai_link z2_dai = {
190 .name = "wm8750", 196 .name = "wm8750",
191 .stream_name = "WM8750", 197 .stream_name = "WM8750",
192 .cpu_dai = &pxa_i2s_dai, 198 .cpu_dai_name = "pxa2xx-i2s",
193 .codec_dai = &wm8750_dai, 199 .codec_dai_name = "wm8750-hifi",
200 .platform_name = "pxa-pcm-audio",
201 .codec_name = "wm8750-codec.0-001b",
194 .init = z2_wm8750_init, 202 .init = z2_wm8750_init,
195 .ops = &z2_ops, 203 .ops = &z2_ops,
196}; 204};
@@ -198,17 +206,10 @@ static struct snd_soc_dai_link z2_dai = {
198/* z2 audio machine driver */ 206/* z2 audio machine driver */
199static struct snd_soc_card snd_soc_z2 = { 207static struct snd_soc_card snd_soc_z2 = {
200 .name = "Z2", 208 .name = "Z2",
201 .platform = &pxa2xx_soc_platform,
202 .dai_link = &z2_dai, 209 .dai_link = &z2_dai,
203 .num_links = 1, 210 .num_links = 1,
204}; 211};
205 212
206/* z2 audio subsystem */
207static struct snd_soc_device z2_snd_devdata = {
208 .card = &snd_soc_z2,
209 .codec_dev = &soc_codec_dev_wm8750,
210};
211
212static struct platform_device *z2_snd_device; 213static struct platform_device *z2_snd_device;
213 214
214static int __init z2_init(void) 215static int __init z2_init(void)
@@ -222,8 +223,7 @@ static int __init z2_init(void)
222 if (!z2_snd_device) 223 if (!z2_snd_device)
223 return -ENOMEM; 224 return -ENOMEM;
224 225
225 platform_set_drvdata(z2_snd_device, &z2_snd_devdata); 226 platform_set_drvdata(z2_snd_device, &snd_soc_z2);
226 z2_snd_devdata.dev = &z2_snd_device->dev;
227 ret = platform_device_add(z2_snd_device); 227 ret = platform_device_add(z2_snd_device);
228 228
229 if (ret) 229 if (ret)
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index dd678ae24398..b6445757fc54 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -20,10 +20,8 @@
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24 23
25#include "../codecs/wm9713.h" 24#include "../codecs/wm9713.h"
26#include "pxa2xx-pcm.h"
27#include "pxa2xx-ac97.h" 25#include "pxa2xx-ac97.h"
28#include "pxa-ssp.h" 26#include "pxa-ssp.h"
29 27
@@ -71,22 +69,25 @@ static const struct snd_soc_dapm_route audio_map[] = {
71 { "Multiactor", NULL, "SPKR" }, 69 { "Multiactor", NULL, "SPKR" },
72}; 70};
73 71
74static int zylonite_wm9713_init(struct snd_soc_codec *codec) 72static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
75{ 73{
74 struct snd_soc_codec *codec = rtd->codec;
75 struct snd_soc_dapm_context *dapm = &codec->dapm;
76
76 if (clk_pout) 77 if (clk_pout)
77 snd_soc_dai_set_pll(&codec->dai[0], 0, 0, 78 snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
78 clk_get_rate(pout), 0); 79 clk_get_rate(pout), 0);
79 80
80 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, 81 snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets,
81 ARRAY_SIZE(zylonite_dapm_widgets)); 82 ARRAY_SIZE(zylonite_dapm_widgets));
82 83
83 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 84 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
84 85
85 /* Static setup for now */ 86 /* Static setup for now */
86 snd_soc_dapm_enable_pin(codec, "Headphone"); 87 snd_soc_dapm_enable_pin(dapm, "Headphone");
87 snd_soc_dapm_enable_pin(codec, "Headset Earpiece"); 88 snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
88 89
89 snd_soc_dapm_sync(codec); 90 snd_soc_dapm_sync(dapm);
90 return 0; 91 return 0;
91} 92}
92 93
@@ -94,8 +95,8 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
94 struct snd_pcm_hw_params *params) 95 struct snd_pcm_hw_params *params)
95{ 96{
96 struct snd_soc_pcm_runtime *rtd = substream->private_data; 97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
97 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 98 struct snd_soc_dai *codec_dai = rtd->codec_dai;
98 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 99 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
99 unsigned int pll_out = 0; 100 unsigned int pll_out = 0;
100 unsigned int wm9713_div = 0; 101 unsigned int wm9713_div = 0;
101 int ret = 0; 102 int ret = 0;
@@ -163,26 +164,32 @@ static struct snd_soc_dai_link zylonite_dai[] = {
163{ 164{
164 .name = "AC97", 165 .name = "AC97",
165 .stream_name = "AC97 HiFi", 166 .stream_name = "AC97 HiFi",
166 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 167 .codec_name = "wm9713-codec",
167 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI], 168 .platform_name = "pxa-pcm-audio",
169 .cpu_dai_name = "pxa2xx-ac97",
170 .codec_dai_name = "wm9713-hifi",
168 .init = zylonite_wm9713_init, 171 .init = zylonite_wm9713_init,
169}, 172},
170{ 173{
171 .name = "AC97 Aux", 174 .name = "AC97 Aux",
172 .stream_name = "AC97 Aux", 175 .stream_name = "AC97 Aux",
173 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 176 .codec_name = "wm9713-codec",
174 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX], 177 .platform_name = "pxa-pcm-audio",
178 .cpu_dai_name = "pxa2xx-ac97-aux",
179 .codec_dai_name = "wm9713-aux",
175}, 180},
176{ 181{
177 .name = "WM9713 Voice", 182 .name = "WM9713 Voice",
178 .stream_name = "WM9713 Voice", 183 .stream_name = "WM9713 Voice",
179 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3], 184 .codec_name = "wm9713-codec",
180 .codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE], 185 .platform_name = "pxa-pcm-audio",
186 .cpu_dai_name = "pxa-ssp-dai.2",
187 .codec_dai_name = "wm9713-voice",
181 .ops = &zylonite_voice_ops, 188 .ops = &zylonite_voice_ops,
182}, 189},
183}; 190};
184 191
185static int zylonite_probe(struct platform_device *pdev) 192static int zylonite_probe(struct snd_soc_card *card)
186{ 193{
187 int ret; 194 int ret;
188 195
@@ -209,7 +216,7 @@ static int zylonite_probe(struct platform_device *pdev)
209 return 0; 216 return 0;
210} 217}
211 218
212static int zylonite_remove(struct platform_device *pdev) 219static int zylonite_remove(struct snd_soc_card *card)
213{ 220{
214 if (clk_pout) { 221 if (clk_pout) {
215 clk_disable(pout); 222 clk_disable(pout);
@@ -219,8 +226,7 @@ static int zylonite_remove(struct platform_device *pdev)
219 return 0; 226 return 0;
220} 227}
221 228
222static int zylonite_suspend_post(struct platform_device *pdev, 229static int zylonite_suspend_post(struct snd_soc_card *card)
223 pm_message_t state)
224{ 230{
225 if (clk_pout) 231 if (clk_pout)
226 clk_disable(pout); 232 clk_disable(pout);
@@ -228,7 +234,7 @@ static int zylonite_suspend_post(struct platform_device *pdev,
228 return 0; 234 return 0;
229} 235}
230 236
231static int zylonite_resume_pre(struct platform_device *pdev) 237static int zylonite_resume_pre(struct snd_soc_card *card)
232{ 238{
233 int ret = 0; 239 int ret = 0;
234 240
@@ -248,14 +254,9 @@ static struct snd_soc_card zylonite = {
248 .remove = &zylonite_remove, 254 .remove = &zylonite_remove,
249 .suspend_post = &zylonite_suspend_post, 255 .suspend_post = &zylonite_suspend_post,
250 .resume_pre = &zylonite_resume_pre, 256 .resume_pre = &zylonite_resume_pre,
251 .platform = &pxa2xx_soc_platform,
252 .dai_link = zylonite_dai, 257 .dai_link = zylonite_dai,
253 .num_links = ARRAY_SIZE(zylonite_dai), 258 .num_links = ARRAY_SIZE(zylonite_dai),
254}; 259 .owner = THIS_MODULE,
255
256static struct snd_soc_device zylonite_snd_ac97_devdata = {
257 .card = &zylonite,
258 .codec_dev = &soc_codec_dev_wm9713,
259}; 260};
260 261
261static struct platform_device *zylonite_snd_ac97_device; 262static struct platform_device *zylonite_snd_ac97_device;
@@ -268,9 +269,7 @@ static int __init zylonite_init(void)
268 if (!zylonite_snd_ac97_device) 269 if (!zylonite_snd_ac97_device)
269 return -ENOMEM; 270 return -ENOMEM;
270 271
271 platform_set_drvdata(zylonite_snd_ac97_device, 272 platform_set_drvdata(zylonite_snd_ac97_device, &zylonite);
272 &zylonite_snd_ac97_devdata);
273 zylonite_snd_ac97_devdata.dev = &zylonite_snd_ac97_device->dev;
274 273
275 ret = platform_device_add(zylonite_snd_ac97_device); 274 ret = platform_device_add(zylonite_snd_ac97_device);
276 if (ret != 0) 275 if (ret != 0)