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