Commit 4ede028f8716523fc31e0d3d01b81405613dfb8f

Authored by Hans-Christian Egtvedt
Committed by Takashi Iwai
1 parent e4967d6016

ALSA: Add ALSA driver for Atmel AC97 controller

This patch adds ALSA support for the AC97 controller found on Atmel
AVR32 devices.

Tested on ATSTK1006 + ATSTK1000 with a development board with a AC97
codec.

Signed-off-by: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

Showing 5 changed files with 1053 additions and 0 deletions Side-by-side Diff

include/sound/atmel-ac97c.h
  1 +/*
  2 + * Driver for the Atmel AC97C controller
  3 + *
  4 + * Copyright (C) 2005-2009 Atmel Corporation
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of the GNU General Public License version 2 as published
  8 + * by the Free Software Foundation.
  9 + */
  10 +#ifndef __INCLUDE_SOUND_ATMEL_AC97C_H
  11 +#define __INCLUDE_SOUND_ATMEL_AC97C_H
  12 +
  13 +#include <linux/dw_dmac.h>
  14 +
  15 +#define AC97C_CAPTURE 0x01
  16 +#define AC97C_PLAYBACK 0x02
  17 +#define AC97C_BOTH (AC97C_CAPTURE | AC97C_PLAYBACK)
  18 +
  19 +/**
  20 + * struct atmel_ac97c_pdata - board specific AC97C configuration
  21 + * @rx_dws: DMA slave interface to use for sound capture.
  22 + * @tx_dws: DMA slave interface to use for sound playback.
  23 + * @reset_pin: GPIO pin wired to the reset input on the external AC97 codec,
  24 + * optional to use, set to -ENODEV if not in use. AC97 layer will
  25 + * try to do a software reset of the external codec anyway.
  26 + * @flags: Flags for which directions should be enabled.
  27 + *
  28 + * If the user do not want to use a DMA channel for playback or capture, i.e.
  29 + * only one feature is required on the board. The slave for playback or capture
  30 + * can be set to NULL. The AC97C driver will take use of this when setting up
  31 + * the sound streams.
  32 + */
  33 +struct ac97c_platform_data {
  34 + struct dw_dma_slave rx_dws;
  35 + struct dw_dma_slave tx_dws;
  36 + unsigned int flags;
  37 + int reset_pin;
  38 +};
  39 +
  40 +#endif /* __INCLUDE_SOUND_ATMEL_AC97C_H */
... ... @@ -8,5 +8,13 @@
8 8 help
9 9 ALSA sound driver for the Atmel Audio Bitstream DAC (ABDAC).
10 10  
  11 +config SND_ATMEL_AC97C
  12 + tristate "Atmel AC97 Controller (AC97C) driver"
  13 + select SND_PCM
  14 + select SND_AC97_CODEC
  15 + depends on DW_DMAC && AVR32
  16 + help
  17 + ALSA sound driver for the Atmel AC97 controller.
  18 +
11 19 endmenu
sound/atmel/Makefile
1 1 snd-atmel-abdac-objs := abdac.o
  2 +snd-atmel-ac97c-objs := ac97c.o
