diff options
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r-- | sound/soc/pxa/Kconfig | 3 | ||||
-rw-r--r-- | sound/soc/pxa/corgi.c | 41 | ||||
-rw-r--r-- | sound/soc/pxa/em-x270.c | 2 | ||||
-rw-r--r-- | sound/soc/pxa/poodle.c | 7 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-ac97.c | 282 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-i2s.c | 67 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-pcm.c | 265 | ||||
-rw-r--r-- | sound/soc/pxa/pxa2xx-pcm.h | 15 | ||||
-rw-r--r-- | sound/soc/pxa/spitz.c | 63 | ||||
-rw-r--r-- | sound/soc/pxa/tosa.c | 6 |
10 files changed, 136 insertions, 615 deletions
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 9212c37a33b8..f8c1cdd940ac 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SND_PXA2XX_SOC | 1 | config SND_PXA2XX_SOC |
2 | tristate "SoC Audio for the Intel PXA2xx chip" | 2 | tristate "SoC Audio for the Intel PXA2xx chip" |
3 | depends on ARCH_PXA | 3 | depends on ARCH_PXA |
4 | select SND_PXA2XX_LIB | ||
4 | help | 5 | help |
5 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
6 | the PXA2xx AC97, I2S or SSP interface. You will also need | 7 | the PXA2xx AC97, I2S or SSP interface. You will also need |
@@ -13,6 +14,8 @@ config SND_PXA2XX_AC97 | |||
13 | config SND_PXA2XX_SOC_AC97 | 14 | config SND_PXA2XX_SOC_AC97 |
14 | tristate | 15 | tristate |
15 | select AC97_BUS | 16 | select AC97_BUS |
17 | select SND_ARM | ||
18 | select SND_PXA2XX_LIB_AC97 | ||
16 | select SND_SOC_AC97_BUS | 19 | select SND_SOC_AC97_BUS |
17 | 20 | ||
18 | config SND_PXA2XX_SOC_I2S | 21 | config SND_PXA2XX_SOC_I2S |
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 0a53f72077fd..2718eaf7895f 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2005 Wolfson Microelectronics PLC. | 4 | * Copyright 2005 Wolfson Microelectronics PLC. |
5 | * Copyright 2005 Openedhand Ltd. | 5 | * Copyright 2005 Openedhand Ltd. |
6 | * | 6 | * |
7 | * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 7 | * Authors: Liam Girdwood <lrg@slimlogic.co.uk> |
8 | * Richard Purdie <richard@openedhand.com> | 8 | * Richard Purdie <richard@openedhand.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
@@ -18,13 +18,13 @@ | |||
18 | #include <linux/timer.h> | 18 | #include <linux/timer.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/gpio.h> | ||
21 | #include <sound/core.h> | 22 | #include <sound/core.h> |
22 | #include <sound/pcm.h> | 23 | #include <sound/pcm.h> |
23 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
24 | #include <sound/soc-dapm.h> | 25 | #include <sound/soc-dapm.h> |
25 | 26 | ||
26 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
27 | #include <asm/hardware/scoop.h> | ||
28 | #include <mach/pxa-regs.h> | 28 | #include <mach/pxa-regs.h> |
29 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include <mach/corgi.h> | 30 | #include <mach/corgi.h> |
@@ -54,8 +54,8 @@ static void corgi_ext_control(struct snd_soc_codec *codec) | |||
54 | switch (corgi_jack_func) { | 54 | switch (corgi_jack_func) { |
55 | case CORGI_HP: | 55 | case CORGI_HP: |
56 | /* set = unmute headphone */ | 56 | /* set = unmute headphone */ |
57 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); | 57 | gpio_set_value(CORGI_GPIO_MUTE_L, 1); |
58 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); | 58 | gpio_set_value(CORGI_GPIO_MUTE_R, 1); |
59 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); | 59 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); |
60 | snd_soc_dapm_disable_pin(codec, "Line Jack"); | 60 | snd_soc_dapm_disable_pin(codec, "Line Jack"); |
61 | snd_soc_dapm_enable_pin(codec, "Headphone Jack"); | 61 | snd_soc_dapm_enable_pin(codec, "Headphone Jack"); |
@@ -63,24 +63,24 @@ static void corgi_ext_control(struct snd_soc_codec *codec) | |||
63 | break; | 63 | break; |
64 | case CORGI_MIC: | 64 | case CORGI_MIC: |
65 | /* reset = mute headphone */ | 65 | /* reset = mute headphone */ |
66 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); | 66 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
67 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); | 67 | gpio_set_value(CORGI_GPIO_MUTE_R, 0); |
68 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); | 68 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); |
69 | snd_soc_dapm_disable_pin(codec, "Line Jack"); | 69 | snd_soc_dapm_disable_pin(codec, "Line Jack"); |
70 | snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 70 | snd_soc_dapm_disable_pin(codec, "Headphone Jack"); |
71 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 71 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); |
72 | break; | 72 | break; |
73 | case CORGI_LINE: | 73 | case CORGI_LINE: |
74 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); | 74 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
75 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); | 75 | gpio_set_value(CORGI_GPIO_MUTE_R, 0); |
76 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); | 76 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); |
77 | snd_soc_dapm_enable_pin(codec, "Line Jack"); | 77 | snd_soc_dapm_enable_pin(codec, "Line Jack"); |
78 | snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 78 | snd_soc_dapm_disable_pin(codec, "Headphone Jack"); |
79 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 79 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); |
80 | break; | 80 | break; |
81 | case CORGI_HEADSET: | 81 | case CORGI_HEADSET: |
82 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); | 82 | gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
83 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); | 83 | gpio_set_value(CORGI_GPIO_MUTE_R, 1); |
84 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); | 84 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); |
85 | snd_soc_dapm_disable_pin(codec, "Line Jack"); | 85 | snd_soc_dapm_disable_pin(codec, "Line Jack"); |
86 | snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 86 | snd_soc_dapm_disable_pin(codec, "Headphone Jack"); |
@@ -114,8 +114,8 @@ static int corgi_shutdown(struct snd_pcm_substream *substream) | |||
114 | struct snd_soc_codec *codec = rtd->socdev->codec; | 114 | struct snd_soc_codec *codec = rtd->socdev->codec; |
115 | 115 | ||
116 | /* set = unmute headphone */ | 116 | /* set = unmute headphone */ |
117 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); | 117 | gpio_set_value(CORGI_GPIO_MUTE_L, 1); |
118 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); | 118 | gpio_set_value(CORGI_GPIO_MUTE_R, 1); |
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
@@ -218,22 +218,14 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol, | |||
218 | static int corgi_amp_event(struct snd_soc_dapm_widget *w, | 218 | static int corgi_amp_event(struct snd_soc_dapm_widget *w, |
219 | struct snd_kcontrol *k, int event) | 219 | struct snd_kcontrol *k, int event) |
220 | { | 220 | { |
221 | if (SND_SOC_DAPM_EVENT_ON(event)) | 221 | gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event)); |
222 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); | ||
223 | else | ||
224 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); | ||
225 | |||
226 | return 0; | 222 | return 0; |
227 | } | 223 | } |
228 | 224 | ||
229 | static int corgi_mic_event(struct snd_soc_dapm_widget *w, | 225 | static int corgi_mic_event(struct snd_soc_dapm_widget *w, |
230 | struct snd_kcontrol *k, int event) | 226 | struct snd_kcontrol *k, int event) |
231 | { | 227 | { |
232 | if (SND_SOC_DAPM_EVENT_ON(event)) | 228 | gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event)); |
233 | set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); | ||
234 | else | ||
235 | reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); | ||
236 | |||
237 | return 0; | 229 | return 0; |
238 | } | 230 | } |
239 | 231 | ||
@@ -289,8 +281,8 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec) | |||
289 | { | 281 | { |
290 | int i, err; | 282 | int i, err; |
291 | 283 | ||
292 | snd_soc_dapm_disable_pin(codec, "LLINEIN"); | 284 | snd_soc_dapm_nc_pin(codec, "LLINEIN"); |
293 | snd_soc_dapm_disable_pin(codec, "RLINEIN"); | 285 | snd_soc_dapm_nc_pin(codec, "RLINEIN"); |
294 | 286 | ||
295 | /* Add corgi specific controls */ | 287 | /* Add corgi specific controls */ |
296 | for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { | 288 | for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { |
@@ -330,6 +322,7 @@ static struct snd_soc_machine snd_soc_machine_corgi = { | |||
330 | 322 | ||
331 | /* corgi audio private data */ | 323 | /* corgi audio private data */ |
332 | static struct wm8731_setup_data corgi_wm8731_setup = { | 324 | static struct wm8731_setup_data corgi_wm8731_setup = { |
325 | .i2c_bus = 0, | ||
333 | .i2c_address = 0x1b, | 326 | .i2c_address = 0x1b, |
334 | }; | 327 | }; |
335 | 328 | ||
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index d9c3f7b28be2..e6ff6929ab4b 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * Copyright 2005 Wolfson Microelectronics PLC. | 9 | * Copyright 2005 Wolfson Microelectronics PLC. |
10 | * Copyright 2005 Openedhand Ltd. | 10 | * Copyright 2005 Openedhand Ltd. |
11 | * | 11 | * |
12 | * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 12 | * Authors: Liam Girdwood <lrg@slimlogic.co.uk> |
13 | * Richard Purdie <richard@openedhand.com> | 13 | * Richard Purdie <richard@openedhand.com> |
14 | * | 14 | * |
15 | * This program is free software; you can redistribute it and/or modify it | 15 | * This program is free software; you can redistribute it and/or modify it |
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index a4697f7e2921..4d9930c52789 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2005 Wolfson Microelectronics PLC. | 4 | * Copyright 2005 Wolfson Microelectronics PLC. |
5 | * Copyright 2005 Openedhand Ltd. | 5 | * Copyright 2005 Openedhand Ltd. |
6 | * | 6 | * |
7 | * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 7 | * Authors: Liam Girdwood <lrg@slimlogic.co.uk> |
8 | * Richard Purdie <richard@openedhand.com> | 8 | * Richard Purdie <richard@openedhand.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
@@ -242,8 +242,8 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec) | |||
242 | { | 242 | { |
243 | int i, err; | 243 | int i, err; |
244 | 244 | ||
245 | snd_soc_dapm_disable_pin(codec, "LLINEIN"); | 245 | snd_soc_dapm_nc_pin(codec, "LLINEIN"); |
246 | snd_soc_dapm_disable_pin(codec, "RLINEIN"); | 246 | snd_soc_dapm_nc_pin(codec, "RLINEIN"); |
247 | snd_soc_dapm_enable_pin(codec, "MICIN"); | 247 | snd_soc_dapm_enable_pin(codec, "MICIN"); |
248 | 248 | ||
249 | /* Add poodle specific controls */ | 249 | /* Add poodle specific controls */ |
@@ -284,6 +284,7 @@ static struct snd_soc_machine snd_soc_machine_poodle = { | |||
284 | 284 | ||
285 | /* poodle audio private data */ | 285 | /* poodle audio private data */ |
286 | static struct wm8731_setup_data poodle_wm8731_setup = { | 286 | static struct wm8731_setup_data poodle_wm8731_setup = { |
287 | .i2c_bus = 0, | ||
287 | .i2c_address = 0x1b, | 288 | .i2c_address = 0x1b, |
288 | }; | 289 | }; |
289 | 290 | ||
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index d94a495bd6bd..a7a3a9c5c6ff 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c | |||
@@ -13,225 +13,30 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/wait.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/delay.h> | ||
20 | 16 | ||
21 | #include <sound/core.h> | 17 | #include <sound/core.h> |
22 | #include <sound/pcm.h> | ||
23 | #include <sound/ac97_codec.h> | 18 | #include <sound/ac97_codec.h> |
24 | #include <sound/initval.h> | ||
25 | #include <sound/soc.h> | 19 | #include <sound/soc.h> |
20 | #include <sound/pxa2xx-lib.h> | ||
26 | 21 | ||
27 | #include <asm/irq.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
30 | #include <mach/pxa-regs.h> | 23 | #include <mach/pxa-regs.h> |
31 | #include <mach/pxa2xx-gpio.h> | ||
32 | #include <mach/audio.h> | ||
33 | 24 | ||
34 | #include "pxa2xx-pcm.h" | 25 | #include "pxa2xx-pcm.h" |
35 | #include "pxa2xx-ac97.h" | 26 | #include "pxa2xx-ac97.h" |
36 | 27 | ||
37 | static DEFINE_MUTEX(car_mutex); | ||
38 | static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); | ||
39 | static volatile long gsr_bits; | ||
40 | static struct clk *ac97_clk; | ||
41 | #ifdef CONFIG_PXA27x | ||
42 | static struct clk *ac97conf_clk; | ||
43 | #endif | ||
44 | |||
45 | /* | ||
46 | * Beware PXA27x bugs: | ||
47 | * | ||
48 | * o Slot 12 read from modem space will hang controller. | ||
49 | * o CDONE, SDONE interrupt fails after any slot 12 IO. | ||
50 | * | ||
51 | * We therefore have an hybrid approach for waiting on SDONE (interrupt or | ||
52 | * 1 jiffy timeout if interrupt never comes). | ||
53 | */ | ||
54 | |||
55 | static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, | ||
56 | unsigned short reg) | ||
57 | { | ||
58 | unsigned short val = -1; | ||
59 | volatile u32 *reg_addr; | ||
60 | |||
61 | mutex_lock(&car_mutex); | ||
62 | |||
63 | /* set up primary or secondary codec/modem space */ | ||
64 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
65 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
66 | #else | ||
67 | if (reg == AC97_GPIO_STATUS) | ||
68 | reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; | ||
69 | else | ||
70 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
71 | #endif | ||
72 | reg_addr += (reg >> 1); | ||
73 | |||
74 | #ifndef CONFIG_PXA27x | ||
75 | if (reg == AC97_GPIO_STATUS) { | ||
76 | /* read from controller cache */ | ||
77 | val = *reg_addr; | ||
78 | goto out; | ||
79 | } | ||
80 | #endif | ||
81 | |||
82 | /* start read access across the ac97 link */ | ||
83 | GSR = GSR_CDONE | GSR_SDONE; | ||
84 | gsr_bits = 0; | ||
85 | val = *reg_addr; | ||
86 | |||
87 | wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); | ||
88 | if (!((GSR | gsr_bits) & GSR_SDONE)) { | ||
89 | printk(KERN_ERR "%s: read error (ac97_reg=%x GSR=%#lx)\n", | ||
90 | __func__, reg, GSR | gsr_bits); | ||
91 | val = -1; | ||
92 | goto out; | ||
93 | } | ||
94 | |||
95 | /* valid data now */ | ||
96 | GSR = GSR_CDONE | GSR_SDONE; | ||
97 | gsr_bits = 0; | ||
98 | val = *reg_addr; | ||
99 | /* but we've just started another cycle... */ | ||
100 | wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); | ||
101 | |||
102 | out: mutex_unlock(&car_mutex); | ||
103 | return val; | ||
104 | } | ||
105 | |||
106 | static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | ||
107 | unsigned short val) | ||
108 | { | ||
109 | volatile u32 *reg_addr; | ||
110 | |||
111 | mutex_lock(&car_mutex); | ||
112 | |||
113 | /* set up primary or secondary codec/modem space */ | ||
114 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
115 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
116 | #else | ||
117 | if (reg == AC97_GPIO_STATUS) | ||
118 | reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; | ||
119 | else | ||
120 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
121 | #endif | ||
122 | reg_addr += (reg >> 1); | ||
123 | |||
124 | GSR = GSR_CDONE | GSR_SDONE; | ||
125 | gsr_bits = 0; | ||
126 | *reg_addr = val; | ||
127 | wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1); | ||
128 | if (!((GSR | gsr_bits) & GSR_CDONE)) | ||
129 | printk(KERN_ERR "%s: write error (ac97_reg=%x GSR=%#lx)\n", | ||
130 | __func__, reg, GSR | gsr_bits); | ||
131 | |||
132 | mutex_unlock(&car_mutex); | ||
133 | } | ||
134 | |||
135 | static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) | 28 | static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) |
136 | { | 29 | { |
137 | #ifdef CONFIG_PXA3xx | 30 | pxa2xx_ac97_try_warm_reset(ac97); |
138 | int timeout = 100; | ||
139 | #endif | ||
140 | gsr_bits = 0; | ||
141 | |||
142 | #ifdef CONFIG_PXA27x | ||
143 | /* warm reset broken on Bulverde, | ||
144 | so manually keep AC97 reset high */ | ||
145 | pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); | ||
146 | udelay(10); | ||
147 | GCR |= GCR_WARM_RST; | ||
148 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
149 | udelay(500); | ||
150 | #elif defined(CONFIG_PXA3xx) | ||
151 | /* Can't use interrupts */ | ||
152 | GCR |= GCR_WARM_RST; | ||
153 | while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) | ||
154 | mdelay(1); | ||
155 | #else | ||
156 | GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN; | ||
157 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
158 | #endif | ||
159 | |||
160 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) | ||
161 | printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", | ||
162 | __func__, gsr_bits); | ||
163 | 31 | ||
164 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | 32 | pxa2xx_ac97_finish_reset(ac97); |
165 | GCR |= GCR_SDONE_IE|GCR_CDONE_IE; | ||
166 | } | 33 | } |
167 | 34 | ||
168 | static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) | 35 | static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) |
169 | { | 36 | { |
170 | #ifdef CONFIG_PXA3xx | 37 | pxa2xx_ac97_try_cold_reset(ac97); |
171 | int timeout = 1000; | ||
172 | |||
173 | /* Hold CLKBPB for 100us */ | ||
174 | GCR = 0; | ||
175 | GCR = GCR_CLKBPB; | ||
176 | udelay(100); | ||
177 | GCR = 0; | ||
178 | #endif | ||
179 | 38 | ||
180 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ | 39 | pxa2xx_ac97_finish_reset(ac97); |
181 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ | ||
182 | |||
183 | gsr_bits = 0; | ||
184 | #ifdef CONFIG_PXA27x | ||
185 | /* PXA27x Developers Manual section 13.5.2.2.1 */ | ||
186 | clk_enable(ac97conf_clk); | ||
187 | udelay(5); | ||
188 | clk_disable(ac97conf_clk); | ||
189 | GCR = GCR_COLD_RST; | ||
190 | udelay(50); | ||
191 | #elif defined(CONFIG_PXA3xx) | ||
192 | /* Can't use interrupts on PXA3xx */ | ||
193 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | ||
194 | |||
195 | GCR = GCR_WARM_RST | GCR_COLD_RST; | ||
196 | while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--) | ||
197 | mdelay(10); | ||
198 | #else | ||
199 | GCR = GCR_COLD_RST; | ||
200 | GCR |= GCR_CDONE_IE|GCR_SDONE_IE; | ||
201 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
202 | #endif | ||
203 | |||
204 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) | ||
205 | printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", | ||
206 | __func__, gsr_bits); | ||
207 | |||
208 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | ||
209 | GCR |= GCR_SDONE_IE|GCR_CDONE_IE; | ||
210 | } | ||
211 | |||
212 | static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) | ||
213 | { | ||
214 | long status; | ||
215 | |||
216 | status = GSR; | ||
217 | if (status) { | ||
218 | GSR = status; | ||
219 | gsr_bits |= status; | ||
220 | wake_up(&gsr_wq); | ||
221 | |||
222 | #ifdef CONFIG_PXA27x | ||
223 | /* Although we don't use those we still need to clear them | ||
224 | since they tend to spuriously trigger when MMC is used | ||
225 | (hardware bug? go figure)... */ | ||
226 | MISR = MISR_EOC; | ||
227 | PISR = PISR_EOC; | ||
228 | MCSR = MCSR_EOC; | ||
229 | #endif | ||
230 | |||
231 | return IRQ_HANDLED; | ||
232 | } | ||
233 | |||
234 | return IRQ_NONE; | ||
235 | } | 40 | } |
236 | 41 | ||
237 | struct snd_ac97_bus_ops soc_ac97_ops = { | 42 | struct snd_ac97_bus_ops soc_ac97_ops = { |
@@ -244,7 +49,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = { | |||
244 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { | 49 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { |
245 | .name = "AC97 PCM Stereo out", | 50 | .name = "AC97 PCM Stereo out", |
246 | .dev_addr = __PREG(PCDR), | 51 | .dev_addr = __PREG(PCDR), |
247 | .drcmr = &DRCMRTXPCDR, | 52 | .drcmr = &DRCMR(12), |
248 | .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | | 53 | .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | |
249 | DCMD_BURST32 | DCMD_WIDTH4, | 54 | DCMD_BURST32 | DCMD_WIDTH4, |
250 | }; | 55 | }; |
@@ -252,7 +57,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { | |||
252 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { | 57 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { |
253 | .name = "AC97 PCM Stereo in", | 58 | .name = "AC97 PCM Stereo in", |
254 | .dev_addr = __PREG(PCDR), | 59 | .dev_addr = __PREG(PCDR), |
255 | .drcmr = &DRCMRRXPCDR, | 60 | .drcmr = &DRCMR(11), |
256 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | | 61 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | |
257 | DCMD_BURST32 | DCMD_WIDTH4, | 62 | DCMD_BURST32 | DCMD_WIDTH4, |
258 | }; | 63 | }; |
@@ -260,7 +65,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { | |||
260 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { | 65 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { |
261 | .name = "AC97 Aux PCM (Slot 5) Mono out", | 66 | .name = "AC97 Aux PCM (Slot 5) Mono out", |
262 | .dev_addr = __PREG(MODR), | 67 | .dev_addr = __PREG(MODR), |
263 | .drcmr = &DRCMRTXMODR, | 68 | .drcmr = &DRCMR(10), |
264 | .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | | 69 | .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | |
265 | DCMD_BURST16 | DCMD_WIDTH2, | 70 | DCMD_BURST16 | DCMD_WIDTH2, |
266 | }; | 71 | }; |
@@ -268,7 +73,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { | |||
268 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { | 73 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { |
269 | .name = "AC97 Aux PCM (Slot 5) Mono in", | 74 | .name = "AC97 Aux PCM (Slot 5) Mono in", |
270 | .dev_addr = __PREG(MODR), | 75 | .dev_addr = __PREG(MODR), |
271 | .drcmr = &DRCMRRXMODR, | 76 | .drcmr = &DRCMR(9), |
272 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | | 77 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | |
273 | DCMD_BURST16 | DCMD_WIDTH2, | 78 | DCMD_BURST16 | DCMD_WIDTH2, |
274 | }; | 79 | }; |
@@ -276,7 +81,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { | |||
276 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { | 81 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { |
277 | .name = "AC97 Mic PCM (Slot 6) Mono in", | 82 | .name = "AC97 Mic PCM (Slot 6) Mono in", |
278 | .dev_addr = __PREG(MCDR), | 83 | .dev_addr = __PREG(MCDR), |
279 | .drcmr = &DRCMRRXMCDR, | 84 | .drcmr = &DRCMR(8), |
280 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | | 85 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | |
281 | DCMD_BURST16 | DCMD_WIDTH2, | 86 | DCMD_BURST16 | DCMD_WIDTH2, |
282 | }; | 87 | }; |
@@ -285,24 +90,13 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { | |||
285 | static int pxa2xx_ac97_suspend(struct platform_device *pdev, | 90 | static int pxa2xx_ac97_suspend(struct platform_device *pdev, |
286 | struct snd_soc_dai *dai) | 91 | struct snd_soc_dai *dai) |
287 | { | 92 | { |
288 | GCR |= GCR_ACLINK_OFF; | 93 | return pxa2xx_ac97_hw_suspend(); |
289 | clk_disable(ac97_clk); | ||
290 | return 0; | ||
291 | } | 94 | } |
292 | 95 | ||
293 | static int pxa2xx_ac97_resume(struct platform_device *pdev, | 96 | static int pxa2xx_ac97_resume(struct platform_device *pdev, |
294 | struct snd_soc_dai *dai) | 97 | struct snd_soc_dai *dai) |
295 | { | 98 | { |
296 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | 99 | return pxa2xx_ac97_hw_resume(); |
297 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | ||
298 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | ||
299 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | ||
300 | #ifdef CONFIG_PXA27x | ||
301 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | ||
302 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
303 | #endif | ||
304 | clk_enable(ac97_clk); | ||
305 | return 0; | ||
306 | } | 100 | } |
307 | 101 | ||
308 | #else | 102 | #else |
@@ -313,61 +107,13 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev, | |||
313 | static int pxa2xx_ac97_probe(struct platform_device *pdev, | 107 | static int pxa2xx_ac97_probe(struct platform_device *pdev, |
314 | struct snd_soc_dai *dai) | 108 | struct snd_soc_dai *dai) |
315 | { | 109 | { |
316 | int ret; | 110 | return pxa2xx_ac97_hw_probe(pdev); |
317 | |||
318 | ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL); | ||
319 | if (ret < 0) | ||
320 | goto err; | ||
321 | |||
322 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | ||
323 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | ||
324 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | ||
325 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | ||
326 | #ifdef CONFIG_PXA27x | ||
327 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | ||
328 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
329 | |||
330 | ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK"); | ||
331 | if (IS_ERR(ac97conf_clk)) { | ||
332 | ret = PTR_ERR(ac97conf_clk); | ||
333 | ac97conf_clk = NULL; | ||
334 | goto err_irq; | ||
335 | } | ||
336 | #endif | ||
337 | ac97_clk = clk_get(&pdev->dev, "AC97CLK"); | ||
338 | if (IS_ERR(ac97_clk)) { | ||
339 | ret = PTR_ERR(ac97_clk); | ||
340 | ac97_clk = NULL; | ||
341 | goto err_irq; | ||
342 | } | ||
343 | clk_enable(ac97_clk); | ||
344 | return 0; | ||
345 | |||
346 | err_irq: | ||
347 | GCR |= GCR_ACLINK_OFF; | ||
348 | #ifdef CONFIG_PXA27x | ||
349 | if (ac97conf_clk) { | ||
350 | clk_put(ac97conf_clk); | ||
351 | ac97conf_clk = NULL; | ||
352 | } | ||
353 | #endif | ||
354 | free_irq(IRQ_AC97, NULL); | ||
355 | err: | ||
356 | return ret; | ||
357 | } | 111 | } |
358 | 112 | ||
359 | static void pxa2xx_ac97_remove(struct platform_device *pdev, | 113 | static void pxa2xx_ac97_remove(struct platform_device *pdev, |
360 | struct snd_soc_dai *dai) | 114 | struct snd_soc_dai *dai) |
361 | { | 115 | { |
362 | GCR |= GCR_ACLINK_OFF; | 116 | pxa2xx_ac97_hw_remove(pdev); |
363 | free_irq(IRQ_AC97, NULL); | ||
364 | #ifdef CONFIG_PXA27x | ||
365 | clk_put(ac97conf_clk); | ||
366 | ac97conf_clk = NULL; | ||
367 | #endif | ||
368 | clk_disable(ac97_clk); | ||
369 | clk_put(ac97_clk); | ||
370 | ac97_clk = NULL; | ||
371 | } | 117 | } |
372 | 118 | ||
373 | static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, | 119 | static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, |
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index c796b1882776..e758034db5c3 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright 2005 Wolfson Microelectronics PLC. | 4 | * Copyright 2005 Wolfson Microelectronics PLC. |
5 | * Author: Liam Girdwood | 5 | * Author: Liam Girdwood |
6 | * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com | 6 | * lrg@slimlogic.co.uk |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -21,6 +21,7 @@ | |||
21 | #include <sound/pcm.h> | 21 | #include <sound/pcm.h> |
22 | #include <sound/initval.h> | 22 | #include <sound/initval.h> |
23 | #include <sound/soc.h> | 23 | #include <sound/soc.h> |
24 | #include <sound/pxa2xx-lib.h> | ||
24 | 25 | ||
25 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
26 | #include <mach/pxa-regs.h> | 27 | #include <mach/pxa-regs.h> |
@@ -30,6 +31,54 @@ | |||
30 | #include "pxa2xx-pcm.h" | 31 | #include "pxa2xx-pcm.h" |
31 | #include "pxa2xx-i2s.h" | 32 | #include "pxa2xx-i2s.h" |
32 | 33 | ||
34 | struct pxa2xx_gpio { | ||
35 | u32 sys; | ||
36 | u32 rx; | ||
37 | u32 tx; | ||
38 | u32 clk; | ||
39 | u32 frm; | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * I2S Controller Register and Bit Definitions | ||
44 | */ | ||
45 | #define SACR0 __REG(0x40400000) /* Global Control Register */ | ||
46 | #define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */ | ||
47 | #define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ | ||
48 | #define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */ | ||
49 | #define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */ | ||
50 | #define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ | ||
51 | #define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ | ||
52 | |||
53 | #define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */ | ||
54 | #define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */ | ||
55 | #define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */ | ||
56 | #define SACR0_EFWR (1 << 4) /* Enable EFWR Function */ | ||
57 | #define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */ | ||
58 | #define SACR0_BCKD (1 << 2) /* Bit Clock Direction */ | ||
59 | #define SACR0_ENB (1 << 0) /* Enable I2S Link */ | ||
60 | #define SACR1_ENLBF (1 << 5) /* Enable Loopback */ | ||
61 | #define SACR1_DRPL (1 << 4) /* Disable Replaying Function */ | ||
62 | #define SACR1_DREC (1 << 3) /* Disable Recording Function */ | ||
63 | #define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */ | ||
64 | |||
65 | #define SASR0_I2SOFF (1 << 7) /* Controller Status */ | ||
66 | #define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */ | ||
67 | #define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */ | ||
68 | #define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */ | ||
69 | #define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */ | ||
70 | #define SASR0_BSY (1 << 2) /* I2S Busy */ | ||
71 | #define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */ | ||
72 | #define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */ | ||
73 | |||
74 | #define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */ | ||
75 | #define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */ | ||
76 | |||
77 | #define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */ | ||
78 | #define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */ | ||
79 | #define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */ | ||
80 | #define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */ | ||
81 | |||
33 | struct pxa_i2s_port { | 82 | struct pxa_i2s_port { |
34 | u32 sadiv; | 83 | u32 sadiv; |
35 | u32 sacr0; | 84 | u32 sacr0; |
@@ -44,7 +93,7 @@ static struct clk *clk_i2s; | |||
44 | static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { | 93 | static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { |
45 | .name = "I2S PCM Stereo out", | 94 | .name = "I2S PCM Stereo out", |
46 | .dev_addr = __PREG(SADR), | 95 | .dev_addr = __PREG(SADR), |
47 | .drcmr = &DRCMRTXSADR, | 96 | .drcmr = &DRCMR(3), |
48 | .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | | 97 | .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | |
49 | DCMD_BURST32 | DCMD_WIDTH4, | 98 | DCMD_BURST32 | DCMD_WIDTH4, |
50 | }; | 99 | }; |
@@ -52,7 +101,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { | |||
52 | static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { | 101 | static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { |
53 | .name = "I2S PCM Stereo in", | 102 | .name = "I2S PCM Stereo in", |
54 | .dev_addr = __PREG(SADR), | 103 | .dev_addr = __PREG(SADR), |
55 | .drcmr = &DRCMRRXSADR, | 104 | .drcmr = &DRCMR(2), |
56 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | | 105 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | |
57 | DCMD_BURST32 | DCMD_WIDTH4, | 106 | DCMD_BURST32 | DCMD_WIDTH4, |
58 | }; | 107 | }; |
@@ -65,11 +114,6 @@ static struct pxa2xx_gpio gpio_bus[] = { | |||
65 | .frm = GPIO31_SYNC_I2S_MD, | 114 | .frm = GPIO31_SYNC_I2S_MD, |
66 | }, | 115 | }, |
67 | { /* I2S SoC Master */ | 116 | { /* I2S SoC Master */ |
68 | #ifdef CONFIG_PXA27x | ||
69 | .sys = GPIO113_I2S_SYSCLK_MD, | ||
70 | #else | ||
71 | .sys = GPIO32_SYSCLK_I2S_MD, | ||
72 | #endif | ||
73 | .rx = GPIO29_SDATA_IN_I2S_MD, | 117 | .rx = GPIO29_SDATA_IN_I2S_MD, |
74 | .tx = GPIO30_SDATA_OUT_I2S_MD, | 118 | .tx = GPIO30_SDATA_OUT_I2S_MD, |
75 | .clk = GPIO28_BITCLK_OUT_I2S_MD, | 119 | .clk = GPIO28_BITCLK_OUT_I2S_MD, |
@@ -343,6 +387,11 @@ static struct platform_driver pxa2xx_i2s_driver = { | |||
343 | 387 | ||
344 | static int __init pxa2xx_i2s_init(void) | 388 | static int __init pxa2xx_i2s_init(void) |
345 | { | 389 | { |
390 | if (cpu_is_pxa27x()) | ||
391 | gpio_bus[1].sys = GPIO113_I2S_SYSCLK_MD; | ||
392 | else | ||
393 | gpio_bus[1].sys = GPIO32_SYSCLK_I2S_MD; | ||
394 | |||
346 | clk_i2s = ERR_PTR(-ENOENT); | 395 | clk_i2s = ERR_PTR(-ENOENT); |
347 | return platform_driver_register(&pxa2xx_i2s_driver); | 396 | return platform_driver_register(&pxa2xx_i2s_driver); |
348 | } | 397 | } |
@@ -356,6 +405,6 @@ module_init(pxa2xx_i2s_init); | |||
356 | module_exit(pxa2xx_i2s_exit); | 405 | module_exit(pxa2xx_i2s_exit); |
357 | 406 | ||
358 | /* Module information */ | 407 | /* Module information */ |
359 | MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); | 408 | MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); |
360 | MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); | 409 | MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); |
361 | MODULE_LICENSE("GPL"); | 410 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index 4345f387fe41..afcd892cd2fa 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c | |||
@@ -10,64 +10,14 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/dma-mapping.h> | 13 | #include <linux/dma-mapping.h> |
18 | 14 | ||
19 | #include <sound/core.h> | 15 | #include <sound/core.h> |
20 | #include <sound/pcm.h> | ||
21 | #include <sound/pcm_params.h> | ||
22 | #include <sound/soc.h> | 16 | #include <sound/soc.h> |
23 | 17 | #include <sound/pxa2xx-lib.h> | |
24 | #include <asm/dma.h> | ||
25 | #include <mach/hardware.h> | ||
26 | #include <mach/pxa-regs.h> | ||
27 | #include <mach/audio.h> | ||
28 | 18 | ||
29 | #include "pxa2xx-pcm.h" | 19 | #include "pxa2xx-pcm.h" |
30 | 20 | #include "../../arm/pxa2xx-pcm.h" | |
31 | static const struct snd_pcm_hardware pxa2xx_pcm_hardware = { | ||
32 | .info = SNDRV_PCM_INFO_MMAP | | ||
33 | SNDRV_PCM_INFO_MMAP_VALID | | ||
34 | SNDRV_PCM_INFO_INTERLEAVED | | ||
35 | SNDRV_PCM_INFO_PAUSE | | ||
36 | SNDRV_PCM_INFO_RESUME, | ||
37 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
38 | SNDRV_PCM_FMTBIT_S24_LE | | ||
39 | SNDRV_PCM_FMTBIT_S32_LE, | ||
40 | .period_bytes_min = 32, | ||
41 | .period_bytes_max = 8192 - 32, | ||
42 | .periods_min = 1, | ||
43 | .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc), | ||
44 | .buffer_bytes_max = 128 * 1024, | ||
45 | .fifo_size = 32, | ||
46 | }; | ||
47 | |||
48 | struct pxa2xx_runtime_data { | ||
49 | int dma_ch; | ||
50 | struct pxa2xx_pcm_dma_params *params; | ||
51 | pxa_dma_desc *dma_desc_array; | ||
52 | dma_addr_t dma_desc_array_phys; | ||
53 | }; | ||
54 | |||
55 | static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) | ||
56 | { | ||
57 | struct snd_pcm_substream *substream = dev_id; | ||
58 | struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; | ||
59 | int dcsr; | ||
60 | |||
61 | dcsr = DCSR(dma_ch); | ||
62 | DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN; | ||
63 | |||
64 | if (dcsr & DCSR_ENDINTR) { | ||
65 | snd_pcm_period_elapsed(substream); | ||
66 | } else { | ||
67 | printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", | ||
68 | prtd->params->name, dma_ch, dcsr); | ||
69 | } | ||
70 | } | ||
71 | 21 | ||
72 | static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, | 22 | static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, |
73 | struct snd_pcm_hw_params *params) | 23 | struct snd_pcm_hw_params *params) |
@@ -76,10 +26,6 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
76 | struct pxa2xx_runtime_data *prtd = runtime->private_data; | 26 | struct pxa2xx_runtime_data *prtd = runtime->private_data; |
77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 27 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
78 | struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; | 28 | struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; |
79 | size_t totsize = params_buffer_bytes(params); | ||
80 | size_t period = params_period_bytes(params); | ||
81 | pxa_dma_desc *dma_desc; | ||
82 | dma_addr_t dma_buff_phys, next_desc_phys; | ||
83 | int ret; | 29 | int ret; |
84 | 30 | ||
85 | /* return if this is a bufferless transfer e.g. | 31 | /* return if this is a bufferless transfer e.g. |
@@ -106,42 +52,16 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
106 | prtd->dma_ch = ret; | 52 | prtd->dma_ch = ret; |
107 | } | 53 | } |
108 | 54 | ||
109 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 55 | return __pxa2xx_pcm_hw_params(substream, params); |
110 | runtime->dma_bytes = totsize; | ||
111 | |||
112 | dma_desc = prtd->dma_desc_array; | ||
113 | next_desc_phys = prtd->dma_desc_array_phys; | ||
114 | dma_buff_phys = runtime->dma_addr; | ||
115 | do { | ||
116 | next_desc_phys += sizeof(pxa_dma_desc); | ||
117 | dma_desc->ddadr = next_desc_phys; | ||
118 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
119 | dma_desc->dsadr = dma_buff_phys; | ||
120 | dma_desc->dtadr = prtd->params->dev_addr; | ||
121 | } else { | ||
122 | dma_desc->dsadr = prtd->params->dev_addr; | ||
123 | dma_desc->dtadr = dma_buff_phys; | ||
124 | } | ||
125 | if (period > totsize) | ||
126 | period = totsize; | ||
127 | dma_desc->dcmd = prtd->params->dcmd | period | DCMD_ENDIRQEN; | ||
128 | dma_desc++; | ||
129 | dma_buff_phys += period; | ||
130 | } while (totsize -= period); | ||
131 | dma_desc[-1].ddadr = prtd->dma_desc_array_phys; | ||
132 | |||
133 | return 0; | ||
134 | } | 56 | } |
135 | 57 | ||
136 | static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) | 58 | static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) |
137 | { | 59 | { |
138 | struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; | 60 | struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; |
139 | 61 | ||
140 | if (prtd && prtd->params) | 62 | __pxa2xx_pcm_hw_free(substream); |
141 | *prtd->params->drcmr = 0; | ||
142 | 63 | ||
143 | if (prtd->dma_ch) { | 64 | if (prtd->dma_ch) { |
144 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
145 | pxa_free_dma(prtd->dma_ch); | 65 | pxa_free_dma(prtd->dma_ch); |
146 | prtd->dma_ch = 0; | 66 | prtd->dma_ch = 0; |
147 | } | 67 | } |
@@ -149,188 +69,21 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
149 | return 0; | 69 | return 0; |
150 | } | 70 | } |
151 | 71 | ||
152 | static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) | ||
153 | { | ||
154 | struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; | ||
155 | |||
156 | DCSR(prtd->dma_ch) &= ~DCSR_RUN; | ||
157 | DCSR(prtd->dma_ch) = 0; | ||
158 | DCMD(prtd->dma_ch) = 0; | ||
159 | *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD; | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
165 | { | ||
166 | struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; | ||
167 | int ret = 0; | ||
168 | |||
169 | switch (cmd) { | ||
170 | case SNDRV_PCM_TRIGGER_START: | ||
171 | DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys; | ||
172 | DCSR(prtd->dma_ch) = DCSR_RUN; | ||
173 | break; | ||
174 | |||
175 | case SNDRV_PCM_TRIGGER_STOP: | ||
176 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
177 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
178 | DCSR(prtd->dma_ch) &= ~DCSR_RUN; | ||
179 | break; | ||
180 | |||
181 | case SNDRV_PCM_TRIGGER_RESUME: | ||
182 | DCSR(prtd->dma_ch) |= DCSR_RUN; | ||
183 | break; | ||
184 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
185 | DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys; | ||
186 | DCSR(prtd->dma_ch) |= DCSR_RUN; | ||
187 | break; | ||
188 | |||
189 | default: | ||
190 | ret = -EINVAL; | ||
191 | } | ||
192 | |||
193 | return ret; | ||
194 | } | ||
195 | |||
196 | static snd_pcm_uframes_t | ||
197 | pxa2xx_pcm_pointer(struct snd_pcm_substream *substream) | ||
198 | { | ||
199 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
200 | struct pxa2xx_runtime_data *prtd = runtime->private_data; | ||
201 | |||
202 | dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
203 | DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch); | ||
204 | snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr); | ||
205 | |||
206 | if (x == runtime->buffer_size) | ||
207 | x = 0; | ||
208 | return x; | ||
209 | } | ||
210 | |||
211 | static int pxa2xx_pcm_open(struct snd_pcm_substream *substream) | ||
212 | { | ||
213 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
214 | struct pxa2xx_runtime_data *prtd; | ||
215 | int ret; | ||
216 | |||
217 | snd_soc_set_runtime_hwparams(substream, &pxa2xx_pcm_hardware); | ||
218 | |||
219 | /* | ||
220 | * For mysterious reasons (and despite what the manual says) | ||
221 | * playback samples are lost if the DMA count is not a multiple | ||
222 | * of the DMA burst size. Let's add a rule to enforce that. | ||
223 | */ | ||
224 | ret = snd_pcm_hw_constraint_step(runtime, 0, | ||
225 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); | ||
226 | if (ret) | ||
227 | goto out; | ||
228 | |||
229 | ret = snd_pcm_hw_constraint_step(runtime, 0, | ||
230 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); | ||
231 | if (ret) | ||
232 | goto out; | ||
233 | |||
234 | ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
235 | if (ret < 0) | ||
236 | goto out; | ||
237 | |||
238 | prtd = kzalloc(sizeof(struct pxa2xx_runtime_data), GFP_KERNEL); | ||
239 | if (prtd == NULL) { | ||
240 | ret = -ENOMEM; | ||
241 | goto out; | ||
242 | } | ||
243 | |||
244 | prtd->dma_desc_array = | ||
245 | dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE, | ||
246 | &prtd->dma_desc_array_phys, GFP_KERNEL); | ||
247 | if (!prtd->dma_desc_array) { | ||
248 | ret = -ENOMEM; | ||
249 | goto err1; | ||
250 | } | ||
251 | |||
252 | runtime->private_data = prtd; | ||
253 | return 0; | ||
254 | |||
255 | err1: | ||
256 | kfree(prtd); | ||
257 | out: | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) | ||
262 | { | ||
263 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
264 | struct pxa2xx_runtime_data *prtd = runtime->private_data; | ||
265 | |||
266 | dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE, | ||
267 | prtd->dma_desc_array, prtd->dma_desc_array_phys); | ||
268 | kfree(prtd); | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, | ||
273 | struct vm_area_struct *vma) | ||
274 | { | ||
275 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
276 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
277 | runtime->dma_area, | ||
278 | runtime->dma_addr, | ||
279 | runtime->dma_bytes); | ||
280 | } | ||
281 | |||
282 | struct snd_pcm_ops pxa2xx_pcm_ops = { | 72 | struct snd_pcm_ops pxa2xx_pcm_ops = { |
283 | .open = pxa2xx_pcm_open, | 73 | .open = __pxa2xx_pcm_open, |
284 | .close = pxa2xx_pcm_close, | 74 | .close = __pxa2xx_pcm_close, |
285 | .ioctl = snd_pcm_lib_ioctl, | 75 | .ioctl = snd_pcm_lib_ioctl, |
286 | .hw_params = pxa2xx_pcm_hw_params, | 76 | .hw_params = pxa2xx_pcm_hw_params, |
287 | .hw_free = pxa2xx_pcm_hw_free, | 77 | .hw_free = pxa2xx_pcm_hw_free, |
288 | .prepare = pxa2xx_pcm_prepare, | 78 | .prepare = __pxa2xx_pcm_prepare, |
289 | .trigger = pxa2xx_pcm_trigger, | 79 | .trigger = pxa2xx_pcm_trigger, |
290 | .pointer = pxa2xx_pcm_pointer, | 80 | .pointer = pxa2xx_pcm_pointer, |
291 | .mmap = pxa2xx_pcm_mmap, | 81 | .mmap = pxa2xx_pcm_mmap, |
292 | }; | 82 | }; |
293 | 83 | ||
294 | static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
295 | { | ||
296 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
297 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
298 | size_t size = pxa2xx_pcm_hardware.buffer_bytes_max; | ||
299 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
300 | buf->dev.dev = pcm->card->dev; | ||
301 | buf->private_data = NULL; | ||
302 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
303 | &buf->addr, GFP_KERNEL); | ||
304 | if (!buf->area) | ||
305 | return -ENOMEM; | ||
306 | buf->bytes = size; | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm) | ||
311 | { | ||
312 | struct snd_pcm_substream *substream; | ||
313 | struct snd_dma_buffer *buf; | ||
314 | int stream; | ||
315 | |||
316 | for (stream = 0; stream < 2; stream++) { | ||
317 | substream = pcm->streams[stream].substream; | ||
318 | if (!substream) | ||
319 | continue; | ||
320 | |||
321 | buf = &substream->dma_buffer; | ||
322 | if (!buf->area) | ||
323 | continue; | ||
324 | |||
325 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
326 | buf->area, buf->addr); | ||
327 | buf->area = NULL; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; | 84 | static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; |
332 | 85 | ||
333 | int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, | 86 | static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, |
334 | struct snd_pcm *pcm) | 87 | struct snd_pcm *pcm) |
335 | { | 88 | { |
336 | int ret = 0; | 89 | int ret = 0; |
@@ -360,7 +113,7 @@ int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, | |||
360 | struct snd_soc_platform pxa2xx_soc_platform = { | 113 | struct snd_soc_platform pxa2xx_soc_platform = { |
361 | .name = "pxa2xx-audio", | 114 | .name = "pxa2xx-audio", |
362 | .pcm_ops = &pxa2xx_pcm_ops, | 115 | .pcm_ops = &pxa2xx_pcm_ops, |
363 | .pcm_new = pxa2xx_pcm_new, | 116 | .pcm_new = pxa2xx_soc_pcm_new, |
364 | .pcm_free = pxa2xx_pcm_free_dma_buffers, | 117 | .pcm_free = pxa2xx_pcm_free_dma_buffers, |
365 | }; | 118 | }; |
366 | EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); | 119 | EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); |
diff --git a/sound/soc/pxa/pxa2xx-pcm.h b/sound/soc/pxa/pxa2xx-pcm.h index 54c9c755e508..60c3b20aeeb4 100644 --- a/sound/soc/pxa/pxa2xx-pcm.h +++ b/sound/soc/pxa/pxa2xx-pcm.h | |||
@@ -13,21 +13,6 @@ | |||
13 | #ifndef _PXA2XX_PCM_H | 13 | #ifndef _PXA2XX_PCM_H |
14 | #define _PXA2XX_PCM_H | 14 | #define _PXA2XX_PCM_H |
15 | 15 | ||
16 | struct pxa2xx_pcm_dma_params { | ||
17 | char *name; /* stream identifier */ | ||
18 | u32 dcmd; /* DMA descriptor dcmd field */ | ||
19 | volatile u32 *drcmr; /* the DMA request channel to use */ | ||
20 | u32 dev_addr; /* device physical address for DMA */ | ||
21 | }; | ||
22 | |||
23 | struct pxa2xx_gpio { | ||
24 | u32 sys; | ||
25 | u32 rx; | ||
26 | u32 tx; | ||
27 | u32 clk; | ||
28 | u32 frm; | ||
29 | }; | ||
30 | |||
31 | /* platform data */ | 16 | /* platform data */ |
32 | extern struct snd_soc_platform pxa2xx_soc_platform; | 17 | extern struct snd_soc_platform pxa2xx_soc_platform; |
33 | 18 | ||
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 37cb768fc933..d307b6757e95 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2005 Wolfson Microelectronics PLC. | 4 | * Copyright 2005 Wolfson Microelectronics PLC. |
5 | * Copyright 2005 Openedhand Ltd. | 5 | * Copyright 2005 Openedhand Ltd. |
6 | * | 6 | * |
7 | * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 7 | * Authors: Liam Girdwood <lrg@slimlogic.co.uk> |
8 | * Richard Purdie <richard@openedhand.com> | 8 | * Richard Purdie <richard@openedhand.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
@@ -19,16 +19,15 @@ | |||
19 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/gpio.h> | ||
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
24 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
25 | #include <sound/soc-dapm.h> | 26 | #include <sound/soc-dapm.h> |
26 | 27 | ||
27 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
28 | #include <asm/hardware/scoop.h> | ||
29 | #include <mach/pxa-regs.h> | 29 | #include <mach/pxa-regs.h> |
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
31 | #include <mach/akita.h> | ||
32 | #include <mach/spitz.h> | 31 | #include <mach/spitz.h> |
33 | #include "../codecs/wm8750.h" | 32 | #include "../codecs/wm8750.h" |
34 | #include "pxa2xx-pcm.h" | 33 | #include "pxa2xx-pcm.h" |
@@ -63,8 +62,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) | |||
63 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); | 62 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); |
64 | snd_soc_dapm_disable_pin(codec, "Line Jack"); | 63 | snd_soc_dapm_disable_pin(codec, "Line Jack"); |
65 | snd_soc_dapm_enable_pin(codec, "Headphone Jack"); | 64 | snd_soc_dapm_enable_pin(codec, "Headphone Jack"); |
66 | set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); | 65 | gpio_set_value(SPITZ_GPIO_MUTE_L, 1); |
67 | set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); | 66 | gpio_set_value(SPITZ_GPIO_MUTE_R, 1); |
68 | break; | 67 | break; |
69 | case SPITZ_MIC: | 68 | case SPITZ_MIC: |
70 | /* enable mic jack and bias, mute hp */ | 69 | /* enable mic jack and bias, mute hp */ |
@@ -72,8 +71,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) | |||
72 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 71 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); |
73 | snd_soc_dapm_disable_pin(codec, "Line Jack"); | 72 | snd_soc_dapm_disable_pin(codec, "Line Jack"); |
74 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); | 73 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); |
75 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); | 74 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
76 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); | 75 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); |
77 | break; | 76 | break; |
78 | case SPITZ_LINE: | 77 | case SPITZ_LINE: |
79 | /* enable line jack, disable mic bias and mute hp */ | 78 | /* enable line jack, disable mic bias and mute hp */ |
@@ -81,8 +80,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) | |||
81 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 80 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); |
82 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); | 81 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); |
83 | snd_soc_dapm_enable_pin(codec, "Line Jack"); | 82 | snd_soc_dapm_enable_pin(codec, "Line Jack"); |
84 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); | 83 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
85 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); | 84 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); |
86 | break; | 85 | break; |
87 | case SPITZ_HEADSET: | 86 | case SPITZ_HEADSET: |
88 | /* enable and unmute headset jack enable mic bias, mute L hp */ | 87 | /* enable and unmute headset jack enable mic bias, mute L hp */ |
@@ -90,8 +89,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) | |||
90 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); | 89 | snd_soc_dapm_enable_pin(codec, "Mic Jack"); |
91 | snd_soc_dapm_disable_pin(codec, "Line Jack"); | 90 | snd_soc_dapm_disable_pin(codec, "Line Jack"); |
92 | snd_soc_dapm_enable_pin(codec, "Headset Jack"); | 91 | snd_soc_dapm_enable_pin(codec, "Headset Jack"); |
93 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); | 92 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
94 | set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); | 93 | gpio_set_value(SPITZ_GPIO_MUTE_R, 1); |
95 | break; | 94 | break; |
96 | case SPITZ_HP_OFF: | 95 | case SPITZ_HP_OFF: |
97 | 96 | ||
@@ -100,8 +99,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) | |||
100 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 99 | snd_soc_dapm_disable_pin(codec, "Headset Jack"); |
101 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); | 100 | snd_soc_dapm_disable_pin(codec, "Mic Jack"); |
102 | snd_soc_dapm_disable_pin(codec, "Line Jack"); | 101 | snd_soc_dapm_disable_pin(codec, "Line Jack"); |
103 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); | 102 | gpio_set_value(SPITZ_GPIO_MUTE_L, 0); |
104 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); | 103 | gpio_set_value(SPITZ_GPIO_MUTE_R, 0); |
105 | break; | 104 | break; |
106 | } | 105 | } |
107 | snd_soc_dapm_sync(codec); | 106 | snd_soc_dapm_sync(codec); |
@@ -215,23 +214,14 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol, | |||
215 | static int spitz_mic_bias(struct snd_soc_dapm_widget *w, | 214 | static int spitz_mic_bias(struct snd_soc_dapm_widget *w, |
216 | struct snd_kcontrol *k, int event) | 215 | struct snd_kcontrol *k, int event) |
217 | { | 216 | { |
218 | if (machine_is_borzoi() || machine_is_spitz()) { | 217 | if (machine_is_borzoi() || machine_is_spitz()) |
219 | if (SND_SOC_DAPM_EVENT_ON(event)) | 218 | gpio_set_value(SPITZ_GPIO_MIC_BIAS, |
220 | set_scoop_gpio(&spitzscoop2_device.dev, | 219 | SND_SOC_DAPM_EVENT_ON(event)); |
221 | SPITZ_SCP2_MIC_BIAS); | 220 | |
222 | else | 221 | if (machine_is_akita()) |
223 | reset_scoop_gpio(&spitzscoop2_device.dev, | 222 | gpio_set_value(AKITA_GPIO_MIC_BIAS, |
224 | SPITZ_SCP2_MIC_BIAS); | 223 | SND_SOC_DAPM_EVENT_ON(event)); |
225 | } | ||
226 | 224 | ||
227 | if (machine_is_akita()) { | ||
228 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
229 | akita_set_ioexp(&akitaioexp_device.dev, | ||
230 | AKITA_IOEXP_MIC_BIAS); | ||
231 | else | ||
232 | akita_reset_ioexp(&akitaioexp_device.dev, | ||
233 | AKITA_IOEXP_MIC_BIAS); | ||
234 | } | ||
235 | return 0; | 225 | return 0; |
236 | } | 226 | } |
237 | 227 | ||
@@ -291,13 +281,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) | |||
291 | int i, err; | 281 | int i, err; |
292 | 282 | ||
293 | /* NC codec pins */ | 283 | /* NC codec pins */ |
294 | snd_soc_dapm_disable_pin(codec, "RINPUT1"); | 284 | snd_soc_dapm_nc_pin(codec, "RINPUT1"); |
295 | snd_soc_dapm_disable_pin(codec, "LINPUT2"); | 285 | snd_soc_dapm_nc_pin(codec, "LINPUT2"); |
296 | snd_soc_dapm_disable_pin(codec, "RINPUT2"); | 286 | snd_soc_dapm_nc_pin(codec, "RINPUT2"); |
297 | snd_soc_dapm_disable_pin(codec, "LINPUT3"); | 287 | snd_soc_dapm_nc_pin(codec, "LINPUT3"); |
298 | snd_soc_dapm_disable_pin(codec, "RINPUT3"); | 288 | snd_soc_dapm_nc_pin(codec, "RINPUT3"); |
299 | snd_soc_dapm_disable_pin(codec, "OUT3"); | 289 | snd_soc_dapm_nc_pin(codec, "OUT3"); |
300 | snd_soc_dapm_disable_pin(codec, "MONO1"); | 290 | snd_soc_dapm_nc_pin(codec, "MONO1"); |
301 | 291 | ||
302 | /* Add spitz specific controls */ | 292 | /* Add spitz specific controls */ |
303 | for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { | 293 | for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { |
@@ -337,6 +327,7 @@ static struct snd_soc_machine snd_soc_machine_spitz = { | |||
337 | 327 | ||
338 | /* spitz audio private data */ | 328 | /* spitz audio private data */ |
339 | static struct wm8750_setup_data spitz_wm8750_setup = { | 329 | static struct wm8750_setup_data spitz_wm8750_setup = { |
330 | .i2c_bus = 0, | ||
340 | .i2c_address = 0x1b, | 331 | .i2c_address = 0x1b, |
341 | }; | 332 | }; |
342 | 333 | ||
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 2baaa750f123..afefe41b8c46 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2005 Wolfson Microelectronics PLC. | 4 | * Copyright 2005 Wolfson Microelectronics PLC. |
5 | * Copyright 2005 Openedhand Ltd. | 5 | * Copyright 2005 Openedhand Ltd. |
6 | * | 6 | * |
7 | * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> | 7 | * Authors: Liam Girdwood <lrg@slimlogic.co.uk> |
8 | * Richard Purdie <richard@openedhand.com> | 8 | * Richard Purdie <richard@openedhand.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
@@ -190,8 +190,8 @@ static int tosa_ac97_init(struct snd_soc_codec *codec) | |||
190 | { | 190 | { |
191 | int i, err; | 191 | int i, err; |
192 | 192 | ||
193 | snd_soc_dapm_disable_pin(codec, "OUT3"); | 193 | snd_soc_dapm_nc_pin(codec, "OUT3"); |
194 | snd_soc_dapm_disable_pin(codec, "MONOOUT"); | 194 | snd_soc_dapm_nc_pin(codec, "MONOOUT"); |
195 | 195 | ||
196 | /* add tosa specific controls */ | 196 | /* add tosa specific controls */ |
197 | for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { | 197 | for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { |