aboutsummaryrefslogtreecommitdiffstats
path: root/sound/arm/pxa2xx-ac97-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/arm/pxa2xx-ac97-lib.c')
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c87
1 files changed, 76 insertions, 11 deletions
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 35afd0c33be5..0afd1a8226fb 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -21,7 +21,6 @@
21#include <sound/pxa2xx-lib.h> 21#include <sound/pxa2xx-lib.h>
22 22
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <mach/hardware.h>
25#include <mach/regs-ac97.h> 24#include <mach/regs-ac97.h>
26#include <mach/pxa2xx-gpio.h> 25#include <mach/pxa2xx-gpio.h>
27#include <mach/audio.h> 26#include <mach/audio.h>
@@ -31,6 +30,7 @@ static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
31static volatile long gsr_bits; 30static volatile long gsr_bits;
32static struct clk *ac97_clk; 31static struct clk *ac97_clk;
33static struct clk *ac97conf_clk; 32static struct clk *ac97conf_clk;
33static int reset_gpio;
34 34
35/* 35/*
36 * Beware PXA27x bugs: 36 * Beware PXA27x bugs:
@@ -42,6 +42,45 @@ static struct clk *ac97conf_clk;
42 * 1 jiffy timeout if interrupt never comes). 42 * 1 jiffy timeout if interrupt never comes).
43 */ 43 */
44 44
45enum {
46 RESETGPIO_FORCE_HIGH,
47 RESETGPIO_FORCE_LOW,
48 RESETGPIO_NORMAL_ALTFUNC
49};
50
51/**
52 * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA
53 * @mode: chosen action
54 *
55 * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line
56 * must be done to insure proper work of AC97 reset line. This function
57 * computes the correct gpio_mode for further use by reset functions, and
58 * applied the change through pxa_gpio_mode.
59 */
60static void set_resetgpio_mode(int resetgpio_action)
61{
62 int mode = 0;
63
64 if (reset_gpio)
65 switch (resetgpio_action) {
66 case RESETGPIO_NORMAL_ALTFUNC:
67 if (reset_gpio == 113)
68 mode = 113 | GPIO_OUT | GPIO_DFLT_LOW;
69 if (reset_gpio == 95)
70 mode = 95 | GPIO_ALT_FN_1_OUT;
71 break;
72 case RESETGPIO_FORCE_LOW:
73 mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW;
74 break;
75 case RESETGPIO_FORCE_HIGH:
76 mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH;
77 break;
78 };
79
80 if (mode)
81 pxa_gpio_mode(mode);
82}
83
45unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 84unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
46{ 85{
47 unsigned short val = -1; 86 unsigned short val = -1;
@@ -137,10 +176,10 @@ static inline void pxa_ac97_warm_pxa27x(void)
137 176
138 /* warm reset broken on Bulverde, 177 /* warm reset broken on Bulverde,
139 so manually keep AC97 reset high */ 178 so manually keep AC97 reset high */
140 pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); 179 set_resetgpio_mode(RESETGPIO_FORCE_HIGH);
141 udelay(10); 180 udelay(10);
142 GCR |= GCR_WARM_RST; 181 GCR |= GCR_WARM_RST;
143 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 182 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
144 udelay(500); 183 udelay(500);
145} 184}
146 185
@@ -199,6 +238,8 @@ static inline void pxa_ac97_cold_pxa3xx(void)
199 238
200bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) 239bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
201{ 240{
241 unsigned long gsr;
242
202#ifdef CONFIG_PXA25x 243#ifdef CONFIG_PXA25x
203 if (cpu_is_pxa25x()) 244 if (cpu_is_pxa25x())
204 pxa_ac97_warm_pxa25x(); 245 pxa_ac97_warm_pxa25x();
@@ -215,10 +256,10 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
215 else 256 else
216#endif 257#endif
217 BUG(); 258 BUG();
218 259 gsr = GSR | gsr_bits;
219 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { 260 if (!(gsr & (GSR_PCR | GSR_SCR))) {
220 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", 261 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
221 __func__, gsr_bits); 262 __func__, gsr);
222 263
223 return false; 264 return false;
224 } 265 }
@@ -229,6 +270,8 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
229 270
230bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) 271bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
231{ 272{
273 unsigned long gsr;
274
232#ifdef CONFIG_PXA25x 275#ifdef CONFIG_PXA25x
233 if (cpu_is_pxa25x()) 276 if (cpu_is_pxa25x())
234 pxa_ac97_cold_pxa25x(); 277 pxa_ac97_cold_pxa25x();
@@ -246,9 +289,10 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
246#endif 289#endif
247 BUG(); 290 BUG();
248 291
249 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { 292 gsr = GSR | gsr_bits;
293 if (!(gsr & (GSR_PCR | GSR_SCR))) {
250 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", 294 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
251 __func__, gsr_bits); 295 __func__, gsr);
252 296
253 return false; 297 return false;
254 } 298 }
@@ -308,8 +352,8 @@ int pxa2xx_ac97_hw_resume(void)
308 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); 352 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
309 } 353 }
310 if (cpu_is_pxa27x()) { 354 if (cpu_is_pxa27x()) {
311 /* Use GPIO 113 as AC97 Reset on Bulverde */ 355 /* Use GPIO 113 or 95 as AC97 Reset on Bulverde */
312 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 356 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
313 } 357 }
314 clk_enable(ac97_clk); 358 clk_enable(ac97_clk);
315 return 0; 359 return 0;
@@ -320,6 +364,27 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
320int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) 364int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
321{ 365{
322 int ret; 366 int ret;
367 struct pxa2xx_ac97_platform_data *pdata = dev->dev.platform_data;
368
369 if (pdata) {
370 switch (pdata->reset_gpio) {
371 case 95:
372 case 113:
373 reset_gpio = pdata->reset_gpio;
374 break;
375 case 0:
376 reset_gpio = 113;
377 break;
378 case -1:
379 break;
380 default:
381 dev_err(&dev->dev, "Invalid reset GPIO %d\n",
382 pdata->reset_gpio);
383 }
384 } else {
385 if (cpu_is_pxa27x())
386 reset_gpio = 113;
387 }
323 388
324 if (cpu_is_pxa25x() || cpu_is_pxa27x()) { 389 if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
325 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 390 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
@@ -330,7 +395,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
330 395
331 if (cpu_is_pxa27x()) { 396 if (cpu_is_pxa27x()) {
332 /* Use GPIO 113 as AC97 Reset on Bulverde */ 397 /* Use GPIO 113 as AC97 Reset on Bulverde */
333 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 398 set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
334 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); 399 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
335 if (IS_ERR(ac97conf_clk)) { 400 if (IS_ERR(ac97conf_clk)) {
336 ret = PTR_ERR(ac97conf_clk); 401 ret = PTR_ERR(ac97conf_clk);