linux/sound/soc/cirrus/ep93xx-ac97.c
<<
>>
Prefs
   1/*
   2 * ASoC driver for Cirrus Logic EP93xx AC97 controller.
   3 *
   4 * Copyright (c) 2010 Mika Westerberg
   5 *
   6 * Based on s3c-ac97 ASoC driver by Jaswinder Singh.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/delay.h>
  14#include <linux/err.h>
  15#include <linux/io.h>
  16#include <linux/init.h>
  17#include <linux/module.h>
  18#include <linux/platform_device.h>
  19#include <linux/slab.h>
  20
  21#include <sound/core.h>
  22#include <sound/dmaengine_pcm.h>
  23#include <sound/ac97_codec.h>
  24#include <sound/soc.h>
  25
  26#include <linux/platform_data/dma-ep93xx.h>
  27
  28#include "ep93xx-pcm.h"
  29
  30/*
  31 * Per channel (1-4) registers.
  32 */
  33#define AC97CH(n)               (((n) - 1) * 0x20)
  34
  35#define AC97DR(n)               (AC97CH(n) + 0x0000)
  36
  37#define AC97RXCR(n)             (AC97CH(n) + 0x0004)
  38#define AC97RXCR_REN            BIT(0)
  39#define AC97RXCR_RX3            BIT(3)
  40#define AC97RXCR_RX4            BIT(4)
  41#define AC97RXCR_CM             BIT(15)
  42
  43#define AC97TXCR(n)             (AC97CH(n) + 0x0008)
  44#define AC97TXCR_TEN            BIT(0)
  45#define AC97TXCR_TX3            BIT(3)
  46#define AC97TXCR_TX4            BIT(4)
  47#define AC97TXCR_CM             BIT(15)
  48
  49#define AC97SR(n)               (AC97CH(n) + 0x000c)
  50#define AC97SR_TXFE             BIT(1)
  51#define AC97SR_TXUE             BIT(6)
  52
  53#define AC97RISR(n)             (AC97CH(n) + 0x0010)
  54#define AC97ISR(n)              (AC97CH(n) + 0x0014)
  55#define AC97IE(n)               (AC97CH(n) + 0x0018)
  56
  57/*
  58 * Global AC97 controller registers.
  59 */
  60#define AC97S1DATA              0x0080
  61#define AC97S2DATA              0x0084
  62#define AC97S12DATA             0x0088
  63
  64#define AC97RGIS                0x008c
  65#define AC97GIS                 0x0090
  66#define AC97IM                  0x0094
  67/*
  68 * Common bits for RGIS, GIS and IM registers.
  69 */
  70#define AC97_SLOT2RXVALID       BIT(1)
  71#define AC97_CODECREADY         BIT(5)
  72#define AC97_SLOT2TXCOMPLETE    BIT(6)
  73
  74#define AC97EOI                 0x0098
  75#define AC97EOI_WINT            BIT(0)
  76#define AC97EOI_CODECREADY      BIT(1)
  77
  78#define AC97GCR                 0x009c
  79#define AC97GCR_AC97IFE         BIT(0)
  80
  81#define AC97RESET               0x00a0
  82#define AC97RESET_TIMEDRESET    BIT(0)
  83
  84#define AC97SYNC                0x00a4
  85#define AC97SYNC_TIMEDSYNC      BIT(0)
  86
  87#define AC97_TIMEOUT            msecs_to_jiffies(5)
  88
  89/**
  90 * struct ep93xx_ac97_info - EP93xx AC97 controller info structure
  91 * @lock: mutex serializing access to the bus (slot 1 & 2 ops)
  92 * @dev: pointer to the platform device dev structure
  93 * @regs: mapped AC97 controller registers
  94 * @done: bus ops wait here for an interrupt
  95 */
  96struct ep93xx_ac97_info {
  97        struct mutex            lock;
  98        struct device           *dev;
  99        void __iomem            *regs;
 100        struct completion       done;
 101        struct snd_dmaengine_dai_dma_data dma_params_rx;
 102        struct snd_dmaengine_dai_dma_data dma_params_tx;
 103};
 104
 105/* currently ALSA only supports a single AC97 device */
 106static struct ep93xx_ac97_info *ep93xx_ac97_info;
 107
 108static struct ep93xx_dma_data ep93xx_ac97_pcm_out = {
 109        .name           = "ac97-pcm-out",
 110        .port           = EP93XX_DMA_AAC1,
 111        .direction      = DMA_MEM_TO_DEV,
 112};
 113
 114static struct ep93xx_dma_data ep93xx_ac97_pcm_in = {
 115        .name           = "ac97-pcm-in",
 116        .port           = EP93XX_DMA_AAC1,
 117        .direction      = DMA_DEV_TO_MEM,
 118};
 119
 120static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info,
 121                                            unsigned reg)
 122{
 123        return __raw_readl(info->regs + reg);
 124}
 125
 126static inline void ep93xx_ac97_write_reg(struct ep93xx_ac97_info *info,
 127                                         unsigned reg, unsigned val)
 128{
 129        __raw_writel(val, info->regs + reg);
 130}
 131
 132static unsigned short ep93xx_ac97_read(struct snd_ac97 *ac97,
 133                                       unsigned short reg)
 134{
 135        struct ep93xx_ac97_info *info = ep93xx_ac97_info;
 136        unsigned short val;
 137
 138        mutex_lock(&info->lock);
 139
 140        ep93xx_ac97_write_reg(info, AC97S1DATA, reg);
 141        ep93xx_ac97_write_reg(info, AC97IM, AC97_SLOT2RXVALID);
 142        if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT)) {
 143                dev_warn(info->dev, "timeout reading register %x\n", reg);
 144                mutex_unlock(&info->lock);
 145                return -ETIMEDOUT;
 146        }
 147        val = (unsigned short)ep93xx_ac97_read_reg(info, AC97S2DATA);
 148
 149        mutex_unlock(&info->lock);
 150        return val;
 151}
 152
 153static void ep93xx_ac97_write(struct snd_ac97 *ac97,
 154                              unsigned short reg,
 155                              unsigned short val)
 156{
 157        struct ep93xx_ac97_info *info = ep93xx_ac97_info;
 158
 159        mutex_lock(&info->lock);
 160
 161        /*
 162         * Writes to the codec need to be done so that slot 2 is filled in
 163         * before slot 1.
 164         */
 165        ep93xx_ac97_write_reg(info, AC97S2DATA, val);
 166        ep93xx_ac97_write_reg(info, AC97S1DATA, reg);
 167
 168        ep93xx_ac97_write_reg(info, AC97IM, AC97_SLOT2TXCOMPLETE);
 169        if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT))
 170                dev_warn(info->dev, "timeout writing register %x\n", reg);
 171
 172        mutex_unlock(&info->lock);
 173}
 174
 175static void ep93xx_ac97_warm_reset(struct snd_ac97 *ac97)
 176{
 177        struct ep93xx_ac97_info *info = ep93xx_ac97_info;
 178
 179        mutex_lock(&info->lock);
 180
 181        /*
 182         * We are assuming that before this functions gets called, the codec
 183         * BIT_CLK is stopped by forcing the codec into powerdown mode. We can
 184         * control the SYNC signal directly via AC97SYNC register. Using
 185         * TIMEDSYNC the controller will keep the SYNC high > 1us.
 186         */
 187        ep93xx_ac97_write_reg(info, AC97SYNC, AC97SYNC_TIMEDSYNC);
 188        ep93xx_ac97_write_reg(info, AC97IM, AC97_CODECREADY);
 189        if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT))
 190                dev_warn(info->dev, "codec warm reset timeout\n");
 191
 192        mutex_unlock(&info->lock);
 193}
 194
 195static void ep93xx_ac97_cold_reset(struct snd_ac97 *ac97)
 196{
 197        struct ep93xx_ac97_info *info = ep93xx_ac97_info;
 198
 199        mutex_lock(&info->lock);
 200
 201        /*
 202         * For doing cold reset, we disable the AC97 controller interface, clear
 203         * WINT and CODECREADY bits, and finally enable the interface again.
 204         */
 205        ep93xx_ac97_write_reg(info, AC97GCR, 0);
 206        ep93xx_ac97_write_reg(info, AC97EOI, AC97EOI_CODECREADY | AC97EOI_WINT);
 207        ep93xx_ac97_write_reg(info, AC97GCR, AC97GCR_AC97IFE);
 208
 209        /*
 210         * Now, assert the reset and wait for the codec to become ready.
 211         */
 212        ep93xx_ac97_write_reg(info, AC97RESET, AC97RESET_TIMEDRESET);
 213        ep93xx_ac97_write_reg(info, AC97IM, AC97_CODECREADY);
 214        if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT))
 215                dev_warn(info->dev, "codec cold reset timeout\n");
 216
 217        /*
 218         * Give the codec some time to come fully out from the reset. This way
 219         * we ensure that the subsequent reads/writes will work.
 220         */
 221        usleep_range(15000, 20000);
 222
 223        mutex_unlock(&info->lock);
 224}
 225
 226static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id)
 227{
 228        struct ep93xx_ac97_info *info = dev_id;
 229        unsigned status, mask;
 230
 231        /*
 232         * Just mask out the interrupt and wake up the waiting thread.
 233         * Interrupts are cleared via reading/writing to slot 1 & 2 registers by
 234         * the waiting thread.
 235         */
 236        status = ep93xx_ac97_read_reg(info, AC97GIS);
 237        mask = ep93xx_ac97_read_reg(info, AC97IM);
 238        mask &= ~status;
 239        ep93xx_ac97_write_reg(info, AC97IM, mask);
 240
 241        complete(&info->done);
 242        return IRQ_HANDLED;
 243}
 244
 245static struct snd_ac97_bus_ops ep93xx_ac97_ops = {
 246        .read           = ep93xx_ac97_read,
 247        .write          = ep93xx_ac97_write,
 248        .reset          = ep93xx_ac97_cold_reset,
 249        .warm_reset     = ep93xx_ac97_warm_reset,
 250};
 251
 252static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
 253                               int cmd, struct snd_soc_dai *dai)
 254{
 255        struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai);
 256        unsigned v = 0;
 257
 258        switch (cmd) {
 259        case SNDRV_PCM_TRIGGER_START:
 260        case SNDRV_PCM_TRIGGER_RESUME:
 261        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 262                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 263                        /*
 264                         * Enable compact mode, TX slots 3 & 4, and the TX FIFO
 265                         * itself.
 266                         */
 267                        v |= AC97TXCR_CM;
 268                        v |= AC97TXCR_TX3 | AC97TXCR_TX4;
 269                        v |= AC97TXCR_TEN;
 270                        ep93xx_ac97_write_reg(info, AC97TXCR(1), v);
 271                } else {
 272                        /*
 273                         * Enable compact mode, RX slots 3 & 4, and the RX FIFO
 274                         * itself.
 275                         */
 276                        v |= AC97RXCR_CM;
 277                        v |= AC97RXCR_RX3 | AC97RXCR_RX4;
 278                        v |= AC97RXCR_REN;
 279                        ep93xx_ac97_write_reg(info, AC97RXCR(1), v);
 280                }
 281                break;
 282
 283        case SNDRV_PCM_TRIGGER_STOP:
 284        case SNDRV_PCM_TRIGGER_SUSPEND:
 285        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 286                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 287                        /*
 288                         * As per Cirrus EP93xx errata described below:
 289                         *
 290                         * http://www.cirrus.com/en/pubs/errata/ER667E2B.pdf
 291                         *
 292                         * we will wait for the TX FIFO to be empty before
 293                         * clearing the TEN bit.
 294                         */
 295                        unsigned long timeout = jiffies + AC97_TIMEOUT;
 296
 297                        do {
 298                                v = ep93xx_ac97_read_reg(info, AC97SR(1));
 299                                if (time_after(jiffies, timeout)) {
 300                                        dev_warn(info->dev, "TX timeout\n");
 301                                        break;
 302                                }
 303                        } while (!(v & (AC97SR_TXFE | AC97SR_TXUE)));
 304
 305                        /* disable the TX FIFO */
 306                        ep93xx_ac97_write_reg(info, AC97TXCR(1), 0);
 307                } else {
 308                        /* disable the RX FIFO */
 309                        ep93xx_ac97_write_reg(info, AC97RXCR(1), 0);
 310                }
 311                break;
 312
 313        default:
 314                dev_warn(info->dev, "unknown command %d\n", cmd);
 315                return -EINVAL;
 316        }
 317
 318        return 0;
 319}
 320
 321static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai)
 322{
 323        struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai);
 324
 325        info->dma_params_tx.filter_data = &ep93xx_ac97_pcm_out;
 326        info->dma_params_rx.filter_data = &ep93xx_ac97_pcm_in;
 327
 328        dai->playback_dma_data = &info->dma_params_tx;
 329        dai->capture_dma_data = &info->dma_params_rx;
 330
 331        return 0;
 332}
 333
 334static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
 335        .trigger        = ep93xx_ac97_trigger,
 336};
 337
 338static struct snd_soc_dai_driver ep93xx_ac97_dai = {
 339        .name           = "ep93xx-ac97",
 340        .id             = 0,
 341        .bus_control    = true,
 342        .probe          = ep93xx_ac97_dai_probe,
 343        .playback       = {
 344                .stream_name    = "AC97 Playback",
 345                .channels_min   = 2,
 346                .channels_max   = 2,
 347                .rates          = SNDRV_PCM_RATE_8000_48000,
 348                .formats        = SNDRV_PCM_FMTBIT_S16_LE,
 349        },
 350        .capture        = {
 351                .stream_name    = "AC97 Capture",
 352                .channels_min   = 2,
 353                .channels_max   = 2,
 354                .rates          = SNDRV_PCM_RATE_8000_48000,
 355                .formats        = SNDRV_PCM_FMTBIT_S16_LE,
 356        },
 357        .ops                    = &ep93xx_ac97_dai_ops,
 358};
 359
 360static const struct snd_soc_component_driver ep93xx_ac97_component = {
 361        .name           = "ep93xx-ac97",
 362};
 363
 364static int ep93xx_ac97_probe(struct platform_device *pdev)
 365{
 366        struct ep93xx_ac97_info *info;
 367        struct resource *res;
 368        unsigned int irq;
 369        int ret;
 370
 371        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 372        if (!info)
 373                return -ENOMEM;
 374
 375        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 376        info->regs = devm_ioremap_resource(&pdev->dev, res);
 377        if (IS_ERR(info->regs))
 378                return PTR_ERR(info->regs);
 379
 380        irq = platform_get_irq(pdev, 0);
 381        if (!irq)
 382                return -ENODEV;
 383
 384        ret = devm_request_irq(&pdev->dev, irq, ep93xx_ac97_interrupt,
 385                               IRQF_TRIGGER_HIGH, pdev->name, info);
 386        if (ret)
 387                goto fail;
 388
 389        dev_set_drvdata(&pdev->dev, info);
 390
 391        mutex_init(&info->lock);
 392        init_completion(&info->done);
 393        info->dev = &pdev->dev;
 394
 395        ep93xx_ac97_info = info;
 396        platform_set_drvdata(pdev, info);
 397
 398        ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops);
 399        if (ret)
 400                goto fail;
 401
 402        ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
 403                                         &ep93xx_ac97_dai, 1);
 404        if (ret)
 405                goto fail;
 406
 407        ret = devm_ep93xx_pcm_platform_register(&pdev->dev);
 408        if (ret)
 409                goto fail_unregister;
 410
 411        return 0;
 412
 413fail_unregister:
 414        snd_soc_unregister_component(&pdev->dev);
 415fail:
 416        ep93xx_ac97_info = NULL;
 417        snd_soc_set_ac97_ops(NULL);
 418        return ret;
 419}
 420
 421static int ep93xx_ac97_remove(struct platform_device *pdev)
 422{
 423        struct ep93xx_ac97_info *info = platform_get_drvdata(pdev);
 424
 425        snd_soc_unregister_component(&pdev->dev);
 426
 427        /* disable the AC97 controller */
 428        ep93xx_ac97_write_reg(info, AC97GCR, 0);
 429
 430        ep93xx_ac97_info = NULL;
 431
 432        snd_soc_set_ac97_ops(NULL);
 433
 434        return 0;
 435}
 436
 437static struct platform_driver ep93xx_ac97_driver = {
 438        .probe  = ep93xx_ac97_probe,
 439        .remove = ep93xx_ac97_remove,
 440        .driver = {
 441                .name = "ep93xx-ac97",
 442        },
 443};
 444
 445module_platform_driver(ep93xx_ac97_driver);
 446
 447MODULE_DESCRIPTION("EP93xx AC97 ASoC Driver");
 448MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
 449MODULE_LICENSE("GPL");
 450MODULE_ALIAS("platform:ep93xx-ac97");
 451