aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDmitry Baryshkov <dbaryshkov@gmail.com>2008-09-09 21:01:18 -0400
committerJaroslav Kysela <perex@perex.cz>2008-09-23 02:18:09 -0400
commit9d1cf39be6709761be3ce0a00e5c9ee5dc805ac5 (patch)
tree84e08a5ec82d1a3c3b107d7214b3848a544a9e8b /sound
parent9c63634221f67450ead19820e33996b69691194f (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')
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c215
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);
30static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); 30static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
31static volatile long gsr_bits; 31static volatile long gsr_bits;
32static struct clk *ac97_clk; 32static struct clk *ac97_clk;
33#ifdef CONFIG_PXA27x
34static struct clk *ac97conf_clk; 33static 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}
119EXPORT_SYMBOL_GPL(pxa2xx_ac97_write); 109EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
120 110
121bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) 111#ifdef CONFIG_PXA25x
112static 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
120static 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
134static 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; 147static 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", 164static 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}
155EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
156 175
157bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) 176static 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); 200bool 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}
228EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
229
230bool 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
246int pxa2xx_ac97_hw_resume(void) 302int 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
294err_irq: 355err_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);
303err: 362err:
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;