• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/regs-ac97.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 static struct clk *ac97conf_clk;
34 
35 /*
36  * Beware PXA27x bugs:
37  *
38  *   o Slot 12 read from modem space will hang controller.
39  *   o CDONE, SDONE interrupt fails after any slot 12 IO.
40  *
41  * We therefore have an hybrid approach for waiting on SDONE (interrupt or
42  * 1 jiffy timeout if interrupt never comes).
43  */
44 
pxa2xx_ac97_read(struct snd_ac97 * ac97,unsigned short reg)45 unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
46 {
47 	unsigned short val = -1;
48 	volatile u32 *reg_addr;
49 
50 	mutex_lock(&car_mutex);
51 
52 	/* set up primary or secondary codec space */
53 	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
54 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
55 	else
56 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
57 	reg_addr += (reg >> 1);
58 
59 	/* start read access across the ac97 link */
60 	GSR = GSR_CDONE | GSR_SDONE;
61 	gsr_bits = 0;
62 	val = *reg_addr;
63 	if (reg == AC97_GPIO_STATUS)
64 		goto out;
65 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
66 	    !((GSR | gsr_bits) & GSR_SDONE)) {
67 		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
68 				__func__, reg, GSR | gsr_bits);
69 		val = -1;
70 		goto out;
71 	}
72 
73 	/* valid data now */
74 	GSR = GSR_CDONE | GSR_SDONE;
75 	gsr_bits = 0;
76 	val = *reg_addr;
77 	/* but we've just started another cycle... */
78 	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
79 
80 out:	mutex_unlock(&car_mutex);
81 	return val;
82 }
83 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
84 
pxa2xx_ac97_write(struct snd_ac97 * ac97,unsigned short reg,unsigned short val)85 void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
86 			unsigned short val)
87 {
88 	volatile u32 *reg_addr;
89 
90 	mutex_lock(&car_mutex);
91 
92 	/* set up primary or secondary codec space */
93 	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
94 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
95 	else
96 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
97 	reg_addr += (reg >> 1);
98 
99 	GSR = GSR_CDONE | GSR_SDONE;
100 	gsr_bits = 0;
101 	*reg_addr = val;
102 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
103 	    !((GSR | gsr_bits) & GSR_CDONE))
104 		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
105 				__func__, reg, GSR | gsr_bits);
106 
107 	mutex_unlock(&car_mutex);
108 }
109 EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
110 
111 #ifdef CONFIG_PXA25x
pxa_ac97_warm_pxa25x(void)112 static inline void pxa_ac97_warm_pxa25x(void)
113 {
114 	gsr_bits = 0;
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 
pxa_ac97_cold_pxa25x(void)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 
133 #ifdef CONFIG_PXA27x
pxa_ac97_warm_pxa27x(void)134 static inline void pxa_ac97_warm_pxa27x(void)
135 {
136 	gsr_bits = 0;
137 
138 	/* warm reset broken on Bulverde,
139 	   so manually keep AC97 reset high */
140 	pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
141 	udelay(10);
142 	GCR |= GCR_WARM_RST;
143 	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
144 	udelay(500);
145 }
146 
pxa_ac97_cold_pxa27x(void)147 static inline void pxa_ac97_cold_pxa27x(void)
148 {
149 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
150 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
151 
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 }
161 #endif
162 
163 #ifdef CONFIG_PXA3xx
pxa_ac97_warm_pxa3xx(void)164 static inline void pxa_ac97_warm_pxa3xx(void)
165 {
166 	int timeout = 100;
167 
168 	gsr_bits = 0;
169 
170 	/* Can't use interrupts */
171 	GCR |= GCR_WARM_RST;
172 	while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
173 		mdelay(1);
174 }
175 
pxa_ac97_cold_pxa3xx(void)176 static inline void pxa_ac97_cold_pxa3xx(void)
177 {
178 	int timeout = 1000;
179 
180 	/* Hold CLKBPB for 100us */
181 	GCR = 0;
182 	GCR = GCR_CLKBPB;
183 	udelay(100);
184 	GCR = 0;
185 
186 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
187 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
188 
189 	gsr_bits = 0;
190 
191 	/* Can't use interrupts on PXA3xx */
192 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
193 
194 	GCR = GCR_WARM_RST | GCR_COLD_RST;
195 	while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
196 		mdelay(10);
197 }
198 #endif
199 
pxa2xx_ac97_try_warm_reset(struct snd_ac97 * ac97)200 bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
201 {
202 #ifdef CONFIG_PXA25x
203 	if (cpu_is_pxa25x())
204 		pxa_ac97_warm_pxa25x();
205 	else
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 
pxa2xx_ac97_try_cold_reset(struct snd_ac97 * ac97)230 bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
231 {
232 #ifdef CONFIG_PXA25x
233 	if (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();
248 
249 	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
250 		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
251 				 __func__, gsr_bits);
252 
253 		return false;
254 	}
255 
256 	return true;
257 }
258 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
259 
260 
pxa2xx_ac97_finish_reset(struct snd_ac97 * ac97)261 void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
262 {
263 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
264 	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
265 }
266 EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
267 
pxa2xx_ac97_irq(int irq,void * dev_id)268 static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
269 {
270 	long status;
271 
272 	status = GSR;
273 	if (status) {
274 		GSR = status;
275 		gsr_bits |= status;
276 		wake_up(&gsr_wq);
277 
278 		/* Although we don't use those we still need to clear them
279 		   since they tend to spuriously trigger when MMC is used
280 		   (hardware bug? go figure)... */
281 		if (cpu_is_pxa27x()) {
282 			MISR = MISR_EOC;
283 			PISR = PISR_EOC;
284 			MCSR = MCSR_EOC;
285 		}
286 
287 		return IRQ_HANDLED;
288 	}
289 
290 	return IRQ_NONE;
291 }
292 
293 #ifdef CONFIG_PM
pxa2xx_ac97_hw_suspend(void)294 int pxa2xx_ac97_hw_suspend(void)
295 {
296 	GCR |= GCR_ACLINK_OFF;
297 	clk_disable(ac97_clk);
298 	return 0;
299 }
300 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
301 
pxa2xx_ac97_hw_resume(void)302 int pxa2xx_ac97_hw_resume(void)
303 {
304 	if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
305 		pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
306 		pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
307 		pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
308 		pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
309 	}
310 	if (cpu_is_pxa27x()) {
311 		/* Use GPIO 113 as AC97 Reset on Bulverde */
312 		pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
313 	}
314 	clk_enable(ac97_clk);
315 	return 0;
316 }
317 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
318 #endif
319 
pxa2xx_ac97_hw_probe(struct platform_device * dev)320 int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
321 {
322 	int ret;
323 
324 	if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
325 		pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
326 		pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
327 		pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
328 		pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
329 	}
330 
331 	if (cpu_is_pxa27x()) {
332 		/* Use GPIO 113 as AC97 Reset on Bulverde */
333 		pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
334 		ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
335 		if (IS_ERR(ac97conf_clk)) {
336 			ret = PTR_ERR(ac97conf_clk);
337 			ac97conf_clk = NULL;
338 			goto err_conf;
339 		}
340 	}
341 
342 	ac97_clk = clk_get(&dev->dev, "AC97CLK");
343 	if (IS_ERR(ac97_clk)) {
344 		ret = PTR_ERR(ac97_clk);
345 		ac97_clk = NULL;
346 		goto err_clk;
347 	}
348 
349 	ret = clk_enable(ac97_clk);
350 	if (ret)
351 		goto err_clk2;
352 
353 	ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
354 	if (ret < 0)
355 		goto err_irq;
356 
357 	return 0;
358 
359 err_irq:
360 	GCR |= GCR_ACLINK_OFF;
361 err_clk2:
362 	clk_put(ac97_clk);
363 	ac97_clk = NULL;
364 err_clk:
365 	if (ac97conf_clk) {
366 		clk_put(ac97conf_clk);
367 		ac97conf_clk = NULL;
368 	}
369 err_conf:
370 	return ret;
371 }
372 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
373 
pxa2xx_ac97_hw_remove(struct platform_device * dev)374 void pxa2xx_ac97_hw_remove(struct platform_device *dev)
375 {
376 	GCR |= GCR_ACLINK_OFF;
377 	free_irq(IRQ_AC97, NULL);
378 	if (ac97conf_clk) {
379 		clk_put(ac97conf_clk);
380 		ac97conf_clk = NULL;
381 	}
382 	clk_disable(ac97_clk);
383 	clk_put(ac97_clk);
384 	ac97_clk = NULL;
385 }
386 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
387 
388 MODULE_AUTHOR("Nicolas Pitre");
389 MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
390 MODULE_LICENSE("GPL");
391 
392