aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r--sound/soc/pxa/Kconfig20
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/corgi.c36
-rw-r--r--sound/soc/pxa/em-x270.c9
-rw-r--r--sound/soc/pxa/imote2.c114
-rw-r--r--sound/soc/pxa/magician.c71
-rw-r--r--sound/soc/pxa/palm27x.c206
-rw-r--r--sound/soc/pxa/poodle.c36
-rw-r--r--sound/soc/pxa/pxa-ssp.c275
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c12
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c46
11 files changed, 367 insertions, 460 deletions
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index ad8a10fe6298..6375b4ea525d 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -89,22 +89,23 @@ config SND_PXA2XX_SOC_E800
89 Toshiba e800 PDA 89 Toshiba e800 PDA
90 90
91config SND_PXA2XX_SOC_EM_X270 91config SND_PXA2XX_SOC_EM_X270
92 tristate "SoC Audio support for CompuLab EM-x270" 92 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300"
93 depends on SND_PXA2XX_SOC && MACH_EM_X270 93 depends on SND_PXA2XX_SOC && MACH_EM_X270
94 select SND_PXA2XX_SOC_AC97 94 select SND_PXA2XX_SOC_AC97
95 select SND_SOC_WM9712 95 select SND_SOC_WM9712
96 help 96 help
97 Say Y if you want to add support for SoC audio on 97 Say Y if you want to add support for SoC audio on
98 CompuLab EM-x270. 98 CompuLab EM-x270, eXeda and CM-X300 machines.
99 99
100config SND_PXA2XX_SOC_PALM27X 100config SND_PXA2XX_SOC_PALM27X
101 bool "SoC Audio support for Palm T|X, T5 and LifeDrive" 101 bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive"
102 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || MACH_PALMT5) 102 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \
103 MACH_PALMT5 || MACH_PALMTE2)
103 select SND_PXA2XX_SOC_AC97 104 select SND_PXA2XX_SOC_AC97
104 select SND_SOC_WM9712 105 select SND_SOC_WM9712
105 help 106 help
106 Say Y if you want to add support for SoC audio on 107 Say Y if you want to add support for SoC audio on
107 Palm T|X, T5 or LifeDrive handheld computer. 108 Palm T|X, T5, E2 or LifeDrive handheld computer.
108 109
109config SND_SOC_ZYLONITE 110config SND_SOC_ZYLONITE
110 tristate "SoC Audio support for Marvell Zylonite" 111 tristate "SoC Audio support for Marvell Zylonite"
@@ -134,3 +135,12 @@ config SND_PXA2XX_SOC_MIOA701
134 help 135 help
135 Say Y if you want to add support for SoC audio on the 136 Say Y if you want to add support for SoC audio on the
136 MIO A701. 137 MIO A701.
138
139config SND_PXA2XX_SOC_IMOTE2
140 tristate "SoC Audio support for IMote 2"
141 depends on SND_PXA2XX_SOC && MACH_INTELMOTE2
142 select SND_PXA2XX_SOC_I2S
143 select SND_SOC_WM8940
144 help
145 Say Y if you want to add support for SoC audio on the
146 IMote 2.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 4b90c3ccae45..6e096b480335 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
22snd-soc-zylonite-objs := zylonite.o 22snd-soc-zylonite-objs := zylonite.o
23snd-soc-magician-objs := magician.o 23snd-soc-magician-objs := magician.o
24snd-soc-mioa701-objs := mioa701_wm9713.o 24snd-soc-mioa701-objs := mioa701_wm9713.o
25snd-soc-imote2-objs := imote2.o
25 26
26obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 27obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
27obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 28obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
35obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 36obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
36obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 37obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
37obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 38obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
39obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index d5be2b30cda5..fefe1a57f31a 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -320,38 +320,6 @@ static struct snd_soc_device corgi_snd_devdata = {
320 .codec_dev = &soc_codec_dev_wm8731, 320 .codec_dev = &soc_codec_dev_wm8731,
321}; 321};
322 322
323/*
324 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
325 * New drivers should register the wm8731 I2C device in the machine
326 * setup code (under arch/arm for ARM systems).
327 */
328static int wm8731_i2c_register(void)
329{
330 struct i2c_board_info info;
331 struct i2c_adapter *adapter;
332 struct i2c_client *client;
333
334 memset(&info, 0, sizeof(struct i2c_board_info));
335 info.addr = 0x1b;
336 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
337
338 adapter = i2c_get_adapter(0);
339 if (!adapter) {
340 printk(KERN_ERR "can't get i2c adapter 0\n");
341 return -ENODEV;
342 }
343
344 client = i2c_new_device(adapter, &info);
345 i2c_put_adapter(adapter);
346 if (!client) {
347 printk(KERN_ERR "can't add i2c device at 0x%x\n",
348 (unsigned int)info.addr);
349 return -ENODEV;
350 }
351
352 return 0;
353}
354
355static struct platform_device *corgi_snd_device; 323static struct platform_device *corgi_snd_device;
356 324
357static int __init corgi_init(void) 325static int __init corgi_init(void)
@@ -362,10 +330,6 @@ static int __init corgi_init(void)
362 machine_is_husky())) 330 machine_is_husky()))
363 return -ENODEV; 331 return -ENODEV;
364 332
365 ret = wm8731_i2c_register();
366 if (ret != 0)
367 return ret;
368
369 corgi_snd_device = platform_device_alloc("soc-audio", -1); 333 corgi_snd_device = platform_device_alloc("soc-audio", -1);
370 if (!corgi_snd_device) 334 if (!corgi_snd_device)
371 return -ENOMEM; 335 return -ENOMEM;
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index 949be9c2a01b..f4756e4025fd 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * em-x270.c -- SoC audio for EM-X270 2 * SoC audio driver for EM-X270, eXeda and CM-X300
3 * 3 *
4 * Copyright 2007 CompuLab, Ltd. 4 * Copyright 2007, 2009 CompuLab, Ltd.
5 * 5 *
6 * Author: Mike Rapoport <mike@compulab.co.il> 6 * Author: Mike Rapoport <mike@compulab.co.il>
7 * 7 *
@@ -68,7 +68,8 @@ static int __init em_x270_init(void)
68{ 68{
69 int ret; 69 int ret;
70 70
71 if (!machine_is_em_x270()) 71 if (!(machine_is_em_x270() || machine_is_exeda()
72 || machine_is_cm_x300()))
72 return -ENODEV; 73 return -ENODEV;
73 74
74 em_x270_snd_device = platform_device_alloc("soc-audio", -1); 75 em_x270_snd_device = platform_device_alloc("soc-audio", -1);
@@ -95,5 +96,5 @@ module_exit(em_x270_exit);
95 96
96/* Module information */ 97/* Module information */
97MODULE_AUTHOR("Mike Rapoport"); 98MODULE_AUTHOR("Mike Rapoport");
98MODULE_DESCRIPTION("ALSA SoC EM-X270"); 99MODULE_DESCRIPTION("ALSA SoC EM-X270, eXeda and CM-X300");
99MODULE_LICENSE("GPL"); 100MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
new file mode 100644
index 000000000000..405587a01160
--- /dev/null
+++ b/sound/soc/pxa/imote2.c
@@ -0,0 +1,114 @@
1
2#include <linux/module.h>
3#include <sound/soc.h>
4
5#include <asm/mach-types.h>
6
7#include "../codecs/wm8940.h"
8#include "pxa2xx-i2s.h"
9#include "pxa2xx-pcm.h"
10
11static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
12 struct snd_pcm_hw_params *params)
13{
14 struct snd_soc_pcm_runtime *rtd = substream->private_data;
15 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
16 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
17 unsigned int clk = 0;
18 int ret;
19
20 switch (params_rate(params)) {
21 case 8000:
22 case 16000:
23 case 48000:
24 case 96000:
25 clk = 12288000;
26 break;
27 case 11025:
28 case 22050:
29 case 44100:
30 clk = 11289600;
31 break;
32 }
33
34 /* set codec DAI configuration */
35 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
36 | SND_SOC_DAIFMT_NB_NF
37 | SND_SOC_DAIFMT_CBS_CFS);
38 if (ret < 0)
39 return ret;
40
41 /* CPU should be clock master */
42 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
43 | SND_SOC_DAIFMT_NB_NF
44 | SND_SOC_DAIFMT_CBS_CFS);
45 if (ret < 0)
46 return ret;
47
48 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
49 SND_SOC_CLOCK_IN);
50 if (ret < 0)
51 return ret;
52
53 /* set the I2S system clock as input (unused) */
54 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, clk,
55 SND_SOC_CLOCK_OUT);
56
57 return ret;
58}
59
60static struct snd_soc_ops imote2_asoc_ops = {
61 .hw_params = imote2_asoc_hw_params,
62};
63
64static struct snd_soc_dai_link imote2_dai = {
65 .name = "WM8940",
66 .stream_name = "WM8940",
67 .cpu_dai = &pxa_i2s_dai,
68 .codec_dai = &wm8940_dai,
69 .ops = &imote2_asoc_ops,
70};
71
72static struct snd_soc_card snd_soc_imote2 = {
73 .name = "Imote2",
74 .platform = &pxa2xx_soc_platform,
75 .dai_link = &imote2_dai,
76 .num_links = 1,
77};
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;
85
86static int __init imote2_asoc_init(void)
87{
88 int ret;
89
90 if (!machine_is_intelmote2())
91 return -ENODEV;
92 imote2_snd_device = platform_device_alloc("soc-audio", -1);
93 if (!imote2_snd_device)
94 return -ENOMEM;
95
96 platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata);
97 imote2_snd_devdata.dev = &imote2_snd_device->dev;
98 ret = platform_device_add(imote2_snd_device);
99 if (ret)
100 platform_device_put(imote2_snd_device);
101
102 return ret;
103}
104module_init(imote2_asoc_init);
105
106static void __exit imote2_asoc_exit(void)
107{
108 platform_device_unregister(imote2_snd_device);
109}
110module_exit(imote2_asoc_exit);
111
112MODULE_AUTHOR("Jonathan Cameron");
113MODULE_DESCRIPTION("ALSA SoC Imote 2");
114MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 0625c342a1c9..9f7c61e23daf 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -20,12 +20,14 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/i2c.h>
23 24
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
27#include <sound/soc.h> 28#include <sound/soc.h>
28#include <sound/soc-dapm.h> 29#include <sound/soc-dapm.h>
30#include <sound/uda1380.h>
29 31
30#include <mach/magician.h> 32#include <mach/magician.h>
31#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -106,7 +108,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
106 /* 513156 Hz ~= _2_ * 8000 Hz * 32 (+0.23%) */ 108 /* 513156 Hz ~= _2_ * 8000 Hz * 32 (+0.23%) */
107 acds = PXA_SSP_CLK_AUDIO_DIV_16; 109 acds = PXA_SSP_CLK_AUDIO_DIV_16;
108 break; 110 break;
109 case 32: 111 default: /* 32 */
110 /* 1026312 Hz ~= _2_ * 8000 Hz * 64 (+0.23%) */ 112 /* 1026312 Hz ~= _2_ * 8000 Hz * 64 (+0.23%) */
111 acds = PXA_SSP_CLK_AUDIO_DIV_8; 113 acds = PXA_SSP_CLK_AUDIO_DIV_8;
112 } 114 }
@@ -118,7 +120,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
118 /* 351375 Hz ~= 11025 Hz * 32 (-0.41%) */ 120 /* 351375 Hz ~= 11025 Hz * 32 (-0.41%) */
119 acds = PXA_SSP_CLK_AUDIO_DIV_4; 121 acds = PXA_SSP_CLK_AUDIO_DIV_4;
120 break; 122 break;
121 case 32: 123 default: /* 32 */
122 /* 702750 Hz ~= 11025 Hz * 64 (-0.41%) */ 124 /* 702750 Hz ~= 11025 Hz * 64 (-0.41%) */
123 acds = PXA_SSP_CLK_AUDIO_DIV_2; 125 acds = PXA_SSP_CLK_AUDIO_DIV_2;
124 } 126 }
@@ -130,7 +132,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
130 /* 702750 Hz ~= 22050 Hz * 32 (-0.41%) */ 132 /* 702750 Hz ~= 22050 Hz * 32 (-0.41%) */
131 acds = PXA_SSP_CLK_AUDIO_DIV_2; 133 acds = PXA_SSP_CLK_AUDIO_DIV_2;
132 break; 134 break;
133 case 32: 135 default: /* 32 */
134 /* 1405500 Hz ~= 22050 Hz * 64 (-0.41%) */ 136 /* 1405500 Hz ~= 22050 Hz * 64 (-0.41%) */
135 acds = PXA_SSP_CLK_AUDIO_DIV_1; 137 acds = PXA_SSP_CLK_AUDIO_DIV_1;
136 } 138 }
@@ -142,7 +144,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
142 /* 1405500 Hz ~= 44100 Hz * 32 (-0.41%) */ 144 /* 1405500 Hz ~= 44100 Hz * 32 (-0.41%) */
143 acds = PXA_SSP_CLK_AUDIO_DIV_2; 145 acds = PXA_SSP_CLK_AUDIO_DIV_2;
144 break; 146 break;
145 case 32: 147 default: /* 32 */
146 /* 2811000 Hz ~= 44100 Hz * 64 (-0.41%) */ 148 /* 2811000 Hz ~= 44100 Hz * 64 (-0.41%) */
147 acds = PXA_SSP_CLK_AUDIO_DIV_1; 149 acds = PXA_SSP_CLK_AUDIO_DIV_1;
148 } 150 }
@@ -154,19 +156,20 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
154 /* 1529375 Hz ~= 48000 Hz * 32 (-0.44%) */ 156 /* 1529375 Hz ~= 48000 Hz * 32 (-0.44%) */
155 acds = PXA_SSP_CLK_AUDIO_DIV_2; 157 acds = PXA_SSP_CLK_AUDIO_DIV_2;
156 break; 158 break;
157 case 32: 159 default: /* 32 */
158 /* 3058750 Hz ~= 48000 Hz * 64 (-0.44%) */ 160 /* 3058750 Hz ~= 48000 Hz * 64 (-0.44%) */
159 acds = PXA_SSP_CLK_AUDIO_DIV_1; 161 acds = PXA_SSP_CLK_AUDIO_DIV_1;
160 } 162 }
161 break; 163 break;
162 case 96000: 164 case 96000:
165 default:
163 acps = 12235000; 166 acps = 12235000;
164 switch (width) { 167 switch (width) {
165 case 16: 168 case 16:
166 /* 3058750 Hz ~= 96000 Hz * 32 (-0.44%) */ 169 /* 3058750 Hz ~= 96000 Hz * 32 (-0.44%) */
167 acds = PXA_SSP_CLK_AUDIO_DIV_1; 170 acds = PXA_SSP_CLK_AUDIO_DIV_1;
168 break; 171 break;
169 case 32: 172 default: /* 32 */
170 /* 6117500 Hz ~= 96000 Hz * 64 (-0.44%) */ 173 /* 6117500 Hz ~= 96000 Hz * 64 (-0.44%) */
171 acds = PXA_SSP_CLK_AUDIO_DIV_2; 174 acds = PXA_SSP_CLK_AUDIO_DIV_2;
172 div4 = PXA_SSP_CLK_SCDB_1; 175 div4 = PXA_SSP_CLK_SCDB_1;
@@ -183,11 +186,11 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
183 186
184 /* set cpu DAI configuration */ 187 /* set cpu DAI configuration */
185 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 188 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
186 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBS_CFS); 189 SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBS_CFS);
187 if (ret < 0) 190 if (ret < 0)
188 return ret; 191 return ret;
189 192
190 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 1); 193 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 0, 1, width);
191 if (ret < 0) 194 if (ret < 0)
192 return ret; 195 return ret;
193 196
@@ -446,34 +449,47 @@ static struct snd_soc_card snd_soc_card_magician = {
446 .platform = &pxa2xx_soc_platform, 449 .platform = &pxa2xx_soc_platform,
447}; 450};
448 451
449/* magician audio private data */
450static struct uda1380_setup_data magician_uda1380_setup = {
451 .i2c_address = 0x18,
452 .dac_clk = UDA1380_DAC_CLK_WSPLL,
453};
454
455/* magician audio subsystem */ 452/* magician audio subsystem */
456static struct snd_soc_device magician_snd_devdata = { 453static struct snd_soc_device magician_snd_devdata = {
457 .card = &snd_soc_card_magician, 454 .card = &snd_soc_card_magician,
458 .codec_dev = &soc_codec_dev_uda1380, 455 .codec_dev = &soc_codec_dev_uda1380,
459 .codec_data = &magician_uda1380_setup,
460}; 456};
461 457
462static struct platform_device *magician_snd_device; 458static struct platform_device *magician_snd_device;
463 459
460/*
461 * FIXME: move into magician board file once merged into the pxa tree
462 */
463static struct uda1380_platform_data uda1380_info = {
464 .gpio_power = EGPIO_MAGICIAN_CODEC_POWER,
465 .gpio_reset = EGPIO_MAGICIAN_CODEC_RESET,
466 .dac_clk = UDA1380_DAC_CLK_WSPLL,
467};
468
469static struct i2c_board_info i2c_board_info[] = {
470 {
471 I2C_BOARD_INFO("uda1380", 0x18),
472 .platform_data = &uda1380_info,
473 },
474};
475
464static int __init magician_init(void) 476static int __init magician_init(void)
465{ 477{
466 int ret; 478 int ret;
479 struct i2c_adapter *adapter;
480 struct i2c_client *client;
467 481
468 if (!machine_is_magician()) 482 if (!machine_is_magician())
469 return -ENODEV; 483 return -ENODEV;
470 484
471 ret = gpio_request(EGPIO_MAGICIAN_CODEC_POWER, "CODEC_POWER"); 485 adapter = i2c_get_adapter(0);
472 if (ret) 486 if (!adapter)
473 goto err_request_power; 487 return -ENODEV;
474 ret = gpio_request(EGPIO_MAGICIAN_CODEC_RESET, "CODEC_RESET"); 488 client = i2c_new_device(adapter, i2c_board_info);
475 if (ret) 489 i2c_put_adapter(adapter);
476 goto err_request_reset; 490 if (!client)
491 return -ENODEV;
492
477 ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER"); 493 ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER");
478 if (ret) 494 if (ret)
479 goto err_request_spk; 495 goto err_request_spk;
@@ -490,14 +506,8 @@ static int __init magician_init(void)
490 if (ret) 506 if (ret)
491 goto err_request_in_sel1; 507 goto err_request_in_sel1;
492 508
493 gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 1);
494 gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0); 509 gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0);
495 510
496 /* we may need to have the clock running here - pH5 */
497 gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 1);
498 udelay(5);
499 gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 0);
500
501 magician_snd_device = platform_device_alloc("soc-audio", -1); 511 magician_snd_device = platform_device_alloc("soc-audio", -1);
502 if (!magician_snd_device) { 512 if (!magician_snd_device) {
503 ret = -ENOMEM; 513 ret = -ENOMEM;
@@ -525,10 +535,6 @@ err_request_mic:
525err_request_ep: 535err_request_ep:
526 gpio_free(EGPIO_MAGICIAN_SPK_POWER); 536 gpio_free(EGPIO_MAGICIAN_SPK_POWER);
527err_request_spk: 537err_request_spk:
528 gpio_free(EGPIO_MAGICIAN_CODEC_RESET);
529err_request_reset:
530 gpio_free(EGPIO_MAGICIAN_CODEC_POWER);
531err_request_power:
532 return ret; 538 return ret;
533} 539}
534 540
@@ -539,15 +545,12 @@ static void __exit magician_exit(void)
539 gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0); 545 gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0);
540 gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0); 546 gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0);
541 gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0); 547 gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0);
542 gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 0);
543 548
544 gpio_free(EGPIO_MAGICIAN_IN_SEL1); 549 gpio_free(EGPIO_MAGICIAN_IN_SEL1);
545 gpio_free(EGPIO_MAGICIAN_IN_SEL0); 550 gpio_free(EGPIO_MAGICIAN_IN_SEL0);
546 gpio_free(EGPIO_MAGICIAN_MIC_POWER); 551 gpio_free(EGPIO_MAGICIAN_MIC_POWER);
547 gpio_free(EGPIO_MAGICIAN_EP_POWER); 552 gpio_free(EGPIO_MAGICIAN_EP_POWER);
548 gpio_free(EGPIO_MAGICIAN_SPK_POWER); 553 gpio_free(EGPIO_MAGICIAN_SPK_POWER);
549 gpio_free(EGPIO_MAGICIAN_CODEC_RESET);
550 gpio_free(EGPIO_MAGICIAN_CODEC_POWER);
551} 554}
552 555
553module_init(magician_init); 556module_init(magician_init);
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 44fcc4e01e08..1f96e3227be5 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -17,13 +17,12 @@
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22 20
23#include <sound/core.h> 21#include <sound/core.h>
24#include <sound/pcm.h> 22#include <sound/pcm.h>
25#include <sound/soc.h> 23#include <sound/soc.h>
26#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25#include <sound/jack.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <mach/audio.h> 28#include <mach/audio.h>
@@ -33,90 +32,31 @@
33#include "pxa2xx-pcm.h" 32#include "pxa2xx-pcm.h"
34#include "pxa2xx-ac97.h" 33#include "pxa2xx-ac97.h"
35 34
36static int palm27x_jack_func = 1; 35static struct snd_soc_jack hs_jack;
37static int palm27x_spk_func = 1;
38static int palm27x_ep_gpio = -1;
39 36
40static void palm27x_ext_control(struct snd_soc_codec *codec) 37/* Headphones jack detection DAPM pins */
41{ 38static struct snd_soc_jack_pin hs_jack_pins[] = {
42 if (!palm27x_spk_func) 39 {
43 snd_soc_dapm_enable_pin(codec, "Speaker"); 40 .pin = "Headphone Jack",
44 else 41 .mask = SND_JACK_HEADPHONE,
45 snd_soc_dapm_disable_pin(codec, "Speaker"); 42 },
46
47 if (!palm27x_jack_func)
48 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
49 else
50 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
51
52 snd_soc_dapm_sync(codec);
53}
54
55static int palm27x_startup(struct snd_pcm_substream *substream)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_codec *codec = rtd->socdev->card->codec;
59
60 /* check the jack status at stream startup */
61 palm27x_ext_control(codec);
62 return 0;
63}
64
65static struct snd_soc_ops palm27x_ops = {
66 .startup = palm27x_startup,
67}; 43};
68 44
69static irqreturn_t palm27x_interrupt(int irq, void *v) 45/* Headphones jack detection gpios */
70{ 46static struct snd_soc_jack_gpio hs_jack_gpios[] = {
71 palm27x_spk_func = gpio_get_value(palm27x_ep_gpio); 47 [0] = {
72 palm27x_jack_func = !palm27x_spk_func; 48 /* gpio is set on per-platform basis */
73 return IRQ_HANDLED; 49 .name = "hp-gpio",
74} 50 .report = SND_JACK_HEADPHONE,
75 51 .debounce_time = 200,
76static int palm27x_get_jack(struct snd_kcontrol *kcontrol, 52 },
77 struct snd_ctl_elem_value *ucontrol) 53};
78{
79 ucontrol->value.integer.value[0] = palm27x_jack_func;
80 return 0;
81}
82
83static int palm27x_set_jack(struct snd_kcontrol *kcontrol,
84 struct snd_ctl_elem_value *ucontrol)
85{
86 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
87
88 if (palm27x_jack_func == ucontrol->value.integer.value[0])
89 return 0;
90
91 palm27x_jack_func = ucontrol->value.integer.value[0];
92 palm27x_ext_control(codec);
93 return 1;
94}
95
96static int palm27x_get_spk(struct snd_kcontrol *kcontrol,
97 struct snd_ctl_elem_value *ucontrol)
98{
99 ucontrol->value.integer.value[0] = palm27x_spk_func;
100 return 0;
101}
102
103static int palm27x_set_spk(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_value *ucontrol)
105{
106 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
107
108 if (palm27x_spk_func == ucontrol->value.integer.value[0])
109 return 0;
110
111 palm27x_spk_func = ucontrol->value.integer.value[0];
112 palm27x_ext_control(codec);
113 return 1;
114}
115 54
116/* PalmTX machine dapm widgets */ 55/* Palm27x machine dapm widgets */
117static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = { 56static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", NULL), 57 SND_SOC_DAPM_HP("Headphone Jack", NULL),
119 SND_SOC_DAPM_SPK("Speaker", NULL), 58 SND_SOC_DAPM_SPK("Ext. Speaker", NULL),
59 SND_SOC_DAPM_MIC("Ext. Microphone", NULL),
120}; 60};
121 61
122/* PalmTX audio map */ 62/* PalmTX audio map */
@@ -126,46 +66,66 @@ static const struct snd_soc_dapm_route audio_map[] = {
126 {"Headphone Jack", NULL, "HPOUTR"}, 66 {"Headphone Jack", NULL, "HPOUTR"},
127 67
128 /* ext speaker connected to ROUT2, LOUT2 */ 68 /* ext speaker connected to ROUT2, LOUT2 */
129 {"Speaker", NULL, "LOUT2"}, 69 {"Ext. Speaker", NULL, "LOUT2"},
130 {"Speaker", NULL, "ROUT2"}, 70 {"Ext. Speaker", NULL, "ROUT2"},
131};
132 71
133static const char *jack_function[] = {"Headphone", "Off"}; 72 /* mic connected to MIC1 */
134static const char *spk_function[] = {"On", "Off"}; 73 {"Ext. Microphone", NULL, "MIC1"},
135static const struct soc_enum palm27x_enum[] = {
136 SOC_ENUM_SINGLE_EXT(2, jack_function),
137 SOC_ENUM_SINGLE_EXT(2, spk_function),
138}; 74};
139 75
140static const struct snd_kcontrol_new palm27x_controls[] = { 76static struct snd_soc_card palm27x_asoc;
141 SOC_ENUM_EXT("Jack Function", palm27x_enum[0], palm27x_get_jack,
142 palm27x_set_jack),
143 SOC_ENUM_EXT("Speaker Function", palm27x_enum[1], palm27x_get_spk,
144 palm27x_set_spk),
145};
146 77
147static int palm27x_ac97_init(struct snd_soc_codec *codec) 78static int palm27x_ac97_init(struct snd_soc_codec *codec)
148{ 79{
149 int err; 80 int err;
150 81
82 /* add palm27x specific widgets */
83 err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
84 ARRAY_SIZE(palm27x_dapm_widgets));
85 if (err)
86 return err;
87
88 /* set up palm27x specific audio path audio_map */
89 err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
90 if (err)
91 return err;
92
93 /* connected pins */
94 if (machine_is_palmld())
95 snd_soc_dapm_enable_pin(codec, "MIC1");
96 snd_soc_dapm_enable_pin(codec, "HPOUTL");
97 snd_soc_dapm_enable_pin(codec, "HPOUTR");
98 snd_soc_dapm_enable_pin(codec, "LOUT2");
99 snd_soc_dapm_enable_pin(codec, "ROUT2");
100
101 /* not connected pins */
151 snd_soc_dapm_nc_pin(codec, "OUT3"); 102 snd_soc_dapm_nc_pin(codec, "OUT3");
152 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 103 snd_soc_dapm_nc_pin(codec, "MONOOUT");
104 snd_soc_dapm_nc_pin(codec, "LINEINL");
105 snd_soc_dapm_nc_pin(codec, "LINEINR");
106 snd_soc_dapm_nc_pin(codec, "PCBEEP");
107 snd_soc_dapm_nc_pin(codec, "PHONE");
108 snd_soc_dapm_nc_pin(codec, "MIC2");
109
110 err = snd_soc_dapm_sync(codec);
111 if (err)
112 return err;
153 113
154 /* add palm27x specific controls */ 114 /* Jack detection API stuff */
155 err = snd_soc_add_controls(codec, palm27x_controls, 115 err = snd_soc_jack_new(&palm27x_asoc, "Headphone Jack",
156 ARRAY_SIZE(palm27x_controls)); 116 SND_JACK_HEADPHONE, &hs_jack);
157 if (err < 0) 117 if (err)
158 return err; 118 return err;
159 119
160 /* add palm27x specific widgets */ 120 err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
161 snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, 121 hs_jack_pins);
162 ARRAY_SIZE(palm27x_dapm_widgets)); 122 if (err)
123 return err;
163 124
164 /* set up palm27x specific audio path audio_map */ 125 err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
165 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 126 hs_jack_gpios);
166 127
167 snd_soc_dapm_sync(codec); 128 return err;
168 return 0;
169} 129}
170 130
171static struct snd_soc_dai_link palm27x_dai[] = { 131static struct snd_soc_dai_link palm27x_dai[] = {
@@ -175,14 +135,12 @@ static struct snd_soc_dai_link palm27x_dai[] = {
175 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 135 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
176 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 136 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
177 .init = palm27x_ac97_init, 137 .init = palm27x_ac97_init,
178 .ops = &palm27x_ops,
179}, 138},
180{ 139{
181 .name = "AC97 Aux", 140 .name = "AC97 Aux",
182 .stream_name = "AC97 Aux", 141 .stream_name = "AC97 Aux",
183 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 142 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
184 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 143 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
185 .ops = &palm27x_ops,
186}, 144},
187}; 145};
188 146
@@ -205,30 +163,20 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
205 int ret; 163 int ret;
206 164
207 if (!(machine_is_palmtx() || machine_is_palmt5() || 165 if (!(machine_is_palmtx() || machine_is_palmt5() ||
208 machine_is_palmld())) 166 machine_is_palmld() || machine_is_palmte2()))
209 return -ENODEV; 167 return -ENODEV;
210 168
211 if (pdev->dev.platform_data) 169 if (!pdev->dev.platform_data) {
212 palm27x_ep_gpio = ((struct palm27x_asoc_info *) 170 dev_err(&pdev->dev, "please supply platform_data\n");
213 (pdev->dev.platform_data))->jack_gpio; 171 return -ENODEV;
214 172 }
215 ret = gpio_request(palm27x_ep_gpio, "Headphone Jack");
216 if (ret)
217 return ret;
218 ret = gpio_direction_input(palm27x_ep_gpio);
219 if (ret)
220 goto err_alloc;
221 173
222 if (request_irq(gpio_to_irq(palm27x_ep_gpio), palm27x_interrupt, 174 hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *)
223 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 175 (pdev->dev.platform_data))->jack_gpio;
224 "Headphone jack", NULL))
225 goto err_alloc;
226 176
227 palm27x_snd_device = platform_device_alloc("soc-audio", -1); 177 palm27x_snd_device = platform_device_alloc("soc-audio", -1);
228 if (!palm27x_snd_device) { 178 if (!palm27x_snd_device)
229 ret = -ENOMEM; 179 return -ENOMEM;
230 goto err_dev;
231 }
232 180
233 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata); 181 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);
234 palm27x_snd_devdata.dev = &palm27x_snd_device->dev; 182 palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
@@ -241,18 +189,12 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
241 189
242put_device: 190put_device:
243 platform_device_put(palm27x_snd_device); 191 platform_device_put(palm27x_snd_device);
244err_dev:
245 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
246err_alloc:
247 gpio_free(palm27x_ep_gpio);
248 192
249 return ret; 193 return ret;
250} 194}
251 195
252static int __devexit palm27x_asoc_remove(struct platform_device *pdev) 196static int __devexit palm27x_asoc_remove(struct platform_device *pdev)
253{ 197{
254 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
255 gpio_free(palm27x_ep_gpio);
256 platform_device_unregister(palm27x_snd_device); 198 platform_device_unregister(palm27x_snd_device);
257 return 0; 199 return 0;
258} 200}
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a51058f66747..c5f36e0eab58 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -280,38 +280,6 @@ static struct snd_soc_card snd_soc_poodle = {
280 .num_links = 1, 280 .num_links = 1,
281}; 281};
282 282
283/*
284 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
285 * New drivers should register the wm8731 I2C device in the machine
286 * setup code (under arch/arm for ARM systems).
287 */
288static int wm8731_i2c_register(void)
289{
290 struct i2c_board_info info;
291 struct i2c_adapter *adapter;
292 struct i2c_client *client;
293
294 memset(&info, 0, sizeof(struct i2c_board_info));
295 info.addr = 0x1b;
296 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
297
298 adapter = i2c_get_adapter(0);
299 if (!adapter) {
300 printk(KERN_ERR "can't get i2c adapter 0\n");
301 return -ENODEV;
302 }
303
304 client = i2c_new_device(adapter, &info);
305 i2c_put_adapter(adapter);
306 if (!client) {
307 printk(KERN_ERR "can't add i2c device at 0x%x\n",
308 (unsigned int)info.addr);
309 return -ENODEV;
310 }
311
312 return 0;
313}
314
315/* poodle audio subsystem */ 283/* poodle audio subsystem */
316static struct snd_soc_device poodle_snd_devdata = { 284static struct snd_soc_device poodle_snd_devdata = {
317 .card = &snd_soc_poodle, 285 .card = &snd_soc_poodle,
@@ -327,10 +295,6 @@ static int __init poodle_init(void)
327 if (!machine_is_poodle()) 295 if (!machine_is_poodle())
328 return -ENODEV; 296 return -ENODEV;
329 297
330 ret = wm8731_i2c_register();
331 if (ret != 0)
332 return ret;
333
334 locomo_gpio_set_dir(&poodle_locomo_device.dev, 298 locomo_gpio_set_dir(&poodle_locomo_device.dev,
335 POODLE_LOCOMO_GPIO_AMP_ON, 0); 299 POODLE_LOCOMO_GPIO_AMP_ON, 0);
336 /* should we mute HP at startup - burning power ?*/ 300 /* should we mute HP at startup - burning power ?*/
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 286be31545df..5b9ed6464789 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -50,139 +50,6 @@ struct ssp_priv {
50#endif 50#endif
51}; 51};
52 52
53#define PXA2xx_SSP1_BASE 0x41000000
54#define PXA27x_SSP2_BASE 0x41700000
55#define PXA27x_SSP3_BASE 0x41900000
56#define PXA3xx_SSP4_BASE 0x41a00000
57
58static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_out = {
59 .name = "SSP1 PCM Mono out",
60 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
61 .drcmr = &DRCMR(14),
62 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
63 DCMD_BURST16 | DCMD_WIDTH2,
64};
65
66static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_in = {
67 .name = "SSP1 PCM Mono in",
68 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
69 .drcmr = &DRCMR(13),
70 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
71 DCMD_BURST16 | DCMD_WIDTH2,
72};
73
74static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_out = {
75 .name = "SSP1 PCM Stereo out",
76 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
77 .drcmr = &DRCMR(14),
78 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
79 DCMD_BURST16 | DCMD_WIDTH4,
80};
81
82static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_in = {
83 .name = "SSP1 PCM Stereo in",
84 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
85 .drcmr = &DRCMR(13),
86 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
87 DCMD_BURST16 | DCMD_WIDTH4,
88};
89
90static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_out = {
91 .name = "SSP2 PCM Mono out",
92 .dev_addr = PXA27x_SSP2_BASE + SSDR,
93 .drcmr = &DRCMR(16),
94 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
95 DCMD_BURST16 | DCMD_WIDTH2,
96};
97
98static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_in = {
99 .name = "SSP2 PCM Mono in",
100 .dev_addr = PXA27x_SSP2_BASE + SSDR,
101 .drcmr = &DRCMR(15),
102 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
103 DCMD_BURST16 | DCMD_WIDTH2,
104};
105
106static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_out = {
107 .name = "SSP2 PCM Stereo out",
108 .dev_addr = PXA27x_SSP2_BASE + SSDR,
109 .drcmr = &DRCMR(16),
110 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
111 DCMD_BURST16 | DCMD_WIDTH4,
112};
113
114static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_in = {
115 .name = "SSP2 PCM Stereo in",
116 .dev_addr = PXA27x_SSP2_BASE + SSDR,
117 .drcmr = &DRCMR(15),
118 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
119 DCMD_BURST16 | DCMD_WIDTH4,
120};
121
122static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_out = {
123 .name = "SSP3 PCM Mono out",
124 .dev_addr = PXA27x_SSP3_BASE + SSDR,
125 .drcmr = &DRCMR(67),
126 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
127 DCMD_BURST16 | DCMD_WIDTH2,
128};
129
130static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_in = {
131 .name = "SSP3 PCM Mono in",
132 .dev_addr = PXA27x_SSP3_BASE + SSDR,
133 .drcmr = &DRCMR(66),
134 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
135 DCMD_BURST16 | DCMD_WIDTH2,
136};
137
138static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_out = {
139 .name = "SSP3 PCM Stereo out",
140 .dev_addr = PXA27x_SSP3_BASE + SSDR,
141 .drcmr = &DRCMR(67),
142 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
143 DCMD_BURST16 | DCMD_WIDTH4,
144};
145
146static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_in = {
147 .name = "SSP3 PCM Stereo in",
148 .dev_addr = PXA27x_SSP3_BASE + SSDR,
149 .drcmr = &DRCMR(66),
150 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
151 DCMD_BURST16 | DCMD_WIDTH4,
152};
153
154static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_out = {
155 .name = "SSP4 PCM Mono out",
156 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
157 .drcmr = &DRCMR(67),
158 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
159 DCMD_BURST16 | DCMD_WIDTH2,
160};
161
162static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_in = {
163 .name = "SSP4 PCM Mono in",
164 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
165 .drcmr = &DRCMR(66),
166 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
167 DCMD_BURST16 | DCMD_WIDTH2,
168};
169
170static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_out = {
171 .name = "SSP4 PCM Stereo out",
172 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
173 .drcmr = &DRCMR(67),
174 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
175 DCMD_BURST16 | DCMD_WIDTH4,
176};
177
178static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_in = {
179 .name = "SSP4 PCM Stereo in",
180 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
181 .drcmr = &DRCMR(66),
182 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
183 DCMD_BURST16 | DCMD_WIDTH4,
184};
185
186static void dump_registers(struct ssp_device *ssp) 53static void dump_registers(struct ssp_device *ssp)
187{ 54{
188 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n", 55 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
@@ -194,25 +61,33 @@ static void dump_registers(struct ssp_device *ssp)
194 ssp_read_reg(ssp, SSACD)); 61 ssp_read_reg(ssp, SSACD));
195} 62}
196 63
197static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = { 64struct pxa2xx_pcm_dma_data {
198 { 65 struct pxa2xx_pcm_dma_params params;
199 &pxa_ssp1_pcm_mono_out, &pxa_ssp1_pcm_mono_in, 66 char name[20];
200 &pxa_ssp1_pcm_stereo_out, &pxa_ssp1_pcm_stereo_in,
201 },
202 {
203 &pxa_ssp2_pcm_mono_out, &pxa_ssp2_pcm_mono_in,
204 &pxa_ssp2_pcm_stereo_out, &pxa_ssp2_pcm_stereo_in,
205 },
206 {
207 &pxa_ssp3_pcm_mono_out, &pxa_ssp3_pcm_mono_in,
208 &pxa_ssp3_pcm_stereo_out, &pxa_ssp3_pcm_stereo_in,
209 },
210 {
211 &pxa_ssp4_pcm_mono_out, &pxa_ssp4_pcm_mono_in,
212 &pxa_ssp4_pcm_stereo_out, &pxa_ssp4_pcm_stereo_in,
213 },
214}; 67};
215 68
69static struct pxa2xx_pcm_dma_params *
70ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
71{
72 struct pxa2xx_pcm_dma_data *dma;
73
74 dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL);
75 if (dma == NULL)
76 return NULL;
77
78 snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id,
79 width4 ? "32-bit" : "16-bit", out ? "out" : "in");
80
81 dma->params.name = dma->name;
82 dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx);
83 dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) :
84 (DCMD_INCTRGADDR | DCMD_FLOWSRC)) |
85 (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16;
86 dma->params.dev_addr = ssp->phys_base + SSDR;
87
88 return &dma->params;
89}
90
216static int pxa_ssp_startup(struct snd_pcm_substream *substream, 91static int pxa_ssp_startup(struct snd_pcm_substream *substream,
217 struct snd_soc_dai *dai) 92 struct snd_soc_dai *dai)
218{ 93{
@@ -227,6 +102,11 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
227 clk_enable(priv->dev.ssp->clk); 102 clk_enable(priv->dev.ssp->clk);
228 ssp_disable(&priv->dev); 103 ssp_disable(&priv->dev);
229 } 104 }
105
106 if (cpu_dai->dma_data) {
107 kfree(cpu_dai->dma_data);
108 cpu_dai->dma_data = NULL;
109 }
230 return ret; 110 return ret;
231} 111}
232 112
@@ -241,6 +121,11 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
241 ssp_disable(&priv->dev); 121 ssp_disable(&priv->dev);
242 clk_disable(priv->dev.ssp->clk); 122 clk_disable(priv->dev.ssp->clk);
243 } 123 }
124
125 if (cpu_dai->dma_data) {
126 kfree(cpu_dai->dma_data);
127 cpu_dai->dma_data = NULL;
128 }
244} 129}
245 130
246#ifdef CONFIG_PM 131#ifdef CONFIG_PM
@@ -323,7 +208,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
323 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 208 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
324 209
325 dev_dbg(&ssp->pdev->dev, 210 dev_dbg(&ssp->pdev->dev,
326 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n", 211 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
327 cpu_dai->id, clk_id, freq); 212 cpu_dai->id, clk_id, freq);
328 213
329 switch (clk_id) { 214 switch (clk_id) {
@@ -472,7 +357,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
472 ssacd |= (0x6 << 4); 357 ssacd |= (0x6 << 4);
473 358
474 dev_dbg(&ssp->pdev->dev, 359 dev_dbg(&ssp->pdev->dev,
475 "Using SSACDD %x to supply %dHz\n", 360 "Using SSACDD %x to supply %uHz\n",
476 val, freq_out); 361 val, freq_out);
477 break; 362 break;
478 } 363 }
@@ -490,21 +375,34 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
490 * Set the active slots in TDM/Network mode 375 * Set the active slots in TDM/Network mode
491 */ 376 */
492static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, 377static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
493 unsigned int mask, int slots) 378 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
494{ 379{
495 struct ssp_priv *priv = cpu_dai->private_data; 380 struct ssp_priv *priv = cpu_dai->private_data;
496 struct ssp_device *ssp = priv->dev.ssp; 381 struct ssp_device *ssp = priv->dev.ssp;
497 u32 sscr0; 382 u32 sscr0;
498 383
499 sscr0 = ssp_read_reg(ssp, SSCR0) & ~SSCR0_SlotsPerFrm(7); 384 sscr0 = ssp_read_reg(ssp, SSCR0);
385 sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
500 386
501 /* set number of active slots */ 387 /* set slot width */
502 sscr0 |= SSCR0_SlotsPerFrm(slots); 388 if (slot_width > 16)
389 sscr0 |= SSCR0_EDSS | SSCR0_DataSize(slot_width - 16);
390 else
391 sscr0 |= SSCR0_DataSize(slot_width);
392
393 if (slots > 1) {
394 /* enable network mode */
395 sscr0 |= SSCR0_MOD;
396
397 /* set number of active slots */
398 sscr0 |= SSCR0_SlotsPerFrm(slots);
399
400 /* set active slot mask */
401 ssp_write_reg(ssp, SSTSA, tx_mask);
402 ssp_write_reg(ssp, SSRSA, rx_mask);
403 }
503 ssp_write_reg(ssp, SSCR0, sscr0); 404 ssp_write_reg(ssp, SSCR0, sscr0);
504 405
505 /* set active slot mask */
506 ssp_write_reg(ssp, SSTSA, mask);
507 ssp_write_reg(ssp, SSRSA, mask);
508 return 0; 406 return 0;
509} 407}
510 408
@@ -572,28 +470,27 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
572 return -EINVAL; 470 return -EINVAL;
573 } 471 }
574 472
575 ssp_write_reg(ssp, SSCR0, sscr0); 473 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
576 ssp_write_reg(ssp, SSCR1, sscr1); 474 case SND_SOC_DAIFMT_NB_NF:
577 ssp_write_reg(ssp, SSPSP, sspsp); 475 sspsp |= SSPSP_SFRMP;
476 break;
477 case SND_SOC_DAIFMT_NB_IF:
478 break;
479 case SND_SOC_DAIFMT_IB_IF:
480 sspsp |= SSPSP_SCMODE(2);
481 break;
482 case SND_SOC_DAIFMT_IB_NF:
483 sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
484 break;
485 default:
486 return -EINVAL;
487 }
578 488
579 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 489 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
580 case SND_SOC_DAIFMT_I2S: 490 case SND_SOC_DAIFMT_I2S:
581 sscr0 |= SSCR0_PSP; 491 sscr0 |= SSCR0_PSP;
582 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; 492 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
583
584 /* See hw_params() */ 493 /* See hw_params() */
585 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
586 case SND_SOC_DAIFMT_NB_NF:
587 sspsp |= SSPSP_SFRMP;
588 break;
589 case SND_SOC_DAIFMT_NB_IF:
590 break;
591 case SND_SOC_DAIFMT_IB_IF:
592 sspsp |= SSPSP_SCMODE(3);
593 break;
594 default:
595 return -EINVAL;
596 }
597 break; 494 break;
598 495
599 case SND_SOC_DAIFMT_DSP_A: 496 case SND_SOC_DAIFMT_DSP_A:
@@ -601,16 +498,6 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
601 case SND_SOC_DAIFMT_DSP_B: 498 case SND_SOC_DAIFMT_DSP_B:
602 sscr0 |= SSCR0_MOD | SSCR0_PSP; 499 sscr0 |= SSCR0_MOD | SSCR0_PSP;
603 sscr1 |= SSCR1_TRAIL | SSCR1_RWOT; 500 sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
604
605 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
606 case SND_SOC_DAIFMT_NB_NF:
607 sspsp |= SSPSP_SFRMP;
608 break;
609 case SND_SOC_DAIFMT_IB_IF:
610 break;
611 default:
612 return -EINVAL;
613 }
614 break; 501 break;
615 502
616 default: 503 default:
@@ -644,25 +531,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
644 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 531 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
645 struct ssp_priv *priv = cpu_dai->private_data; 532 struct ssp_priv *priv = cpu_dai->private_data;
646 struct ssp_device *ssp = priv->dev.ssp; 533 struct ssp_device *ssp = priv->dev.ssp;
647 int dma = 0, chn = params_channels(params); 534 int chn = params_channels(params);
648 u32 sscr0; 535 u32 sscr0;
649 u32 sspsp; 536 u32 sspsp;
650 int width = snd_pcm_format_physical_width(params_format(params)); 537 int width = snd_pcm_format_physical_width(params_format(params));
651 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; 538 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
652 539
653 /* select correct DMA params */ 540 /* generate correct DMA params */
654 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 541 if (cpu_dai->dma_data)
655 dma = 1; /* capture DMA offset is 1,3 */ 542 kfree(cpu_dai->dma_data);
543
656 /* Network mode with one active slot (ttsa == 1) can be used 544 /* Network mode with one active slot (ttsa == 1) can be used
657 * to force 16-bit frame width on the wire (for S16_LE), even 545 * to force 16-bit frame width on the wire (for S16_LE), even
658 * with two channels. Use 16-bit DMA transfers for this case. 546 * with two channels. Use 16-bit DMA transfers for this case.
659 */ 547 */
660 if (((chn == 2) && (ttsa != 1)) || (width == 32)) 548 cpu_dai->dma_data = ssp_get_dma_params(ssp,
661 dma += 2; /* 32-bit DMA offset is 2, 16-bit is 0 */ 549 ((chn == 2) && (ttsa != 1)) || (width == 32),
662 550 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
663 cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
664
665 dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma);
666 551
667 /* we can only change the settings if the port is not in use */ 552 /* we can only change the settings if the port is not in use */
668 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 553 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d9c94d71fa61..7330e5c5b9df 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -22,6 +22,7 @@
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23#include <mach/regs-ac97.h> 23#include <mach/regs-ac97.h>
24#include <mach/dma.h> 24#include <mach/dma.h>
25#include <mach/audio.h>
25 26
26#include "pxa2xx-pcm.h" 27#include "pxa2xx-pcm.h"
27#include "pxa2xx-ac97.h" 28#include "pxa2xx-ac97.h"
@@ -241,9 +242,18 @@ EXPORT_SYMBOL_GPL(soc_ac97_ops);
241static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev) 242static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev)
242{ 243{
243 int i; 244 int i;
245 pxa2xx_audio_ops_t *pdata = pdev->dev.platform_data;
244 246
245 for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) 247 if (pdev->id >= 0) {
248 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
249 return -ENXIO;
250 }
251
252 for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) {
246 pxa_ac97_dai[i].dev = &pdev->dev; 253 pxa_ac97_dai[i].dev = &pdev->dev;
254 if (pdata && pdata->codec_pdata)
255 pxa_ac97_dai[i].ac97_pdata = pdata->codec_pdata;
256 }
247 257
248 /* Punt most of the init to the SoC probe; we may need the machine 258 /* Punt most of the init to the SoC probe; we may need the machine
249 * driver to do interesting things with the clocking to get us up 259 * driver to do interesting things with the clocking to get us up
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 2f4b6e489b78..6b8f655d1ad8 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -106,10 +106,8 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
106 if (IS_ERR(clk_i2s)) 106 if (IS_ERR(clk_i2s))
107 return PTR_ERR(clk_i2s); 107 return PTR_ERR(clk_i2s);
108 108
109 if (!cpu_dai->active) { 109 if (!cpu_dai->active)
110 SACR0 |= SACR0_RST;
111 SACR0 = 0; 110 SACR0 = 0;
112 }
113 111
114 return 0; 112 return 0;
115} 113}
@@ -169,6 +167,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
169 167
170 BUG_ON(IS_ERR(clk_i2s)); 168 BUG_ON(IS_ERR(clk_i2s));
171 clk_enable(clk_i2s); 169 clk_enable(clk_i2s);
170 dai->private_data = dai;
172 pxa_i2s_wait(); 171 pxa_i2s_wait();
173 172
174 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 173 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -178,9 +177,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
178 177
179 /* is port used by another stream */ 178 /* is port used by another stream */
180 if (!(SACR0 & SACR0_ENB)) { 179 if (!(SACR0 & SACR0_ENB)) {
181
182 SACR0 = 0; 180 SACR0 = 0;
183 SACR1 = 0;
184 if (pxa_i2s.master) 181 if (pxa_i2s.master)
185 SACR0 |= SACR0_BCKD; 182 SACR0 |= SACR0_BCKD;
186 183
@@ -226,6 +223,10 @@ static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
226 223
227 switch (cmd) { 224 switch (cmd) {
228 case SNDRV_PCM_TRIGGER_START: 225 case SNDRV_PCM_TRIGGER_START:
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
227 SACR1 &= ~SACR1_DRPL;
228 else
229 SACR1 &= ~SACR1_DREC;
229 SACR0 |= SACR0_ENB; 230 SACR0 |= SACR0_ENB;
230 break; 231 break;
231 case SNDRV_PCM_TRIGGER_RESUME: 232 case SNDRV_PCM_TRIGGER_RESUME:
@@ -252,21 +253,19 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
252 SAIMR &= ~SAIMR_RFS; 253 SAIMR &= ~SAIMR_RFS;
253 } 254 }
254 255
255 if (SACR1 & (SACR1_DREC | SACR1_DRPL)) { 256 if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
256 SACR0 &= ~SACR0_ENB; 257 SACR0 &= ~SACR0_ENB;
257 pxa_i2s_wait(); 258 pxa_i2s_wait();
258 clk_disable(clk_i2s); 259 if (dai->private_data != NULL) {
260 clk_disable(clk_i2s);
261 dai->private_data = NULL;
262 }
259 } 263 }
260
261 clk_put(clk_i2s);
262} 264}
263 265
264#ifdef CONFIG_PM 266#ifdef CONFIG_PM
265static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai) 267static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
266{ 268{
267 if (!dai->active)
268 return 0;
269
270 /* store registers */ 269 /* store registers */
271 pxa_i2s.sacr0 = SACR0; 270 pxa_i2s.sacr0 = SACR0;
272 pxa_i2s.sacr1 = SACR1; 271 pxa_i2s.sacr1 = SACR1;
@@ -281,16 +280,14 @@ static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
281 280
282static int pxa2xx_i2s_resume(struct snd_soc_dai *dai) 281static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
283{ 282{
284 if (!dai->active)
285 return 0;
286
287 pxa_i2s_wait(); 283 pxa_i2s_wait();
288 284
289 SACR0 = pxa_i2s.sacr0 &= ~SACR0_ENB; 285 SACR0 = pxa_i2s.sacr0 & ~SACR0_ENB;
290 SACR1 = pxa_i2s.sacr1; 286 SACR1 = pxa_i2s.sacr1;
291 SAIMR = pxa_i2s.saimr; 287 SAIMR = pxa_i2s.saimr;
292 SADIV = pxa_i2s.sadiv; 288 SADIV = pxa_i2s.sadiv;
293 SACR0 |= SACR0_ENB; 289
290 SACR0 = pxa_i2s.sacr0;
294 291
295 return 0; 292 return 0;
296} 293}
@@ -329,6 +326,7 @@ struct snd_soc_dai pxa_i2s_dai = {
329 .rates = PXA2XX_I2S_RATES, 326 .rates = PXA2XX_I2S_RATES,
330 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 327 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
331 .ops = &pxa_i2s_dai_ops, 328 .ops = &pxa_i2s_dai_ops,
329 .symmetric_rates = 1,
332}; 330};
333 331
334EXPORT_SYMBOL_GPL(pxa_i2s_dai); 332EXPORT_SYMBOL_GPL(pxa_i2s_dai);
@@ -342,10 +340,24 @@ static int pxa2xx_i2s_probe(struct platform_device *dev)
342 return PTR_ERR(clk_i2s); 340 return PTR_ERR(clk_i2s);
343 341
344 pxa_i2s_dai.dev = &dev->dev; 342 pxa_i2s_dai.dev = &dev->dev;
343 pxa_i2s_dai.private_data = NULL;
345 ret = snd_soc_register_dai(&pxa_i2s_dai); 344 ret = snd_soc_register_dai(&pxa_i2s_dai);
346 if (ret != 0) 345 if (ret != 0)
347 clk_put(clk_i2s); 346 clk_put(clk_i2s);
348 347
348 /*
349 * PXA Developer's Manual:
350 * If SACR0[ENB] is toggled in the middle of a normal operation,
351 * the SACR0[RST] bit must also be set and cleared to reset all
352 * I2S controller registers.
353 */
354 SACR0 = SACR0_RST;
355 SACR0 = 0;
356 /* Make sure RPL and REC are disabled */
357 SACR1 = SACR1_DRPL | SACR1_DREC;
358 /* Along with FIFO servicing */
359 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
360
349 return ret; 361 return ret;
350} 362}
351 363