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> 259c636342SDmitry Baryshkov #include <mach/pxa-regs.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; 349c636342SDmitry Baryshkov 359c636342SDmitry Baryshkov /* 369c636342SDmitry Baryshkov * Beware PXA27x bugs: 379c636342SDmitry Baryshkov * 389c636342SDmitry Baryshkov * o Slot 12 read from modem space will hang controller. 399c636342SDmitry Baryshkov * o CDONE, SDONE interrupt fails after any slot 12 IO. 409c636342SDmitry Baryshkov * 419c636342SDmitry Baryshkov * We therefore have an hybrid approach for waiting on SDONE (interrupt or 429c636342SDmitry Baryshkov * 1 jiffy timeout if interrupt never comes). 439c636342SDmitry Baryshkov */ 449c636342SDmitry Baryshkov 459c636342SDmitry Baryshkov unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 469c636342SDmitry Baryshkov { 479c636342SDmitry Baryshkov unsigned short val = -1; 489c636342SDmitry Baryshkov volatile u32 *reg_addr; 499c636342SDmitry Baryshkov 509c636342SDmitry Baryshkov mutex_lock(&car_mutex); 519c636342SDmitry Baryshkov 529c636342SDmitry Baryshkov /* set up primary or secondary codec space */ 53*9d1cf39bSDmitry Baryshkov if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS) 549c636342SDmitry Baryshkov reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; 559c636342SDmitry Baryshkov else 569c636342SDmitry Baryshkov reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; 579c636342SDmitry Baryshkov reg_addr += (reg >> 1); 589c636342SDmitry Baryshkov 599c636342SDmitry Baryshkov /* start read access across the ac97 link */ 609c636342SDmitry Baryshkov GSR = GSR_CDONE | GSR_SDONE; 619c636342SDmitry Baryshkov gsr_bits = 0; 629c636342SDmitry Baryshkov val = *reg_addr; 639c636342SDmitry Baryshkov if (reg == AC97_GPIO_STATUS) 649c636342SDmitry Baryshkov goto out; 659c636342SDmitry Baryshkov if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 && 669c636342SDmitry Baryshkov !((GSR | gsr_bits) & GSR_SDONE)) { 679c636342SDmitry Baryshkov printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", 689c636342SDmitry Baryshkov __func__, reg, GSR | gsr_bits); 699c636342SDmitry Baryshkov val = -1; 709c636342SDmitry Baryshkov goto out; 719c636342SDmitry Baryshkov } 729c636342SDmitry Baryshkov 739c636342SDmitry Baryshkov /* valid data now */ 749c636342SDmitry Baryshkov GSR = GSR_CDONE | GSR_SDONE; 759c636342SDmitry Baryshkov gsr_bits = 0; 769c636342SDmitry Baryshkov val = *reg_addr; 779c636342SDmitry Baryshkov /* but we've just started another cycle... */ 789c636342SDmitry Baryshkov wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); 799c636342SDmitry Baryshkov 809c636342SDmitry Baryshkov out: mutex_unlock(&car_mutex); 819c636342SDmitry Baryshkov return val; 829c636342SDmitry Baryshkov } 839c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_read); 849c636342SDmitry Baryshkov 859c636342SDmitry Baryshkov void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, 869c636342SDmitry Baryshkov unsigned short val) 879c636342SDmitry Baryshkov { 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 */ 93*9d1cf39bSDmitry Baryshkov if ((cpu_is_pxa21x() || 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 GSR = GSR_CDONE | GSR_SDONE; 1009c636342SDmitry Baryshkov gsr_bits = 0; 1019c636342SDmitry Baryshkov *reg_addr = val; 1029c636342SDmitry Baryshkov if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 && 1039c636342SDmitry Baryshkov !((GSR | gsr_bits) & GSR_CDONE)) 1049c636342SDmitry Baryshkov printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", 1059c636342SDmitry Baryshkov __func__, reg, GSR | gsr_bits); 1069c636342SDmitry Baryshkov 1079c636342SDmitry Baryshkov mutex_unlock(&car_mutex); 1089c636342SDmitry Baryshkov } 1099c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_write); 1109c636342SDmitry Baryshkov 111*9d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA25x 112*9d1cf39bSDmitry Baryshkov static inline void pxa_ac97_warm_pxa25x(void) 1139c636342SDmitry Baryshkov { 1149c636342SDmitry Baryshkov gsr_bits = 0; 1159c636342SDmitry Baryshkov 116*9d1cf39bSDmitry Baryshkov GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN; 117*9d1cf39bSDmitry Baryshkov wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); 118*9d1cf39bSDmitry Baryshkov } 119*9d1cf39bSDmitry Baryshkov 120*9d1cf39bSDmitry Baryshkov static inline void pxa_ac97_cold_pxa25x(void) 121*9d1cf39bSDmitry Baryshkov { 122*9d1cf39bSDmitry Baryshkov GCR &= GCR_COLD_RST; /* clear everything but nCRST */ 123*9d1cf39bSDmitry Baryshkov GCR &= ~GCR_COLD_RST; /* then assert nCRST */ 124*9d1cf39bSDmitry Baryshkov 125*9d1cf39bSDmitry Baryshkov gsr_bits = 0; 126*9d1cf39bSDmitry Baryshkov 127*9d1cf39bSDmitry Baryshkov GCR = GCR_COLD_RST; 128*9d1cf39bSDmitry Baryshkov GCR |= GCR_CDONE_IE|GCR_SDONE_IE; 129*9d1cf39bSDmitry Baryshkov wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); 130*9d1cf39bSDmitry Baryshkov } 131*9d1cf39bSDmitry Baryshkov #endif 132*9d1cf39bSDmitry Baryshkov 1339c636342SDmitry Baryshkov #ifdef CONFIG_PXA27x 134*9d1cf39bSDmitry Baryshkov static inline void pxa_ac97_warm_pxa27x(void) 135*9d1cf39bSDmitry Baryshkov { 136*9d1cf39bSDmitry Baryshkov gsr_bits = 0; 137*9d1cf39bSDmitry Baryshkov 1389c636342SDmitry Baryshkov /* warm reset broken on Bulverde, 1399c636342SDmitry Baryshkov so manually keep AC97 reset high */ 1409c636342SDmitry Baryshkov pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); 1419c636342SDmitry Baryshkov udelay(10); 1429c636342SDmitry Baryshkov GCR |= GCR_WARM_RST; 1439c636342SDmitry Baryshkov pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 1449c636342SDmitry Baryshkov udelay(500); 145*9d1cf39bSDmitry Baryshkov } 146*9d1cf39bSDmitry Baryshkov 147*9d1cf39bSDmitry Baryshkov static inline void pxa_ac97_cold_pxa27x(void) 148*9d1cf39bSDmitry Baryshkov { 149*9d1cf39bSDmitry Baryshkov GCR &= GCR_COLD_RST; /* clear everything but nCRST */ 150*9d1cf39bSDmitry Baryshkov GCR &= ~GCR_COLD_RST; /* then assert nCRST */ 151*9d1cf39bSDmitry Baryshkov 152*9d1cf39bSDmitry Baryshkov gsr_bits = 0; 153*9d1cf39bSDmitry Baryshkov 154*9d1cf39bSDmitry Baryshkov /* PXA27x Developers Manual section 13.5.2.2.1 */ 155*9d1cf39bSDmitry Baryshkov clk_enable(ac97conf_clk); 156*9d1cf39bSDmitry Baryshkov udelay(5); 157*9d1cf39bSDmitry Baryshkov clk_disable(ac97conf_clk); 158*9d1cf39bSDmitry Baryshkov GCR = GCR_COLD_RST; 159*9d1cf39bSDmitry Baryshkov udelay(50); 160*9d1cf39bSDmitry Baryshkov } 161*9d1cf39bSDmitry Baryshkov #endif 162*9d1cf39bSDmitry Baryshkov 163*9d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA3xx 164*9d1cf39bSDmitry Baryshkov static inline void pxa_ac97_warm_pxa3xx(void) 165*9d1cf39bSDmitry Baryshkov { 166*9d1cf39bSDmitry Baryshkov int timeout = 100; 167*9d1cf39bSDmitry Baryshkov 168*9d1cf39bSDmitry Baryshkov gsr_bits = 0; 169*9d1cf39bSDmitry Baryshkov 1709c636342SDmitry Baryshkov /* Can't use interrupts */ 1719c636342SDmitry Baryshkov GCR |= GCR_WARM_RST; 1729c636342SDmitry Baryshkov while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) 1739c636342SDmitry Baryshkov mdelay(1); 174*9d1cf39bSDmitry Baryshkov } 175*9d1cf39bSDmitry Baryshkov 176*9d1cf39bSDmitry Baryshkov static inline void pxa_ac97_cold_pxa3xx(void) 177*9d1cf39bSDmitry Baryshkov { 178*9d1cf39bSDmitry Baryshkov int timeout = 1000; 179*9d1cf39bSDmitry Baryshkov 180*9d1cf39bSDmitry Baryshkov /* Hold CLKBPB for 100us */ 181*9d1cf39bSDmitry Baryshkov GCR = 0; 182*9d1cf39bSDmitry Baryshkov GCR = GCR_CLKBPB; 183*9d1cf39bSDmitry Baryshkov udelay(100); 184*9d1cf39bSDmitry Baryshkov GCR = 0; 185*9d1cf39bSDmitry Baryshkov 186*9d1cf39bSDmitry Baryshkov GCR &= GCR_COLD_RST; /* clear everything but nCRST */ 187*9d1cf39bSDmitry Baryshkov GCR &= ~GCR_COLD_RST; /* then assert nCRST */ 188*9d1cf39bSDmitry Baryshkov 189*9d1cf39bSDmitry Baryshkov gsr_bits = 0; 190*9d1cf39bSDmitry Baryshkov 191*9d1cf39bSDmitry Baryshkov /* Can't use interrupts on PXA3xx */ 192*9d1cf39bSDmitry Baryshkov GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); 193*9d1cf39bSDmitry Baryshkov 194*9d1cf39bSDmitry Baryshkov GCR = GCR_WARM_RST | GCR_COLD_RST; 195*9d1cf39bSDmitry Baryshkov while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--) 196*9d1cf39bSDmitry Baryshkov mdelay(10); 197*9d1cf39bSDmitry Baryshkov } 1989c636342SDmitry Baryshkov #endif 1999c636342SDmitry Baryshkov 200*9d1cf39bSDmitry Baryshkov bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) 201*9d1cf39bSDmitry Baryshkov { 202*9d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA25x 203*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa21x() || cpu_is_pxa25x()) 204*9d1cf39bSDmitry Baryshkov pxa_ac97_warm_pxa25x(); 205*9d1cf39bSDmitry Baryshkov else 206*9d1cf39bSDmitry Baryshkov #endif 207*9d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA27x 208*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa27x()) 209*9d1cf39bSDmitry Baryshkov pxa_ac97_warm_pxa27x(); 210*9d1cf39bSDmitry Baryshkov else 211*9d1cf39bSDmitry Baryshkov #endif 212*9d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA3xx 213*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa3xx()) 214*9d1cf39bSDmitry Baryshkov pxa_ac97_warm_pxa3xx(); 215*9d1cf39bSDmitry Baryshkov else 216*9d1cf39bSDmitry Baryshkov #endif 217*9d1cf39bSDmitry Baryshkov BUG(); 218*9d1cf39bSDmitry Baryshkov 2199c636342SDmitry Baryshkov if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { 2209c636342SDmitry Baryshkov printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", 2219c636342SDmitry Baryshkov __func__, gsr_bits); 2229c636342SDmitry Baryshkov 2239c636342SDmitry Baryshkov return false; 2249c636342SDmitry Baryshkov } 2259c636342SDmitry Baryshkov 2269c636342SDmitry Baryshkov return true; 2279c636342SDmitry Baryshkov } 2289c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset); 2299c636342SDmitry Baryshkov 2309c636342SDmitry Baryshkov bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) 2319c636342SDmitry Baryshkov { 232*9d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA25x 233*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa21x() || cpu_is_pxa25x()) 234*9d1cf39bSDmitry Baryshkov pxa_ac97_cold_pxa25x(); 235*9d1cf39bSDmitry Baryshkov else 2369c636342SDmitry Baryshkov #endif 2379c636342SDmitry Baryshkov #ifdef CONFIG_PXA27x 238*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa27x()) 239*9d1cf39bSDmitry Baryshkov pxa_ac97_cold_pxa27x(); 240*9d1cf39bSDmitry Baryshkov else 2419c636342SDmitry Baryshkov #endif 242*9d1cf39bSDmitry Baryshkov #ifdef CONFIG_PXA3xx 243*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa3xx()) 244*9d1cf39bSDmitry Baryshkov pxa_ac97_cold_pxa3xx(); 245*9d1cf39bSDmitry Baryshkov else 246*9d1cf39bSDmitry Baryshkov #endif 247*9d1cf39bSDmitry Baryshkov BUG(); 2489c636342SDmitry Baryshkov 2499c636342SDmitry Baryshkov if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { 2509c636342SDmitry Baryshkov printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", 2519c636342SDmitry Baryshkov __func__, gsr_bits); 2529c636342SDmitry Baryshkov 2539c636342SDmitry Baryshkov return false; 2549c636342SDmitry Baryshkov } 2559c636342SDmitry Baryshkov 2569c636342SDmitry Baryshkov return true; 2579c636342SDmitry Baryshkov } 2589c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset); 2599c636342SDmitry Baryshkov 2609c636342SDmitry Baryshkov 2619c636342SDmitry Baryshkov void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97) 2629c636342SDmitry Baryshkov { 2639c636342SDmitry Baryshkov GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); 2649c636342SDmitry Baryshkov GCR |= GCR_SDONE_IE|GCR_CDONE_IE; 2659c636342SDmitry Baryshkov } 2669c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset); 2679c636342SDmitry Baryshkov 2689c636342SDmitry Baryshkov static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) 2699c636342SDmitry Baryshkov { 2709c636342SDmitry Baryshkov long status; 2719c636342SDmitry Baryshkov 2729c636342SDmitry Baryshkov status = GSR; 2739c636342SDmitry Baryshkov if (status) { 2749c636342SDmitry Baryshkov GSR = status; 2759c636342SDmitry Baryshkov gsr_bits |= status; 2769c636342SDmitry Baryshkov wake_up(&gsr_wq); 2779c636342SDmitry Baryshkov 2789c636342SDmitry Baryshkov /* Although we don't use those we still need to clear them 2799c636342SDmitry Baryshkov since they tend to spuriously trigger when MMC is used 2809c636342SDmitry Baryshkov (hardware bug? go figure)... */ 281*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa27x()) { 2829c636342SDmitry Baryshkov MISR = MISR_EOC; 2839c636342SDmitry Baryshkov PISR = PISR_EOC; 2849c636342SDmitry Baryshkov MCSR = MCSR_EOC; 285*9d1cf39bSDmitry Baryshkov } 2869c636342SDmitry Baryshkov 2879c636342SDmitry Baryshkov return IRQ_HANDLED; 2889c636342SDmitry Baryshkov } 2899c636342SDmitry Baryshkov 2909c636342SDmitry Baryshkov return IRQ_NONE; 2919c636342SDmitry Baryshkov } 2929c636342SDmitry Baryshkov 2939c636342SDmitry Baryshkov #ifdef CONFIG_PM 2949c636342SDmitry Baryshkov int pxa2xx_ac97_hw_suspend(void) 2959c636342SDmitry Baryshkov { 2969c636342SDmitry Baryshkov GCR |= GCR_ACLINK_OFF; 2979c636342SDmitry Baryshkov clk_disable(ac97_clk); 2989c636342SDmitry Baryshkov return 0; 2999c636342SDmitry Baryshkov } 3009c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend); 3019c636342SDmitry Baryshkov 3029c636342SDmitry Baryshkov int pxa2xx_ac97_hw_resume(void) 3039c636342SDmitry Baryshkov { 304*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) { 3059c636342SDmitry Baryshkov pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 3069c636342SDmitry Baryshkov pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); 3079c636342SDmitry Baryshkov pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); 3089c636342SDmitry Baryshkov pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); 309*9d1cf39bSDmitry Baryshkov } 310*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa27x()) { 3119c636342SDmitry Baryshkov /* Use GPIO 113 as AC97 Reset on Bulverde */ 3129c636342SDmitry Baryshkov pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 313*9d1cf39bSDmitry Baryshkov } 3149c636342SDmitry Baryshkov clk_enable(ac97_clk); 3159c636342SDmitry Baryshkov return 0; 3169c636342SDmitry Baryshkov } 3179c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume); 3189c636342SDmitry Baryshkov #endif 3199c636342SDmitry Baryshkov 3209c636342SDmitry Baryshkov int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) 3219c636342SDmitry Baryshkov { 3229c636342SDmitry Baryshkov int ret; 3239c636342SDmitry Baryshkov 3249c636342SDmitry Baryshkov ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); 3259c636342SDmitry Baryshkov if (ret < 0) 3269c636342SDmitry Baryshkov goto err; 3279c636342SDmitry Baryshkov 328*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) { 3299c636342SDmitry Baryshkov pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 3309c636342SDmitry Baryshkov pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); 3319c636342SDmitry Baryshkov pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); 3329c636342SDmitry Baryshkov pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); 333*9d1cf39bSDmitry Baryshkov } 334*9d1cf39bSDmitry Baryshkov 335*9d1cf39bSDmitry Baryshkov if (cpu_is_pxa27x()) { 3369c636342SDmitry Baryshkov /* Use GPIO 113 as AC97 Reset on Bulverde */ 3379c636342SDmitry Baryshkov pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); 3389c636342SDmitry Baryshkov ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); 3399c636342SDmitry Baryshkov if (IS_ERR(ac97conf_clk)) { 3409c636342SDmitry Baryshkov ret = PTR_ERR(ac97conf_clk); 3419c636342SDmitry Baryshkov ac97conf_clk = NULL; 3429c636342SDmitry Baryshkov goto err_irq; 3439c636342SDmitry Baryshkov } 344*9d1cf39bSDmitry Baryshkov } 3459c636342SDmitry Baryshkov 3469c636342SDmitry Baryshkov ac97_clk = clk_get(&dev->dev, "AC97CLK"); 3479c636342SDmitry Baryshkov if (IS_ERR(ac97_clk)) { 3489c636342SDmitry Baryshkov ret = PTR_ERR(ac97_clk); 3499c636342SDmitry Baryshkov ac97_clk = NULL; 3509c636342SDmitry Baryshkov goto err_irq; 3519c636342SDmitry Baryshkov } 3529c636342SDmitry Baryshkov 3539c636342SDmitry Baryshkov return clk_enable(ac97_clk); 3549c636342SDmitry Baryshkov 3559c636342SDmitry Baryshkov err_irq: 3569c636342SDmitry Baryshkov GCR |= GCR_ACLINK_OFF; 3579c636342SDmitry Baryshkov if (ac97conf_clk) { 3589c636342SDmitry Baryshkov clk_put(ac97conf_clk); 3599c636342SDmitry Baryshkov ac97conf_clk = NULL; 3609c636342SDmitry Baryshkov } 3619c636342SDmitry Baryshkov free_irq(IRQ_AC97, NULL); 3629c636342SDmitry Baryshkov err: 3639c636342SDmitry Baryshkov return ret; 3649c636342SDmitry Baryshkov } 3659c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); 3669c636342SDmitry Baryshkov 3679c636342SDmitry Baryshkov void pxa2xx_ac97_hw_remove(struct platform_device *dev) 3689c636342SDmitry Baryshkov { 3699c636342SDmitry Baryshkov GCR |= GCR_ACLINK_OFF; 3709c636342SDmitry Baryshkov free_irq(IRQ_AC97, NULL); 371*9d1cf39bSDmitry Baryshkov if (ac97conf_clk) { 3729c636342SDmitry Baryshkov clk_put(ac97conf_clk); 3739c636342SDmitry Baryshkov ac97conf_clk = NULL; 374*9d1cf39bSDmitry Baryshkov } 3759c636342SDmitry Baryshkov clk_disable(ac97_clk); 3769c636342SDmitry Baryshkov clk_put(ac97_clk); 3779c636342SDmitry Baryshkov ac97_clk = NULL; 3789c636342SDmitry Baryshkov } 3799c636342SDmitry Baryshkov EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove); 3809c636342SDmitry Baryshkov 3819c636342SDmitry Baryshkov MODULE_AUTHOR("Nicolas Pitre"); 3829c636342SDmitry Baryshkov MODULE_DESCRIPTION("Intel/Marvell PXA sound library"); 3839c636342SDmitry Baryshkov MODULE_LICENSE("GPL"); 3849c636342SDmitry Baryshkov 385