Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Based on sound/arm/pxa2xx-ac97.c and sound/soc/pxa/pxa2xx-ac97.c
0004  * which contain:
0005  *
0006  * Author:  Nicolas Pitre
0007  * Created: Dec 02, 2004
0008  * Copyright:   MontaVista Software Inc.
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/clk.h>
0015 #include <linux/delay.h>
0016 #include <linux/module.h>
0017 #include <linux/io.h>
0018 #include <linux/gpio.h>
0019 #include <linux/of_gpio.h>
0020 #include <linux/soc/pxa/cpu.h>
0021 
0022 #include <sound/pxa2xx-lib.h>
0023 
0024 #include <linux/platform_data/asoc-pxa.h>
0025 
0026 #include "pxa2xx-ac97-regs.h"
0027 
0028 static DEFINE_MUTEX(car_mutex);
0029 static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
0030 static volatile long gsr_bits;
0031 static struct clk *ac97_clk;
0032 static struct clk *ac97conf_clk;
0033 static int reset_gpio;
0034 static void __iomem *ac97_reg_base;
0035 
0036 extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio);
0037 
0038 /*
0039  * Beware PXA27x bugs:
0040  *
0041  *   o Slot 12 read from modem space will hang controller.
0042  *   o CDONE, SDONE interrupt fails after any slot 12 IO.
0043  *
0044  * We therefore have an hybrid approach for waiting on SDONE (interrupt or
0045  * 1 jiffy timeout if interrupt never comes).
0046  */
0047 
0048 int pxa2xx_ac97_read(int slot, unsigned short reg)
0049 {
0050     int val = -ENODEV;
0051     u32 __iomem *reg_addr;
0052 
0053     if (slot > 0)
0054         return -ENODEV;
0055 
0056     mutex_lock(&car_mutex);
0057 
0058     /* set up primary or secondary codec space */
0059     if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
0060         reg_addr = ac97_reg_base +
0061                (slot ? SMC_REG_BASE : PMC_REG_BASE);
0062     else
0063         reg_addr = ac97_reg_base +
0064                (slot ? SAC_REG_BASE : PAC_REG_BASE);
0065     reg_addr += (reg >> 1);
0066 
0067     /* start read access across the ac97 link */
0068     writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
0069     gsr_bits = 0;
0070     val = (readl(reg_addr) & 0xffff);
0071     if (reg == AC97_GPIO_STATUS)
0072         goto out;
0073     if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1) <= 0 &&
0074         !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE)) {
0075         printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
0076                 __func__, reg, readl(ac97_reg_base + GSR) | gsr_bits);
0077         val = -ETIMEDOUT;
0078         goto out;
0079     }
0080 
0081     /* valid data now */
0082     writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
0083     gsr_bits = 0;
0084     val = (readl(reg_addr) & 0xffff);
0085     /* but we've just started another cycle... */
0086     wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1);
0087 
0088 out:    mutex_unlock(&car_mutex);
0089     return val;
0090 }
0091 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
0092 
0093 int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
0094 {
0095     u32 __iomem *reg_addr;
0096     int ret = 0;
0097 
0098     mutex_lock(&car_mutex);
0099 
0100     /* set up primary or secondary codec space */
0101     if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
0102         reg_addr = ac97_reg_base +
0103                (slot ? SMC_REG_BASE : PMC_REG_BASE);
0104     else
0105         reg_addr = ac97_reg_base +
0106                (slot ? SAC_REG_BASE : PAC_REG_BASE);
0107     reg_addr += (reg >> 1);
0108 
0109     writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR);
0110     gsr_bits = 0;
0111     writel(val, reg_addr);
0112     if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE, 1) <= 0 &&
0113         !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE)) {
0114         printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
0115                 __func__, reg, readl(ac97_reg_base + GSR) | gsr_bits);
0116         ret = -EIO;
0117     }
0118 
0119     mutex_unlock(&car_mutex);
0120     return ret;
0121 }
0122 EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
0123 
0124 #ifdef CONFIG_PXA25x
0125 static inline void pxa_ac97_warm_pxa25x(void)
0126 {
0127     gsr_bits = 0;
0128 
0129     writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
0130 }
0131 
0132 static inline void pxa_ac97_cold_pxa25x(void)
0133 {
0134     writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR);  /* clear everything but nCRST */
0135     writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR);  /* then assert nCRST */
0136 
0137     gsr_bits = 0;
0138 
0139     writel(GCR_COLD_RST, ac97_reg_base + GCR);
0140 }
0141 #endif
0142 
0143 #ifdef CONFIG_PXA27x
0144 static inline void pxa_ac97_warm_pxa27x(void)
0145 {
0146     gsr_bits = 0;
0147 
0148     /* warm reset broken on Bulverde, so manually keep AC97 reset high */
0149     pxa27x_configure_ac97reset(reset_gpio, true);
0150     udelay(10);
0151     writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
0152     pxa27x_configure_ac97reset(reset_gpio, false);
0153     udelay(500);
0154 }
0155 
0156 static inline void pxa_ac97_cold_pxa27x(void)
0157 {
0158     writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR);  /* clear everything but nCRST */
0159     writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR);  /* then assert nCRST */
0160 
0161     gsr_bits = 0;
0162 
0163     /* PXA27x Developers Manual section 13.5.2.2.1 */
0164     clk_prepare_enable(ac97conf_clk);
0165     udelay(5);
0166     clk_disable_unprepare(ac97conf_clk);
0167     writel(GCR_COLD_RST | GCR_WARM_RST, ac97_reg_base + GCR);
0168 }
0169 #endif
0170 
0171 #ifdef CONFIG_PXA3xx
0172 static inline void pxa_ac97_warm_pxa3xx(void)
0173 {
0174     gsr_bits = 0;
0175 
0176     /* Can't use interrupts */
0177     writel(readl(ac97_reg_base + GCR) | (GCR_WARM_RST), ac97_reg_base + GCR);
0178 }
0179 
0180 static inline void pxa_ac97_cold_pxa3xx(void)
0181 {
0182     /* Hold CLKBPB for 100us */
0183     writel(0, ac97_reg_base + GCR);
0184     writel(GCR_CLKBPB, ac97_reg_base + GCR);
0185     udelay(100);
0186     writel(0, ac97_reg_base + GCR);
0187 
0188     writel(readl(ac97_reg_base + GCR) & ( GCR_COLD_RST), ac97_reg_base + GCR);  /* clear everything but nCRST */
0189     writel(readl(ac97_reg_base + GCR) & (~GCR_COLD_RST), ac97_reg_base + GCR);  /* then assert nCRST */
0190 
0191     gsr_bits = 0;
0192 
0193     /* Can't use interrupts on PXA3xx */
0194     writel(readl(ac97_reg_base + GCR) & (~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN)), ac97_reg_base + GCR);
0195 
0196     writel(GCR_WARM_RST | GCR_COLD_RST, ac97_reg_base + GCR);
0197 }
0198 #endif
0199 
0200 bool pxa2xx_ac97_try_warm_reset(void)
0201 {
0202     unsigned long gsr;
0203     unsigned int timeout = 100;
0204 
0205 #ifdef CONFIG_PXA25x
0206     if (cpu_is_pxa25x())
0207         pxa_ac97_warm_pxa25x();
0208     else
0209 #endif
0210 #ifdef CONFIG_PXA27x
0211     if (cpu_is_pxa27x())
0212         pxa_ac97_warm_pxa27x();
0213     else
0214 #endif
0215 #ifdef CONFIG_PXA3xx
0216     if (cpu_is_pxa3xx())
0217         pxa_ac97_warm_pxa3xx();
0218     else
0219 #endif
0220         snd_BUG();
0221 
0222     while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
0223         mdelay(1);
0224 
0225     gsr = readl(ac97_reg_base + GSR) | gsr_bits;
0226     if (!(gsr & (GSR_PCR | GSR_SCR))) {
0227         printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
0228                  __func__, gsr);
0229 
0230         return false;
0231     }
0232 
0233     return true;
0234 }
0235 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
0236 
0237 bool pxa2xx_ac97_try_cold_reset(void)
0238 {
0239     unsigned long gsr;
0240     unsigned int timeout = 1000;
0241 
0242 #ifdef CONFIG_PXA25x
0243     if (cpu_is_pxa25x())
0244         pxa_ac97_cold_pxa25x();
0245     else
0246 #endif
0247 #ifdef CONFIG_PXA27x
0248     if (cpu_is_pxa27x())
0249         pxa_ac97_cold_pxa27x();
0250     else
0251 #endif
0252 #ifdef CONFIG_PXA3xx
0253     if (cpu_is_pxa3xx())
0254         pxa_ac97_cold_pxa3xx();
0255     else
0256 #endif
0257         snd_BUG();
0258 
0259     while (!((readl(ac97_reg_base + GSR) | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
0260         mdelay(1);
0261 
0262     gsr = readl(ac97_reg_base + GSR) | gsr_bits;
0263     if (!(gsr & (GSR_PCR | GSR_SCR))) {
0264         printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
0265                  __func__, gsr);
0266 
0267         return false;
0268     }
0269 
0270     return true;
0271 }
0272 EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
0273 
0274 
0275 void pxa2xx_ac97_finish_reset(void)
0276 {
0277     u32 gcr = readl(ac97_reg_base + GCR);
0278     gcr &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
0279     gcr |= GCR_SDONE_IE|GCR_CDONE_IE;
0280     writel(gcr, ac97_reg_base + GCR);
0281 }
0282 EXPORT_SYMBOL_GPL(pxa2xx_ac97_finish_reset);
0283 
0284 static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
0285 {
0286     long status;
0287 
0288     status = readl(ac97_reg_base + GSR);
0289     if (status) {
0290         writel(status, ac97_reg_base + GSR);
0291         gsr_bits |= status;
0292         wake_up(&gsr_wq);
0293 
0294         /* Although we don't use those we still need to clear them
0295            since they tend to spuriously trigger when MMC is used
0296            (hardware bug? go figure)... */
0297         if (cpu_is_pxa27x()) {
0298             writel(MISR_EOC, ac97_reg_base + MISR);
0299             writel(PISR_EOC, ac97_reg_base + PISR);
0300             writel(MCSR_EOC, ac97_reg_base + MCSR);
0301         }
0302 
0303         return IRQ_HANDLED;
0304     }
0305 
0306     return IRQ_NONE;
0307 }
0308 
0309 #ifdef CONFIG_PM
0310 int pxa2xx_ac97_hw_suspend(void)
0311 {
0312     writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
0313     clk_disable_unprepare(ac97_clk);
0314     return 0;
0315 }
0316 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
0317 
0318 int pxa2xx_ac97_hw_resume(void)
0319 {
0320     clk_prepare_enable(ac97_clk);
0321     return 0;
0322 }
0323 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
0324 #endif
0325 
0326 int pxa2xx_ac97_hw_probe(struct platform_device *dev)
0327 {
0328     int ret;
0329     int irq;
0330     pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
0331 
0332     ac97_reg_base = devm_platform_ioremap_resource(dev, 0);
0333     if (IS_ERR(ac97_reg_base)) {
0334         dev_err(&dev->dev, "Missing MMIO resource\n");
0335         return PTR_ERR(ac97_reg_base);
0336     }
0337 
0338     if (pdata) {
0339         switch (pdata->reset_gpio) {
0340         case 95:
0341         case 113:
0342             reset_gpio = pdata->reset_gpio;
0343             break;
0344         case 0:
0345             reset_gpio = 113;
0346             break;
0347         case -1:
0348             break;
0349         default:
0350             dev_err(&dev->dev, "Invalid reset GPIO %d\n",
0351                 pdata->reset_gpio);
0352         }
0353     } else if (!pdata && dev->dev.of_node) {
0354         pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
0355         if (!pdata)
0356             return -ENOMEM;
0357         pdata->reset_gpio = of_get_named_gpio(dev->dev.of_node,
0358                               "reset-gpios", 0);
0359         if (pdata->reset_gpio == -ENOENT)
0360             pdata->reset_gpio = -1;
0361         else if (pdata->reset_gpio < 0)
0362             return pdata->reset_gpio;
0363         reset_gpio = pdata->reset_gpio;
0364     } else {
0365         if (cpu_is_pxa27x())
0366             reset_gpio = 113;
0367     }
0368 
0369     if (cpu_is_pxa27x()) {
0370         /*
0371          * This gpio is needed for a work-around to a bug in the ac97
0372          * controller during warm reset.  The direction and level is set
0373          * here so that it is an output driven high when switching from
0374          * AC97_nRESET alt function to generic gpio.
0375          */
0376         ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH,
0377                        "pxa27x ac97 reset");
0378         if (ret < 0) {
0379             pr_err("%s: gpio_request_one() failed: %d\n",
0380                    __func__, ret);
0381             goto err_conf;
0382         }
0383         pxa27x_configure_ac97reset(reset_gpio, false);
0384 
0385         ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
0386         if (IS_ERR(ac97conf_clk)) {
0387             ret = PTR_ERR(ac97conf_clk);
0388             ac97conf_clk = NULL;
0389             goto err_conf;
0390         }
0391     }
0392 
0393     ac97_clk = clk_get(&dev->dev, "AC97CLK");
0394     if (IS_ERR(ac97_clk)) {
0395         ret = PTR_ERR(ac97_clk);
0396         ac97_clk = NULL;
0397         goto err_clk;
0398     }
0399 
0400     ret = clk_prepare_enable(ac97_clk);
0401     if (ret)
0402         goto err_clk2;
0403 
0404     irq = platform_get_irq(dev, 0);
0405     if (!irq)
0406         goto err_irq;
0407 
0408     ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL);
0409     if (ret < 0)
0410         goto err_irq;
0411 
0412     return 0;
0413 
0414 err_irq:
0415     writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
0416 err_clk2:
0417     clk_put(ac97_clk);
0418     ac97_clk = NULL;
0419 err_clk:
0420     if (ac97conf_clk) {
0421         clk_put(ac97conf_clk);
0422         ac97conf_clk = NULL;
0423     }
0424 err_conf:
0425     return ret;
0426 }
0427 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
0428 
0429 void pxa2xx_ac97_hw_remove(struct platform_device *dev)
0430 {
0431     if (cpu_is_pxa27x())
0432         gpio_free(reset_gpio);
0433     writel(readl(ac97_reg_base + GCR) | (GCR_ACLINK_OFF), ac97_reg_base + GCR);
0434     free_irq(platform_get_irq(dev, 0), NULL);
0435     if (ac97conf_clk) {
0436         clk_put(ac97conf_clk);
0437         ac97conf_clk = NULL;
0438     }
0439     clk_disable_unprepare(ac97_clk);
0440     clk_put(ac97_clk);
0441     ac97_clk = NULL;
0442 }
0443 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_remove);
0444 
0445 u32 pxa2xx_ac97_read_modr(void)
0446 {
0447     if (!ac97_reg_base)
0448         return 0;
0449 
0450     return readl(ac97_reg_base + MODR);
0451 }
0452 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_modr);
0453 
0454 u32 pxa2xx_ac97_read_misr(void)
0455 {
0456     if (!ac97_reg_base)
0457         return 0;
0458 
0459     return readl(ac97_reg_base + MISR);
0460 }
0461 EXPORT_SYMBOL_GPL(pxa2xx_ac97_read_misr);
0462 
0463 MODULE_AUTHOR("Nicolas Pitre");
0464 MODULE_DESCRIPTION("Intel/Marvell PXA sound library");
0465 MODULE_LICENSE("GPL");
0466