diff options
author | Dmitry Baryshkov <dbaryshkov@gmail.com> | 2008-09-09 21:01:17 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-09-23 02:18:08 -0400 |
commit | 9c63634221f67450ead19820e33996b69691194f (patch) | |
tree | e21917379124783bbf37348c84bf9765cd1dc5d1 /sound/arm | |
parent | 081b355dd5a17788880a0241ed988c7483c1e40f (diff) |
ALSA: Separate common pxa2xx-ac97 code
ASoC and non-ASoC drivers for ACLINK on PXA share lot's of common code.
Move all common code into separate module snd-pxa2xx-lib.
[Fixed handing of SND_AC97_CODEC in Kconfig and some checkpatch warnings
-- broonie]
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/arm')
-rw-r--r-- | sound/arm/Kconfig | 5 | ||||
-rw-r--r-- | sound/arm/Makefile | 3 | ||||
-rw-r--r-- | sound/arm/pxa2xx-ac97-lib.c | 325 | ||||
-rw-r--r-- | sound/arm/pxa2xx-ac97.c | 247 |
4 files changed, 351 insertions, 229 deletions
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig index 351e19ea378..2e554815e27 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig | |||
@@ -32,11 +32,16 @@ config SND_PXA2XX_PCM | |||
32 | tristate | 32 | tristate |
33 | select SND_PCM | 33 | select SND_PCM |
34 | 34 | ||
35 | config SND_PXA2XX_LIB | ||
36 | tristate | ||
37 | select SND_AC97_CODEC | ||
38 | |||
35 | config SND_PXA2XX_AC97 | 39 | config SND_PXA2XX_AC97 |
36 | tristate "AC97 driver for the Intel PXA2xx chip" | 40 | tristate "AC97 driver for the Intel PXA2xx chip" |
37 | depends on ARCH_PXA | 41 | depends on ARCH_PXA |
38 | select SND_PXA2XX_PCM | 42 | select SND_PXA2XX_PCM |
39 | select SND_AC97_CODEC | 43 | select SND_AC97_CODEC |
44 | select SND_PXA2XX_LIB | ||
40 | help | 45 | help |
41 | Say Y or M if you want to support any AC97 codec attached to | 46 | Say Y or M if you want to support any AC97 codec attached to |
42 | the PXA2xx AC97 interface. | 47 | the PXA2xx AC97 interface. |
diff --git a/sound/arm/Makefile b/sound/arm/Makefile index 4ef6dd00c6e..bb2ed884acd 100644 --- a/sound/arm/Makefile +++ b/sound/arm/Makefile | |||
@@ -11,5 +11,8 @@ snd-aaci-objs := aaci.o devdma.o | |||
11 | obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o | 11 | obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o |
12 | snd-pxa2xx-pcm-objs := pxa2xx-pcm.o | 12 | snd-pxa2xx-pcm-objs := pxa2xx-pcm.o |
13 | 13 | ||
14 | obj-$(CONFIG_SND_PXA2XX_LIB) += snd-pxa2xx-lib.o | ||
15 | snd-pxa2xx-lib-objs := pxa2xx-ac97-lib.o | ||
16 | |||
14 | obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o | 17 | obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o |
15 | snd-pxa2xx-ac97-objs := pxa2xx-ac97.o | 18 | snd-pxa2xx-ac97-objs := pxa2xx-ac97.o |
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c new file mode 100644 index 00000000000..95f8ead44f2 --- /dev/null +++ b/sound/arm/pxa2xx-ac97-lib.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* | ||
2 | * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c | ||
3 | * which contain: | ||
4 | * | ||
5 | * Author: Nicolas Pitre | ||
6 | * Created: Dec 02, 2004 | ||
7 | * Copyright: MontaVista Software Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/delay.h> | ||
19 | |||
20 | #include <sound/ac97_codec.h> | ||
21 | #include <sound/pxa2xx-lib.h> | ||
22 | |||
23 | #include <asm/irq.h> | ||
24 | #include <mach/hardware.h> | ||
25 | #include <mach/pxa-regs.h> | ||
26 | #include <mach/pxa2xx-gpio.h> | ||
27 | #include <mach/audio.h> | ||
28 | |||
29 | static DEFINE_MUTEX(car_mutex); | ||
30 | static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); | ||
31 | static volatile long gsr_bits; | ||
32 | static struct clk *ac97_clk; | ||
33 | #ifdef CONFIG_PXA27x | ||
34 | static struct clk *ac97conf_clk; | ||
35 | #endif | ||
36 | |||
37 | /* | ||
38 | * Beware PXA27x bugs: | ||
39 | * | ||
40 | * o Slot 12 read from modem space will hang controller. | ||
41 | * o CDONE, SDONE interrupt fails after any slot 12 IO. | ||
42 | * | ||
43 | * We therefore have an hybrid approach for waiting on SDONE (interrupt or | ||
44 | * 1 jiffy timeout if interrupt never comes). | ||
45 | */ | ||
46 | |||
47 | unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | ||
48 | { | ||
49 | unsigned short val = -1; | ||
50 | volatile u32 *reg_addr; | ||
51 | |||
52 | mutex_lock(&car_mutex); | ||
53 | |||
54 | /* set up primary or secondary codec space */ | ||
55 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
56 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
57 | #else | ||
58 | if (reg == AC97_GPIO_STATUS) | ||
59 | reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; | ||
60 | else | ||
61 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
62 | #endif | ||
63 | reg_addr += (reg >> 1); | ||
64 | |||
65 | /* start read access across the ac97 link */ | ||
66 | GSR = GSR_CDONE | GSR_SDONE; | ||
67 | gsr_bits = 0; | ||
68 | val = *reg_addr; | ||
69 | if (reg == AC97_GPIO_STATUS) | ||
70 | goto out; | ||
71 | if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 && | ||
72 | !((GSR | gsr_bits) & GSR_SDONE)) { | ||
73 | printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", | ||
74 | __func__, reg, GSR | gsr_bits); | ||
75 | val = -1; | ||
76 | goto out; | ||
77 | } | ||
78 | |||
79 | /* valid data now */ | ||
80 | GSR = GSR_CDONE | GSR_SDONE; | ||
81 | gsr_bits = 0; | ||
82 | val = *reg_addr; | ||
83 | /* but we've just started another cycle... */ | ||
84 | wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); | ||
85 | |||
86 | out: mutex_unlock(&car_mutex); | ||
87 | return val; | ||
88 | } | ||
89 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_read); | ||
90 | |||
91 | void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | ||
92 | unsigned short val) | ||
93 | { | ||
94 | volatile u32 *reg_addr; | ||
95 | |||
96 | mutex_lock(&car_mutex); | ||
97 | |||
98 | /* set up primary or secondary codec space */ | ||
99 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
100 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
101 | #else | ||
102 | if (reg == AC97_GPIO_STATUS) | ||
103 | reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; | ||
104 | else | ||
105 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
106 | #endif | ||
107 | reg_addr += (reg >> 1); | ||
108 | |||
109 | GSR = GSR_CDONE | GSR_SDONE; | ||
110 | gsr_bits = 0; | ||
111 | *reg_addr = val; | ||
112 | if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 && | ||
113 | !((GSR | gsr_bits) & GSR_CDONE)) | ||
114 | printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", | ||
115 | __func__, reg, GSR | gsr_bits); | ||
116 | |||
117 | mutex_unlock(&car_mutex); | ||
118 | } | ||
119 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_write); | ||
120 | |||
121 | bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) | ||
122 | { | ||
123 | #ifdef CONFIG_PXA3xx | ||
124 | int timeout = 100; | ||
125 | #endif | ||
126 | gsr_bits = 0; | ||
127 | |||
128 | #ifdef CONFIG_PXA27x | ||
129 | /* warm reset broken on Bulverde, | ||
130 | so manually keep AC97 reset high */ | ||
131 | pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); | ||
132 | udelay(10); | ||
133 | GCR |= GCR_WARM_RST; | ||
134 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
135 | udelay(500); | ||
136 | #elif defined(CONFIG_PXA3xx) | ||
137 | /* Can't use interrupts */ | ||
138 | GCR |= GCR_WARM_RST; | ||
139 | while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) | ||
140 | mdelay(1); | ||
141 | #else | ||
142 | GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN; | ||
143 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
144 | #endif | ||
145 | |||
146 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { | ||
147 | printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", | ||
148 | __func__, gsr_bits); | ||
149 | |||
150 | return false; | ||
151 | } | ||
152 | |||
153 | return true; | ||
154 | } | ||
155 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset); | ||
156 | |||
157 | bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) | ||
158 | { | ||
159 | #ifdef CONFIG_PXA3xx | ||
160 | int timeout = 1000; | ||
161 | |||
162 | /* Hold CLKBPB for 100us */ | ||
163 | GCR = 0; | ||
164 | GCR = GCR_CLKBPB; | ||
165 | udelay(100); | ||
166 | GCR = 0; | ||
167 | #endif | ||
168 | |||
169 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ | ||
170 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ | ||
171 | |||
172 | gsr_bits = 0; | ||
173 | #ifdef CONFIG_PXA27x | ||
174 | /* PXA27x Developers Manual section 13.5.2.2.1 */ | ||
175 | clk_enable(ac97conf_clk); | ||
176 | udelay(5); | ||
177 | clk_disable(ac97conf_clk); | ||
178 | GCR = GCR_COLD_RST; | ||
179 | udelay(50); | ||
180 | #elif defined(CONFIG_PXA3xx) | ||
181 | /* Can't use interrupts on PXA3xx */ | ||
182 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | ||
183 | |||
184 | GCR = GCR_WARM_RST | GCR_COLD_RST; | ||
185 | while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--) | ||
186 | mdelay(10); | ||
187 | #else | ||
188 | GCR = GCR_COLD_RST; | ||
189 | GCR |= GCR_CDONE_IE|GCR_SDONE_IE; | ||
190 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
191 | #endif | ||
192 | |||
193 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { | ||
194 | printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", | ||
195 | __func__, gsr_bits); | ||
196 | |||
197 | return false; | ||
198 | } | ||
199 | |||
200 | return true; | ||
201 | } | ||
202 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset); | ||
203 | |||
204 | |||
205 | void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97) | ||
206 | { | ||
207 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | ||
208 | GCR |= GCR_SDONE_IE|GCR_CDONE_IE; | ||
209 | } | ||
210 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset); | ||
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 | } | ||
236 | |||
237 | #ifdef CONFIG_PM | ||
238 | int pxa2xx_ac97_hw_suspend(void) | ||
239 | { | ||
240 | GCR |= GCR_ACLINK_OFF; | ||
241 | clk_disable(ac97_clk); | ||
242 | return 0; | ||
243 | } | ||
244 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend); | ||
245 | |||
246 | int pxa2xx_ac97_hw_resume(void) | ||
247 | { | ||
248 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | ||
249 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | ||
250 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | ||
251 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | ||
252 | #ifdef CONFIG_PXA27x | ||
253 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | ||
254 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
255 | #endif | ||
256 | clk_enable(ac97_clk); | ||
257 | return 0; | ||
258 | } | ||
259 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume); | ||
260 | #endif | ||
261 | |||
262 | int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) | ||
263 | { | ||
264 | int ret; | ||
265 | |||
266 | ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); | ||
267 | if (ret < 0) | ||
268 | goto err; | ||
269 | |||
270 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | ||
271 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | ||
272 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | ||
273 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | ||
274 | #ifdef CONFIG_PXA27x | ||
275 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | ||
276 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
277 | ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); | ||
278 | if (IS_ERR(ac97conf_clk)) { | ||
279 | ret = PTR_ERR(ac97conf_clk); | ||
280 | ac97conf_clk = NULL; | ||
281 | goto err_irq; | ||
282 | } | ||
283 | #endif | ||
284 | |||
285 | ac97_clk = clk_get(&dev->dev, "AC97CLK"); | ||
286 | if (IS_ERR(ac97_clk)) { | ||
287 | ret = PTR_ERR(ac97_clk); | ||
288 | ac97_clk = NULL; | ||
289 | goto err_irq; | ||
290 | } | ||
291 | |||
292 | return clk_enable(ac97_clk); | ||
293 | |||
294 | err_irq: | ||
295 | GCR |= GCR_ACLINK_OFF; | ||
296 | #ifdef CONFIG_PXA27x | ||
297 | if (ac97conf_clk) { | ||
298 | clk_put(ac97conf_clk); | ||
299 | ac97conf_clk = NULL; | ||
300 | } | ||
301 | #endif | ||
302 | free_irq(IRQ_AC97, NULL); | ||
303 | err: | ||
304 | return ret; | ||
305 | } | ||
306 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); | ||
307 | |||
308 | void pxa2xx_ac97_hw_remove(struct platform_device *dev) | ||
309 | { | ||
310 | GCR |= GCR_ACLINK_OFF; | ||
311 | free_irq(IRQ_AC97, NULL); | ||
312 | #ifdef CONFIG_PXA27x | ||
313 | clk_put(ac97conf_clk); | ||
314 | ac97conf_clk = NULL; | ||
315 | #endif | ||
316 | clk_disable(ac97_clk); | ||
317 | clk_put(ac97_clk); | ||
318 | ac97_clk = NULL; | ||
319 | } | ||
320 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove); | ||
321 | |||
322 | MODULE_AUTHOR("Nicolas Pitre"); | ||
323 | MODULE_DESCRIPTION("Intel/Marvell PXA sound library"); | ||
324 | MODULE_LICENSE("GPL"); | ||
325 | |||
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 199cca3366d..cba71d86754 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c | |||
@@ -12,198 +12,27 @@ | |||
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | ||
16 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/wait.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/delay.h> | ||
21 | 16 | ||
22 | #include <sound/core.h> | 17 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 18 | #include <sound/pcm.h> |
24 | #include <sound/ac97_codec.h> | 19 | #include <sound/ac97_codec.h> |
25 | #include <sound/initval.h> | 20 | #include <sound/initval.h> |
21 | #include <sound/pxa2xx-lib.h> | ||
26 | 22 | ||
27 | #include <asm/irq.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
30 | #include <mach/pxa-regs.h> | 24 | #include <mach/pxa-regs.h> |
31 | #include <mach/pxa2xx-gpio.h> | ||
32 | #include <mach/audio.h> | 25 | #include <mach/audio.h> |
33 | 26 | ||
34 | #include "pxa2xx-pcm.h" | 27 | #include "pxa2xx-pcm.h" |
35 | 28 | ||
36 | |||
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, unsigned short reg) | ||
56 | { | ||
57 | unsigned short val = -1; | ||
58 | volatile u32 *reg_addr; | ||
59 | |||
60 | mutex_lock(&car_mutex); | ||
61 | |||
62 | /* set up primary or secondary codec space */ | ||
63 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
64 | reg_addr += (reg >> 1); | ||
65 | |||
66 | /* start read access across the ac97 link */ | ||
67 | GSR = GSR_CDONE | GSR_SDONE; | ||
68 | gsr_bits = 0; | ||
69 | val = *reg_addr; | ||
70 | if (reg == AC97_GPIO_STATUS) | ||
71 | goto out; | ||
72 | if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 && | ||
73 | !((GSR | gsr_bits) & GSR_SDONE)) { | ||
74 | printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", | ||
75 | __func__, reg, GSR | gsr_bits); | ||
76 | val = -1; | ||
77 | goto out; | ||
78 | } | ||
79 | |||
80 | /* valid data now */ | ||
81 | GSR = GSR_CDONE | GSR_SDONE; | ||
82 | gsr_bits = 0; | ||
83 | val = *reg_addr; | ||
84 | /* but we've just started another cycle... */ | ||
85 | wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); | ||
86 | |||
87 | out: mutex_unlock(&car_mutex); | ||
88 | return val; | ||
89 | } | ||
90 | |||
91 | static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) | ||
92 | { | ||
93 | volatile u32 *reg_addr; | ||
94 | |||
95 | mutex_lock(&car_mutex); | ||
96 | |||
97 | /* set up primary or secondary codec space */ | ||
98 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
99 | reg_addr += (reg >> 1); | ||
100 | |||
101 | GSR = GSR_CDONE | GSR_SDONE; | ||
102 | gsr_bits = 0; | ||
103 | *reg_addr = val; | ||
104 | if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 && | ||
105 | !((GSR | gsr_bits) & GSR_CDONE)) | ||
106 | printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", | ||
107 | __func__, reg, GSR | gsr_bits); | ||
108 | |||
109 | mutex_unlock(&car_mutex); | ||
110 | } | ||
111 | |||
112 | static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) | 29 | static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) |
113 | { | 30 | { |
114 | /* First, try cold reset */ | 31 | if (!pxa2xx_ac97_try_cold_reset(ac97)) { |
115 | #ifdef CONFIG_PXA3xx | 32 | pxa2xx_ac97_try_warm_reset(ac97); |
116 | int timeout; | ||
117 | |||
118 | /* Hold CLKBPB for 100us */ | ||
119 | GCR = 0; | ||
120 | GCR = GCR_CLKBPB; | ||
121 | udelay(100); | ||
122 | GCR = 0; | ||
123 | #endif | ||
124 | |||
125 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ | ||
126 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ | ||
127 | |||
128 | gsr_bits = 0; | ||
129 | #ifdef CONFIG_PXA27x | ||
130 | /* PXA27x Developers Manual section 13.5.2.2.1 */ | ||
131 | clk_enable(ac97conf_clk); | ||
132 | udelay(5); | ||
133 | clk_disable(ac97conf_clk); | ||
134 | GCR = GCR_COLD_RST; | ||
135 | udelay(50); | ||
136 | #elif defined(CONFIG_PXA3xx) | ||
137 | timeout = 1000; | ||
138 | /* Can't use interrupts on PXA3xx */ | ||
139 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | ||
140 | |||
141 | GCR = GCR_WARM_RST | GCR_COLD_RST; | ||
142 | while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--) | ||
143 | mdelay(10); | ||
144 | #else | ||
145 | GCR = GCR_COLD_RST; | ||
146 | GCR |= GCR_CDONE_IE|GCR_SDONE_IE; | ||
147 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
148 | #endif | ||
149 | |||
150 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { | ||
151 | printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", | ||
152 | __func__, gsr_bits); | ||
153 | |||
154 | /* let's try warm reset */ | ||
155 | gsr_bits = 0; | ||
156 | #ifdef CONFIG_PXA27x | ||
157 | /* warm reset broken on Bulverde, | ||
158 | so manually keep AC97 reset high */ | ||
159 | pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); | ||
160 | udelay(10); | ||
161 | GCR |= GCR_WARM_RST; | ||
162 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
163 | udelay(500); | ||
164 | #elif defined(CONFIG_PXA3xx) | ||
165 | timeout = 100; | ||
166 | /* Can't use interrupts */ | ||
167 | GCR |= GCR_WARM_RST; | ||
168 | while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) | ||
169 | mdelay(1); | ||
170 | #else | ||
171 | GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN; | ||
172 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
173 | #endif | ||
174 | |||
175 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) | ||
176 | printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", | ||
177 | __func__, gsr_bits); | ||
178 | } | ||
179 | |||
180 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | ||
181 | GCR |= GCR_SDONE_IE|GCR_CDONE_IE; | ||
182 | } | ||
183 | |||
184 | static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) | ||
185 | { | ||
186 | long status; | ||
187 | |||
188 | status = GSR; | ||
189 | if (status) { | ||
190 | GSR = status; | ||
191 | gsr_bits |= status; | ||
192 | wake_up(&gsr_wq); | ||
193 | |||
194 | #ifdef CONFIG_PXA27x | ||
195 | /* Although we don't use those we still need to clear them | ||
196 | since they tend to spuriously trigger when MMC is used | ||
197 | (hardware bug? go figure)... */ | ||
198 | MISR = MISR_EOC; | ||
199 | PISR = PISR_EOC; | ||
200 | MCSR = MCSR_EOC; | ||
201 | #endif | ||
202 | |||
203 | return IRQ_HANDLED; | ||
204 | } | 33 | } |
205 | 34 | ||
206 | return IRQ_NONE; | 35 | pxa2xx_ac97_finish_reset(ac97); |
207 | } | 36 | } |
208 | 37 | ||
209 | static struct snd_ac97_bus_ops pxa2xx_ac97_ops = { | 38 | static struct snd_ac97_bus_ops pxa2xx_ac97_ops = { |
@@ -288,17 +117,19 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) | |||
288 | snd_ac97_suspend(pxa2xx_ac97_ac97); | 117 | snd_ac97_suspend(pxa2xx_ac97_ac97); |
289 | if (platform_ops && platform_ops->suspend) | 118 | if (platform_ops && platform_ops->suspend) |
290 | platform_ops->suspend(platform_ops->priv); | 119 | platform_ops->suspend(platform_ops->priv); |
291 | GCR |= GCR_ACLINK_OFF; | ||
292 | clk_disable(ac97_clk); | ||
293 | 120 | ||
294 | return 0; | 121 | return pxa2xx_ac97_hw_suspend(); |
295 | } | 122 | } |
296 | 123 | ||
297 | static int pxa2xx_ac97_do_resume(struct snd_card *card) | 124 | static int pxa2xx_ac97_do_resume(struct snd_card *card) |
298 | { | 125 | { |
299 | pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; | 126 | pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; |
127 | int rc; | ||
128 | |||
129 | rc = pxa2xx_ac97_hw_resume(); | ||
130 | if (rc) | ||
131 | return rc; | ||
300 | 132 | ||
301 | clk_enable(ac97_clk); | ||
302 | if (platform_ops && platform_ops->resume) | 133 | if (platform_ops && platform_ops->resume) |
303 | platform_ops->resume(platform_ops->priv); | 134 | platform_ops->resume(platform_ops->priv); |
304 | snd_ac97_resume(pxa2xx_ac97_ac97); | 135 | snd_ac97_resume(pxa2xx_ac97_ac97); |
@@ -354,40 +185,17 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) | |||
354 | if (ret) | 185 | if (ret) |
355 | goto err; | 186 | goto err; |
356 | 187 | ||
357 | ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); | 188 | ret = pxa2xx_ac97_hw_probe(dev); |
358 | if (ret < 0) | 189 | if (ret) |
359 | goto err; | ||
360 | |||
361 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | ||
362 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | ||
363 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | ||
364 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | ||
365 | #ifdef CONFIG_PXA27x | ||
366 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | ||
367 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
368 | ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); | ||
369 | if (IS_ERR(ac97conf_clk)) { | ||
370 | ret = PTR_ERR(ac97conf_clk); | ||
371 | ac97conf_clk = NULL; | ||
372 | goto err; | ||
373 | } | ||
374 | #endif | ||
375 | |||
376 | ac97_clk = clk_get(&dev->dev, "AC97CLK"); | ||
377 | if (IS_ERR(ac97_clk)) { | ||
378 | ret = PTR_ERR(ac97_clk); | ||
379 | ac97_clk = NULL; | ||
380 | goto err; | 190 | goto err; |
381 | } | ||
382 | clk_enable(ac97_clk); | ||
383 | 191 | ||
384 | ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); | 192 | ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); |
385 | if (ret) | 193 | if (ret) |
386 | goto err; | 194 | goto err_remove; |
387 | memset(&ac97_template, 0, sizeof(ac97_template)); | 195 | memset(&ac97_template, 0, sizeof(ac97_template)); |
388 | ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97); | 196 | ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97); |
389 | if (ret) | 197 | if (ret) |
390 | goto err; | 198 | goto err_remove; |
391 | 199 | ||
392 | snprintf(card->shortname, sizeof(card->shortname), | 200 | snprintf(card->shortname, sizeof(card->shortname), |
393 | "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97)); | 201 | "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97)); |
@@ -401,22 +209,11 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) | |||
401 | return 0; | 209 | return 0; |
402 | } | 210 | } |
403 | 211 | ||
404 | err: | 212 | err_remove: |
213 | pxa2xx_ac97_hw_remove(dev); | ||
214 | err: | ||
405 | if (card) | 215 | if (card) |
406 | snd_card_free(card); | 216 | snd_card_free(card); |
407 | if (ac97_clk) { | ||
408 | GCR |= GCR_ACLINK_OFF; | ||
409 | free_irq(IRQ_AC97, NULL); | ||
410 | clk_disable(ac97_clk); | ||
411 | clk_put(ac97_clk); | ||
412 | ac97_clk = NULL; | ||
413 | } | ||
414 | #ifdef CONFIG_PXA27x | ||
415 | if (ac97conf_clk) { | ||
416 | clk_put(ac97conf_clk); | ||
417 | ac97conf_clk = NULL; | ||
418 | } | ||
419 | #endif | ||
420 | return ret; | 217 | return ret; |
421 | } | 218 | } |
422 | 219 | ||
@@ -427,15 +224,7 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev) | |||
427 | if (card) { | 224 | if (card) { |
428 | snd_card_free(card); | 225 | snd_card_free(card); |
429 | platform_set_drvdata(dev, NULL); | 226 | platform_set_drvdata(dev, NULL); |
430 | GCR |= GCR_ACLINK_OFF; | 227 | pxa2xx_ac97_hw_remove(dev); |
431 | free_irq(IRQ_AC97, NULL); | ||
432 | clk_disable(ac97_clk); | ||
433 | clk_put(ac97_clk); | ||
434 | ac97_clk = NULL; | ||
435 | #ifdef CONFIG_PXA27x | ||
436 | clk_put(ac97conf_clk); | ||
437 | ac97conf_clk = NULL; | ||
438 | #endif | ||
439 | } | 228 | } |
440 | 229 | ||
441 | return 0; | 230 | return 0; |