diff options
author | Dmitry Baryshkov <dbaryshkov@gmail.com> | 2008-09-09 21:01:18 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-09-23 02:18:09 -0400 |
commit | 9d1cf39be6709761be3ce0a00e5c9ee5dc805ac5 (patch) | |
tree | 84e08a5ec82d1a3c3b107d7214b3848a544a9e8b /sound/arm | |
parent | 9c63634221f67450ead19820e33996b69691194f (diff) |
ALSA: pxa2xx-ac97-lib: support building for several CPUs
Support building of pxa2xx-ac97-lib for several CPUs by making code
run-time selected, not only compile-time.
[Fixed 3XX->3xx typos in ifdef checks -- 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/pxa2xx-ac97-lib.c | 215 |
1 files changed, 137 insertions, 78 deletions
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c index 95f8ead44f2a..99026dfb81ea 100644 --- a/sound/arm/pxa2xx-ac97-lib.c +++ b/sound/arm/pxa2xx-ac97-lib.c | |||
@@ -30,9 +30,7 @@ static DEFINE_MUTEX(car_mutex); | |||
30 | static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); | 30 | static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); |
31 | static volatile long gsr_bits; | 31 | static volatile long gsr_bits; |
32 | static struct clk *ac97_clk; | 32 | static struct clk *ac97_clk; |
33 | #ifdef CONFIG_PXA27x | ||
34 | static struct clk *ac97conf_clk; | 33 | static struct clk *ac97conf_clk; |
35 | #endif | ||
36 | 34 | ||
37 | /* | 35 | /* |
38 | * Beware PXA27x bugs: | 36 | * Beware PXA27x bugs: |
@@ -52,14 +50,10 @@ unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
52 | mutex_lock(&car_mutex); | 50 | mutex_lock(&car_mutex); |
53 | 51 | ||
54 | /* set up primary or secondary codec space */ | 52 | /* set up primary or secondary codec space */ |
55 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | 53 | if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS) |
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; | 54 | reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; |
60 | else | 55 | else |
61 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | 56 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; |
62 | #endif | ||
63 | reg_addr += (reg >> 1); | 57 | reg_addr += (reg >> 1); |
64 | 58 | ||
65 | /* start read access across the ac97 link */ | 59 | /* start read access across the ac97 link */ |
@@ -96,14 +90,10 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
96 | mutex_lock(&car_mutex); | 90 | mutex_lock(&car_mutex); |
97 | 91 | ||
98 | /* set up primary or secondary codec space */ | 92 | /* set up primary or secondary codec space */ |
99 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | 93 | if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS) |
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; | 94 | reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; |
104 | else | 95 | else |
105 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; | 96 | reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; |
106 | #endif | ||
107 | reg_addr += (reg >> 1); | 97 | reg_addr += (reg >> 1); |
108 | 98 | ||
109 | GSR = GSR_CDONE | GSR_SDONE; | 99 | GSR = GSR_CDONE | GSR_SDONE; |
@@ -118,14 +108,33 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
118 | } | 108 | } |
119 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_write); | 109 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_write); |
120 | 110 | ||
121 | bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) | 111 | #ifdef CONFIG_PXA25x |
112 | static inline void pxa_ac97_warm_pxa25x(void) | ||
122 | { | 113 | { |
123 | #ifdef CONFIG_PXA3xx | ||
124 | int timeout = 100; | ||
125 | #endif | ||
126 | gsr_bits = 0; | 114 | gsr_bits = 0; |
127 | 115 | ||
116 | GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN; | ||
117 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
118 | } | ||
119 | |||
120 | static inline void pxa_ac97_cold_pxa25x(void) | ||
121 | { | ||
122 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ | ||
123 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ | ||
124 | |||
125 | gsr_bits = 0; | ||
126 | |||
127 | GCR = GCR_COLD_RST; | ||
128 | GCR |= GCR_CDONE_IE|GCR_SDONE_IE; | ||
129 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
130 | } | ||
131 | #endif | ||
132 | |||
128 | #ifdef CONFIG_PXA27x | 133 | #ifdef CONFIG_PXA27x |
134 | static inline void pxa_ac97_warm_pxa27x(void) | ||
135 | { | ||
136 | gsr_bits = 0; | ||
137 | |||
129 | /* warm reset broken on Bulverde, | 138 | /* warm reset broken on Bulverde, |
130 | so manually keep AC97 reset high */ | 139 | so manually keep AC97 reset high */ |
131 | pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); | 140 | pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); |
@@ -133,30 +142,39 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) | |||
133 | GCR |= GCR_WARM_RST; | 142 | GCR |= GCR_WARM_RST; |
134 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | 143 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); |
135 | udelay(500); | 144 | udelay(500); |
136 | #elif defined(CONFIG_PXA3xx) | 145 | } |
137 | /* Can't use interrupts */ | 146 | |
138 | GCR |= GCR_WARM_RST; | 147 | static inline void pxa_ac97_cold_pxa27x(void) |
139 | while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) | 148 | { |
140 | mdelay(1); | 149 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ |
141 | #else | 150 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ |
142 | GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN; | 151 | |
143 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | 152 | gsr_bits = 0; |
153 | |||
154 | /* PXA27x Developers Manual section 13.5.2.2.1 */ | ||
155 | clk_enable(ac97conf_clk); | ||
156 | udelay(5); | ||
157 | clk_disable(ac97conf_clk); | ||
158 | GCR = GCR_COLD_RST; | ||
159 | udelay(50); | ||
160 | } | ||
144 | #endif | 161 | #endif |
145 | 162 | ||
146 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { | 163 | #ifdef CONFIG_PXA3xx |
147 | printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", | 164 | static inline void pxa_ac97_warm_pxa3xx(void) |
148 | __func__, gsr_bits); | 165 | { |
166 | int timeout = 100; | ||
149 | 167 | ||
150 | return false; | 168 | gsr_bits = 0; |
151 | } | ||
152 | 169 | ||
153 | return true; | 170 | /* Can't use interrupts */ |
171 | GCR |= GCR_WARM_RST; | ||
172 | while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) | ||
173 | mdelay(1); | ||
154 | } | 174 | } |
155 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset); | ||
156 | 175 | ||
157 | bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) | 176 | static inline void pxa_ac97_cold_pxa3xx(void) |
158 | { | 177 | { |
159 | #ifdef CONFIG_PXA3xx | ||
160 | int timeout = 1000; | 178 | int timeout = 1000; |
161 | 179 | ||
162 | /* Hold CLKBPB for 100us */ | 180 | /* Hold CLKBPB for 100us */ |
@@ -164,31 +182,69 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) | |||
164 | GCR = GCR_CLKBPB; | 182 | GCR = GCR_CLKBPB; |
165 | udelay(100); | 183 | udelay(100); |
166 | GCR = 0; | 184 | GCR = 0; |
167 | #endif | ||
168 | 185 | ||
169 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ | 186 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ |
170 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ | 187 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ |
171 | 188 | ||
172 | gsr_bits = 0; | 189 | gsr_bits = 0; |
173 | #ifdef CONFIG_PXA27x | 190 | |
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 */ | 191 | /* Can't use interrupts on PXA3xx */ |
182 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | 192 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); |
183 | 193 | ||
184 | GCR = GCR_WARM_RST | GCR_COLD_RST; | 194 | GCR = GCR_WARM_RST | GCR_COLD_RST; |
185 | while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--) | 195 | while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--) |
186 | mdelay(10); | 196 | mdelay(10); |
187 | #else | 197 | } |
188 | GCR = GCR_COLD_RST; | 198 | #endif |
189 | GCR |= GCR_CDONE_IE|GCR_SDONE_IE; | 199 | |
190 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | 200 | bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) |
201 | { | ||
202 | #ifdef CONFIG_PXA25x | ||
203 | if (cpu_is_pxa21x() || cpu_is_pxa25x()) | ||
204 | pxa_ac97_warm_pxa25x(); | ||
205 | else | ||
191 | #endif | 206 | #endif |
207 | #ifdef CONFIG_PXA27x | ||
208 | if (cpu_is_pxa27x()) | ||
209 | pxa_ac97_warm_pxa27x(); | ||
210 | else | ||
211 | #endif | ||
212 | #ifdef CONFIG_PXA3xx | ||
213 | if (cpu_is_pxa3xx()) | ||
214 | pxa_ac97_warm_pxa3xx(); | ||
215 | else | ||
216 | #endif | ||
217 | BUG(); | ||
218 | |||
219 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { | ||
220 | printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", | ||
221 | __func__, gsr_bits); | ||
222 | |||
223 | return false; | ||
224 | } | ||
225 | |||
226 | return true; | ||
227 | } | ||
228 | EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset); | ||
229 | |||
230 | bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) | ||
231 | { | ||
232 | #ifdef CONFIG_PXA25x | ||
233 | if (cpu_is_pxa21x() || cpu_is_pxa25x()) | ||
234 | pxa_ac97_cold_pxa25x(); | ||
235 | else | ||
236 | #endif | ||
237 | #ifdef CONFIG_PXA27x | ||
238 | if (cpu_is_pxa27x()) | ||
239 | pxa_ac97_cold_pxa27x(); | ||
240 | else | ||
241 | #endif | ||
242 | #ifdef CONFIG_PXA3xx | ||
243 | if (cpu_is_pxa3xx()) | ||
244 | pxa_ac97_cold_pxa3xx(); | ||
245 | else | ||
246 | #endif | ||
247 | BUG(); | ||
192 | 248 | ||
193 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { | 249 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { |
194 | printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", | 250 | printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", |
@@ -219,14 +275,14 @@ static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) | |||
219 | gsr_bits |= status; | 275 | gsr_bits |= status; |
220 | wake_up(&gsr_wq); | 276 | wake_up(&gsr_wq); |
221 | 277 | ||
222 | #ifdef CONFIG_PXA27x | ||
223 | /* Although we don't use those we still need to clear them | 278 | /* Although we don't use those we still need to clear them |
224 | since they tend to spuriously trigger when MMC is used | 279 | since they tend to spuriously trigger when MMC is used |
225 | (hardware bug? go figure)... */ | 280 | (hardware bug? go figure)... */ |
226 | MISR = MISR_EOC; | 281 | if (cpu_is_pxa27x()) { |
227 | PISR = PISR_EOC; | 282 | MISR = MISR_EOC; |
228 | MCSR = MCSR_EOC; | 283 | PISR = PISR_EOC; |
229 | #endif | 284 | MCSR = MCSR_EOC; |
285 | } | ||
230 | 286 | ||
231 | return IRQ_HANDLED; | 287 | return IRQ_HANDLED; |
232 | } | 288 | } |
@@ -245,14 +301,16 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend); | |||
245 | 301 | ||
246 | int pxa2xx_ac97_hw_resume(void) | 302 | int pxa2xx_ac97_hw_resume(void) |
247 | { | 303 | { |
248 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | 304 | if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) { |
249 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | 305 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); |
250 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | 306 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); |
251 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | 307 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); |
252 | #ifdef CONFIG_PXA27x | 308 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); |
253 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | 309 | } |
254 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | 310 | if (cpu_is_pxa27x()) { |
255 | #endif | 311 | /* Use GPIO 113 as AC97 Reset on Bulverde */ |
312 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
313 | } | ||
256 | clk_enable(ac97_clk); | 314 | clk_enable(ac97_clk); |
257 | return 0; | 315 | return 0; |
258 | } | 316 | } |
@@ -267,20 +325,23 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) | |||
267 | if (ret < 0) | 325 | if (ret < 0) |
268 | goto err; | 326 | goto err; |
269 | 327 | ||
270 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | 328 | if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) { |
271 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | 329 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); |
272 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | 330 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); |
273 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | 331 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); |
274 | #ifdef CONFIG_PXA27x | 332 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); |
275 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | 333 | } |
276 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | 334 | |
277 | ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); | 335 | if (cpu_is_pxa27x()) { |
278 | if (IS_ERR(ac97conf_clk)) { | 336 | /* Use GPIO 113 as AC97 Reset on Bulverde */ |
279 | ret = PTR_ERR(ac97conf_clk); | 337 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); |
280 | ac97conf_clk = NULL; | 338 | ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); |
281 | goto err_irq; | 339 | if (IS_ERR(ac97conf_clk)) { |
340 | ret = PTR_ERR(ac97conf_clk); | ||
341 | ac97conf_clk = NULL; | ||
342 | goto err_irq; | ||
343 | } | ||
282 | } | 344 | } |
283 | #endif | ||
284 | 345 | ||
285 | ac97_clk = clk_get(&dev->dev, "AC97CLK"); | 346 | ac97_clk = clk_get(&dev->dev, "AC97CLK"); |
286 | if (IS_ERR(ac97_clk)) { | 347 | if (IS_ERR(ac97_clk)) { |
@@ -293,12 +354,10 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) | |||
293 | 354 | ||
294 | err_irq: | 355 | err_irq: |
295 | GCR |= GCR_ACLINK_OFF; | 356 | GCR |= GCR_ACLINK_OFF; |
296 | #ifdef CONFIG_PXA27x | ||
297 | if (ac97conf_clk) { | 357 | if (ac97conf_clk) { |
298 | clk_put(ac97conf_clk); | 358 | clk_put(ac97conf_clk); |
299 | ac97conf_clk = NULL; | 359 | ac97conf_clk = NULL; |
300 | } | 360 | } |
301 | #endif | ||
302 | free_irq(IRQ_AC97, NULL); | 361 | free_irq(IRQ_AC97, NULL); |
303 | err: | 362 | err: |
304 | return ret; | 363 | return ret; |
@@ -309,10 +368,10 @@ void pxa2xx_ac97_hw_remove(struct platform_device *dev) | |||
309 | { | 368 | { |
310 | GCR |= GCR_ACLINK_OFF; | 369 | GCR |= GCR_ACLINK_OFF; |
311 | free_irq(IRQ_AC97, NULL); | 370 | free_irq(IRQ_AC97, NULL); |
312 | #ifdef CONFIG_PXA27x | 371 | if (ac97conf_clk) { |
313 | clk_put(ac97conf_clk); | 372 | clk_put(ac97conf_clk); |
314 | ac97conf_clk = NULL; | 373 | ac97conf_clk = NULL; |
315 | #endif | 374 | } |
316 | clk_disable(ac97_clk); | 375 | clk_disable(ac97_clk); |
317 | clk_put(ac97_clk); | 376 | clk_put(ac97_clk); |
318 | ac97_clk = NULL; | 377 | ac97_clk = NULL; |