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