diff options
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r-- | sound/soc/pxa/Kconfig | 20 | ||||
-rw-r--r-- | sound/soc/pxa/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/pxa/corgi.c | 36 | ||||
-rw-r--r-- | sound/soc/pxa/em-x270.c | 9 | ||||
-rw-r--r-- | sound/soc/pxa/imote2.c | 114 | ||||
-rw-r--r-- | sound/soc/pxa/magician.c | 71 | ||||
-rw-r--r-- | sound/soc/pxa/palm27x.c | 206 | ||||
-rw-r--r-- | sound/soc/pxa/poodle.c | 36 | ||||
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 275 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-ac97.c | 12 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-i2s.c | 46 |
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 | ||
91 | config SND_PXA2XX_SOC_EM_X270 | 91 | config 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 | ||
100 | config SND_PXA2XX_SOC_PALM27X | 100 | config 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 | ||
109 | config SND_SOC_ZYLONITE | 110 | config 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 | |||
139 | config 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 | |||
22 | snd-soc-zylonite-objs := zylonite.o | 22 | snd-soc-zylonite-objs := zylonite.o |
23 | snd-soc-magician-objs := magician.o | 23 | snd-soc-magician-objs := magician.o |
24 | snd-soc-mioa701-objs := mioa701_wm9713.o | 24 | snd-soc-mioa701-objs := mioa701_wm9713.o |
25 | snd-soc-imote2-objs := imote2.o | ||
25 | 26 | ||
26 | obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o | 27 | obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o |
27 | obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o | 28 | obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o |
@@ -35,3 +36,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o | |||
35 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o | 36 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o |
36 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o | 37 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o |
37 | obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o | 38 | obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o |
39 | obj-$(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 | */ | ||
328 | static 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 | |||
355 | static struct platform_device *corgi_snd_device; | 323 | static struct platform_device *corgi_snd_device; |
356 | 324 | ||
357 | static int __init corgi_init(void) | 325 | static 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 */ |
97 | MODULE_AUTHOR("Mike Rapoport"); | 98 | MODULE_AUTHOR("Mike Rapoport"); |
98 | MODULE_DESCRIPTION("ALSA SoC EM-X270"); | 99 | MODULE_DESCRIPTION("ALSA SoC EM-X270, eXeda and CM-X300"); |
99 | MODULE_LICENSE("GPL"); | 100 | MODULE_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 | |||
11 | static 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 | |||
60 | static struct snd_soc_ops imote2_asoc_ops = { | ||
61 | .hw_params = imote2_asoc_hw_params, | ||
62 | }; | ||
63 | |||
64 | static 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 | |||
72 | static 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 | |||
79 | static struct snd_soc_device imote2_snd_devdata = { | ||
80 | .card = &snd_soc_imote2, | ||
81 | .codec_dev = &soc_codec_dev_wm8940, | ||
82 | }; | ||
83 | |||
84 | static struct platform_device *imote2_snd_device; | ||
85 | |||
86 | static 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 | } | ||
104 | module_init(imote2_asoc_init); | ||
105 | |||
106 | static void __exit imote2_asoc_exit(void) | ||
107 | { | ||
108 | platform_device_unregister(imote2_snd_device); | ||
109 | } | ||
110 | module_exit(imote2_asoc_exit); | ||
111 | |||
112 | MODULE_AUTHOR("Jonathan Cameron"); | ||
113 | MODULE_DESCRIPTION("ALSA SoC Imote 2"); | ||
114 | MODULE_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 */ | ||
450 | static 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 */ |
456 | static struct snd_soc_device magician_snd_devdata = { | 453 | static 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 | ||
462 | static struct platform_device *magician_snd_device; | 458 | static struct platform_device *magician_snd_device; |
463 | 459 | ||
460 | /* | ||
461 | * FIXME: move into magician board file once merged into the pxa tree | ||
462 | */ | ||
463 | static 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 | |||
469 | static struct i2c_board_info i2c_board_info[] = { | ||
470 | { | ||
471 | I2C_BOARD_INFO("uda1380", 0x18), | ||
472 | .platform_data = &uda1380_info, | ||
473 | }, | ||
474 | }; | ||
475 | |||
464 | static int __init magician_init(void) | 476 | static 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: | |||
525 | err_request_ep: | 535 | err_request_ep: |
526 | gpio_free(EGPIO_MAGICIAN_SPK_POWER); | 536 | gpio_free(EGPIO_MAGICIAN_SPK_POWER); |
527 | err_request_spk: | 537 | err_request_spk: |
528 | gpio_free(EGPIO_MAGICIAN_CODEC_RESET); | ||
529 | err_request_reset: | ||
530 | gpio_free(EGPIO_MAGICIAN_CODEC_POWER); | ||
531 | err_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 | ||
553 | module_init(magician_init); | 556 | module_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 | ||
36 | static int palm27x_jack_func = 1; | 35 | static struct snd_soc_jack hs_jack; |
37 | static int palm27x_spk_func = 1; | ||
38 | static int palm27x_ep_gpio = -1; | ||
39 | 36 | ||
40 | static void palm27x_ext_control(struct snd_soc_codec *codec) | 37 | /* Headphones jack detection DAPM pins */ |
41 | { | 38 | static 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 | |||
55 | static 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 | |||
65 | static struct snd_soc_ops palm27x_ops = { | ||
66 | .startup = palm27x_startup, | ||
67 | }; | 43 | }; |
68 | 44 | ||
69 | static irqreturn_t palm27x_interrupt(int irq, void *v) | 45 | /* Headphones jack detection gpios */ |
70 | { | 46 | static 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, | |
76 | static 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 | |||
83 | static 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 | |||
96 | static 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 | |||
103 | static 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 */ |
117 | static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = { | 56 | static 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 | ||
133 | static const char *jack_function[] = {"Headphone", "Off"}; | 72 | /* mic connected to MIC1 */ |
134 | static const char *spk_function[] = {"On", "Off"}; | 73 | {"Ext. Microphone", NULL, "MIC1"}, |
135 | static 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 | ||
140 | static const struct snd_kcontrol_new palm27x_controls[] = { | 76 | static 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 | ||
147 | static int palm27x_ac97_init(struct snd_soc_codec *codec) | 78 | static 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 | ||
171 | static struct snd_soc_dai_link palm27x_dai[] = { | 131 | static 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 | ||
242 | put_device: | 190 | put_device: |
243 | platform_device_put(palm27x_snd_device); | 191 | platform_device_put(palm27x_snd_device); |
244 | err_dev: | ||
245 | free_irq(gpio_to_irq(palm27x_ep_gpio), NULL); | ||
246 | err_alloc: | ||
247 | gpio_free(palm27x_ep_gpio); | ||
248 | 192 | ||
249 | return ret; | 193 | return ret; |
250 | } | 194 | } |
251 | 195 | ||
252 | static int __devexit palm27x_asoc_remove(struct platform_device *pdev) | 196 | static 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 | */ | ||
288 | static 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 */ |
316 | static struct snd_soc_device poodle_snd_devdata = { | 284 | static 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 | |||
58 | static 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 | |||
66 | static 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 | |||
74 | static 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 | |||
82 | static 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 | |||
90 | static 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 | |||
98 | static 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 | |||
106 | static 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 | |||
114 | static 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 | |||
122 | static 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 | |||
130 | static 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 | |||
138 | static 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 | |||
146 | static 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 | |||
154 | static 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 | |||
162 | static 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 | |||
170 | static 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 | |||
178 | static 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 | |||
186 | static void dump_registers(struct ssp_device *ssp) | 53 | static 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 | ||
197 | static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = { | 64 | struct 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 | ||
69 | static struct pxa2xx_pcm_dma_params * | ||
70 | ssp_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 | |||
216 | static int pxa_ssp_startup(struct snd_pcm_substream *substream, | 91 | static 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 | */ |
492 | static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, | 377 | static 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); | |||
241 | static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev) | 242 | static 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 |
265 | static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai) | 267 | static 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 | ||
282 | static int pxa2xx_i2s_resume(struct snd_soc_dai *dai) | 281 | static 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 | ||
334 | EXPORT_SYMBOL_GPL(pxa_i2s_dai); | 332 | EXPORT_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 | ||