2 3  
3 4 obj-$(CONFIG_SND_ATMEL_ABDAC) += snd-atmel-abdac.o
  5 +obj-$(CONFIG_SND_ATMEL_AC97C) += snd-atmel-ac97c.o
  1 +/*
  2 + * Driver for the Atmel AC97C controller
  3 + *
  4 + * Copyright (C) 2005-2009 Atmel Corporation
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of the GNU General Public License version 2 as published by
  8 + * the Free Software Foundation.
  9 + */
  10 +#include <linux/clk.h>
  11 +#include <linux/delay.h>
  12 +#include <linux/bitmap.h>
  13 +#include <linux/dmaengine.h>
  14 +#include <linux/dma-mapping.h>
  15 +#include <linux/init.h>
  16 +#include <linux/interrupt.h>
  17 +#include <linux/module.h>
  18 +#include <linux/platform_device.h>
  19 +#include <linux/mutex.h>
  20 +#include <linux/gpio.h>
  21 +#include <linux/io.h>
  22 +
  23 +#include <sound/core.h>
  24 +#include <sound/initval.h>
  25 +#include <sound/pcm.h>
  26 +#include <sound/pcm_params.h>
  27 +#include <sound/ac97_codec.h>
  28 +#include <sound/atmel-ac97c.h>
  29 +#include <sound/memalloc.h>
  30 +
  31 +#include <linux/dw_dmac.h>
  32 +
  33 +#include "ac97c.h"
  34 +
  35 +enum {
  36 + DMA_TX_READY = 0,
  37 + DMA_RX_READY,
  38 + DMA_TX_CHAN_PRESENT,
  39 + DMA_RX_CHAN_PRESENT,
  40 +};
  41 +
  42 +/* Serialize access to opened variable */
  43 +static DEFINE_MUTEX(opened_mutex);
  44 +
  45 +struct atmel_ac97c_dma {
  46 + struct dma_chan *rx_chan;
  47 + struct dma_chan *tx_chan;
  48 +};
  49 +
  50 +struct atmel_ac97c {
  51 + struct clk *pclk;
  52 + struct platform_device *pdev;
  53 + struct atmel_ac97c_dma dma;
  54 +
  55 + struct snd_pcm_substream *playback_substream;
  56 + struct snd_pcm_substream *capture_substream;
  57 + struct snd_card *card;
  58 + struct snd_pcm *pcm;
  59 + struct snd_ac97 *ac97;
  60 + struct snd_ac97_bus *ac97_bus;
  61 +
  62 + u64 cur_format;
  63 + unsigned int cur_rate;
  64 + unsigned long flags;
  65 + /* Serialize access to opened variable */
  66 + spinlock_t lock;
  67 + void __iomem *regs;
  68 + int opened;
  69 + int reset_pin;
  70 +};
  71 +
  72 +#define get_chip(card) ((struct atmel_ac97c *)(card)->private_data)
  73 +
  74 +#define ac97c_writel(chip, reg, val) \
  75 + __raw_writel((val), (chip)->regs + AC97C_##reg)
  76 +#define ac97c_readl(chip, reg) \
  77 + __raw_readl((chip)->regs + AC97C_##reg)
  78 +
  79 +/* This function is called by the DMA driver. */
  80 +static void atmel_ac97c_dma_playback_period_done(void *arg)
  81 +{
  82 + struct atmel_ac97c *chip = arg;
  83 + snd_pcm_period_elapsed(chip->playback_substream);
  84 +}
  85 +
  86 +static void atmel_ac97c_dma_capture_period_done(void *arg)
  87 +{
  88 + struct atmel_ac97c *chip = arg;
  89 + snd_pcm_period_elapsed(chip->capture_substream);
  90 +}
  91 +
  92 +static int atmel_ac97c_prepare_dma(struct atmel_ac97c *chip,
  93 + struct snd_pcm_substream *substream,
  94 + enum dma_data_direction direction)
  95 +{
  96 + struct dma_chan *chan;
  97 + struct dw_cyclic_desc *cdesc;
  98 + struct snd_pcm_runtime *runtime = substream->runtime;
  99 + unsigned long buffer_len, period_len;
  100 +
  101 + /*
  102 + * We don't do DMA on "complex" transfers, i.e. with
  103 + * non-halfword-aligned buffers or lengths.
  104 + */
  105 + if (runtime->dma_addr & 1 || runtime->buffer_size & 1) {
  106 + dev_dbg(&chip->pdev->dev, "too complex transfer\n");
  107 + return -EINVAL;
  108 + }
  109 +
  110 + if (direction == DMA_TO_DEVICE)
  111 + chan = chip->dma.tx_chan;
  112 + else
  113 + chan = chip->dma.rx_chan;
  114 +
  115 + buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
  116 + period_len = frames_to_bytes(runtime, runtime->period_size);
  117 +
  118 + cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len,
  119 + period_len, direction);
  120 + if (IS_ERR(cdesc)) {
  121 + dev_dbg(&chip->pdev->dev, "could not prepare cyclic DMA\n");
  122 + return PTR_ERR(cdesc);
  123 + }
  124 +
  125 + if (direction == DMA_TO_DEVICE) {
  126 + cdesc->period_callback = atmel_ac97c_dma_playback_period_done;
  127 + set_bit(DMA_TX_READY, &chip->flags);
  128 + } else {
  129 + cdesc->period_callback = atmel_ac97c_dma_capture_period_done;
  130 + set_bit(DMA_RX_READY, &chip->flags);
  131 + }
  132 +
  133 + cdesc->period_callback_param = chip;
  134 +
  135 + return 0;
  136 +}
  137 +
  138 +static struct snd_pcm_hardware atmel_ac97c_hw = {
  139 + .info = (SNDRV_PCM_INFO_MMAP
  140 + | SNDRV_PCM_INFO_MMAP_VALID
  141 + | SNDRV_PCM_INFO_INTERLEAVED
  142 + | SNDRV_PCM_INFO_BLOCK_TRANSFER
  143 + | SNDRV_PCM_INFO_JOINT_DUPLEX
  144 + | SNDRV_PCM_INFO_RESUME
  145 + | SNDRV_PCM_INFO_PAUSE),
  146 + .formats = (SNDRV_PCM_FMTBIT_S16_BE
  147 + | SNDRV_PCM_FMTBIT_S16_LE),
  148 + .rates = (SNDRV_PCM_RATE_CONTINUOUS),
  149 + .rate_min = 4000,
  150 + .rate_max = 48000,
  151 + .channels_min = 1,
  152 + .channels_max = 2,
  153 + .buffer_bytes_max = 64 * 4096,
  154 + .period_bytes_min = 4096,
  155 + .period_bytes_max = 4096,
  156 + .periods_min = 4,
  157 + .periods_max = 64,
  158 +};
  159 +
  160 +static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream)
  161 +{
  162 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  163 + struct snd_pcm_runtime *runtime = substream->runtime;
  164 +
  165 + mutex_lock(&opened_mutex);
  166 + chip->opened++;
  167 + runtime->hw = atmel_ac97c_hw;
  168 + if (chip->cur_rate) {
  169 + runtime->hw.rate_min = chip->cur_rate;
  170 + runtime->hw.rate_max = chip->cur_rate;
  171 + }
  172 + if (chip->cur_format)
  173 + runtime->hw.formats = (1ULL << chip->cur_format);
  174 + mutex_unlock(&opened_mutex);
  175 + chip->playback_substream = substream;
  176 + return 0;
  177 +}
  178 +
  179 +static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream)
  180 +{
  181 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  182 + struct snd_pcm_runtime *runtime = substream->runtime;
  183 +
  184 + mutex_lock(&opened_mutex);
  185 + chip->opened++;
  186 + runtime->hw = atmel_ac97c_hw;
  187 + if (chip->cur_rate) {
  188 + runtime->hw.rate_min = chip->cur_rate;
  189 + runtime->hw.rate_max = chip->cur_rate;
  190 + }
  191 + if (chip->cur_format)
  192 + runtime->hw.formats = (1ULL << chip->cur_format);
  193 + mutex_unlock(&opened_mutex);
  194 + chip->capture_substream = substream;
  195 + return 0;
  196 +}
  197 +
  198 +static int atmel_ac97c_playback_close(struct snd_pcm_substream *substream)
  199 +{
  200 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  201 +
  202 + mutex_lock(&opened_mutex);
  203 + chip->opened--;
  204 + if (!chip->opened) {
  205 + chip->cur_rate = 0;
  206 + chip->cur_format = 0;
  207 + }
  208 + mutex_unlock(&opened_mutex);
  209 +
  210 + chip->playback_substream = NULL;
  211 +
  212 + return 0;
  213 +}
  214 +
  215 +static int atmel_ac97c_capture_close(struct snd_pcm_substream *substream)
  216 +{
  217 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  218 +
  219 + mutex_lock(&opened_mutex);
  220 + chip->opened--;
  221 + if (!chip->opened) {
  222 + chip->cur_rate = 0;
  223 + chip->cur_format = 0;
  224 + }
  225 + mutex_unlock(&opened_mutex);
  226 +
  227 + chip->capture_substream = NULL;
  228 +
  229 + return 0;
  230 +}
  231 +
  232 +static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
  233 + struct snd_pcm_hw_params *hw_params)
  234 +{
  235 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  236 + int retval;
  237 +
  238 + retval = snd_pcm_lib_malloc_pages(substream,
  239 + params_buffer_bytes(hw_params));
  240 + if (retval < 0)
  241 + return retval;
  242 + /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
  243 + if (retval == 1)
  244 + if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
  245 + dw_dma_cyclic_free(chip->dma.tx_chan);
  246 +
  247 + /* Set restrictions to params. */
  248 + mutex_lock(&opened_mutex);
  249 + chip->cur_rate = params_rate(hw_params);
  250 + chip->cur_format = params_format(hw_params);
  251 + mutex_unlock(&opened_mutex);
  252 +
  253 + return retval;
  254 +}
  255 +
  256 +static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
  257 + struct snd_pcm_hw_params *hw_params)
  258 +{
  259 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  260 + int retval;
  261 +
  262 + retval = snd_pcm_lib_malloc_pages(substream,
  263 + params_buffer_bytes(hw_params));
  264 + if (retval < 0)
  265 + return retval;
  266 + /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
  267 + if (retval == 1)
  268 + if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
  269 + dw_dma_cyclic_free(chip->dma.rx_chan);
  270 +
  271 + /* Set restrictions to params. */
  272 + mutex_lock(&opened_mutex);
  273 + chip->cur_rate = params_rate(hw_params);
  274 + chip->cur_format = params_format(hw_params);
  275 + mutex_unlock(&opened_mutex);
  276 +
  277 + return retval;
  278 +}
  279 +
  280 +static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream)
  281 +{
  282 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  283 + if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
  284 + dw_dma_cyclic_free(chip->dma.tx_chan);
  285 + return snd_pcm_lib_free_pages(substream);
  286 +}
  287 +
  288 +static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream)
  289 +{
  290 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  291 + if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
  292 + dw_dma_cyclic_free(chip->dma.rx_chan);
  293 + return snd_pcm_lib_free_pages(substream);
  294 +}
  295 +
  296 +static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
  297 +{
  298 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  299 + struct snd_pcm_runtime *runtime = substream->runtime;
  300 + unsigned long word = 0;
  301 + int retval;
  302 +
  303 + /* assign channels to AC97C channel A */
  304 + switch (runtime->channels) {
  305 + case 1:
  306 + word |= AC97C_CH_ASSIGN(PCM_LEFT, A);
  307 + break;
  308 + case 2:
  309 + word |= AC97C_CH_ASSIGN(PCM_LEFT, A)
  310 + | AC97C_CH_ASSIGN(PCM_RIGHT, A);
  311 + break;
  312 + default:
  313 + /* TODO: support more than two channels */
  314 + return -EINVAL;
  315 + break;
  316 + }
  317 + ac97c_writel(chip, OCA, word);
  318 +
  319 + /* configure sample format and size */
  320 + word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
  321 +
  322 + switch (runtime->format) {
  323 + case SNDRV_PCM_FORMAT_S16_LE:
  324 + word |= AC97C_CMR_CEM_LITTLE;
  325 + break;
  326 + case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
  327 + default:
  328 + word &= ~(AC97C_CMR_CEM_LITTLE);
  329 + break;
  330 + }
  331 +
  332 + ac97c_writel(chip, CAMR, word);
  333 +
  334 + /* set variable rate if needed */
  335 + if (runtime->rate != 48000) {
  336 + word = ac97c_readl(chip, MR);
  337 + word |= AC97C_MR_VRA;
  338 + ac97c_writel(chip, MR, word);
  339 + } else {
  340 + word = ac97c_readl(chip, MR);
  341 + word &= ~(AC97C_MR_VRA);
  342 + ac97c_writel(chip, MR, word);
  343 + }
  344 +
  345 + retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
  346 + runtime->rate);
  347 + if (retval)
  348 + dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
  349 + runtime->rate);
  350 +
  351 + if (!test_bit(DMA_TX_READY, &chip->flags))
  352 + retval = atmel_ac97c_prepare_dma(chip, substream,
  353 + DMA_TO_DEVICE);
  354 +
  355 + return retval;
  356 +}
  357 +
  358 +static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
  359 +{
  360 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  361 + struct snd_pcm_runtime *runtime = substream->runtime;
  362 + unsigned long word = 0;
  363 + int retval;
  364 +
  365 + /* assign channels to AC97C channel A */
  366 + switch (runtime->channels) {
  367 + case 1:
  368 + word |= AC97C_CH_ASSIGN(PCM_LEFT, A);
  369 + break;
  370 + case 2:
  371 + word |= AC97C_CH_ASSIGN(PCM_LEFT, A)
  372 + | AC97C_CH_ASSIGN(PCM_RIGHT, A);
  373 + break;
  374 + default:
  375 + /* TODO: support more than two channels */
  376 + return -EINVAL;
  377 + break;
  378 + }
  379 + ac97c_writel(chip, ICA, word);
  380 +
  381 + /* configure sample format and size */
  382 + word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
  383 +
  384 + switch (runtime->format) {
  385 + case SNDRV_PCM_FORMAT_S16_LE:
  386 + word |= AC97C_CMR_CEM_LITTLE;
  387 + break;
  388 + case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
  389 + default:
  390 + word &= ~(AC97C_CMR_CEM_LITTLE);
  391 + break;
  392 + }
  393 +
  394 + ac97c_writel(chip, CAMR, word);
  395 +
  396 + /* set variable rate if needed */
  397 + if (runtime->rate != 48000) {
  398 + word = ac97c_readl(chip, MR);
  399 + word |= AC97C_MR_VRA;
  400 + ac97c_writel(chip, MR, word);
  401 + } else {
  402 + word = ac97c_readl(chip, MR);
  403 + word &= ~(AC97C_MR_VRA);
  404 + ac97c_writel(chip, MR, word);
  405 + }
  406 +
  407 + retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE,
  408 + runtime->rate);
  409 + if (retval)
  410 + dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
  411 + runtime->rate);
  412 +
  413 + if (!test_bit(DMA_RX_READY, &chip->flags))
  414 + retval = atmel_ac97c_prepare_dma(chip, substream,
  415 + DMA_FROM_DEVICE);
  416 +
  417 + return retval;
  418 +}
  419 +
  420 +static int
  421 +atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
  422 +{
  423 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  424 + unsigned long camr;
  425 + int retval = 0;
  426 +
  427 + camr = ac97c_readl(chip, CAMR);
  428 +
  429 + switch (cmd) {
  430 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
  431 + case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
  432 + case SNDRV_PCM_TRIGGER_START:
  433 + retval = dw_dma_cyclic_start(chip->dma.tx_chan);
  434 + if (retval)
  435 + goto out;
  436 + camr |= AC97C_CMR_CENA;
  437 + break;
  438 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
  439 + case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
  440 + case SNDRV_PCM_TRIGGER_STOP:
  441 + dw_dma_cyclic_stop(chip->dma.tx_chan);
  442 + if (chip->opened <= 1)
  443 + camr &= ~AC97C_CMR_CENA;
  444 + break;
  445 + default:
  446 + retval = -EINVAL;
  447 + goto out;
  448 + }
  449 +
  450 + ac97c_writel(chip, CAMR, camr);
  451 +out:
  452 + return retval;
  453 +}
  454 +
  455 +static int
  456 +atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
  457 +{
  458 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  459 + unsigned long camr;
  460 + int retval = 0;
  461 +
  462 + camr = ac97c_readl(chip, CAMR);
  463 +
  464 + switch (cmd) {
  465 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
  466 + case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
  467 + case SNDRV_PCM_TRIGGER_START:
  468 + retval = dw_dma_cyclic_start(chip->dma.rx_chan);
  469 + if (retval)
  470 + goto out;
  471 + camr |= AC97C_CMR_CENA;
  472 + break;
  473 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
  474 + case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
  475 + case SNDRV_PCM_TRIGGER_STOP:
  476 + dw_dma_cyclic_stop(chip->dma.rx_chan);
  477 + if (chip->opened <= 1)
  478 + camr &= ~AC97C_CMR_CENA;
  479 + break;
  480 + default:
  481 + retval = -EINVAL;
  482 + break;
  483 + }
  484 +
  485 + ac97c_writel(chip, CAMR, camr);
  486 +out:
  487 + return retval;
  488 +}
  489 +
  490 +static snd_pcm_uframes_t
  491 +atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
  492 +{
  493 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  494 + struct snd_pcm_runtime *runtime = substream->runtime;
  495 + snd_pcm_uframes_t frames;
  496 + unsigned long bytes;
  497 +
  498 + bytes = dw_dma_get_src_addr(chip->dma.tx_chan);
  499 + bytes -= runtime->dma_addr;
  500 +
  501 + frames = bytes_to_frames(runtime, bytes);
  502 + if (frames >= runtime->buffer_size)
  503 + frames -= runtime->buffer_size;
  504 + return frames;
  505 +}
  506 +
  507 +static snd_pcm_uframes_t
  508 +atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
  509 +{
  510 + struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
  511 + struct snd_pcm_runtime *runtime = substream->runtime;
  512 + snd_pcm_uframes_t frames;
  513 + unsigned long bytes;
  514 +
  515 + bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
  516 + bytes -= runtime->dma_addr;
  517 +
  518 + frames = bytes_to_frames(runtime, bytes);
  519 + if (frames >= runtime->buffer_size)
  520 + frames -= runtime->buffer_size;
  521 + return frames;
  522 +}
  523 +
  524 +static struct snd_pcm_ops atmel_ac97_playback_ops = {
  525 + .open = atmel_ac97c_playback_open,
  526 + .close = atmel_ac97c_playback_close,
  527 + .ioctl = snd_pcm_lib_ioctl,
  528 + .hw_params = atmel_ac97c_playback_hw_params,
  529 + .hw_free = atmel_ac97c_playback_hw_free,
  530 + .prepare = atmel_ac97c_playback_prepare,
  531 + .trigger = atmel_ac97c_playback_trigger,
  532 + .pointer = atmel_ac97c_playback_pointer,
  533 +};
  534 +
  535 +static struct snd_pcm_ops atmel_ac97_capture_ops = {
  536 + .open = atmel_ac97c_capture_open,
  537 + .close = atmel_ac97c_capture_close,
  538 + .ioctl = snd_pcm_lib_ioctl,
  539 + .hw_params = atmel_ac97c_capture_hw_params,
  540 + .hw_free = atmel_ac97c_capture_hw_free,
  541 + .prepare = atmel_ac97c_capture_prepare,
  542 + .trigger = atmel_ac97c_capture_trigger,
  543 + .pointer = atmel_ac97c_capture_pointer,
  544 +};
  545 +
  546 +static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
  547 +{
  548 + struct snd_pcm *pcm;
  549 + struct snd_pcm_hardware hw = atmel_ac97c_hw;
  550 + int capture, playback, retval;
  551 +
  552 + capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
  553 + playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
  554 +
  555 + retval = snd_pcm_new(chip->card, chip->card->shortname,
  556 + chip->pdev->id, playback, capture, &pcm);
  557 + if (retval)
  558 + return retval;
  559 +
  560 + if (capture)
  561 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
  562 + &atmel_ac97_capture_ops);
  563 + if (playback)
  564 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  565 + &atmel_ac97_playback_ops);
  566 +
  567 + retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
  568 + &chip->pdev->dev, hw.periods_min * hw.period_bytes_min,
  569 + hw.buffer_bytes_max);
  570 + if (retval)
  571 + return retval;
  572 +
  573 + pcm->private_data = chip;
  574 + pcm->info_flags = 0;
  575 + strcpy(pcm->name, chip->card->shortname);
  576 + chip->pcm = pcm;
  577 +
  578 + return 0;
  579 +}
  580 +
  581 +static int atmel_ac97c_mixer_new(struct atmel_ac97c *chip)
  582 +{
  583 + struct snd_ac97_template template;
  584 + memset(&template, 0, sizeof(template));
  585 + template.private_data = chip;
  586 + return snd_ac97_mixer(chip->ac97_bus, &template, &chip->ac97);
  587 +}
  588 +
  589 +static void atmel_ac97c_write(struct snd_ac97 *ac97, unsigned short reg,
  590 + unsigned short val)
  591 +{
  592 + struct atmel_ac97c *chip = get_chip(ac97);
  593 + unsigned long word;
  594 + int timeout = 40;
  595 +
  596 + word = (reg & 0x7f) << 16 | val;
  597 +
  598 + do {
  599 + if (ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) {
  600 + ac97c_writel(chip, COTHR, word);
  601 + return;
  602 + }
  603 + udelay(1);
  604 + } while (--timeout);
  605 +
  606 + dev_dbg(&chip->pdev->dev, "codec write timeout\n");
  607 +}
  608 +
  609 +static unsigned short atmel_ac97c_read(struct snd_ac97 *ac97,
  610 + unsigned short reg)
  611 +{
  612 + struct atmel_ac97c *chip = get_chip(ac97);
  613 + unsigned long word;
  614 + int timeout = 40;
  615 + int write = 10;
  616 +
  617 + word = (0x80 | (reg & 0x7f)) << 16;
  618 +
  619 + if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0)
  620 + ac97c_readl(chip, CORHR);
  621 +
  622 +retry_write:
  623 + timeout = 40;
  624 +
  625 + do {
  626 + if ((ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) != 0) {
  627 + ac97c_writel(chip, COTHR, word);
  628 + goto read_reg;
  629 + }
  630 + udelay(10);
  631 + } while (--timeout);
  632 +
  633 + if (!--write)
  634 + goto timed_out;
  635 + goto retry_write;
  636 +
  637 +read_reg:
  638 + do {
  639 + if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) {
  640 + unsigned short val = ac97c_readl(chip, CORHR);
  641 + return val;
  642 + }
  643 + udelay(10);
  644 + } while (--timeout);
  645 +
  646 + if (!--write)
  647 + goto timed_out;
  648 + goto retry_write;
  649 +
  650 +timed_out:
  651 + dev_dbg(&chip->pdev->dev, "codec read timeout\n");
  652 + return 0xffff;
  653 +}
  654 +
  655 +static bool filter(struct dma_chan *chan, void *slave)
  656 +{
  657 + struct dw_dma_slave *dws = slave;
  658 +
  659 + if (dws->dma_dev == chan->device->dev) {
  660 + chan->private = dws;
  661 + return true;
  662 + } else
  663 + return false;
  664 +}
  665 +
  666 +static void atmel_ac97c_reset(struct atmel_ac97c *chip)
  667 +{
  668 + ac97c_writel(chip, MR, AC97C_MR_WRST);
  669 +
  670 + if (gpio_is_valid(chip->reset_pin)) {
  671 + gpio_set_value(chip->reset_pin, 0);
  672 + /* AC97 v2.2 specifications says minimum 1 us. */
  673 + udelay(10);
  674 + gpio_set_value(chip->reset_pin, 1);
  675 + }
  676 +
  677 + udelay(1);
  678 + ac97c_writel(chip, MR, AC97C_MR_ENA);
  679 +}
  680 +
  681 +static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
  682 +{
  683 + struct snd_card *card;
  684 + struct atmel_ac97c *chip;
  685 + struct resource *regs;
  686 + struct ac97c_platform_data *pdata;
  687 + struct clk *pclk;
  688 + static struct snd_ac97_bus_ops ops = {
  689 + .write = atmel_ac97c_write,
  690 + .read = atmel_ac97c_read,
  691 + };
  692 + int retval;
  693 +
  694 + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  695 + if (!regs) {
  696 + dev_dbg(&pdev->dev, "no memory resource\n");
  697 + return -ENXIO;
  698 + }
  699 +
  700 + pdata = pdev->dev.platform_data;
  701 + if (!pdata) {
  702 + dev_dbg(&pdev->dev, "no platform data\n");
  703 + return -ENXIO;
  704 + }
  705 +
  706 + pclk = clk_get(&pdev->dev, "pclk");
  707 + if (IS_ERR(pclk)) {
  708 + dev_dbg(&pdev->dev, "no peripheral clock\n");
  709 + return PTR_ERR(pclk);
  710 + }
  711 + clk_enable(pclk);
  712 +
  713 + retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
  714 + THIS_MODULE, sizeof(struct atmel_ac97c), &card);
  715 + if (retval) {
  716 + dev_dbg(&pdev->dev, "could not create sound card device\n");
  717 + goto err_snd_card_new;
  718 + }
  719 +
  720 + chip = get_chip(card);
  721 +
  722 + spin_lock_init(&chip->lock);
  723 +
  724 + strcpy(card->driver, "Atmel AC97C");
  725 + strcpy(card->shortname, "Atmel AC97C");
  726 + sprintf(card->longname, "Atmel AC97 controller");
  727 +
  728 + chip->card = card;
  729 + chip->pclk = pclk;
  730 + chip->pdev = pdev;
  731 + chip->regs = ioremap(regs->start, regs->end - regs->start + 1);
  732 +
  733 + if (!chip->regs) {
  734 + dev_dbg(&pdev->dev, "could not remap register memory\n");
  735 + goto err_ioremap;
  736 + }
  737 +
  738 + if (gpio_is_valid(pdata->reset_pin)) {
  739 + if (gpio_request(pdata->reset_pin, "reset_pin")) {
  740 + dev_dbg(&pdev->dev, "reset pin not available\n");
  741 + chip->reset_pin = -ENODEV;
  742 + } else {
  743 + gpio_direction_output(pdata->reset_pin, 1);
  744 + chip->reset_pin = pdata->reset_pin;
  745 + }
  746 + }
  747 +
  748 + snd_card_set_dev(card, &pdev->dev);
  749 +
  750 + retval = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
  751 + if (retval) {
  752 + dev_dbg(&pdev->dev, "could not register on ac97 bus\n");
  753 + goto err_ac97_bus;
  754 + }
  755 +
  756 + atmel_ac97c_reset(chip);
  757 +
  758 + retval = atmel_ac97c_mixer_new(chip);
  759 + if (retval) {
  760 + dev_dbg(&pdev->dev, "could not register ac97 mixer\n");
  761 + goto err_ac97_bus;
  762 + }
  763 +
  764 + if (pdata->rx_dws.dma_dev) {
  765 + struct dw_dma_slave *dws = &pdata->rx_dws;
  766 + dma_cap_mask_t mask;
  767 +
  768 + dws->rx_reg = regs->start + AC97C_CARHR + 2;
  769 +
  770 + dma_cap_zero(mask);
  771 + dma_cap_set(DMA_SLAVE, mask);
  772 +
  773 + chip->dma.rx_chan = dma_request_channel(mask, filter, dws);
  774 +
  775 + dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
  776 + chip->dma.rx_chan->dev->device.bus_id);
  777 + set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
  778 + }
  779 +
  780 + if (pdata->tx_dws.dma_dev) {
  781 + struct dw_dma_slave *dws = &pdata->tx_dws;
  782 + dma_cap_mask_t mask;
  783 +
  784 + dws->tx_reg = regs->start + AC97C_CATHR + 2;
  785 +
  786 + dma_cap_zero(mask);
  787 + dma_cap_set(DMA_SLAVE, mask);
  788 +
  789 + chip->dma.tx_chan = dma_request_channel(mask, filter, dws);
  790 +
  791 + dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
  792 + chip->dma.tx_chan->dev->device.bus_id);
  793 + set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
  794 + }
  795 +
  796 + if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) &&
  797 + !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) {
  798 + dev_dbg(&pdev->dev, "DMA not available\n");
  799 + retval = -ENODEV;
  800 + goto err_dma;
  801 + }
  802 +
  803 + retval = atmel_ac97c_pcm_new(chip);
  804 + if (retval) {
  805 + dev_dbg(&pdev->dev, "could not register ac97 pcm device\n");
  806 + goto err_dma;
  807 + }
  808 +
  809 + retval = snd_card_register(card);
  810 + if (retval) {
  811 + dev_dbg(&pdev->dev, "could not register sound card\n");
  812 + goto err_ac97_bus;
  813 + }
  814 +
  815 + platform_set_drvdata(pdev, card);
  816 +
  817 + dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n",
  818 + chip->regs);
  819 +
  820 + return 0;
  821 +
  822 +err_dma:
  823 + if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
  824 + dma_release_channel(chip->dma.rx_chan);
  825 + if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
  826 + dma_release_channel(chip->dma.tx_chan);
  827 + clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
  828 + clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
  829 + chip->dma.rx_chan = NULL;
  830 + chip->dma.tx_chan = NULL;
  831 +err_ac97_bus:
  832 + snd_card_set_dev(card, NULL);
  833 +
  834 + if (gpio_is_valid(chip->reset_pin))
  835 + gpio_free(chip->reset_pin);
  836 +
  837 + iounmap(chip->regs);
  838 +err_ioremap:
  839 + snd_card_free(card);
  840 +err_snd_card_new:
  841 + clk_disable(pclk);
  842 + clk_put(pclk);
  843 + return retval;
  844 +}
  845 +
  846 +#ifdef CONFIG_PM
  847 +static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
  848 +{
  849 + struct snd_card *card = platform_get_drvdata(pdev);
  850 + struct atmel_ac97c *chip = card->private_data;
  851 +
  852 + if (test_bit(DMA_RX_READY, &chip->flags))
  853 + dw_dma_cyclic_stop(chip->dma.rx_chan);
  854 + if (test_bit(DMA_TX_READY, &chip->flags))
  855 + dw_dma_cyclic_stop(chip->dma.tx_chan);
  856 + clk_disable(chip->pclk);
  857 +
  858 + return 0;
  859 +}
  860 +
  861 +static int atmel_ac97c_resume(struct platform_device *pdev)
  862 +{
  863 + struct snd_card *card = platform_get_drvdata(pdev);
  864 + struct atmel_ac97c *chip = card->private_data;
  865 +
  866 + clk_enable(chip->pclk);
  867 + if (test_bit(DMA_RX_READY, &chip->flags))
  868 + dw_dma_cyclic_start(chip->dma.rx_chan);
  869 + if (test_bit(DMA_TX_READY, &chip->flags))
  870 + dw_dma_cyclic_start(chip->dma.tx_chan);
  871 +
  872 + return 0;
  873 +}
  874 +#else
  875 +#define atmel_ac97c_suspend NULL
  876 +#define atmel_ac97c_resume NULL
  877 +#endif
  878 +
  879 +static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
  880 +{
  881 + struct snd_card *card = platform_get_drvdata(pdev);
  882 + struct atmel_ac97c *chip = get_chip(card);
  883 +
  884 + if (gpio_is_valid(chip->reset_pin))
  885 + gpio_free(chip->reset_pin);
  886 +
  887 + clk_disable(chip->pclk);
  888 + clk_put(chip->pclk);
  889 + iounmap(chip->regs);
  890 +
  891 + if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
  892 + dma_release_channel(chip->dma.rx_chan);
  893 + if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
  894 + dma_release_channel(chip->dma.tx_chan);
  895 + clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
  896 + clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
  897 + chip->dma.rx_chan = NULL;
  898 + chip->dma.tx_chan = NULL;
  899 +
  900 + snd_card_set_dev(card, NULL);
  901 + snd_card_free(card);
  902 +
  903 + platform_set_drvdata(pdev, NULL);
  904 +
  905 + return 0;
  906 +}
  907 +
  908 +static struct platform_driver atmel_ac97c_driver = {
  909 + .remove = __devexit_p(atmel_ac97c_remove),
  910 + .driver = {
  911 + .name = "atmel_ac97c",
  912 + },
  913 + .suspend = atmel_ac97c_suspend,
  914 + .resume = atmel_ac97c_resume,
  915 +};
  916 +
  917 +static int __init atmel_ac97c_init(void)
  918 +{
  919 + return platform_driver_probe(&atmel_ac97c_driver,
  920 + atmel_ac97c_probe);
  921 +}
  922 +module_init(atmel_ac97c_init);
  923 +
  924 +static void __exit atmel_ac97c_exit(void)
  925 +{
  926 + platform_driver_unregister(&atmel_ac97c_driver);
  927 +}
  928 +module_exit(atmel_ac97c_exit);
  929 +
  930 +MODULE_LICENSE("GPL");
  931 +MODULE_DESCRIPTION("Driver for Atmel AC97 controller");
  932 +MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>");
  1 +/*
  2 + * Register definitions for the Atmel AC97C controller
  3 + *
  4 + * Copyright (C) 2005-2009 Atmel Corporation
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of the GNU General Public License version 2 as published
  8 + * by the Free Software Foundation.
  9 + */
  10 +#ifndef __SOUND_ATMEL_AC97C_H
  11 +#define __SOUND_ATMEL_AC97C_H
  12 +
  13 +#define AC97C_MR 0x08
  14 +#define AC97C_ICA 0x10
  15 +#define AC97C_OCA 0x14
  16 +#define AC97C_CARHR 0x20
  17 +#define AC97C_CATHR 0x24
  18 +#define AC97C_CASR 0x28
  19 +#define AC97C_CAMR 0x2c
  20 +#define AC97C_CBRHR 0x30
  21 +#define AC97C_CBTHR 0x34
  22 +#define AC97C_CBSR 0x38
  23 +#define AC97C_CBMR 0x3c
  24 +#define AC97C_CORHR 0x40
  25 +#define AC97C_COTHR 0x44
  26 +#define AC97C_COSR 0x48
  27 +#define AC97C_COMR 0x4c
  28 +#define AC97C_SR 0x50
  29 +#define AC97C_IER 0x54
  30 +#define AC97C_IDR 0x58
  31 +#define AC97C_IMR 0x5c
  32 +#define AC97C_VERSION 0xfc
  33 +
  34 +#define AC97C_CATPR PDC_TPR
  35 +#define AC97C_CATCR PDC_TCR
  36 +#define AC97C_CATNPR PDC_TNPR
  37 +#define AC97C_CATNCR PDC_TNCR
  38 +#define AC97C_CARPR PDC_RPR
  39 +#define AC97C_CARCR PDC_RCR
  40 +#define AC97C_CARNPR PDC_RNPR
  41 +#define AC97C_CARNCR PDC_RNCR
  42 +#define AC97C_PTCR PDC_PTCR
  43 +
  44 +#define AC97C_MR_ENA (1 << 0)
  45 +#define AC97C_MR_WRST (1 << 1)
  46 +#define AC97C_MR_VRA (1 << 2)
  47 +
  48 +#define AC97C_CSR_TXRDY (1 << 0)
  49 +#define AC97C_CSR_UNRUN (1 << 2)
  50 +#define AC97C_CSR_RXRDY (1 << 4)
  51 +#define AC97C_CSR_ENDTX (1 << 10)
  52 +#define AC97C_CSR_ENDRX (1 << 14)
  53 +
  54 +#define AC97C_CMR_SIZE_20 (0 << 16)
  55 +#define AC97C_CMR_SIZE_18 (1 << 16)
  56 +#define AC97C_CMR_SIZE_16 (2 << 16)
  57 +#define AC97C_CMR_SIZE_10 (3 << 16)
  58 +#define AC97C_CMR_CEM_LITTLE (1 << 18)
  59 +#define AC97C_CMR_CEM_BIG (0 << 18)
  60 +#define AC97C_CMR_CENA (1 << 21)
  61 +#define AC97C_CMR_DMAEN (1 << 22)
  62 +
  63 +#define AC97C_SR_CAEVT (1 << 3)
  64 +
  65 +#define AC97C_CH_ASSIGN(slot, channel) \
  66 + (AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3)))
  67 +#define AC97C_CHANNEL_NONE 0x0
  68 +#define AC97C_CHANNEL_A 0x1
  69 +#define AC97C_CHANNEL_B 0x2
  70 +
  71 +#endif /* __SOUND_ATMEL_AC97C_H */