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