xref: /openbmc/linux/sound/arm/pxa2xx-ac97-lib.c (revision 1f2186951e02f2a5bcda9459f63136918932385a)
19c636342SDmitry Baryshkov /*
29c636342SDmitry Baryshkov  * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
39c636342SDmitry Baryshkov  * which contain:
49c636342SDmitry Baryshkov  *
59c636342SDmitry Baryshkov  * Author:	Nicolas Pitre
69c636342SDmitry Baryshkov  * Created:	Dec 02, 2004
79c636342SDmitry Baryshkov  * Copyright:	MontaVista Software Inc.
89c636342SDmitry Baryshkov  *
99c636342SDmitry Baryshkov  * This program is free software; you can redistribute it and/or modify
109c636342SDmitry Baryshkov  * it under the terms of the GNU General Public License version 2 as
119c636342SDmitry Baryshkov  * published by the Free Software Foundation.
129c636342SDmitry Baryshkov  */
139c636342SDmitry Baryshkov 
149c636342SDmitry Baryshkov #include <linux/kernel.h>
159c636342SDmitry Baryshkov #include <linux/platform_device.h>
169c636342SDmitry Baryshkov #include <linux/interrupt.h>
179c636342SDmitry Baryshkov #include <linux/clk.h>
189c636342SDmitry Baryshkov #include <linux/delay.h>
199c636342SDmitry Baryshkov 
209c636342SDmitry Baryshkov #include <sound/ac97_codec.h>
219c636342SDmitry Baryshkov #include <sound/pxa2xx-lib.h>
229c636342SDmitry Baryshkov 
239c636342SDmitry Baryshkov #include <asm/irq.h>
249c636342SDmitry Baryshkov #include <mach/hardware.h>
251f017a99SEric Miao #include <mach/regs-ac97.h>
269c636342SDmitry Baryshkov #include <mach/pxa2xx-gpio.h>
279c636342SDmitry Baryshkov #include <mach/audio.h>
289c636342SDmitry Baryshkov 
299c636342SDmitry Baryshkov static DEFINE_MUTEX(car_mutex);
309c636342SDmitry Baryshkov static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
319c636342SDmitry Baryshkov static volatile long gsr_bits;
329c636342SDmitry Baryshkov static struct clk *ac97_clk;
339c636342SDmitry Baryshkov static struct clk *ac97conf_clk;
3426ade896SRobert Jarzmik static int reset_gpio;
359c636342SDmitry Baryshkov 
369c636342SDmitry Baryshkov /*
379c636342SDmitry Baryshkov  * Beware PXA27x bugs:
389c636342SDmitry Baryshkov  *
399c636342SDmitry Baryshkov  *   o Slot 12 read from modem space will hang controller.
409c636342SDmitry Baryshkov  *   o CDONE, SDONE interrupt fails after any slot 12 IO.
419c636342SDmitry Baryshkov  *
429c636342SDmitry Baryshkov  * We therefore have an hybrid approach for waiting on SDONE (interrupt or
439c636342SDmitry Baryshkov  * 1 jiffy timeout if interrupt never comes).
449c636342SDmitry Baryshkov  */
459c636342SDmitry Baryshkov 
4626ade896SRobert Jarzmik enum {
4726ade896SRobert Jarzmik 	RESETGPIO_FORCE_HIGH,
4826ade896SRobert Jarzmik 	RESETGPIO_FORCE_LOW,
4926ade896SRobert Jarzmik 	RESETGPIO_NORMAL_ALTFUNC
5026ade896SRobert Jarzmik };
5126ade896SRobert Jarzmik 
5226ade896SRobert Jarzmik /**
5326ade896SRobert Jarzmik  * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA
5426ade896SRobert Jarzmik  * @mode: chosen action
5526ade896SRobert Jarzmik  *
5626ade896SRobert Jarzmik  * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line
5726ade896SRobert Jarzmik  * must be done to insure proper work of AC97 reset line.  This function
5826ade896SRobert Jarzmik  * computes the correct gpio_mode for further use by reset functions, and
5926ade896SRobert Jarzmik  * applied the change through pxa_gpio_mode.
6026ade896SRobert Jarzmik  */
6126ade896SRobert Jarzmik static void set_resetgpio_mode(int resetgpio_action)
6226ade896SRobert Jarzmik {
6326ade896SRobert Jarzmik 	int mode = 0;
6426ade896SRobert Jarzmik 
6526ade896SRobert Jarzmik 	if (reset_gpio)
6626ade896SRobert Jarzmik 		switch (resetgpio_action) {
6726ade896SRobert Jarzmik 		case RESETGPIO_NORMAL_ALTFUNC:
6826ade896SRobert Jarzmik 			if (reset_gpio == 113)
6926ade896SRobert Jarzmik 				mode = 113 | GPIO_OUT | GPIO_DFLT_LOW;
7026ade896SRobert Jarzmik 			if (reset_gpio == 95)
7126ade896SRobert Jarzmik 				mode = 95 | GPIO_ALT_FN_1_OUT;
7226ade896SRobert Jarzmik 			break;
7326ade896SRobert Jarzmik 		case RESETGPIO_FORCE_LOW:
7426ade896SRobert Jarzmik 			mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW;
7526ade896SRobert Jarzmik 			break;
7626ade896SRobert Jarzmik 		case RESETGPIO_FORCE_HIGH:
7726ade896SRobert Jarzmik 			mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH;
7826ade896SRobert Jarzmik 			break;
7926ade896SRobert Jarzmik 		};
8026ade896SRobert Jarzmik 
8126ade896SRobert Jarzmik 	if (mode)
8226ade896SRobert Jarzmik 		pxa_gpio_mode(mode);
8326ade896SRobert Jarzmik }
8426ade896SRobert Jarzmik 
859c636342SDmitry Baryshkov unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
869c636342SDmitry Baryshkov {
879c636342SDmitry Baryshkov 	unsigned short val = -1;
889c636342SDmitry Baryshkov 	volatile u32 *reg_addr;
899c636342SDmitry Baryshkov 
909c636342SDmitry Baryshkov 	mutex_lock(&car_mutex);
919c636342SDmitry Baryshkov 
929c636342SDmitry Baryshkov 	/* set up primary or secondary codec space */
938825e8e8SMarc Zyngier 	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
949c636342SDmitry Baryshkov 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
959c636342SDmitry Baryshkov 	else
969c636342SDmitry Baryshkov 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
979c636342SDmitry Baryshkov 	reg_addr += (reg >> 1);
989c636342SDmitry Baryshkov 
999c636342SDmitry Baryshkov 	/* start read access across the ac97 link */
1009c636342SDmitry Baryshkov 	GSR = GSR_CDONE | GSR_SDONE;
1019c636342SDmitry Baryshkov 	gsr_bits = 0;
1029c636342SDmitry Baryshkov 	val = *reg_addr;
1039c636342SDmitry Baryshkov 	if (reg == AC97_GPIO_STATUS)
1049c636342SDmitry Baryshkov 		goto out;
1059c636342SDmitry Baryshkov 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
1069c636342SDmitry Baryshkov 	    !((GSR | gsr_bits) & GSR_SDONE)) {
1079c636342SDmitry Baryshkov 		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
1089c636342SDmitry Baryshkov 				__func__, reg, GSR | gsr_bits);
1099c636342SDmitry Baryshkov 		val = -1;
1109c636342SDmitry Baryshkov 		goto out;
1119c636342SDmitry Baryshkov 	}
1129c636342SDmitry Baryshkov 
1139c636342SDmitry Baryshkov 	/* valid data now */
1149c636342SDmitry Baryshkov 	GSR = GSR_CDONE | GSR_SDONE;
1159c636342SDmitry Baryshkov 	gsr_bits = 0;
1169c636342SDmitry Baryshkov 	val = *reg_addr;
1179c636342SDmitry Baryshkov 	/* but we've just started another cycle... */
1189c636342SDmitry Baryshkov 	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
1199c636342SDmitry Baryshkov 
1209c636342SDmitry Baryshkov out:	mutex_unlock(&car_mutex);
1219c636342SDmitry Baryshkov 	return val;
1229c636342SDmitry Baryshkov }
1239c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
1249c636342SDmitry Baryshkov 
1259c636342SDmitry Baryshkov void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
1269c636342SDmitry Baryshkov 			unsigned short val)
1279c636342SDmitry Baryshkov {
1289c636342SDmitry Baryshkov 	volatile u32 *reg_addr;
1299c636342SDmitry Baryshkov 
1309c636342SDmitry Baryshkov 	mutex_lock(&car_mutex);
1319c636342SDmitry Baryshkov 
1329c636342SDmitry Baryshkov 	/* set up primary or secondary codec space */
1338825e8e8SMarc Zyngier 	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
1349c636342SDmitry Baryshkov 		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
1359c636342SDmitry Baryshkov 	else
1369c636342SDmitry Baryshkov 		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
1379c636342SDmitry Baryshkov 	reg_addr += (reg >> 1);
1389c636342SDmitry Baryshkov 
1399c636342SDmitry Baryshkov 	GSR = GSR_CDONE | GSR_SDONE;
1409c636342SDmitry Baryshkov 	gsr_bits = 0;
1419c636342SDmitry Baryshkov 	*reg_addr = val;
1429c636342SDmitry Baryshkov 	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
1439c636342SDmitry Baryshkov 	    !((GSR | gsr_bits) & GSR_CDONE))
1449c636342SDmitry Baryshkov 		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
1459c636342SDmitry Baryshkov 				__func__, reg, GSR | gsr_bits);
1469c636342SDmitry Baryshkov 
1479c636342SDmitry Baryshkov 	mutex_unlock(&car_mutex);
1489c636342SDmitry Baryshkov }
1499c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
1509c636342SDmitry Baryshkov 
1519d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA25x
1529d1cf39bSDmitry Baryshkov static inline void pxa_ac97_warm_pxa25x(void)
1539c636342SDmitry Baryshkov {
1549c636342SDmitry Baryshkov 	gsr_bits = 0;
1559c636342SDmitry Baryshkov 
1569d1cf39bSDmitry Baryshkov 	GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
1579d1cf39bSDmitry Baryshkov 	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
1589d1cf39bSDmitry Baryshkov }
1599d1cf39bSDmitry Baryshkov 
1609d1cf39bSDmitry Baryshkov static inline void pxa_ac97_cold_pxa25x(void)
1619d1cf39bSDmitry Baryshkov {
1629d1cf39bSDmitry Baryshkov 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
1639d1cf39bSDmitry Baryshkov 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
1649d1cf39bSDmitry Baryshkov 
1659d1cf39bSDmitry Baryshkov 	gsr_bits = 0;
1669d1cf39bSDmitry Baryshkov 
1679d1cf39bSDmitry Baryshkov 	GCR = GCR_COLD_RST;
1689d1cf39bSDmitry Baryshkov 	GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
1699d1cf39bSDmitry Baryshkov 	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
1709d1cf39bSDmitry Baryshkov }
1719d1cf39bSDmitry Baryshkov #endif
1729d1cf39bSDmitry Baryshkov 
1739c636342SDmitry Baryshkov #ifdef CONFIG_PXA27x
1749d1cf39bSDmitry Baryshkov static inline void pxa_ac97_warm_pxa27x(void)
1759d1cf39bSDmitry Baryshkov {
1769d1cf39bSDmitry Baryshkov 	gsr_bits = 0;
1779d1cf39bSDmitry Baryshkov 
1789c636342SDmitry Baryshkov 	/* warm reset broken on Bulverde,
1799c636342SDmitry Baryshkov 	   so manually keep AC97 reset high */
18026ade896SRobert Jarzmik 	set_resetgpio_mode(RESETGPIO_FORCE_HIGH);
1819c636342SDmitry Baryshkov 	udelay(10);
1829c636342SDmitry Baryshkov 	GCR |= GCR_WARM_RST;
18326ade896SRobert Jarzmik 	set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
1849c636342SDmitry Baryshkov 	udelay(500);
1859d1cf39bSDmitry Baryshkov }
1869d1cf39bSDmitry Baryshkov 
1879d1cf39bSDmitry Baryshkov static inline void pxa_ac97_cold_pxa27x(void)
1889d1cf39bSDmitry Baryshkov {
1899d1cf39bSDmitry Baryshkov 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
1909d1cf39bSDmitry Baryshkov 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
1919d1cf39bSDmitry Baryshkov 
1929d1cf39bSDmitry Baryshkov 	gsr_bits = 0;
1939d1cf39bSDmitry Baryshkov 
1949d1cf39bSDmitry Baryshkov 	/* PXA27x Developers Manual section 13.5.2.2.1 */
1959d1cf39bSDmitry Baryshkov 	clk_enable(ac97conf_clk);
1969d1cf39bSDmitry Baryshkov 	udelay(5);
1979d1cf39bSDmitry Baryshkov 	clk_disable(ac97conf_clk);
1989d1cf39bSDmitry Baryshkov 	GCR = GCR_COLD_RST;
1999d1cf39bSDmitry Baryshkov 	udelay(50);
2009d1cf39bSDmitry Baryshkov }
2019d1cf39bSDmitry Baryshkov #endif
2029d1cf39bSDmitry Baryshkov 
2039d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA3xx
2049d1cf39bSDmitry Baryshkov static inline void pxa_ac97_warm_pxa3xx(void)
2059d1cf39bSDmitry Baryshkov {
2069d1cf39bSDmitry Baryshkov 	int timeout = 100;
2079d1cf39bSDmitry Baryshkov 
2089d1cf39bSDmitry Baryshkov 	gsr_bits = 0;
2099d1cf39bSDmitry Baryshkov 
2109c636342SDmitry Baryshkov 	/* Can't use interrupts */
2119c636342SDmitry Baryshkov 	GCR |= GCR_WARM_RST;
2129c636342SDmitry Baryshkov 	while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
2139c636342SDmitry Baryshkov 		mdelay(1);
2149d1cf39bSDmitry Baryshkov }
2159d1cf39bSDmitry Baryshkov 
2169d1cf39bSDmitry Baryshkov static inline void pxa_ac97_cold_pxa3xx(void)
2179d1cf39bSDmitry Baryshkov {
2189d1cf39bSDmitry Baryshkov 	int timeout = 1000;
2199d1cf39bSDmitry Baryshkov 
2209d1cf39bSDmitry Baryshkov 	/* Hold CLKBPB for 100us */
2219d1cf39bSDmitry Baryshkov 	GCR = 0;
2229d1cf39bSDmitry Baryshkov 	GCR = GCR_CLKBPB;
2239d1cf39bSDmitry Baryshkov 	udelay(100);
2249d1cf39bSDmitry Baryshkov 	GCR = 0;
2259d1cf39bSDmitry Baryshkov 
2269d1cf39bSDmitry Baryshkov 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
2279d1cf39bSDmitry Baryshkov 	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
2289d1cf39bSDmitry Baryshkov 
2299d1cf39bSDmitry Baryshkov 	gsr_bits = 0;
2309d1cf39bSDmitry Baryshkov 
2319d1cf39bSDmitry Baryshkov 	/* Can't use interrupts on PXA3xx */
2329d1cf39bSDmitry Baryshkov 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
2339d1cf39bSDmitry Baryshkov 
2349d1cf39bSDmitry Baryshkov 	GCR = GCR_WARM_RST | GCR_COLD_RST;
2359d1cf39bSDmitry Baryshkov 	while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
2369d1cf39bSDmitry Baryshkov 		mdelay(10);
2379d1cf39bSDmitry Baryshkov }
2389c636342SDmitry Baryshkov #endif
2399c636342SDmitry Baryshkov 
2409d1cf39bSDmitry Baryshkov bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
2419d1cf39bSDmitry Baryshkov {
2429d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA25x
2438825e8e8SMarc Zyngier 	if (cpu_is_pxa25x())
2449d1cf39bSDmitry Baryshkov 		pxa_ac97_warm_pxa25x();
2459d1cf39bSDmitry Baryshkov 	else
2469d1cf39bSDmitry Baryshkov #endif
2479d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA27x
2489d1cf39bSDmitry Baryshkov 	if (cpu_is_pxa27x())
2499d1cf39bSDmitry Baryshkov 		pxa_ac97_warm_pxa27x();
2509d1cf39bSDmitry Baryshkov 	else
2519d1cf39bSDmitry Baryshkov #endif
2529d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA3xx
2539d1cf39bSDmitry Baryshkov 	if (cpu_is_pxa3xx())
2549d1cf39bSDmitry Baryshkov 		pxa_ac97_warm_pxa3xx();
2559d1cf39bSDmitry Baryshkov 	else
2569d1cf39bSDmitry Baryshkov #endif
2579d1cf39bSDmitry Baryshkov 		BUG();
2589d1cf39bSDmitry Baryshkov 
2599c636342SDmitry Baryshkov 	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
2609c636342SDmitry Baryshkov 		printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
2619c636342SDmitry Baryshkov 				 __func__, gsr_bits);
2629c636342SDmitry Baryshkov 
2639c636342SDmitry Baryshkov 		return false;
2649c636342SDmitry Baryshkov 	}
2659c636342SDmitry Baryshkov 
2669c636342SDmitry Baryshkov 	return true;
2679c636342SDmitry Baryshkov }
2689c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
2699c636342SDmitry Baryshkov 
2709c636342SDmitry Baryshkov bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
2719c636342SDmitry Baryshkov {
2729d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA25x
2738825e8e8SMarc Zyngier 	if (cpu_is_pxa25x())
2749d1cf39bSDmitry Baryshkov 		pxa_ac97_cold_pxa25x();
2759d1cf39bSDmitry Baryshkov 	else
2769c636342SDmitry Baryshkov #endif
2779c636342SDmitry Baryshkov #ifdef CONFIG_PXA27x
2789d1cf39bSDmitry Baryshkov 	if (cpu_is_pxa27x())
2799d1cf39bSDmitry Baryshkov 		pxa_ac97_cold_pxa27x();
2809d1cf39bSDmitry Baryshkov 	else
2819c636342SDmitry Baryshkov #endif
2829d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA3xx
2839d1cf39bSDmitry Baryshkov 	if (cpu_is_pxa3xx())
2849d1cf39bSDmitry Baryshkov 		pxa_ac97_cold_pxa3xx();
2859d1cf39bSDmitry Baryshkov 	else
2869d1cf39bSDmitry Baryshkov #endif
2879d1cf39bSDmitry Baryshkov 		BUG();
2889c636342SDmitry Baryshkov 
2899c636342SDmitry Baryshkov 	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
2909c636342SDmitry Baryshkov 		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
2919c636342SDmitry Baryshkov 				 __func__, gsr_bits);
2929c636342SDmitry Baryshkov 
2939c636342SDmitry Baryshkov 		return false;
2949c636342SDmitry Baryshkov 	}
2959c636342SDmitry Baryshkov 
2969c636342SDmitry Baryshkov 	return true;
2979c636342SDmitry Baryshkov }
2989c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
2999c636342SDmitry Baryshkov 
3009c636342SDmitry Baryshkov 
3019c636342SDmitry Baryshkov void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
3029c636342SDmitry Baryshkov {
3039c636342SDmitry Baryshkov 	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
3049c636342SDmitry Baryshkov 	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
3059c636342SDmitry Baryshkov }
3069c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
3079c636342SDmitry Baryshkov 
3089c636342SDmitry Baryshkov static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
3099c636342SDmitry Baryshkov {
3109c636342SDmitry Baryshkov 	long status;
3119c636342SDmitry Baryshkov 
3129c636342SDmitry Baryshkov 	status = GSR;
3139c636342SDmitry Baryshkov 	if (status) {
3149c636342SDmitry Baryshkov 		GSR = status;
3159c636342SDmitry Baryshkov 		gsr_bits |= status;
3169c636342SDmitry Baryshkov 		wake_up(&gsr_wq);
3179c636342SDmitry Baryshkov 
3189c636342SDmitry Baryshkov 		/* Although we don't use those we still need to clear them
3199c636342SDmitry Baryshkov 		   since they tend to spuriously trigger when MMC is used
3209c636342SDmitry Baryshkov 		   (hardware bug? go figure)... */
3219d1cf39bSDmitry Baryshkov 		if (cpu_is_pxa27x()) {
3229c636342SDmitry Baryshkov 			MISR = MISR_EOC;
3239c636342SDmitry Baryshkov 			PISR = PISR_EOC;
3249c636342SDmitry Baryshkov 			MCSR = MCSR_EOC;
3259d1cf39bSDmitry Baryshkov 		}
3269c636342SDmitry Baryshkov 
3279c636342SDmitry Baryshkov 		return IRQ_HANDLED;
3289c636342SDmitry Baryshkov 	}
3299c636342SDmitry Baryshkov 
3309c636342SDmitry Baryshkov 	return IRQ_NONE;
3319c636342SDmitry Baryshkov }
3329c636342SDmitry Baryshkov 
3339c636342SDmitry Baryshkov #ifdef CONFIG_PM
3349c636342SDmitry Baryshkov int pxa2xx_ac97_hw_suspend(void)
3359c636342SDmitry Baryshkov {
3369c636342SDmitry Baryshkov 	GCR |= GCR_ACLINK_OFF;
3379c636342SDmitry Baryshkov 	clk_disable(ac97_clk);
3389c636342SDmitry Baryshkov 	return 0;
3399c636342SDmitry Baryshkov }
3409c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
3419c636342SDmitry Baryshkov 
3429c636342SDmitry Baryshkov int pxa2xx_ac97_hw_resume(void)
3439c636342SDmitry Baryshkov {
3448825e8e8SMarc Zyngier 	if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
3459c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
3469c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
3479c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
3489c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
3499d1cf39bSDmitry Baryshkov 	}
3509d1cf39bSDmitry Baryshkov 	if (cpu_is_pxa27x()) {
35126ade896SRobert Jarzmik 		/* Use GPIO 113 or 95 as AC97 Reset on Bulverde */
35226ade896SRobert Jarzmik 		set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
3539d1cf39bSDmitry Baryshkov 	}
3549c636342SDmitry Baryshkov 	clk_enable(ac97_clk);
3559c636342SDmitry Baryshkov 	return 0;
3569c636342SDmitry Baryshkov }
3579c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
3589c636342SDmitry Baryshkov #endif
3599c636342SDmitry Baryshkov 
3609c636342SDmitry Baryshkov int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
3619c636342SDmitry Baryshkov {
3629c636342SDmitry Baryshkov 	int ret;
36326ade896SRobert Jarzmik 	struct pxa2xx_ac97_platform_data *pdata = dev->dev.platform_data;
36426ade896SRobert Jarzmik 
36526ade896SRobert Jarzmik 	if (pdata) {
36626ade896SRobert Jarzmik 		switch (pdata->reset_gpio) {
36726ade896SRobert Jarzmik 		case 95:
36826ade896SRobert Jarzmik 		case 113:
36926ade896SRobert Jarzmik 			reset_gpio = pdata->reset_gpio;
37026ade896SRobert Jarzmik 			break;
37126ade896SRobert Jarzmik 		case 0:
37226ade896SRobert Jarzmik 			reset_gpio = 113;
37326ade896SRobert Jarzmik 			break;
37426ade896SRobert Jarzmik 		case -1:
37526ade896SRobert Jarzmik 			break;
37626ade896SRobert Jarzmik 		default:
377*1f218695STakashi Iwai 			dev_err(&dev->dev, "Invalid reset GPIO %d\n",
37826ade896SRobert Jarzmik 				pdata->reset_gpio);
37926ade896SRobert Jarzmik 		}
38026ade896SRobert Jarzmik 	} else {
38126ade896SRobert Jarzmik 		if (cpu_is_pxa27x())
38226ade896SRobert Jarzmik 			reset_gpio = 113;
38326ade896SRobert Jarzmik 	}
3849c636342SDmitry Baryshkov 
3858825e8e8SMarc Zyngier 	if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
3869c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
3879c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
3889c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
3899c636342SDmitry Baryshkov 		pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
3909d1cf39bSDmitry Baryshkov 	}
3919d1cf39bSDmitry Baryshkov 
3929d1cf39bSDmitry Baryshkov 	if (cpu_is_pxa27x()) {
3939c636342SDmitry Baryshkov 		/* Use GPIO 113 as AC97 Reset on Bulverde */
39426ade896SRobert Jarzmik 		set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC);
3959c636342SDmitry Baryshkov 		ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
3969c636342SDmitry Baryshkov 		if (IS_ERR(ac97conf_clk)) {
3979c636342SDmitry Baryshkov 			ret = PTR_ERR(ac97conf_clk);
3989c636342SDmitry Baryshkov 			ac97conf_clk = NULL;
39979612336SDmitry Baryshkov 			goto err_conf;
4009c636342SDmitry Baryshkov 		}
4019d1cf39bSDmitry Baryshkov 	}
4029c636342SDmitry Baryshkov 
4039c636342SDmitry Baryshkov 	ac97_clk = clk_get(&dev->dev, "AC97CLK");
4049c636342SDmitry Baryshkov 	if (IS_ERR(ac97_clk)) {
4059c636342SDmitry Baryshkov 		ret = PTR_ERR(ac97_clk);
4069c636342SDmitry Baryshkov 		ac97_clk = NULL;
40779612336SDmitry Baryshkov 		goto err_clk;
4089c636342SDmitry Baryshkov 	}
4099c636342SDmitry Baryshkov 
41079612336SDmitry Baryshkov 	ret = clk_enable(ac97_clk);
41179612336SDmitry Baryshkov 	if (ret)
41279612336SDmitry Baryshkov 		goto err_clk2;
41379612336SDmitry Baryshkov 
41479612336SDmitry Baryshkov 	ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
41579612336SDmitry Baryshkov 	if (ret < 0)
41679612336SDmitry Baryshkov 		goto err_irq;
41779612336SDmitry Baryshkov 
41879612336SDmitry Baryshkov 	return 0;
4199c636342SDmitry Baryshkov 
4209c636342SDmitry Baryshkov err_irq:
4219c636342SDmitry Baryshkov 	GCR |= GCR_ACLINK_OFF;
42279612336SDmitry Baryshkov err_clk2:
42379612336SDmitry Baryshkov 	clk_put(ac97_clk);
42479612336SDmitry Baryshkov 	ac97_clk = NULL;
42579612336SDmitry Baryshkov err_clk:
4269c636342SDmitry Baryshkov 	if (ac97conf_clk) {
4279c636342SDmitry Baryshkov 		clk_put(ac97conf_clk);
4289c636342SDmitry Baryshkov 		ac97conf_clk = NULL;
4299c636342SDmitry Baryshkov 	}
43079612336SDmitry Baryshkov err_conf:
4319c636342SDmitry Baryshkov 	return ret;
4329c636342SDmitry Baryshkov }
4339c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
4349c636342SDmitry Baryshkov 
4359c636342SDmitry Baryshkov void pxa2xx_ac97_hw_remove(struct platform_device *dev)
4369c636342SDmitry Baryshkov {
4379c636342SDmitry Baryshkov 	GCR |= GCR_ACLINK_OFF;
4389c636342SDmitry Baryshkov 	free_irq(IRQ_AC97, NULL);
4399d1cf39bSDmitry Baryshkov 	if (ac97conf_clk) {
4409c636342SDmitry Baryshkov 		clk_put(ac97conf_clk);
4419c636342SDmitry Baryshkov 		ac97conf_clk = NULL;
4429d1cf39bSDmitry Baryshkov 	}
4439c636342SDmitry Baryshkov 	clk_disable(ac97_clk);
4449c636342SDmitry Baryshkov 	clk_put(ac97_clk);
4459c636342SDmitry Baryshkov 	ac97_clk = NULL;
4469c636342SDmitry Baryshkov }
4479c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
4489c636342SDmitry Baryshkov 
4499c636342SDmitry Baryshkov MODULE_AUTHOR("Nicolas Pitre");
4509c636342SDmitry Baryshkov MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
4519c636342SDmitry Baryshkov MODULE_LICENSE("GPL");
4529c636342SDmitry Baryshkov 
453