1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c 4 * which contain: 5 * 6 * Author: Nicolas Pitre 7 * Created: Dec 02, 2004 8 * Copyright: MontaVista Software Inc. 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/platform_device.h> 13 #include <linux/interrupt.h> 14 #include <linux/clk.h> 15 #include <linux/delay.h> 16 #include <linux/module.h> 17 #include <linux/io.h> 18 #include <linux/gpio.h> 19 #include <linux/of_gpio.h> 20 #include <linux/soc/pxa/cpu.h> 21 22 #include <sound/pxa2xx-lib.h> 23 24 #include <linux/platform_data/asoc-pxa.h> 25 26 #include "pxa2xx-ac97-regs.h" 27 28 static DEFINE_MUTEX(car_mutex); 29 static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); 30 static volatile long gsr_bits; 31 static struct clk *ac97_clk; 32 static struct clk *ac97conf_clk; 33 static int reset_gpio; 34 static void __iomem *ac97_reg_base; 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 46 int pxa2xx_ac97_read(int slot, unsigned short reg) 47 { 48 int val = -ENODEV; 49 u32 __iomem *reg_addr; 50 51 if (slot > 0) 52 return -ENODEV; 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_reg_base + 59 (slot ? SMC_REG_BASE : PMC_REG_BASE); 60 else 61 reg_addr = ac97_reg_base + 62 (slot ? SAC_REG_BASE : PAC_REG_BASE); 63 reg_addr += (reg >> 1); 64 65 /* start read access across the ac97 link */ 66 writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR); 67 gsr_bits = 0; 68 val = (readl(reg_addr) & 0xffff); 69 if (reg == AC97_GPIO_STATUS) 70 goto out; 71 if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1) <= 0 && 72 !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE)) { 73 printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", 74 __func__, reg, readl(ac97_reg_base + GSR) | gsr_bits); 75 val = -ETIMEDOUT; 76 goto out; 77 } 78 79 /* valid data now */ 80 writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR); 81 gsr_bits = 0; 82 val = (readl(reg_addr) & 0xffff); 83 /* but we've just started another cycle... */ 84 wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1); 85 86 out: mutex_unlock(&car_mutex); 87 return val; 88 } 89 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read); 90 91 int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val) 92 { 93 u32 __iomem *reg_addr; 94 int ret = 0; 95 96 mutex_lock(&car_mutex); 97 98 /* set up primary or secondary codec space */ 99 if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS) 100 reg_addr = ac97_reg_base + 101 (slot ? SMC_REG_BASE : PMC_REG_BASE); 102 else 103 reg_addr = ac97_reg_base + 104 (slot ? SAC_REG_BASE : PAC_REG_BASE); 105 reg_addr += (reg >> 1); 106 107 writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR); 108 gsr_bits = 0; 109 writel(val, reg_addr); 110 if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE, 1) <= 0 && 111 !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE)) { 112 printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", 113 __func__, reg, readl(ac97_reg_base + GSR) | gsr_bits); 114 ret = -EIO; 115 } 116 117 mutex_unlock(&car_mutex); 118 return ret; 119 } 120 EXPORT_SYMBOL_GPL(pxa2xx_ac97_write); 121 122 #ifdef CONFIG_PXA25x 123 static inline void pxa_ac97_warm_pxa25x(void) 124 { 125 gsr_bits = 0; 126 127 writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR); 128 } 129 130 static inline void pxa_ac97_cold_pxa25x(void) 131 { 132 writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR); /* clear everything but nCRST */ 133 writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR); /* then assert nCRST */ 134 135 gsr_bits = 0; 136 137 writel(GCR_COLD_RST, ac97_reg_base + GCR); 138 } 139 #endif 140 141 #ifdef CONFIG_PXA27x 142 static inline void pxa_ac97_warm_pxa27x(void) 143 { 144 gsr_bits = 0; 145 146 /* warm reset broken on Bulverde, so manually keep AC97 reset high */ 147 pxa27x_configure_ac97reset(reset_gpio, true); 148 udelay(10); 149 writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR); 150 pxa27x_configure_ac97reset(reset_gpio, false); 151 udelay(500); 152 } 153 154 static inline void pxa_ac97_cold_pxa27x(void) 155 { 156 writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR); /* clear everything but nCRST */ 157 writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR); /* then assert nCRST */ 158 159 gsr_bits = 0; 160 161 /* PXA27x Developers Manual section 13.5.2.2.1 */ 162 clk_prepare_enable(ac97conf_clk); 163 udelay(5); 164 clk_disable_unprepare(ac97conf_clk); 165 writel(GCR_COLD_RST | GCR_WARM_RST, ac97_reg_base + GCR); 166 } 167 #endif 168 169 #ifdef CONFIG_PXA3xx 170 static inline void pxa_ac97_warm_pxa3xx(void) 171 { 172 gsr_bits = 0; 173 174 /* Can't use interrupts */ 175 writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR); 176 } 177 178 static inline void pxa_ac97_cold_pxa3xx(void) 179 { 180 /* Hold CLKBPB for 100us */ 181 writel(0, ac97_reg_base + GCR); 182 writel(GCR_CLKBPB, ac97_reg_base + GCR); 183 udelay(100); 184 writel(0, ac97_reg_base + GCR); 185 186 writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR); /* clear everything but nCRST */ 187 writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR); /* then assert nCRST */ 188 189 gsr_bits = 0; 190 191 /* Can't use interrupts on PXA3xx */ 192 writel(readl(ac97_reg_base + GCR) & (~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN)), ac97_reg_base + GCR); 193 194 writel(GCR_WARM_RST | GCR_COLD_RST, ac97_reg_base + GCR); 195 } 196 #endif 197 198 bool pxa2xx_ac97_try_warm_reset(void) 199 { 200 unsigned long gsr; 201 unsigned int timeout = 100; 202 203 #ifdef CONFIG_PXA25x 204 if (cpu_is_pxa25x()) 205 pxa_ac97_warm_pxa25x(); 206 else 207 #endif 208 #ifdef CONFIG_PXA27x 209 if (cpu_is_pxa27x()) 210 pxa_ac97_warm_pxa27x(); 211 else 212 #endif 213 #ifdef CONFIG_PXA3xx 214 if (cpu_is_pxa3xx()) 215 pxa_ac97_warm_pxa3xx(); 216 else 217 #endif 218 snd_BUG(); 219 220 while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) 221 mdelay(1); 222 223 gsr = readl(ac97_reg_base + GSR) | gsr_bits; 224 if (!(gsr & (GSR_PCR | GSR_SCR))) { 225 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", 226 __func__, gsr); 227 228 return false; 229 } 230 231 return true; 232 } 233 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset); 234 235 bool pxa2xx_ac97_try_cold_reset(void) 236 { 237 unsigned long gsr; 238 unsigned int timeout = 1000; 239 240 #ifdef CONFIG_PXA25x 241 if (cpu_is_pxa25x()) 242 pxa_ac97_cold_pxa25x(); 243 else 244 #endif 245 #ifdef CONFIG_PXA27x 246 if (cpu_is_pxa27x()) 247 pxa_ac97_cold_pxa27x(); 248 else 249 #endif 250 #ifdef CONFIG_PXA3xx 251 if (cpu_is_pxa3xx()) 252 pxa_ac97_cold_pxa3xx(); 253 else 254 #endif 255 snd_BUG(); 256 257 while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--) 258 mdelay(1); 259 260 gsr = readl(ac97_reg_base + 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 } 270 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset); 271 272 273 void pxa2xx_ac97_finish_reset(void) 274 { 275 u32 gcr = readl(ac97_reg_base + GCR); 276 gcr &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); 277 gcr |= GCR_SDONE_IE|GCR_CDONE_IE; 278 writel(gcr, ac97_reg_base + GCR); 279 } 280 EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset); 281 282 static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) 283 { 284 long status; 285 286 status = readl(ac97_reg_base + GSR); 287 if (status) { 288 writel(status, ac97_reg_base + GSR); 289 gsr_bits |= status; 290 wake_up(&gsr_wq); 291 292 /* Although we don't use those we still need to clear them 293 since they tend to spuriously trigger when MMC is used 294 (hardware bug? go figure)... */ 295 if (cpu_is_pxa27x()) { 296 writel(MISR_EOC, ac97_reg_base + MISR); 297 writel(PISR_EOC, ac97_reg_base + PISR); 298 writel(MCSR_EOC, ac97_reg_base + MCSR); 299 } 300 301 return IRQ_HANDLED; 302 } 303 304 return IRQ_NONE; 305 } 306 307 #ifdef CONFIG_PM 308 int pxa2xx_ac97_hw_suspend(void) 309 { 310 writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR); 311 clk_disable_unprepare(ac97_clk); 312 return 0; 313 } 314 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend); 315 316 int pxa2xx_ac97_hw_resume(void) 317 { 318 clk_prepare_enable(ac97_clk); 319 return 0; 320 } 321 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume); 322 #endif 323 324 int pxa2xx_ac97_hw_probe(struct platform_device *dev) 325 { 326 int ret; 327 int irq; 328 pxa2xx_audio_ops_t *pdata = dev->dev.platform_data; 329 330 ac97_reg_base = devm_platform_ioremap_resource(dev, 0); 331 if (IS_ERR(ac97_reg_base)) { 332 dev_err(&dev->dev, "Missing MMIO resource\n"); 333 return PTR_ERR(ac97_reg_base); 334 } 335 336 if (pdata) { 337 switch (pdata->reset_gpio) { 338 case 95: 339 case 113: 340 reset_gpio = pdata->reset_gpio; 341 break; 342 case 0: 343 reset_gpio = 113; 344 break; 345 case -1: 346 break; 347 default: 348 dev_err(&dev->dev, "Invalid reset GPIO %d\n", 349 pdata->reset_gpio); 350 } 351 } else if (!pdata && dev->dev.of_node) { 352 pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); 353 if (!pdata) 354 return -ENOMEM; 355 pdata->reset_gpio = of_get_named_gpio(dev->dev.of_node, 356 "reset-gpios", 0); 357 if (pdata->reset_gpio == -ENOENT) 358 pdata->reset_gpio = -1; 359 else if (pdata->reset_gpio < 0) 360 return pdata->reset_gpio; 361 reset_gpio = pdata->reset_gpio; 362 } else { 363 if (cpu_is_pxa27x()) 364 reset_gpio = 113; 365 } 366 367 if (cpu_is_pxa27x()) { 368 /* 369 * This gpio is needed for a work-around to a bug in the ac97 370 * controller during warm reset. The direction and level is set 371 * here so that it is an output driven high when switching from 372 * AC97_nRESET alt function to generic gpio. 373 */ 374 ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH, 375 "pxa27x ac97 reset"); 376 if (ret < 0) { 377 pr_err("%s: gpio_request_one() failed: %d\n", 378 __func__, ret); 379 goto err_conf; 380 } 381 pxa27x_configure_ac97reset(reset_gpio, false); 382 383 ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); 384 if (IS_ERR(ac97conf_clk)) { 385 ret = PTR_ERR(ac97conf_clk); 386 ac97conf_clk = NULL; 387 goto err_conf; 388 } 389 } 390 391 ac97_clk = clk_get(&dev->dev, "AC97CLK"); 392 if (IS_ERR(ac97_clk)) { 393 ret = PTR_ERR(ac97_clk); 394 ac97_clk = NULL; 395 goto err_clk; 396 } 397 398 ret = clk_prepare_enable(ac97_clk); 399 if (ret) 400 goto err_clk2; 401 402 irq = platform_get_irq(dev, 0); 403 if (irq < 0) { 404 ret = irq; 405 goto err_irq; 406 } 407 408 ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL); 409 if (ret < 0) 410 goto err_irq; 411 412 return 0; 413 414 err_irq: 415 writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR); 416 err_clk2: 417 clk_put(ac97_clk); 418 ac97_clk = NULL; 419 err_clk: 420 if (ac97conf_clk) { 421 clk_put(ac97conf_clk); 422 ac97conf_clk = NULL; 423 } 424 err_conf: 425 return ret; 426 } 427 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); 428 429 void pxa2xx_ac97_hw_remove(struct platform_device *dev) 430 { 431 if (cpu_is_pxa27x()) 432 gpio_free(reset_gpio); 433 writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR); 434 free_irq(platform_get_irq(dev, 0), NULL); 435 if (ac97conf_clk) { 436 clk_put(ac97conf_clk); 437 ac97conf_clk = NULL; 438 } 439 clk_disable_unprepare(ac97_clk); 440 clk_put(ac97_clk); 441 ac97_clk = NULL; 442 } 443 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove); 444 445 u32 pxa2xx_ac97_read_modr(void) 446 { 447 if (!ac97_reg_base) 448 return 0; 449 450 return readl(ac97_reg_base + MODR); 451 } 452 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_modr); 453 454 u32 pxa2xx_ac97_read_misr(void) 455 { 456 if (!ac97_reg_base) 457 return 0; 458 459 return readl(ac97_reg_base + MISR); 460 } 461 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_misr); 462 463 MODULE_AUTHOR("Nicolas Pitre"); 464 MODULE_DESCRIPTION("Intel/Marvell PXA sound library"); 465 MODULE_LICENSE("GPL"); 466 467