Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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