diff options
Diffstat (limited to 'packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch')
-rw-r--r-- | packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch | 1383 |
1 files changed, 0 insertions, 1383 deletions
diff --git a/packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch b/packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch deleted file mode 100644 index fe3d2ee209..0000000000 --- a/packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch +++ /dev/null @@ -1,1383 +0,0 @@ ---- - sound/avr32/Kconfig | 25 + - sound/avr32/Makefile | 3 - sound/avr32/ac97c.c | 1250 +++++++++++++++++++++++++++++++++++++++++++++++++++ - sound/avr32/ac97c.h | 71 ++ - 4 files changed, 1349 insertions(+) - -Index: linux-2.6.18-avr32/sound/avr32/Kconfig -=================================================================== ---- linux-2.6.18-avr32.orig/sound/avr32/Kconfig 2006-11-02 15:56:20.000000000 +0100 -+++ linux-2.6.18-avr32/sound/avr32/Kconfig 2006-11-02 16:02:29.000000000 +0100 -@@ -3,4 +3,29 @@ - menu "ALSA AVR32 devices" - depends on SND != n && AVR32 - -+config SND_ATMEL_AC97 -+ tristate "Atmel AC97 Controller Driver" -+ depends on SND -+ select SND_PCM -+ select SND_AC97_CODEC -+ help -+ ALSA sound driver for the Atmel AC97 controller. -+ -+config SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS -+ bool "Use the built-in malloc calls in the alsa driver" -+ default n -+ depends on SND_ATMEL_AC97 -+ help -+ Say Y if the built-in malloc calls in the alsa driver should be -+ used instead of the native dma_alloc_coherent and dma_free_coherent -+ function calls. Enabling this feature may break the rmmod feature. -+ -+config SND_ATMEL_AC97C_USE_PDC -+ bool "Use PDC for DMA transfers to/from the Atmel AC97 Controller" -+ default n -+ depends on SND_ATMEL_AC97 -+ help -+ Say Y if PDC (Peripheral DMA Controller) is used for DMA transfers -+ to/from the Atmel AC97C instead of using the generic DMA framework. -+ - endmenu -Index: linux-2.6.18-avr32/sound/avr32/Makefile -=================================================================== ---- linux-2.6.18-avr32.orig/sound/avr32/Makefile 2006-11-02 15:56:20.000000000 +0100 -+++ linux-2.6.18-avr32/sound/avr32/Makefile 2006-11-02 16:02:29.000000000 +0100 -@@ -1,3 +1,6 @@ - # - # Makefile for ALSA - # -+ -+snd-atmel-ac97-objs := ac97c.o -+obj-$(CONFIG_SND_ATMEL_AC97) += snd-atmel-ac97.o -Index: linux-2.6.18-avr32/sound/avr32/ac97c.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.18-avr32/sound/avr32/ac97c.c 2006-11-02 16:02:56.000000000 +0100 -@@ -0,0 +1,1250 @@ -+/* -+ * Driver for the Atmel AC97 Controller -+ * -+ * Copyright (C) 2005-2006 Atmel Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include <linux/clk.h> -+#include <linux/delay.h> -+#include <linux/dma-mapping.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/mutex.h> -+ -+#include <sound/driver.h> -+#include <sound/core.h> -+#include <sound/initval.h> -+#include <sound/pcm.h> -+#include <sound/pcm_params.h> -+#include <sound/ac97_codec.h> -+#ifndef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS -+#include <sound/memalloc.h> -+#endif -+ -+#include <asm/io.h> -+ -+#include "ac97c.h" -+ -+static DEFINE_MUTEX(opened_mutex); -+ -+/* module parameters */ -+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; -+ -+module_param_array(index, int, NULL, 0444); -+MODULE_PARM_DESC(index, "Index value for AC97 controller"); -+module_param_array(id, charp, NULL, 0444); -+MODULE_PARM_DESC(id, "ID string for AC97 controller"); -+module_param_array(enable, bool, NULL, 0444); -+MODULE_PARM_DESC(enable, "Enable AC97 controller"); -+ -+#ifndef CONFIG_SND_ATMEL_AC97C_USE_PDC -+#include <asm/dma-controller.h> -+ -+struct atmel_ac97_dma_info { -+ struct dma_request_cyclic req_tx; -+ struct dma_request_cyclic req_rx; -+ unsigned short rx_periph_id; -+ unsigned short tx_periph_id; -+}; -+#endif -+ -+ -+typedef struct atmel_ac97 { -+ spinlock_t lock; -+ void __iomem *regs; -+ int period; -+ -+ snd_pcm_substream_t *playback_substream; -+ snd_pcm_substream_t *capture_substream; -+ snd_card_t *card; -+ snd_pcm_t *pcm; -+ ac97_t *ac97; -+ ac97_bus_t *ac97_bus; -+ int irq; -+ int opened; -+ u64 cur_format; -+ unsigned int cur_rate; -+ struct clk *mck; -+ struct platform_device *pdev; -+ struct atmel_ac97_dma_info dma; -+} atmel_ac97_t; -+#define get_chip(card) ((atmel_ac97_t *)(card)->private_data) -+ -+#define ac97c_writel(chip, reg, val) \ -+ __raw_writel((val), (chip)->regs + AC97C_##reg) -+#define ac97c_readl(chip, reg) \ -+ __raw_readl((chip)->regs + AC97C_##reg) -+ -+/* PCM part */ -+ -+static snd_pcm_hardware_t snd_atmel_ac97_playback_hw = { -+ .info = (SNDRV_PCM_INFO_INTERLEAVED -+ |SNDRV_PCM_INFO_MMAP -+ |SNDRV_PCM_INFO_MMAP_VALID -+ |SNDRV_PCM_INFO_BLOCK_TRANSFER -+ |SNDRV_PCM_INFO_JOINT_DUPLEX), -+ .formats = (SNDRV_PCM_FMTBIT_S16_BE|SNDRV_PCM_FMTBIT_S16_LE), -+ .rates = (SNDRV_PCM_RATE_CONTINUOUS), -+ .rate_min = 4000, -+ .rate_max = 48000, -+ .channels_min = 1, -+ .channels_max = 6, -+ .buffer_bytes_max = 64*1024, -+ .period_bytes_min = 512, -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ .period_bytes_max = 64*1024, -+#else -+ .period_bytes_max = 4095, -+#endif -+ .periods_min = 8, -+ .periods_max = 1024, -+}; -+ -+static snd_pcm_hardware_t snd_atmel_ac97_capture_hw = { -+ .info = (SNDRV_PCM_INFO_INTERLEAVED -+ |SNDRV_PCM_INFO_MMAP -+ |SNDRV_PCM_INFO_MMAP_VALID -+ |SNDRV_PCM_INFO_BLOCK_TRANSFER -+ |SNDRV_PCM_INFO_JOINT_DUPLEX), -+ .formats = (SNDRV_PCM_FMTBIT_S16_BE|SNDRV_PCM_FMTBIT_S16_LE), -+ .rates = (SNDRV_PCM_RATE_CONTINUOUS), -+ .rate_min = 4000, -+ .rate_max = 48000, -+ .channels_min = 1, -+ .channels_max = 2, -+ .buffer_bytes_max = 64*1024, -+ .period_bytes_min = 512, -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ .period_bytes_max = 64*1024, -+#else -+ .period_bytes_max = 4095, -+#endif -+ .periods_min = 8, -+ .periods_max = 1024, -+}; -+ -+/* Joint full duplex variables */ -+unsigned int hw_rates[1]; -+unsigned int hw_formats[1]; -+struct snd_pcm_hw_constraint_list hw_constraint_rates; -+struct snd_pcm_hw_constraint_list hw_constraint_formats; -+ -+/* -+ * PCM functions -+ */ -+static int -+snd_atmel_ac97_playback_open(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ snd_pcm_runtime_t *runtime = substream->runtime; -+ -+ mutex_lock(&opened_mutex); -+ chip->opened++; -+ runtime->hw = snd_atmel_ac97_playback_hw; -+ if (chip->cur_rate) { -+ runtime->hw.rate_min = chip->cur_rate; -+ runtime->hw.rate_max = chip->cur_rate; -+ } -+ if (chip->cur_format) -+ runtime->hw.formats = (1ULL<<chip->cur_format); -+ mutex_unlock(&opened_mutex); -+ chip->playback_substream = substream; -+ chip->period = 0; -+ return 0; -+} -+ -+static int -+snd_atmel_ac97_capture_open(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ snd_pcm_runtime_t *runtime = substream->runtime; -+ -+ mutex_lock(&opened_mutex); -+ chip->opened++; -+ runtime->hw = snd_atmel_ac97_capture_hw; -+ if (chip->cur_rate) { -+ runtime->hw.rate_min = chip->cur_rate; -+ runtime->hw.rate_max = chip->cur_rate; -+ } -+ if (chip->cur_format) -+ runtime->hw.formats = (1ULL<<chip->cur_format); -+ mutex_unlock(&opened_mutex); -+ chip->capture_substream = substream; -+ chip->period = 0; -+ return 0; -+} -+ -+static int snd_atmel_ac97_playback_close(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ mutex_lock(&opened_mutex); -+ chip->opened--; -+ if (!chip->opened) { -+ chip->cur_rate = 0; -+ chip->cur_format = 0; -+ } -+ mutex_unlock(&opened_mutex); -+ return 0; -+} -+ -+static int snd_atmel_ac97_capture_close(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ mutex_lock(&opened_mutex); -+ chip->opened--; -+ if (!chip->opened) { -+ chip->cur_rate = 0; -+ chip->cur_format = 0; -+ } -+ mutex_unlock(&opened_mutex); -+ return 0; -+} -+ -+static int snd_atmel_ac97_playback_hw_params(snd_pcm_substream_t *substream, -+ snd_pcm_hw_params_t *hw_params) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS -+ int err; -+ err = snd_pcm_lib_malloc_pages(substream, -+ params_buffer_bytes(hw_params)); -+ -+ if (err < 0) -+ return err; -+ -+ /* Set restrictions to params */ -+ mutex_lock(&opened_mutex); -+ chip->cur_rate = params_rate(hw_params); -+ chip->cur_format = params_format(hw_params); -+ mutex_unlock(&opened_mutex); -+ -+ return err; -+#else -+ int pg; -+ size_t size = params_buffer_bytes(hw_params); -+ struct snd_pcm_runtime *runtime; -+ struct snd_dma_buffer *dmab = NULL; -+ -+ substream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV; -+ snd_assert(substream != NULL, return -EINVAL); -+ runtime = substream->runtime; -+ snd_assert(runtime != NULL, return -EINVAL); -+ -+ /* Set restrictions to params */ -+ mutex_lock(&opened_mutex); -+ chip->cur_rate = params_rate(hw_params); -+ chip->cur_format = params_format(hw_params); -+ mutex_unlock(&opened_mutex); -+ -+ /* check if buffer is already allocated */ -+ if (runtime->dma_buffer_p) { -+ size_t size_previouse; -+ int pg_previouse; -+ -+ /* new buffer is smaler than previouse allocated buffer */ -+ if (runtime->dma_buffer_p->bytes >= size) { -+ runtime->dma_bytes = size; -+ return 0; /* don't change buffer size */ -+ } -+ -+ size_previouse = runtime->dma_buffer_p->bytes; -+ pg_previouse = get_order(size_previouse); -+ -+ dma_free_coherent(runtime->dma_buffer_p->dev.dev, -+ PAGE_SIZE << pg_previouse, -+ runtime->dma_buffer_p->area, -+ runtime->dma_buffer_p->addr); -+ -+ kfree(runtime->dma_buffer_p); -+ } -+ -+ dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); -+ if (!dmab) -+ return -ENOMEM; -+ -+ dmab->dev = substream->dma_buffer.dev; -+ dmab->bytes = 0; -+ -+ pg = get_order(size); -+ -+ dmab->area = dma_alloc_coherent( -+ substream->dma_buffer.dev.dev, -+ PAGE_SIZE << pg, -+ (dma_addr_t *)&dmab->addr, -+ GFP_KERNEL); -+ -+ if (!dmab->area) { -+ kfree(dmab); -+ return -ENOMEM; -+ } -+ -+ dmab->bytes = size; -+ -+ snd_pcm_set_runtime_buffer(substream, dmab); -+ runtime->dma_bytes = size; -+ return 1; -+#endif -+} -+ -+static int snd_atmel_ac97_capture_hw_params(snd_pcm_substream_t *substream, -+ snd_pcm_hw_params_t *hw_params) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS -+ int err; -+ err = snd_pcm_lib_malloc_pages(substream, -+ params_buffer_bytes(hw_params)); -+ -+ if (err < 0) -+ return err; -+ -+ /* Set restrictions to params */ -+ mutex_lock(&opened_mutex); -+ chip->cur_rate = params_rate(hw_params); -+ chip->cur_format = params_format(hw_params); -+ mutex_unlock(&opened_mutex); -+ -+ return err; -+#else -+ int pg; -+ size_t size = params_buffer_bytes(hw_params); -+ struct snd_pcm_runtime *runtime; -+ struct snd_dma_buffer *dmab = NULL; -+ -+ substream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV; -+ snd_assert(substream != NULL, return -EINVAL); -+ runtime = substream->runtime; -+ snd_assert(runtime != NULL, return -EINVAL); -+ -+ /* Set restrictions to params */ -+ mutex_lock(&opened_mutex); -+ chip->cur_rate = params_rate(hw_params); -+ chip->cur_format = params_format(hw_params); -+ mutex_unlock(&opened_mutex); -+ -+ /* check if buffer is already allocated */ -+ if (runtime->dma_buffer_p) { -+ size_t size_previouse; -+ int pg_previouse; -+ -+ /* new buffer is smaler than previouse allocated buffer */ -+ if (runtime->dma_buffer_p->bytes >= size) { -+ runtime->dma_bytes = size; -+ return 0; /* don't change buffer size */ -+ } -+ -+ size_previouse = runtime->dma_buffer_p->bytes; -+ pg_previouse = get_order(size_previouse); -+ -+ dma_free_coherent(runtime->dma_buffer_p->dev.dev, -+ PAGE_SIZE << pg_previouse, -+ runtime->dma_buffer_p->area, -+ runtime->dma_buffer_p->addr); -+ -+ kfree(runtime->dma_buffer_p); -+ } -+ -+ dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); -+ if (!dmab) -+ return -ENOMEM; -+ -+ dmab->dev = substream->dma_buffer.dev; -+ dmab->bytes = 0; -+ -+ pg = get_order(size); -+ -+ dmab->area = dma_alloc_coherent( -+ substream->dma_buffer.dev.dev, -+ PAGE_SIZE << pg, -+ (dma_addr_t *)&dmab->addr, -+ GFP_KERNEL); -+ -+ if (!dmab->area) { -+ kfree(dmab); -+ return -ENOMEM; -+ } -+ -+ dmab->bytes = size; -+ -+ snd_pcm_set_runtime_buffer(substream, dmab); -+ runtime->dma_bytes = size; -+ return 1; -+#endif -+} -+ -+static int snd_atmel_ac97_playback_hw_free(snd_pcm_substream_t *substream) -+{ -+#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS -+ return snd_pcm_lib_free_pages(substream); -+#else -+ int pg; -+ struct snd_pcm_runtime *runtime; -+ struct snd_dma_buffer *dmab = NULL; -+ -+ snd_assert(substream != NULL, return -EINVAL); -+ runtime = substream->runtime; -+ snd_assert(runtime != NULL, return -EINVAL); -+ dmab = runtime->dma_buffer_p; -+ -+ if (!dmab) -+ return 0; -+ -+ if (!dmab->area) -+ return 0; -+ -+ pg = get_order(dmab->bytes); -+ dma_free_coherent(dmab->dev.dev, PAGE_SIZE << pg, dmab->area, dmab->addr); -+ kfree(runtime->dma_buffer_p); -+ snd_pcm_set_runtime_buffer(substream, NULL); -+ return 0; -+#endif -+} -+ -+static int snd_atmel_ac97_capture_hw_free(snd_pcm_substream_t *substream) -+{ -+ -+#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS -+ return snd_pcm_lib_free_pages(substream); -+#else -+ int pg; -+ struct snd_pcm_runtime *runtime; -+ struct snd_dma_buffer *dmab = NULL; -+ -+ snd_assert(substream != NULL, return -EINVAL); -+ runtime = substream->runtime; -+ snd_assert(runtime != NULL, return -EINVAL); -+ dmab = runtime->dma_buffer_p; -+ -+ if (!dmab) -+ return 0; -+ -+ if (!dmab->area) -+ return 0; -+ -+ pg = get_order(dmab->bytes); -+ dma_free_coherent(dmab->dev.dev, PAGE_SIZE << pg, dmab->area, dmab->addr); -+ kfree(runtime->dma_buffer_p); -+ snd_pcm_set_runtime_buffer(substream, NULL); -+ return 0; -+#endif -+} -+ -+static int snd_atmel_ac97_playback_prepare(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ struct platform_device *pdev = chip->pdev; -+ snd_pcm_runtime_t *runtime = substream->runtime; -+ int block_size = frames_to_bytes(runtime, runtime->period_size); -+ unsigned long word = 0; -+ unsigned long buffer_size = 0; -+ -+ dma_sync_single_for_device(&pdev->dev, runtime->dma_addr, -+ block_size * 2, DMA_TO_DEVICE); -+ -+ /* Assign slots to channels */ -+ switch (substream->runtime->channels) { -+ case 1: -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A); -+ break; -+ case 2: -+ /* Assign Left and Right slot to Channel A */ -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A) -+ | AC97C_CH_ASSIGN(PCM_RIGHT, A); -+ break; -+ default: -+ /* TODO: support more than two channels */ -+ return -EINVAL; -+ break; -+ } -+ ac97c_writel(chip, OCA, word); -+ -+ /* Configure sample format and size */ -+ word = AC97C_CMR_PDCEN | AC97C_CMR_SIZE_16; -+ -+ switch (runtime->format){ -+ case SNDRV_PCM_FORMAT_S16_LE: -+ word |= AC97C_CMR_CEM_LITTLE; -+ break; -+ case SNDRV_PCM_FORMAT_S16_BE: -+ default: -+ word &= ~AC97C_CMR_CEM_LITTLE; -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, word); -+ -+ /* Set variable rate if needed */ -+ if (runtime->rate != 48000) { -+ word = ac97c_readl(chip, MR); -+ word |= AC97C_MR_VRA; -+ ac97c_writel(chip, MR, word); -+ } else { -+ /* Clear Variable Rate Bit */ -+ word = ac97c_readl(chip, MR); -+ word &= ~AC97C_MR_VRA; -+ ac97c_writel(chip, MR, word); -+ } -+ -+ /* Set rate */ -+ snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate); -+ -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ /* Initialize and start the PDC */ -+ ac97c_writel(chip, CATPR, runtime->dma_addr); -+ ac97c_writel(chip, CATCR, block_size / 4); -+ ac97c_writel(chip, CATNPR, runtime->dma_addr + block_size); -+ ac97c_writel(chip, CATNCR, block_size / 4); -+ ac97c_writel(chip, PTCR, PDC_PTCR_TXTEN); -+ /* Enable Channel A interrupts */ -+ ac97c_writel(chip, IER, AC97C_SR_CAEVT); -+#else -+ buffer_size = frames_to_bytes(runtime, runtime->period_size) * -+ runtime->periods; -+ -+ chip->dma.req_tx.buffer_size = buffer_size; -+ chip->dma.req_tx.periods = runtime->periods; -+ -+ BUG_ON(chip->dma.req_tx.buffer_size != -+ (chip->dma.req_tx.periods * -+ frames_to_bytes(runtime, runtime->period_size))); -+ -+ chip->dma.req_tx.buffer_start = runtime->dma_addr; -+ chip->dma.req_tx.data_reg = (dma_addr_t)(chip->regs + AC97C_CATHR + 2); -+ chip->dma.req_tx.periph_id = chip->dma.tx_periph_id; -+ chip->dma.req_tx.direction = DMA_DIR_MEM_TO_PERIPH; -+ chip->dma.req_tx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_tx.dev_id = chip; -+#endif -+ -+ return 0; -+} -+ -+static int snd_atmel_ac97_capture_prepare(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ struct platform_device *pdev = chip->pdev; -+ snd_pcm_runtime_t *runtime = substream->runtime; -+ int block_size = frames_to_bytes(runtime, runtime->period_size); -+ unsigned long word = 0; -+ unsigned long buffer_size = 0; -+ -+ dma_sync_single_for_device(&pdev->dev, runtime->dma_addr, -+ block_size * 2, DMA_FROM_DEVICE); -+ -+ /* Assign slots to channels */ -+ switch (substream->runtime->channels) { -+ case 1: -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A); -+ break; -+ case 2: -+ /* Assign Left and Right slot to Channel A */ -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A) -+ | AC97C_CH_ASSIGN(PCM_RIGHT, A); -+ break; -+ default: -+ /* TODO: support more than two channels */ -+ return -EINVAL; -+ break; -+ } -+ ac97c_writel(chip, ICA, word); -+ -+ /* Configure sample format and size */ -+ word = AC97C_CMR_PDCEN | AC97C_CMR_SIZE_16; -+ -+ switch (runtime->format) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ word |= AC97C_CMR_CEM_LITTLE; -+ break; -+ case SNDRV_PCM_FORMAT_S16_BE: -+ default: -+ word &= ~(AC97C_CMR_CEM_LITTLE); -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, word); -+ -+ /* Set variable rate if needed */ -+ if (runtime->rate != 48000) { -+ word = ac97c_readl(chip, MR); -+ word |= AC97C_MR_VRA; -+ ac97c_writel(chip, MR, word); -+ } else { -+ /* Clear Variable Rate Bit */ -+ word = ac97c_readl(chip, MR); -+ word &= ~(AC97C_MR_VRA); -+ ac97c_writel(chip, MR, word); -+ } -+ -+ /* Set rate */ -+ snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); -+ -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ /* Initialize and start the PDC */ -+ ac97c_writel(chip, CARPR, runtime->dma_addr); -+ ac97c_writel(chip, CARCR, block_size / 4); -+ ac97c_writel(chip, CARNPR, runtime->dma_addr + block_size); -+ ac97c_writel(chip, CARNCR, block_size / 4); -+ ac97c_writel(chip, PTCR, PDC_PTCR_RXEN); -+ /* Enable Channel A interrupts */ -+ ac97c_writel(chip, IER, AC97C_SR_CAEVT); -+#else -+ buffer_size = frames_to_bytes(runtime, runtime->period_size) * -+ runtime->periods; -+ -+ chip->dma.req_rx.buffer_size = buffer_size; -+ chip->dma.req_rx.periods = runtime->periods; -+ -+ BUG_ON(chip->dma.req_rx.buffer_size != -+ (chip->dma.req_rx.periods * -+ frames_to_bytes(runtime, runtime->period_size))); -+ -+ chip->dma.req_rx.buffer_start = runtime->dma_addr; -+ chip->dma.req_rx.data_reg = (dma_addr_t)(chip->regs + AC97C_CARHR + 2); -+ chip->dma.req_rx.periph_id = chip->dma.rx_periph_id; -+ chip->dma.req_rx.direction = DMA_DIR_PERIPH_TO_MEM; -+ chip->dma.req_rx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_rx.dev_id = chip; -+#endif -+ -+ return 0; -+} -+ -+static int snd_atmel_ac97_playback_trigger(snd_pcm_substream_t *substream, int cmd) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ unsigned long camr; -+ int flags, err = 0; -+ -+ spin_lock_irqsave(&chip->lock, flags); -+ camr = ac97c_readl(chip, CAMR); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ err = dma_prepare_request_cyclic(chip->dma.req_tx.req.dmac, -+ &chip->dma.req_tx); -+ dma_start_request(chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel); -+ camr |= (AC97C_CMR_CENA -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ |AC97C_CMR_TXRDY -+#endif -+ ); -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ err = dma_stop_request(chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel); -+ if (chip->opened <= 1) { -+ camr &= ~(AC97C_CMR_CENA -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ |AC97C_CMR_TXRDY -+#endif -+ ); -+ } -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ else { -+ camr &= ~(AC97C_CMR_TXRDY); -+ } -+#endif -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, camr); -+ -+ spin_unlock_irqrestore(&chip->lock, flags); -+ return err; -+} -+ -+static int snd_atmel_ac97_capture_trigger(snd_pcm_substream_t *substream, int cmd) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ unsigned long camr; -+ int flags, err = 0; -+ -+ spin_lock_irqsave(&chip->lock, flags); -+ camr = ac97c_readl(chip, CAMR); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ err = dma_prepare_request_cyclic(chip->dma.req_rx.req.dmac, -+ &chip->dma.req_rx); -+ dma_start_request(chip->dma.req_rx.req.dmac, -+ chip->dma.req_rx.req.channel); -+ camr |= (AC97C_CMR_CENA -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ | AC97C_CMR_RXRDY -+#endif -+ ); -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ err = dma_stop_request(chip->dma.req_rx.req.dmac, -+ chip->dma.req_rx.req.channel); -+ mutex_lock(&opened_mutex); -+ if (chip->opened <= 1) { -+ camr &= ~(AC97C_CMR_CENA -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ | AC97C_CMR_RXRDY -+#endif -+ ); -+ } -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ else { -+ camr &= ~(AC97C_CSR_RXRDY); -+ } -+#endif -+ mutex_unlock(&opened_mutex); -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, camr); -+ -+ spin_unlock_irqrestore(&chip->lock, flags); -+ return err; -+} -+ -+static snd_pcm_uframes_t snd_atmel_ac97_playback_pointer(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ snd_pcm_runtime_t *runtime = substream->runtime; -+ snd_pcm_uframes_t pos; -+ unsigned long bytes; -+ -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ bytes = ac97c_readl(chip, CATPR) - runtime->dma_addr; -+#else -+ bytes = (dma_get_current_pos -+ (chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel) - runtime->dma_addr); -+#endif -+ pos = bytes_to_frames(runtime, bytes); -+ if (pos >= runtime->buffer_size) -+ pos -= runtime->buffer_size; -+ -+ return pos; -+} -+ -+static snd_pcm_uframes_t snd_atmel_ac97_capture_pointer(snd_pcm_substream_t *substream) -+{ -+ atmel_ac97_t *chip = snd_pcm_substream_chip(substream); -+ snd_pcm_runtime_t *runtime = substream->runtime; -+ snd_pcm_uframes_t pos; -+ unsigned long bytes; -+ -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ bytes = ac97c_readl(chip, CARPR) - runtime->dma_addr; -+#else -+ bytes = (dma_get_current_pos -+ (chip->dma.req_rx.req.dmac,chip->dma.req_rx.req.channel) - -+ runtime->dma_addr); -+#endif -+ pos = bytes_to_frames(runtime, bytes); -+ if (pos >= runtime->buffer_size) -+ pos -= runtime->buffer_size; -+ -+ -+ return pos; -+} -+ -+static snd_pcm_ops_t atmel_ac97_playback_ops = { -+ .open = snd_atmel_ac97_playback_open, -+ .close = snd_atmel_ac97_playback_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_atmel_ac97_playback_hw_params, -+ .hw_free = snd_atmel_ac97_playback_hw_free, -+ .prepare = snd_atmel_ac97_playback_prepare, -+ .trigger = snd_atmel_ac97_playback_trigger, -+ .pointer = snd_atmel_ac97_playback_pointer, -+}; -+ -+static snd_pcm_ops_t atmel_ac97_capture_ops = { -+ .open = snd_atmel_ac97_capture_open, -+ .close = snd_atmel_ac97_capture_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_atmel_ac97_capture_hw_params, -+ .hw_free = snd_atmel_ac97_capture_hw_free, -+ .prepare = snd_atmel_ac97_capture_prepare, -+ .trigger = snd_atmel_ac97_capture_trigger, -+ .pointer = snd_atmel_ac97_capture_pointer, -+}; -+ -+static struct ac97_pcm atmel_ac97_pcm_defs[] __devinitdata = { -+ /* Playback */ -+ { -+ .exclusive = 1, -+ .r = { { -+ .slots = ((1 << AC97_SLOT_PCM_LEFT) -+ | (1 << AC97_SLOT_PCM_RIGHT) -+ | (1 << AC97_SLOT_PCM_CENTER) -+ | (1 << AC97_SLOT_PCM_SLEFT) -+ | (1 << AC97_SLOT_PCM_SRIGHT) -+ | (1 << AC97_SLOT_LFE)), -+ } } -+ }, -+ /* PCM in */ -+ { -+ .stream = 1, -+ .exclusive = 1, -+ .r = { { -+ .slots = ((1 << AC97_SLOT_PCM_LEFT) -+ | (1 << AC97_SLOT_PCM_RIGHT)), -+ } } -+ }, -+ /* Mic in */ -+ { -+ .stream = 1, -+ .exclusive = 1, -+ .r = { { -+ .slots = (1<<AC97_SLOT_MIC), -+ } } -+ }, -+}; -+ -+static int __devinit snd_atmel_ac97_pcm_new(atmel_ac97_t *chip) -+{ -+ snd_pcm_t *pcm; -+ int err; -+ -+ err = snd_ac97_pcm_assign(chip->ac97_bus, -+ ARRAY_SIZE(atmel_ac97_pcm_defs), -+ atmel_ac97_pcm_defs); -+ if (err) -+ return err; -+ -+ err = snd_pcm_new(chip->card, "Atmel-AC97", 0, 1, 1, &pcm); -+ if (err) -+ return err; -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -+ &atmel_ac97_playback_ops); -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, -+ &atmel_ac97_capture_ops); -+ -+#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ &chip->pdev->dev, -+ 128 * 1024, 128 * 1024); -+#endif -+ -+ pcm->private_data = chip; -+ pcm->info_flags = 0; -+ strcpy(pcm->name, "Atmel-AC97"); -+ chip->pcm = pcm; -+ -+ return 0; -+} -+ -+/* Mixer part */ -+static int snd_atmel_ac97_mixer_new(atmel_ac97_t *chip) -+{ -+ int err; -+ ac97_template_t template; -+ -+ memset(&template, 0, sizeof(template)); -+ template.private_data = chip; -+ err = snd_ac97_mixer(chip->ac97_bus, &template, &chip->ac97); -+ -+ return err; -+} -+ -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+static irqreturn_t snd_atmel_ac97_interrupt(int irq, void *dev_id, -+ struct pt_regs *regs) -+{ -+ atmel_ac97_t *chip = dev_id; -+ unsigned long status; -+ -+ status = ac97c_readl(chip, SR); -+ -+ if (status & AC97C_SR_CAEVT) { -+ snd_pcm_runtime_t *runtime; -+ int offset, next_period, block_size; -+ unsigned long casr; -+ -+ /* FIXME: separate playback from capture */ -+ runtime = chip->playback_substream->runtime; -+ block_size = frames_to_bytes(runtime, runtime->period_size); -+ -+ casr = ac97c_readl(chip, CASR); -+ -+ if (casr & AC97C_CSR_ENDTX) { -+ chip->period++; -+ if (chip->period == runtime->periods) -+ chip->period = 0; -+ next_period = chip->period + 1; -+ if (next_period == runtime->periods) -+ next_period = 0; -+ -+ offset = block_size * next_period; -+ -+ ac97c_writel(chip, CATNPR, -+ runtime->dma_addr + offset); -+ ac97c_writel(chip, CATNCR, block_size / 4); -+ -+ snd_pcm_period_elapsed(chip->playback_substream); -+ } -+ else if (casr & AC97C_CSR_ENDRX) { -+ chip->period++; -+ if (chip->period == runtime->periods) -+ chip->period = 0; -+ next_period = chip->period + 1; -+ if (next_period == runtime->periods) -+ next_period = 0; -+ -+ offset = block_size * next_period; -+ -+ ac97c_writel(chip, CARNPR, -+ runtime->dma_addr + offset); -+ ac97c_writel(chip, CARNCR, block_size / 4); -+ -+ snd_pcm_period_elapsed(chip->capture_substream); -+ } else { -+ snd_printk(KERN_INFO -+ "atmel-ac97: spurious interrupt, status = 0x%08lx\n", -+ (unsigned long)casr); -+ } -+ } else { -+ snd_printk(KERN_INFO -+ "atmel-ac97: spurious interrupt, status = 0x%08lx\n", -+ status); -+ } -+ -+ (volatile int)ac97c_readl(chip, SR); -+ -+ return IRQ_HANDLED; -+} -+ -+#else -+ -+static void atmel_ac97_error(struct dma_request *_req) -+{ -+ struct dma_request_cyclic *req = to_dma_request_cyclic(_req); -+ -+ printk(KERN_WARNING -+ "DMA Controller error, channel %d (AC97C)\n", -+ req->req.channel); -+} -+ -+static void atmel_ac97_block_complete(struct dma_request *_req) -+{ -+ struct dma_request_cyclic *req = to_dma_request_cyclic(_req); -+ atmel_ac97_t *chip = req->dev_id; -+ if (req->periph_id == chip->dma.tx_periph_id) -+ snd_pcm_period_elapsed(chip->playback_substream); -+ else -+ snd_pcm_period_elapsed(chip->capture_substream); -+} -+ -+#endif -+ -+/* CODEC part */ -+ -+static void snd_atmel_ac97_write(ac97_t *ac97, unsigned short reg, -+ unsigned short val) -+{ -+ atmel_ac97_t *chip = ac97->private_data; -+ unsigned long word; -+ int timeout = 40; -+ -+ word = (reg & 0x7f) << 16 | val; -+ -+ do { -+ if (ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) { -+ ac97c_writel(chip, COTHR, word); -+ return; -+ } -+ udelay(1); -+ } while (--timeout); -+ -+ snd_printk(KERN_WARNING "atmel-ac97: codec write timeout\n"); -+} -+ -+static unsigned short snd_atmel_ac97_read(ac97_t *ac97, -+ unsigned short reg) -+{ -+ atmel_ac97_t *chip = ac97->private_data; -+ unsigned long word; -+ int timeout = 40; -+ int write = 10; -+ -+ word = (0x80 | (reg & 0x7f)) << 16; -+ -+ if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) -+ ac97c_readl(chip, CORHR); -+ -+retry_write: -+ timeout = 40; -+ -+ do { -+ if ((ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) != 0) { -+ ac97c_writel(chip, COTHR, word); -+ goto read_reg; -+ } -+ mdelay(10); -+ } while (--timeout); -+ -+ if (!--write) -+ goto timed_out; -+ goto retry_write; -+ -+read_reg: -+ do { -+ if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0){ -+ unsigned short val = ac97c_readl(chip, CORHR); -+ return val; -+ } -+ mdelay(10); -+ } while (--timeout); -+ -+ if (!--write) -+ goto timed_out; -+ goto retry_write; -+ -+timed_out: -+ snd_printk(KERN_INFO "atmel-ac97: codec read timeout\n"); -+ return 0xffff; -+} -+ -+static void snd_atmel_ac97_reset(atmel_ac97_t *chip) -+{ -+ /* TODO: Perform hard reset of codec as well */ -+ ac97c_writel(chip, MR, AC97C_MR_WRST); -+ mdelay(1); -+ ac97c_writel(chip, MR, AC97C_MR_ENA); -+} -+ -+static void snd_atmel_ac97_destroy(snd_card_t *card) -+{ -+ atmel_ac97_t *chip = get_chip(card); -+ -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ if (chip->irq != -1) -+ free_irq(chip->irq, chip); -+#endif -+ if (chip->regs) -+ iounmap(chip->regs); -+ -+ if (chip->mck) { -+ clk_disable(chip->mck); -+ clk_put(chip->mck); -+ } -+ -+#ifndef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ if (chip->dma.req_tx.req.dmac){ -+ dma_release_channel(chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel); -+ } -+ if (chip->dma.req_rx.req.dmac) { -+ dma_release_channel(chip->dma.req_rx.req.dmac, -+ chip->dma.req_rx.req.channel); -+ } -+#endif -+} -+ -+static int __devinit snd_atmel_ac97_create(snd_card_t *card, -+ struct platform_device *pdev) -+{ -+ static ac97_bus_ops_t ops = { -+ .write = snd_atmel_ac97_write, -+ .read = snd_atmel_ac97_read, -+ }; -+ atmel_ac97_t *chip = get_chip(card); -+ struct resource *regs; -+ struct clk *mck; -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ int irq; -+#endif -+ int err; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) -+ return -ENXIO; -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+#endif -+ -+ mck = clk_get(&pdev->dev, "mck"); -+ if (IS_ERR(mck)) -+ return PTR_ERR(mck); -+ clk_enable(mck); -+ chip->mck = mck; -+ -+ card->private_free = snd_atmel_ac97_destroy; -+ -+ spin_lock_init(&chip->lock); -+ chip->card = card; -+ chip->pdev = pdev; -+ chip->irq = -1; -+ -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ err = request_irq(irq, snd_atmel_ac97_interrupt, 0, -+ "ac97", chip); -+ if (err) { -+ snd_printk("unable to request IRQ%d\n", irq); -+ return err; -+ } -+ chip->irq = irq; -+#endif -+ -+ chip->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!chip->regs) -+ return -ENOMEM; -+ -+ snd_card_set_dev(card, &pdev->dev); -+ -+ err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus); -+ -+ return err; -+} -+ -+static int __devinit snd_atmel_ac97_probe(struct platform_device *pdev) -+{ -+ static int dev; -+ snd_card_t *card; -+ atmel_ac97_t *chip; -+ int err; -+ int ch; -+ -+ if (dev >= SNDRV_CARDS) -+ return -ENODEV; -+ if (!enable[dev]) { -+ dev++; -+ return -ENOENT; -+ } -+ -+ err = -ENOMEM; -+ -+ mutex_init(&opened_mutex); -+ -+ card = snd_card_new(index[dev], id[dev], THIS_MODULE, -+ sizeof(atmel_ac97_t)); -+ if (!card) -+ goto out; -+ chip = get_chip(card); -+ -+ err = snd_atmel_ac97_create(card, pdev); -+ if (err) -+ goto out_free_card; -+ -+ snd_atmel_ac97_reset(chip); -+ -+ err = snd_atmel_ac97_mixer_new(chip); -+ if (err) -+ goto out_free_card; -+ -+ err = snd_atmel_ac97_pcm_new(chip); -+ if (err) -+ goto out_free_card; -+ -+#ifndef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ /* TODO: Get this information from the platform device */ -+ chip->dma.req_tx.req.dmac = find_dma_controller(0); -+ if (!chip->dma.req_tx.req.dmac) { -+ printk(KERN_ERR -+ "atmel-ac97c: No DMA controller for TX, aborting\n"); -+ goto out_free_card; -+ } -+ chip->dma.req_rx.req.dmac = find_dma_controller(0); -+ if (!chip->dma.req_rx.req.dmac) { -+ snd_printk(KERN_ERR -+ "atmel-ac97c: No DMA controller available for RX, aborting\n"); -+ goto out_free_card; -+ } -+ -+ chip->dma.rx_periph_id = 3; -+ chip->dma.tx_periph_id = 4; -+ -+ ch = dma_alloc_channel(chip->dma.req_tx.req.dmac); -+ if (ch < 0) { -+ printk(KERN_ERR -+ "atmel-ac97c: Unable to allocate TX DMA channel, aborting\n"); -+ goto out_free_card; -+ } -+ chip->dma.req_tx.req.channel = ch; -+ chip->dma.req_tx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_tx.req.block_complete = atmel_ac97_block_complete; -+ chip->dma.req_tx.req.error = atmel_ac97_error; -+ -+ ch = dma_alloc_channel(chip->dma.req_rx.req.dmac); -+ if (ch < 0) { -+ snd_printk(KERN_ERR -+ "atmel-ac97c: Unable to allocate RX DMA channel, aborting\n"); -+ goto out_free_card; -+ } -+ chip->dma.req_rx.req.channel = ch; -+ chip->dma.req_rx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_rx.req.block_complete = atmel_ac97_block_complete; -+ chip->dma.req_rx.req.error = atmel_ac97_error; -+#endif -+ -+ strcpy(card->driver, "ac97c"); -+ strcpy(card->shortname, "Atmel-AC97"); -+#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC -+ sprintf(card->longname, "Atmel AVR32 AC97 Controller at 0x%p, irq %i", -+ chip->regs, chip->irq); -+#else -+ sprintf(card->longname, "Atmel AVR32 AC97 Controller at 0x%p, dma rx %i and tx %i", -+ chip->regs, chip->dma.rx_periph_id, chip->dma.tx_periph_id); -+#endif -+ -+ err = snd_card_register(card); -+ if (err) -+ goto out_free_card; -+ -+ platform_set_drvdata(pdev, card); -+ dev++; -+ return 0; -+ -+out_free_card: -+ snd_card_free(card); -+out: -+ return err; -+} -+ -+static int __devexit snd_atmel_ac97_remove(struct platform_device *pdev) -+{ -+ snd_card_t *card = platform_get_drvdata(pdev); -+ -+ snd_card_free(card); -+ platform_set_drvdata(pdev, NULL); -+ return 0; -+} -+ -+static struct platform_driver atmel_ac97_driver = { -+ .probe = snd_atmel_ac97_probe, -+ .remove = __devexit_p(snd_atmel_ac97_remove), -+ .driver = { -+ .name = "ac97c", -+ }, -+}; -+ -+static int __init atmel_ac97_init(void) -+{ -+ return platform_driver_register(&atmel_ac97_driver); -+} -+ -+static void __exit atmel_ac97_exit(void) -+{ -+ platform_driver_unregister(&atmel_ac97_driver); -+} -+ -+module_init(atmel_ac97_init); -+module_exit(atmel_ac97_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Driver for Atmel AC97 Controller"); -+MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); -Index: linux-2.6.18-avr32/sound/avr32/ac97c.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.18-avr32/sound/avr32/ac97c.h 2006-11-02 15:56:20.000000000 +0100 -@@ -0,0 +1,71 @@ -+/* -+ * Register definitions for the Atmel AC97 Controller. -+ * -+ * Copyright (C) 2005-2006 Atmel Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __SOUND_AVR32_AC97C_H -+#define __SOUND_AVR32_AC97C_H -+ -+#define AC97C_MR 0x08 -+#define AC97C_ICA 0x10 -+#define AC97C_OCA 0x14 -+#define AC97C_CARHR 0x20 -+#define AC97C_CATHR 0x24 -+#define AC97C_CASR 0x28 -+#define AC97C_CAMR 0x2c -+#define AC97C_CBRHR 0x30 -+#define AC97C_CBTHR 0x34 -+#define AC97C_CBSR 0x38 -+#define AC97C_CBMR 0x3c -+#define AC97C_CORHR 0x40 -+#define AC97C_COTHR 0x44 -+#define AC97C_COSR 0x48 -+#define AC97C_COMR 0x4c -+#define AC97C_SR 0x50 -+#define AC97C_IER 0x54 -+#define AC97C_IDR 0x58 -+#define AC97C_IMR 0x5c -+#define AC97C_VERSION 0xfc -+ -+#define AC97C_CATPR PDC_TPR -+#define AC97C_CATCR PDC_TCR -+#define AC97C_CATNPR PDC_TNPR -+#define AC97C_CATNCR PDC_TNCR -+#define AC97C_CARPR PDC_RPR -+#define AC97C_CARCR PDC_RCR -+#define AC97C_CARNPR PDC_RNPR -+#define AC97C_CARNCR PDC_RNCR -+#define AC97C_PTCR PDC_PTCR -+ -+#define AC97C_MR_ENA (1 << 0) -+#define AC97C_MR_WRST (1 << 1) -+#define AC97C_MR_VRA (1 << 2) -+ -+#define AC97C_CSR_TXRDY (1 << 0) -+#define AC97C_CSR_UNRUN (1 << 2) -+#define AC97C_CSR_RXRDY (1 << 4) -+#define AC97C_CSR_ENDTX (1 << 10) -+#define AC97C_CSR_ENDRX (1 << 14) -+ -+#define AC97C_CMR_SIZE_20 (0 << 16) -+#define AC97C_CMR_SIZE_18 (1 << 16) -+#define AC97C_CMR_SIZE_16 (2 << 16) -+#define AC97C_CMR_SIZE_10 (3 << 16) -+#define AC97C_CMR_CEM_LITTLE (1 << 18) -+#define AC97C_CMR_CEM_BIG (0 << 18) -+#define AC97C_CMR_CENA (1 << 21) -+#define AC97C_CMR_PDCEN (1 << 22) -+ -+#define AC97C_SR_CAEVT (1 << 3) -+ -+#define AC97C_CH_ASSIGN(slot, channel) \ -+ (AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3))) -+#define AC97C_CHANNEL_NONE 0x0 -+#define AC97C_CHANNEL_A 0x1 -+#define AC97C_CHANNEL_B 0x2 -+ -+#endif /* __SOUND_AVR32_AC97C_H */ |