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/regs-ac97.h> 25#include <mach/audio.h> 26 27static DEFINE_MUTEX(car_mutex); 28static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); 29static volatile long gsr_bits; 30static struct clk *ac97_clk; 31static struct clk *ac97conf_clk; 32static int reset_gpio; 33 34extern void pxa27x_assert_ac97reset(int reset_gpio, int on); 35 36/* 37 * Beware PXA27x bugs: 38 * 39 * o Slot 12 read from modem space will hang controller. 40 * o CDONE, SDONE interrupt fails after any slot 12 IO. 41 * 42 * We therefore have an hybrid approach for waiting on SDONE (interrupt or 43 * 1 jiffy timeout if interrupt never comes). 44 */ 45 46unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 47{ 48 unsigned short val = -1; 49 volatile u32 *reg_addr; 50 51 mutex_lock(&car_mutex); 52 53 /* set up primary or secondary codec space */ 54 if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS) 55 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; 56 else 57 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; 58 reg_addr += (reg >> 1); 59 60 /* start read access across the ac97 link */ 61 GSR = GSR_CDONE | GSR_SDONE; 62 gsr_bits = 0; 63 val = *reg_addr; 64 if (reg == AC97_GPIO_STATUS) 65 goto out; 66 if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 && 67 !((GSR | gsr_bits) & GSR_SDONE)) { 68 printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", 69 __func__, reg, GSR | gsr_bits); 70 val = -1; 71 goto out; 72 } 73 74 /* valid data now */ 75 GSR = GSR_CDONE | GSR_SDONE; 76 gsr_bits = 0; 77 val = *reg_addr; 78 /* but we've just started another cycle... */ 79 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); 80 81out: mutex_unlock(&car_mutex); 82 return val; 83} 84EXPORT_SYMBOL_GPL(pxa2xx_ac97_read); 85 86void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, 87 unsigned short val) 88{ 89 volatile u32 *reg_addr; 90 91 mutex_lock(&car_mutex); 92 93 /* set up primary or secondary codec space */ 94 if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS) 95 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; 96 else 97 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; 98 reg_addr += (reg >> 1); 99 100 GSR = GSR_CDONE | GSR_SDONE; 101 gsr_bits = 0; 102 *reg_addr = val; 103 if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 && 104 !((GSR | gsr_bits) & GSR_CDONE)) 105 printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", 106 __func__, reg, GSR | gsr_bits); 107 108 mutex_unlock(&car_mutex); 109} 110EXPORT_SYMBOL_GPL(pxa2xx_ac97_write); 111 112#ifdef CONFIG_PXA25x 113static inline void pxa_ac97_warm_pxa25x(void) 114{ 115 gsr_bits = 0; 116 117 GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN; 118 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); 119} 120 121static inline void pxa_ac97_cold_pxa25x(void) 122{ 123 GCR &= GCR_COLD_RST; /* clear everything but nCRST */ 124 GCR &= ~GCR_COLD_RST; /* then assert nCRST */ 125 126 gsr_bits = 0; 127 128 GCR = GCR_COLD_RST; 129 GCR |= GCR_CDONE_IE|GCR_SDONE_IE; 130 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); 131} 132#endif 133 134#ifdef CONFIG_PXA27x 135static inline void pxa_ac97_warm_pxa27x(void) 136{ 137 gsr_bits = 0; 138 139 /* warm reset broken on Bulverde, so manually keep AC97 reset high */ 140 pxa27x_assert_ac97reset(reset_gpio, 1); 141 udelay(10); 142 GCR |= GCR_WARM_RST; 143 pxa27x_assert_ac97reset(reset_gpio, 0); 144 udelay(500); 145} 146 147static 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 164static 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 176static 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 200bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) 201{ 202 unsigned long gsr; 203 204#ifdef CONFIG_PXA25x 205 if (cpu_is_pxa25x()) 206 pxa_ac97_warm_pxa25x(); 207 else 208#endif 209#ifdef CONFIG_PXA27x 210 if (cpu_is_pxa27x()) 211 pxa_ac97_warm_pxa27x(); 212 else 213#endif 214#ifdef CONFIG_PXA3xx 215 if (cpu_is_pxa3xx()) 216 pxa_ac97_warm_pxa3xx(); 217 else 218#endif 219 BUG(); 220 gsr = GSR | gsr_bits; 221 if (!(gsr & (GSR_PCR | GSR_SCR))) { 222 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", 223 __func__, gsr); 224 225 return false; 226 } 227 228 return true; 229} 230EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset); 231 232bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) 233{ 234 unsigned long gsr; 235 236#ifdef CONFIG_PXA25x 237 if (cpu_is_pxa25x()) 238 pxa_ac97_cold_pxa25x(); 239 else 240#endif 241#ifdef CONFIG_PXA27x 242 if (cpu_is_pxa27x()) 243 pxa_ac97_cold_pxa27x(); 244 else 245#endif 246#ifdef CONFIG_PXA3xx 247 if (cpu_is_pxa3xx()) 248 pxa_ac97_cold_pxa3xx(); 249 else 250#endif 251 BUG(); 252 253 gsr = GSR | gsr_bits; 254 if (!(gsr & (GSR_PCR | GSR_SCR))) { 255 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", 256 __func__, gsr); 257 258 return false; 259 } 260 261 return true; 262} 263EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset); 264 265 266void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97) 267{ 268 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); 269 GCR |= GCR_SDONE_IE|GCR_CDONE_IE; 270} 271EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset); 272 273static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) 274{ 275 long status; 276 277 status = GSR; 278 if (status) { 279 GSR = status; 280 gsr_bits |= status; 281 wake_up(&gsr_wq); 282 283 /* Although we don't use those we still need to clear them 284 since they tend to spuriously trigger when MMC is used 285 (hardware bug? go figure)... */ 286 if (cpu_is_pxa27x()) { 287 MISR = MISR_EOC; 288 PISR = PISR_EOC; 289 MCSR = MCSR_EOC; 290 } 291 292 return IRQ_HANDLED; 293 } 294 295 return IRQ_NONE; 296} 297 298#ifdef CONFIG_PM 299int pxa2xx_ac97_hw_suspend(void) 300{ 301 GCR |= GCR_ACLINK_OFF; 302 clk_disable(ac97_clk); 303 return 0; 304} 305EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend); 306 307int pxa2xx_ac97_hw_resume(void) 308{ 309 clk_enable(ac97_clk); 310 return 0; 311} 312EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume); 313#endif 314 315int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) 316{ 317 int ret; 318 pxa2xx_audio_ops_t *pdata = dev->dev.platform_data; 319 320 if (pdata) { 321 switch (pdata->reset_gpio) { 322 case 95: 323 case 113: 324 reset_gpio = pdata->reset_gpio; 325 break; 326 case 0: 327 reset_gpio = 113; 328 break; 329 case -1: 330 break; 331 default: 332 dev_err(&dev->dev, "Invalid reset GPIO %d\n", 333 pdata->reset_gpio); 334 } 335 } else { 336 if (cpu_is_pxa27x()) 337 reset_gpio = 113; 338 } 339 340 if (cpu_is_pxa27x()) { 341 /* Use GPIO 113 as AC97 Reset on Bulverde */ 342 pxa27x_assert_ac97reset(reset_gpio, 0); 343 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); 344 if (IS_ERR(ac97conf_clk)) { 345 ret = PTR_ERR(ac97conf_clk); 346 ac97conf_clk = NULL; 347 goto err_conf; 348 } 349 } 350 351 ac97_clk = clk_get(&dev->dev, "AC97CLK"); 352 if (IS_ERR(ac97_clk)) { 353 ret = PTR_ERR(ac97_clk); 354 ac97_clk = NULL; 355 goto err_clk; 356 } 357 358 ret = clk_enable(ac97_clk); 359 if (ret) 360 goto err_clk2; 361 362 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL); 363 if (ret < 0) 364 goto err_irq; 365 366 return 0; 367 368err_irq: 369 GCR |= GCR_ACLINK_OFF; 370err_clk2: 371 clk_put(ac97_clk); 372 ac97_clk = NULL; 373err_clk: 374 if (ac97conf_clk) { 375 clk_put(ac97conf_clk); 376 ac97conf_clk = NULL; 377 } 378err_conf: 379 return ret; 380} 381EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); 382 383void pxa2xx_ac97_hw_remove(struct platform_device *dev) 384{ 385 GCR |= GCR_ACLINK_OFF; 386 free_irq(IRQ_AC97, NULL); 387 if (ac97conf_clk) { 388 clk_put(ac97conf_clk); 389 ac97conf_clk = NULL; 390 } 391 clk_disable(ac97_clk); 392 clk_put(ac97_clk); 393 ac97_clk = NULL; 394} 395EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove); 396 397MODULE_AUTHOR("Nicolas Pitre"); 398MODULE_DESCRIPTION("Intel/Marvell PXA sound library"); 399MODULE_LICENSE("GPL"); 400