diff for duplicates of <20100527130338.968177114@mandriva.com> diff --git a/a/1.txt b/N1/1.txt index ae3d25a..c72c568 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,1108 +1,3 @@ -This patch enables support for the i2s controller available on kirkwood platforms - -Signed-off-by: Arnaud Patard <apatard@mandriva.com> - -Index: sound-2.6/sound/soc/kirkwood/Kconfig -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ sound-2.6/sound/soc/kirkwood/Kconfig 2010-05-27 14:09:55.807674540 +0200 -@@ -0,0 +1,11 @@ -+config SND_KIRKWOOD_SOC -+ tristate "SoC Audio for the Marvell Kirkwood chip" -+ depends on ARCH_KIRKWOOD -+ help -+ Say Y or M if you want to add support for codecs attached to -+ the Kirkwood I2S interface. You will also need to select the -+ audio interfaces to support below. -+ -+config SND_KIRKWOOD_SOC_I2S -+ tristate -+ -Index: sound-2.6/sound/soc/kirkwood/kirkwood-dma.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ sound-2.6/sound/soc/kirkwood/kirkwood-dma.c 2010-05-27 14:09:55.844174800 +0200 -@@ -0,0 +1,383 @@ -+/* -+ * kirkwood-dma.c -+ * -+ * (c) 2010 Arnaud Patard <apatard@mandriva.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/device.h> -+#include <linux/io.h> -+#include <linux/slab.h> -+#include <linux/interrupt.h> -+#include <linux/dma-mapping.h> -+#include <linux/mbus.h> -+#include <sound/soc.h> -+#include "kirkwood-dma.h" -+#include "kirkwood.h" -+ -+#define KIRKWOOD_RATES \ -+ (SNDRV_PCM_RATE_44100 | \ -+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) -+#define KIRKWOOD_FORMATS \ -+ (SNDRV_PCM_FMTBIT_S16_LE | \ -+ SNDRV_PCM_FMTBIT_S24_LE | \ -+ SNDRV_PCM_FMTBIT_S32_LE) -+ -+struct kirkwood_dma_priv { -+ struct snd_pcm_substream *play_stream; -+ struct snd_pcm_substream *rec_stream; -+ struct kirkwood_dma_data *data; -+}; -+ -+static struct snd_pcm_hardware kirkwood_dma_snd_hw = { -+ .info = (SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_MMAP | -+ SNDRV_PCM_INFO_MMAP_VALID | -+ SNDRV_PCM_INFO_BLOCK_TRANSFER | -+ SNDRV_PCM_INFO_PAUSE), -+ .formats = KIRKWOOD_FORMATS, -+ .rates = KIRKWOOD_RATES, -+ .rate_min = 44100, -+ .rate_max = 96000, -+ .channels_min = 1, -+ .channels_max = 2, -+ .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, -+ .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, -+ .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, -+ .periods_min = KIRKWOOD_SND_MIN_PERIODS, -+ .periods_max = KIRKWOOD_SND_MAX_PERIODS, -+ .fifo_size = 0, -+}; -+ -+static u64 kirkwood_dma_dmamask = 0xFFFFFFFFUL; -+ -+static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) -+{ -+ struct kirkwood_dma_priv *prdata = dev_id; -+ struct kirkwood_dma_data *priv = prdata->data; -+ unsigned long mask, status, cause; -+ -+ mask = readl(priv->io + KIRKWOOD_INT_MASK); -+ status = readl(priv->io + KIRKWOOD_INT_CAUSE) & mask; -+ -+ cause = readl(priv->io + KIRKWOOD_ERR_CAUSE); -+ if (unlikely(cause)) { -+ printk(KERN_WARNING "%s: got err interrupt 0x%lx\n", -+ __func__, cause); -+ writel(cause, priv->io + KIRKWOOD_ERR_CAUSE); -+ return IRQ_HANDLED; -+ } -+ -+ /* we've enabled only bytes interrupts ... */ -+ if (status & ~(KIRKWOOD_INT_CAUSE_PLAY_BYTES | \ -+ KIRKWOOD_INT_CAUSE_REC_BYTES)) { -+ printk(KERN_WARNING "%s: unexpected interrupt %lx\n", -+ __func__, status); -+ return IRQ_NONE; -+ } -+ -+ /* ack int */ -+ writel(status, priv->io + KIRKWOOD_INT_CAUSE); -+ -+ if (status & KIRKWOOD_INT_CAUSE_PLAY_BYTES) -+ snd_pcm_period_elapsed(prdata->play_stream); -+ -+ if (status & KIRKWOOD_INT_CAUSE_REC_BYTES) -+ snd_pcm_period_elapsed(prdata->rec_stream); -+ -+ return IRQ_HANDLED; -+} -+ -+static void kirkwood_dma_conf_mbus_windows(void __iomem *base, int win, -+ unsigned long dma, -+ struct mbus_dram_target_info *dram) -+{ -+ int i; -+ -+ /* First disable and clear windows */ -+ writel(0, base + KIRKWOOD_AUDIO_WIN_CTRL_REG(win)); -+ writel(0, base + KIRKWOOD_AUDIO_WIN_BASE_REG(win)); -+ -+ /* try to find matching cs for current dma address */ -+ for (i = 0; i < dram->num_cs; i++) { -+ struct mbus_dram_window *cs = dram->cs + i; -+ if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) { -+ writel(cs->base & 0xffff0000, -+ base + KIRKWOOD_AUDIO_WIN_BASE_REG(win)); -+ writel(((cs->size - 1) & 0xffff0000) | -+ (cs->mbus_attr << 8) | -+ (dram->mbus_dram_target_id << 4) | 1, -+ base + KIRKWOOD_AUDIO_WIN_CTRL_REG(win)); -+ } -+ } -+} -+ -+static int kirkwood_dma_open(struct snd_pcm_substream *substream) -+{ -+ int err; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; -+ struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; -+ struct kirkwood_dma_data *priv; -+ struct kirkwood_dma_priv *prdata = cpu_dai->private_data; -+ unsigned long addr; -+ -+ priv = snd_soc_dai_get_dma_data(cpu_dai, substream); -+ snd_soc_set_runtime_hwparams(substream, &kirkwood_dma_snd_hw); -+ -+ /* Ensure that all constraints linked to dma burst are fullfilled */ -+ err = snd_pcm_hw_constraint_minmax(runtime, -+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -+ priv->burst * 2, -+ KIRKWOOD_AUDIO_BUF_MAX-1); -+ if (err < 0) -+ return err; -+ -+ err = snd_pcm_hw_constraint_step(runtime, 0, -+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -+ priv->burst); -+ if (err < 0) -+ return err; -+ -+ err = snd_pcm_hw_constraint_step(substream->runtime, 0, -+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -+ priv->burst); -+ if (err < 0) -+ return err; -+ -+ if (soc_runtime->dai->cpu_dai->private_data == NULL) { -+ prdata = kzalloc(sizeof(struct kirkwood_dma_priv), GFP_KERNEL); -+ if (prdata == NULL) -+ return -ENOMEM; -+ -+ prdata->data = priv; -+ -+ err = request_irq(priv->irq, kirkwood_dma_irq, IRQF_SHARED, -+ "kirkwood-i2s", prdata); -+ if (err) { -+ kfree(prdata); -+ return -EBUSY; -+ } -+ -+ soc_runtime->dai->cpu_dai->private_data = prdata; -+ -+ /* -+ * Enable Error interrupts. We're only ack'ing them but -+ * it's usefull for diagnostics -+ */ -+ writel((unsigned long)-1, priv->io + KIRKWOOD_ERR_MASK); -+ } -+ -+ addr = virt_to_phys(substream->dma_buffer.area); -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ prdata->play_stream = substream; -+ kirkwood_dma_conf_mbus_windows(priv->io, -+ KIRKWOOD_PLAYBACK_WIN, addr, priv->dram); -+ } else { -+ prdata->rec_stream = substream; -+ kirkwood_dma_conf_mbus_windows(priv->io, -+ KIRKWOOD_RECORD_WIN, addr, priv->dram); -+ } -+ -+ return 0; -+} -+ -+static int kirkwood_dma_close(struct snd_pcm_substream *substream) -+{ -+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; -+ struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; -+ struct kirkwood_dma_priv *prdata = cpu_dai->private_data; -+ struct kirkwood_dma_data *priv; -+ -+ priv = snd_soc_dai_get_dma_data(cpu_dai, substream); -+ -+ if (!prdata || !priv) -+ return 0; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ prdata->play_stream = NULL; -+ else -+ prdata->rec_stream = NULL; -+ -+ if (!prdata->play_stream && !prdata->rec_stream) { -+ writel(0, priv->io + KIRKWOOD_ERR_MASK); -+ free_irq(priv->irq, prdata); -+ kfree(prdata); -+ soc_runtime->dai->cpu_dai->private_data = NULL; -+ } -+ -+ return 0; -+} -+ -+static int kirkwood_dma_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ -+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); -+ runtime->dma_bytes = params_buffer_bytes(params); -+ -+ return 0; -+} -+ -+static int kirkwood_dma_hw_free(struct snd_pcm_substream *substream) -+{ -+ snd_pcm_set_runtime_buffer(substream, NULL); -+ return 0; -+} -+ -+static int kirkwood_dma_prepare(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; -+ struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; -+ struct kirkwood_dma_data *priv; -+ unsigned long size, count; -+ -+ priv = snd_soc_dai_get_dma_data(cpu_dai, substream); -+ -+ /* compute buffer size in term of "words" as requested in specs */ -+ size = frames_to_bytes(runtime, runtime->buffer_size); -+ size = (size>>2)-1; -+ count = snd_pcm_lib_period_bytes(substream); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ writel(count, priv->io + KIRKWOOD_PLAY_BYTE_INT_COUNT); -+ writel(runtime->dma_addr, priv->io + KIRKWOOD_PLAY_BUF_ADDR); -+ writel(size, priv->io + KIRKWOOD_PLAY_BUF_SIZE); -+ } else { -+ writel(count, priv->io + KIRKWOOD_REC_BYTE_INT_COUNT); -+ writel(runtime->dma_addr, priv->io + KIRKWOOD_REC_BUF_ADDR); -+ writel(size, priv->io + KIRKWOOD_REC_BUF_SIZE); -+ } -+ -+ -+ return 0; -+} -+ -+static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream -+ *substream) -+{ -+ struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; -+ struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; -+ struct kirkwood_dma_data *priv; -+ snd_pcm_uframes_t count; -+ -+ priv = snd_soc_dai_get_dma_data(cpu_dai, substream); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ count = bytes_to_frames(substream->runtime, -+ readl(priv->io + KIRKWOOD_PLAY_BYTE_COUNT)); -+ else -+ count = bytes_to_frames(substream->runtime, -+ readl(priv->io + KIRKWOOD_REC_BYTE_COUNT)); -+ -+ return count; -+} -+ -+struct snd_pcm_ops kirkwood_dma_ops = { -+ .open = kirkwood_dma_open, -+ .close = kirkwood_dma_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = kirkwood_dma_hw_params, -+ .hw_free = kirkwood_dma_hw_free, -+ .prepare = kirkwood_dma_prepare, -+ .pointer = kirkwood_dma_pointer, -+}; -+ -+static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm, -+ int stream) -+{ -+ struct snd_pcm_substream *substream = pcm->streams[stream].substream; -+ struct snd_dma_buffer *buf = &substream->dma_buffer; -+ size_t size = kirkwood_dma_snd_hw.buffer_bytes_max; -+ -+ buf->dev.type = SNDRV_DMA_TYPE_DEV; -+ buf->dev.dev = pcm->card->dev; -+ buf->area = dma_alloc_coherent(pcm->card->dev, size, -+ &buf->addr, GFP_KERNEL); -+ if (!buf->area) -+ return -ENOMEM; -+ buf->bytes = size; -+ buf->private_data = NULL; -+ -+ return 0; -+} -+ -+static int kirkwood_dma_new(struct snd_card *card, -+ struct snd_soc_dai *dai, struct snd_pcm *pcm) -+{ -+ int ret; -+ -+ if (!card->dev->dma_mask) -+ card->dev->dma_mask = &kirkwood_dma_dmamask; -+ if (!card->dev->coherent_dma_mask) -+ card->dev->coherent_dma_mask = 0xffffffff; -+ -+ if (dai->playback.channels_min) { -+ ret = kirkwood_dma_preallocate_dma_buffer(pcm, -+ SNDRV_PCM_STREAM_PLAYBACK); -+ if (ret) -+ return ret; -+ } -+ -+ if (dai->capture.channels_min) { -+ ret = kirkwood_dma_preallocate_dma_buffer(pcm, -+ SNDRV_PCM_STREAM_CAPTURE); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm) -+{ -+ struct snd_pcm_substream *substream; -+ struct snd_dma_buffer *buf; -+ int stream; -+ -+ for (stream = 0; stream < 2; stream++) { -+ substream = pcm->streams[stream].substream; -+ if (!substream) -+ continue; -+ buf = &substream->dma_buffer; -+ if (!buf->area) -+ continue; -+ -+ dma_free_coherent(pcm->card->dev, buf->bytes, -+ buf->area, buf->addr); -+ buf->area = NULL; -+ } -+} -+ -+struct snd_soc_platform kirkwood_soc_platform = { -+ .name = "kirkwood-dma", -+ .pcm_ops = &kirkwood_dma_ops, -+ .pcm_new = kirkwood_dma_new, -+ .pcm_free = kirkwood_dma_free_dma_buffers, -+}; -+EXPORT_SYMBOL_GPL(kirkwood_soc_platform); -+ -+static int __init kirkwood_soc_platform_init(void) -+{ -+ return snd_soc_register_platform(&kirkwood_soc_platform); -+} -+module_init(kirkwood_soc_platform_init); -+ -+static void __exit kirkwood_soc_platform_exit(void) -+{ -+ snd_soc_unregister_platform(&kirkwood_soc_platform); -+} -+module_exit(kirkwood_soc_platform_exit); -+ -+MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>"); -+MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module"); -+MODULE_LICENSE("GPL"); -+ -Index: sound-2.6/sound/soc/kirkwood/kirkwood.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ sound-2.6/sound/soc/kirkwood/kirkwood.h 2010-05-27 14:09:55.851714894 +0200 -@@ -0,0 +1,126 @@ -+/* -+ * kirkwood.h -+ * -+ * (c) 2010 Arnaud Patard <apatard@mandriva.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#ifndef _KIRKWOOD_AUDIO_H -+#define _KIRKWOOD_AUDIO_H -+ -+#define KIRKWOOD_RECORD_WIN 0 -+#define KIRKWOOD_PLAYBACK_WIN 1 -+#define KIRKWOOD_MAX_AUDIO_WIN 2 -+ -+#define KIRKWOOD_AUDIO_WIN_BASE_REG(win) (0xA00 + ((win)<<3)) -+#define KIRKWOOD_AUDIO_WIN_CTRL_REG(win) (0xA04 + ((win)<<3)) -+ -+ -+#define KIRKWOOD_RECCTL 0x1000 -+#define KIRKWOOD_RECCTL_SPDIF_EN (1<<11) -+#define KIRKWOOD_RECCTL_I2S_EN (1<<10) -+#define KIRKWOOD_RECCTL_PAUSE (1<<9) -+#define KIRKWOOD_RECCTL_MUTE (1<<8) -+#define KIRKWOOD_RECCTL_BURST_MASK (3<<5) -+#define KIRKWOOD_RECCTL_BURST_128 (2<<5) -+#define KIRKWOOD_RECCTL_BURST_32 (1<<5) -+#define KIRKWOOD_RECCTL_MONO (1<<4) -+#define KIRKWOOD_RECCTL_MONO_CHAN_RIGHT (1<<3) -+#define KIRKWOOD_RECCTL_MONO_CHAN_LEFT (0<<3) -+#define KIRKWOOD_RECCTL_SIZE_MASK (7<<0) -+#define KIRKWOOD_RECCTL_SIZE_16 (7<<0) -+#define KIRKWOOD_RECCTL_SIZE_16_C (3<<0) -+#define KIRKWOOD_RECCTL_SIZE_20 (2<<0) -+#define KIRKWOOD_RECCTL_SIZE_24 (1<<0) -+#define KIRKWOOD_RECCTL_SIZE_32 (0<<0) -+ -+#define KIRKWOOD_REC_BUF_ADDR 0x1004 -+#define KIRKWOOD_REC_BUF_SIZE 0x1008 -+#define KIRKWOOD_REC_BYTE_COUNT 0x100C -+ -+#define KIRKWOOD_PLAYCTL 0x1100 -+#define KIRKWOOD_PLAYCTL_PLAY_BUSY (1<<16) -+#define KIRKWOOD_PLAYCTL_BURST_MASK (3<<11) -+#define KIRKWOOD_PLAYCTL_BURST_128 (2<<11) -+#define KIRKWOOD_PLAYCTL_BURST_32 (1<<11) -+#define KIRKWOOD_PLAYCTL_PAUSE (1<<9) -+#define KIRKWOOD_PLAYCTL_SPDIF_MUTE (1<<8) -+#define KIRKWOOD_PLAYCTL_I2S_MUTE (1<<7) -+#define KIRKWOOD_PLAYCTL_SPDIF_EN (1<<4) -+#define KIRKWOOD_PLAYCTL_I2S_EN (1<<3) -+#define KIRKWOOD_PLAYCTL_SIZE_MASK (7<<0) -+#define KIRKWOOD_PLAYCTL_SIZE_16 (7<<0) -+#define KIRKWOOD_PLAYCTL_SIZE_16_C (3<<0) -+#define KIRKWOOD_PLAYCTL_SIZE_20 (2<<0) -+#define KIRKWOOD_PLAYCTL_SIZE_24 (1<<0) -+#define KIRKWOOD_PLAYCTL_SIZE_32 (0<<0) -+ -+#define KIRKWOOD_PLAY_BUF_ADDR 0x1104 -+#define KIRKWOOD_PLAY_BUF_SIZE 0x1108 -+#define KIRKWOOD_PLAY_BYTE_COUNT 0x110C -+ -+#define KIRKWOOD_DCO_CTL 0x1204 -+#define KIRKWOOD_DCO_CTL_OFFSET_MASK (0xFFF<<2) -+#define KIRKWOOD_DCO_CTL_OFFSET_0 (0x800<<2) -+#define KIRKWOOD_DCO_CTL_FREQ_MASK (3<<0) -+#define KIRKWOOD_DCO_CTL_FREQ_11 (0<<0) -+#define KIRKWOOD_DCO_CTL_FREQ_12 (1<<0) -+#define KIRKWOOD_DCO_CTL_FREQ_24 (2<<0) -+ -+#define KIRKWOOD_DCO_SPCR_STATUS 0x120c -+#define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16) -+ -+#define KIRKWOOD_ERR_CAUSE 0x1300 -+#define KIRKWOOD_ERR_MASK 0x1304 -+ -+#define KIRKWOOD_INT_CAUSE 0x1308 -+#define KIRKWOOD_INT_MASK 0x130C -+#define KIRKWOOD_INT_CAUSE_PLAY_BYTES (1<<14) -+#define KIRKWOOD_INT_CAUSE_REC_BYTES (1<<13) -+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_END (1<<7) -+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_3Q (1<<6) -+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_HALF (1<<5) -+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_1Q (1<<4) -+#define KIRKWOOD_INT_CAUSE_DMA_REC_END (1<<3) -+#define KIRKWOOD_INT_CAUSE_DMA_REC_3Q (1<<2) -+#define KIRKWOOD_INT_CAUSE_DMA_REC_HALF (1<<1) -+#define KIRKWOOD_INT_CAUSE_DMA_REC_1Q (1<<0) -+ -+#define KIRKWOOD_REC_BYTE_INT_COUNT 0x1310 -+#define KIRKWOOD_PLAY_BYTE_INT_COUNT 0x1314 -+#define KIRKWOOD_BYTE_INT_COUNT_MASK 0xffffff -+ -+#define KIRKWOOD_I2S_PLAYCTL 0x2508 -+#define KIRKWOOD_I2S_RECCTL 0x2408 -+#define KIRKWOOD_I2S_CTL_JUST_MASK (0xf<<26) -+#define KIRKWOOD_I2S_CTL_LJ (0<<26) -+#define KIRKWOOD_I2S_CTL_I2S (5<<26) -+#define KIRKWOOD_I2S_CTL_RJ (8<<26) -+#define KIRKWOOD_I2S_CTL_SIZE_MASK (3<<30) -+#define KIRKWOOD_I2S_CTL_SIZE_16 (3<<30) -+#define KIRKWOOD_I2S_CTL_SIZE_20 (2<<30) -+#define KIRKWOOD_I2S_CTL_SIZE_24 (1<<30) -+#define KIRKWOOD_I2S_CTL_SIZE_32 (0<<30) -+ -+#define KIRKWOOD_AUDIO_BUF_MAX (16*1024*1024) -+ -+/* Theses values come from the marvell alsa driver */ -+/* need to find where they come from */ -+#define KIRKWOOD_SND_MIN_PERIODS 8 -+#define KIRKWOOD_SND_MAX_PERIODS 16 -+#define KIRKWOOD_SND_MIN_PERIOD_BYTES 0x4000 -+#define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 -+ -+struct kirkwood_dma_data { -+ struct resource *mem; -+ void __iomem *io; -+ int irq; -+ int burst; -+ struct mbus_dram_target_info *dram; -+}; -+ -+#endif -Index: sound-2.6/sound/soc/kirkwood/kirkwood-i2s.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ sound-2.6/sound/soc/kirkwood/kirkwood-i2s.c 2010-05-27 14:09:55.859694735 +0200 -@@ -0,0 +1,485 @@ -+/* -+ * kirkwood-i2s.c -+ * -+ * (c) 2010 Arnaud Patard <apatard@mandriva.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/io.h> -+#include <linux/slab.h> -+#include <linux/mbus.h> -+#include <linux/delay.h> -+#include <sound/pcm.h> -+#include <sound/pcm_params.h> -+#include <sound/soc.h> -+#include <plat/audio.h> -+#include "kirkwood-i2s.h" -+#include "kirkwood.h" -+ -+#define DRV_NAME "kirkwood-i2s" -+ -+#define KIRKWOOD_I2S_RATES \ -+ (SNDRV_PCM_RATE_44100 | \ -+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) -+#define KIRKWOOD_I2S_FORMATS \ -+ (SNDRV_PCM_FMTBIT_S16_LE | \ -+ SNDRV_PCM_FMTBIT_S24_LE | \ -+ SNDRV_PCM_FMTBIT_S32_LE) -+ -+ -+struct snd_soc_dai kirkwood_i2s_dai; -+static struct kirkwood_dma_data *priv; -+ -+static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai, -+ unsigned int fmt) -+{ -+ unsigned long mask; -+ unsigned long value; -+ -+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_RIGHT_J: -+ mask = KIRKWOOD_I2S_CTL_RJ; -+ break; -+ case SND_SOC_DAIFMT_LEFT_J: -+ mask = KIRKWOOD_I2S_CTL_LJ; -+ break; -+ case SND_SOC_DAIFMT_I2S: -+ mask = KIRKWOOD_I2S_CTL_I2S; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* -+ * Set same format for playback and record -+ * This avoids some troubles. -+ */ -+ value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL); -+ value &= ~KIRKWOOD_I2S_CTL_JUST_MASK; -+ value |= mask; -+ writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL); -+ -+ value = readl(priv->io+KIRKWOOD_I2S_RECCTL); -+ value &= ~KIRKWOOD_I2S_CTL_JUST_MASK; -+ value |= mask; -+ writel(value, priv->io+KIRKWOOD_I2S_RECCTL); -+ -+ return 0; -+} -+ -+static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate) -+{ -+ unsigned long value; -+ -+ value = KIRKWOOD_DCO_CTL_OFFSET_0; -+ switch (rate) { -+ default: -+ case 44100: -+ value |= KIRKWOOD_DCO_CTL_FREQ_11; -+ break; -+ case 48000: -+ value |= KIRKWOOD_DCO_CTL_FREQ_12; -+ break; -+ case 96000: -+ value |= KIRKWOOD_DCO_CTL_FREQ_24; -+ break; -+ } -+ writel(value, io + KIRKWOOD_DCO_CTL); -+ -+ /* wait for dco locked */ -+ do { -+ cpu_relax(); -+ value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); -+ value &= KIRKWOOD_DCO_SPCR_STATUS; -+ } while (value == 0); -+} -+ -+static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ unsigned int i2s_reg, reg; -+ unsigned long i2s_value, value; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ i2s_reg = KIRKWOOD_I2S_PLAYCTL; -+ reg = KIRKWOOD_PLAYCTL; -+ } else { -+ i2s_reg = KIRKWOOD_I2S_RECCTL; -+ reg = KIRKWOOD_RECCTL; -+ } -+ -+ /* set dco conf */ -+ kirkwood_set_dco(priv->io, params_rate(params)); -+ -+ i2s_value = readl(priv->io+i2s_reg); -+ i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; -+ -+ value = readl(priv->io+reg); -+ value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK; -+ -+ /* -+ * Size settings in play/rec i2s control regs and play/rec control -+ * regs must be the same. -+ */ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; -+ value |= KIRKWOOD_PLAYCTL_SIZE_16_C; -+ break; -+ /* -+ * doesn't work... S20_3LE != kirkwood 20bit format ? -+ * -+ case SNDRV_PCM_FORMAT_S20_3LE: -+ i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; -+ value |= KIRKWOOD_PLAYCTL_SIZE_20; -+ break; -+ */ -+ case SNDRV_PCM_FORMAT_S24_LE: -+ i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; -+ value |= KIRKWOOD_PLAYCTL_SIZE_24; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; -+ value |= KIRKWOOD_PLAYCTL_SIZE_32; -+ break; -+ default: -+ return -EINVAL; -+ } -+ writel(i2s_value, priv->io+i2s_reg); -+ writel(value, priv->io+reg); -+ -+ return 0; -+} -+ -+static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, -+ int cmd, struct snd_soc_dai *dai) -+{ -+ unsigned long value; -+ -+ /* -+ * specs says KIRKWOOD_PLAYCTL must be read 2 times before -+ * changing it. So read 1 time here and 1 later. -+ */ -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ /* stop audio, enable interrupts */ -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ value |= KIRKWOOD_PLAYCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_PLAYCTL); -+ -+ value = readl(priv->io + KIRKWOOD_INT_MASK); -+ value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; -+ writel(value, priv->io + KIRKWOOD_INT_MASK); -+ -+ /* configure audio & enable i2s playback */ -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ value &= ~KIRKWOOD_PLAYCTL_BURST_MASK; -+ value &= ~(KIRKWOOD_PLAYCTL_PAUSE|KIRKWOOD_PLAYCTL_SPDIF_EN); -+ -+ if (priv->burst == 32) -+ value |= KIRKWOOD_PLAYCTL_BURST_32; -+ else -+ value |= KIRKWOOD_PLAYCTL_BURST_128; -+ value |= KIRKWOOD_PLAYCTL_I2S_EN; -+ writel(value, priv->io + KIRKWOOD_PLAYCTL); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ /* stop audio, disable interrupts */ -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ value |= KIRKWOOD_PLAYCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_PLAYCTL); -+ -+ value = readl(priv->io + KIRKWOOD_INT_MASK); -+ value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES; -+ writel(value, priv->io + KIRKWOOD_INT_MASK); -+ -+ /* disable all playbacks */ -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); -+ writel(value, priv->io + KIRKWOOD_PLAYCTL); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ value |= KIRKWOOD_PLAYCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_PLAYCTL); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_RESUME: -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ value &= ~KIRKWOOD_PLAYCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_PLAYCTL); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, -+ int cmd, struct snd_soc_dai *dai) -+{ -+ unsigned long value; -+ -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ /* stop audio, enable interrupts */ -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ value |= KIRKWOOD_RECCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_RECCTL); -+ -+ value = readl(priv->io + KIRKWOOD_INT_MASK); -+ value |= KIRKWOOD_INT_CAUSE_REC_BYTES; -+ writel(value, priv->io + KIRKWOOD_INT_MASK); -+ -+ /* configure audio & enable i2s record */ -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ value &= ~KIRKWOOD_RECCTL_BURST_MASK; -+ value &= ~KIRKWOOD_RECCTL_MONO; -+ value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_SPDIF_EN); -+ -+ if (priv->burst == 32) -+ value |= KIRKWOOD_RECCTL_BURST_32; -+ else -+ value |= KIRKWOOD_RECCTL_BURST_128; -+ value |= KIRKWOOD_RECCTL_I2S_EN; -+ -+ writel(value, priv->io + KIRKWOOD_RECCTL); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ /* stop audio, disable interrupts */ -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ value |= KIRKWOOD_RECCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_RECCTL); -+ -+ value = readl(priv->io + KIRKWOOD_INT_MASK); -+ value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES; -+ writel(value, priv->io + KIRKWOOD_INT_MASK); -+ -+ /* disable all records */ -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN); -+ writel(value, priv->io + KIRKWOOD_RECCTL); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ value |= KIRKWOOD_RECCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_RECCTL); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_RESUME: -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ value &= ~KIRKWOOD_RECCTL_PAUSE; -+ writel(value, priv->io + KIRKWOOD_RECCTL); -+ break; -+ -+ default: -+ return -EINVAL; -+ break; -+ } -+ -+ return 0; -+} -+ -+static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd, -+ struct snd_soc_dai *dai) -+{ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ return kirkwood_i2s_play_trigger(substream, cmd, dai); -+ else -+ return kirkwood_i2s_rec_trigger(substream, cmd, dai); -+ -+ return 0; -+} -+ -+static int kirkwood_i2s_probe(struct platform_device *pdev, -+ struct snd_soc_dai *dai) -+{ -+ unsigned long value; -+ unsigned int reg_data; -+ -+ /* put system in a "safe" state : */ -+ /* disable audio interrupts */ -+ writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE); -+ writel(0, priv->io + KIRKWOOD_INT_MASK); -+ -+ reg_data = readl(priv->io + 0x1200); -+ reg_data &= (~(0x333FF8)); -+ reg_data |= 0x111D18; -+ writel(reg_data, priv->io + 0x1200); -+ -+ msleep(500); -+ -+ reg_data = readl(priv->io + 0x1200); -+ reg_data &= (~(0x333FF8)); -+ reg_data |= 0x111D18; -+ writel(reg_data, priv->io + 0x1200); -+ -+ /* disable playback/record */ -+ value = readl(priv->io + KIRKWOOD_PLAYCTL); -+ value &= ~(KIRKWOOD_PLAYCTL_I2S_EN|KIRKWOOD_PLAYCTL_SPDIF_EN); -+ writel(value, priv->io + KIRKWOOD_PLAYCTL); -+ -+ value = readl(priv->io + KIRKWOOD_RECCTL); -+ value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN); -+ writel(value, priv->io + KIRKWOOD_RECCTL); -+ -+ return 0; -+ -+} -+ -+static void kirkwood_i2s_remove(struct platform_device *pdev, -+ struct snd_soc_dai *dai) -+{ -+} -+ -+static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = { -+ .trigger = kirkwood_i2s_trigger, -+ .hw_params = kirkwood_i2s_hw_params, -+ .set_fmt = kirkwood_i2s_set_fmt, -+}; -+ -+ -+struct snd_soc_dai kirkwood_i2s_dai = { -+ .name = DRV_NAME, -+ .id = 0, -+ .probe = kirkwood_i2s_probe, -+ .remove = kirkwood_i2s_remove, -+ .playback = { -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = KIRKWOOD_I2S_RATES, -+ .formats = KIRKWOOD_I2S_FORMATS,}, -+ .capture = { -+ .channels_min = 1, -+ .channels_max = 2, -+ .rates = KIRKWOOD_I2S_RATES, -+ .formats = KIRKWOOD_I2S_FORMATS,}, -+ .ops = &kirkwood_i2s_dai_ops, -+}; -+EXPORT_SYMBOL_GPL(kirkwood_i2s_dai); -+ -+static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) -+{ -+ struct resource *mem; -+ struct kirkwood_asoc_platform_data *data = -+ pdev->dev.platform_data; -+ int err; -+ -+ priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL); -+ if (!priv) { -+ dev_err(&pdev->dev, "allocation failed\n"); -+ err = -ENOMEM; -+ goto error; -+ } -+ -+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!mem) { -+ dev_err(&pdev->dev, "platform_get_resource failed\n"); -+ err = -ENXIO; -+ goto err_alloc; -+ } -+ -+ priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME); -+ if (!priv->mem) { -+ dev_err(&pdev->dev, "request_mem_region failed\n"); -+ err = -EBUSY; -+ goto error; -+ } -+ -+ priv->io = ioremap(priv->mem->start, SZ_16K); -+ if (!priv->io) { -+ dev_err(&pdev->dev, "ioremap failed\n"); -+ err = -ENOMEM; -+ goto err_iomem; -+ } -+ -+ priv->irq = platform_get_irq(pdev, 0); -+ if (priv->irq <= 0) { -+ dev_err(&pdev->dev, "platform_get_irq failed\n"); -+ err = -ENXIO; -+ goto err_ioremap; -+ } -+ -+ if (!data || !data->dram) { -+ dev_err(&pdev->dev, "no platform data ?!\n"); -+ err = -EINVAL; -+ goto err_ioremap; -+ } -+ -+ priv->dram = data->dram; -+ priv->burst = data->burst; -+ -+ kirkwood_i2s_dai.capture.dma_data = priv; -+ kirkwood_i2s_dai.playback.dma_data = priv; -+ -+ return snd_soc_register_dai(&kirkwood_i2s_dai); -+ -+err_ioremap: -+ iounmap(priv->io); -+err_iomem: -+ release_mem_region(priv->mem->start, SZ_16K); -+err_alloc: -+ kfree(priv); -+error: -+ return err; -+} -+ -+static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev) -+{ -+ if (priv) { -+ iounmap(priv->io); -+ release_mem_region(priv->mem->start, SZ_16K); -+ kfree(priv); -+ } -+ snd_soc_unregister_dai(&kirkwood_i2s_dai); -+ return 0; -+} -+ -+static struct platform_driver kirkwood_i2s_driver = { -+ .probe = kirkwood_i2s_dev_probe, -+ .remove = kirkwood_i2s_dev_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init kirkwood_i2s_init(void) -+{ -+ return platform_driver_register(&kirkwood_i2s_driver); -+} -+module_init(kirkwood_i2s_init); -+ -+static void __exit kirkwood_i2s_exit(void) -+{ -+ platform_driver_unregister(&kirkwood_i2s_driver); -+} -+module_exit(kirkwood_i2s_exit); -+ -+/* Module information */ -+MODULE_AUTHOR("Arnaud Patard, <apatard@mandriva.com>"); -+MODULE_DESCRIPTION("Kirkwood I2S SoC Interface"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:kirkwood-i2s"); -Index: sound-2.6/sound/soc/kirkwood/Makefile -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ sound-2.6/sound/soc/kirkwood/Makefile 2010-05-27 14:09:55.867694480 +0200 -@@ -0,0 +1,6 @@ -+snd-soc-kirkwood-objs := kirkwood-dma.o -+snd-soc-kirkwood-i2s-objs := kirkwood-i2s.o -+ -+obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o -+obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o -+ -Index: sound-2.6/sound/soc/Makefile -=================================================================== ---- sound-2.6.orig/sound/soc/Makefile 2010-05-27 14:09:32.411724822 +0200 -+++ sound-2.6/sound/soc/Makefile 2010-05-27 14:09:55.875714679 +0200 -@@ -10,6 +10,7 @@ obj-$(CONFIG_SND_SOC) += fsl/ - obj-$(CONFIG_SND_SOC) += imx/ - obj-$(CONFIG_SND_SOC) += nuc900/ - obj-$(CONFIG_SND_SOC) += omap/ -+obj-$(CONFIG_SND_SOC) += kirkwood/ - obj-$(CONFIG_SND_SOC) += pxa/ - obj-$(CONFIG_SND_SOC) += s3c24xx/ - obj-$(CONFIG_SND_SOC) += s6000/ -Index: sound-2.6/sound/soc/kirkwood/kirkwood-dma.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ sound-2.6/sound/soc/kirkwood/kirkwood-dma.h 2010-05-27 14:09:55.883714769 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * kirkwood-dma.h -+ * -+ * (c) 2010 Arnaud Patard <apatard@mandriva.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#ifndef _KIRKWOOD_DMA_H -+#define _KIRKWOOD_DMA_H -+ -+extern struct snd_soc_platform kirkwood_soc_platform; -+ -+#endif -Index: sound-2.6/sound/soc/kirkwood/kirkwood-i2s.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ sound-2.6/sound/soc/kirkwood/kirkwood-i2s.h 2010-05-27 14:09:55.891695033 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * kirkwood-i2s.h -+ * -+ * (c) 2010 Arnaud Patard <apatard@mandriva.com> -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#ifndef _KIRKWOOD_I2S_H -+#define _KIRKWOOD_I2S_H -+ -+extern struct snd_soc_dai kirkwood_i2s_dai; -+ -+#endif -Index: sound-2.6/sound/soc/Kconfig -=================================================================== ---- sound-2.6.orig/sound/soc/Kconfig 2010-05-27 14:09:32.303673990 +0200 -+++ sound-2.6/sound/soc/Kconfig 2010-05-27 14:09:55.899714700 +0200 -@@ -32,6 +32,7 @@ source "sound/soc/fsl/Kconfig" - source "sound/soc/imx/Kconfig" - source "sound/soc/nuc900/Kconfig" - source "sound/soc/omap/Kconfig" -+source "sound/soc/kirkwood/Kconfig" - source "sound/soc/pxa/Kconfig" - source "sound/soc/s3c24xx/Kconfig" - source "sound/soc/s6000/Kconfig" +An embedded and charset-unspecified text was scrubbed... +Name: kirkwood_i2s.patch +URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100527/e0e3feaa/attachment.el> diff --git a/a/content_digest b/N1/content_digest index 1679213..6ad9647 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,1125 +1,12 @@ "ref\020100527125737.524554667@mandriva.com\0" - "From\0apatard@mandriva.com\0" + "From\0apatard@mandriva.com (apatard at mandriva.com)\0" "Subject\0[patch 5/6] kirkwood: Add i2s support\0" "Date\0Thu, 27 May 2010 14:57:42 +0200\0" - "To\0alsa-devel@alsa-project.org\0" - "Cc\0nico@fluxnic.net" - broonie@opensource.wolfsonmicro.com - saeed@marvell.com - Arnaud Patard <apatard@mandriva.com> - tbm@cyrius.com - linux-arm-kernel@lists.infradead.org - " lrg@slimlogic.co.uk\0" + "To\0linux-arm-kernel@lists.infradead.org\0" "\00:1\0" - "fn\0kirkwood_i2s.patch\0" "b\0" - "This patch enables support for the i2s controller available on kirkwood platforms\n" - "\n" - "Signed-off-by: Arnaud Patard <apatard@mandriva.com>\n" - "\n" - "Index: sound-2.6/sound/soc/kirkwood/Kconfig\n" - "===================================================================\n" - "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n" - "+++ sound-2.6/sound/soc/kirkwood/Kconfig\t2010-05-27 14:09:55.807674540 +0200\n" - "@@ -0,0 +1,11 @@\n" - "+config SND_KIRKWOOD_SOC\n" - "+\ttristate \"SoC Audio for the Marvell Kirkwood chip\"\n" - "+\tdepends on ARCH_KIRKWOOD\n" - "+\thelp\n" - "+\t Say Y or M if you want to add support for codecs attached to\n" - "+\t the Kirkwood I2S interface. You will also need to select the\n" - "+\t audio interfaces to support below.\n" - "+\n" - "+config SND_KIRKWOOD_SOC_I2S\n" - "+\ttristate\n" - "+\n" - "Index: sound-2.6/sound/soc/kirkwood/kirkwood-dma.c\n" - "===================================================================\n" - "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n" - "+++ sound-2.6/sound/soc/kirkwood/kirkwood-dma.c\t2010-05-27 14:09:55.844174800 +0200\n" - "@@ -0,0 +1,383 @@\n" - "+/*\n" - "+ * kirkwood-dma.c\n" - "+ *\n" - "+ * (c) 2010 Arnaud Patard <apatard@mandriva.com>\n" - "+ *\n" - "+ * This program is free software; you can redistribute it and/or modify it\n" - "+ * under the terms of the GNU General Public License as published by the\n" - "+ * Free Software Foundation; either version 2 of the License, or (at your\n" - "+ * option) any later version.\n" - "+ */\n" - "+\n" - "+#include <linux/init.h>\n" - "+#include <linux/module.h>\n" - "+#include <linux/device.h>\n" - "+#include <linux/io.h>\n" - "+#include <linux/slab.h>\n" - "+#include <linux/interrupt.h>\n" - "+#include <linux/dma-mapping.h>\n" - "+#include <linux/mbus.h>\n" - "+#include <sound/soc.h>\n" - "+#include \"kirkwood-dma.h\"\n" - "+#include \"kirkwood.h\"\n" - "+\n" - "+#define KIRKWOOD_RATES \\\n" - "+\t(SNDRV_PCM_RATE_44100 | \\\n" - "+\t SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)\n" - "+#define KIRKWOOD_FORMATS \\\n" - "+\t(SNDRV_PCM_FMTBIT_S16_LE | \\\n" - "+\t SNDRV_PCM_FMTBIT_S24_LE | \\\n" - "+\t SNDRV_PCM_FMTBIT_S32_LE)\n" - "+\n" - "+struct kirkwood_dma_priv {\n" - "+\tstruct snd_pcm_substream *play_stream;\n" - "+\tstruct snd_pcm_substream *rec_stream;\n" - "+\tstruct kirkwood_dma_data *data;\n" - "+};\n" - "+\n" - "+static struct snd_pcm_hardware kirkwood_dma_snd_hw = {\n" - "+\t.info = (SNDRV_PCM_INFO_INTERLEAVED |\n" - "+\t\t SNDRV_PCM_INFO_MMAP |\n" - "+\t\t SNDRV_PCM_INFO_MMAP_VALID |\n" - "+\t\t SNDRV_PCM_INFO_BLOCK_TRANSFER |\n" - "+\t\t SNDRV_PCM_INFO_PAUSE),\n" - "+\t.formats\t\t= KIRKWOOD_FORMATS,\n" - "+\t.rates\t\t\t= KIRKWOOD_RATES,\n" - "+\t.rate_min\t\t= 44100,\n" - "+\t.rate_max\t\t= 96000,\n" - "+\t.channels_min\t\t= 1,\n" - "+\t.channels_max\t\t= 2,\n" - "+\t.buffer_bytes_max\t= KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS,\n" - "+\t.period_bytes_min\t= KIRKWOOD_SND_MIN_PERIOD_BYTES,\n" - "+\t.period_bytes_max\t= KIRKWOOD_SND_MAX_PERIOD_BYTES,\n" - "+\t.periods_min\t\t= KIRKWOOD_SND_MIN_PERIODS,\n" - "+\t.periods_max\t\t= KIRKWOOD_SND_MAX_PERIODS,\n" - "+\t.fifo_size\t\t= 0,\n" - "+};\n" - "+\n" - "+static u64 kirkwood_dma_dmamask = 0xFFFFFFFFUL;\n" - "+\n" - "+static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)\n" - "+{\n" - "+\tstruct kirkwood_dma_priv *prdata = dev_id;\n" - "+\tstruct kirkwood_dma_data *priv = prdata->data;\n" - "+\tunsigned long mask, status, cause;\n" - "+\n" - "+\tmask = readl(priv->io + KIRKWOOD_INT_MASK);\n" - "+\tstatus = readl(priv->io + KIRKWOOD_INT_CAUSE) & mask;\n" - "+\n" - "+\tcause = readl(priv->io + KIRKWOOD_ERR_CAUSE);\n" - "+\tif (unlikely(cause)) {\n" - "+\t\tprintk(KERN_WARNING \"%s: got err interrupt 0x%lx\\n\",\n" - "+\t\t\t\t__func__, cause);\n" - "+\t\twritel(cause, priv->io + KIRKWOOD_ERR_CAUSE);\n" - "+\t\treturn IRQ_HANDLED;\n" - "+\t}\n" - "+\n" - "+\t/* we've enabled only bytes interrupts ... */\n" - "+\tif (status & ~(KIRKWOOD_INT_CAUSE_PLAY_BYTES | \\\n" - "+\t\t\tKIRKWOOD_INT_CAUSE_REC_BYTES)) {\n" - "+\t\tprintk(KERN_WARNING \"%s: unexpected interrupt %lx\\n\",\n" - "+\t\t\t__func__, status);\n" - "+\t\treturn IRQ_NONE;\n" - "+\t}\n" - "+\n" - "+\t/* ack int */\n" - "+\twritel(status, priv->io + KIRKWOOD_INT_CAUSE);\n" - "+\n" - "+\tif (status & KIRKWOOD_INT_CAUSE_PLAY_BYTES)\n" - "+\t\tsnd_pcm_period_elapsed(prdata->play_stream);\n" - "+\n" - "+\tif (status & KIRKWOOD_INT_CAUSE_REC_BYTES)\n" - "+\t\tsnd_pcm_period_elapsed(prdata->rec_stream);\n" - "+\n" - "+\treturn IRQ_HANDLED;\n" - "+}\n" - "+\n" - "+static void kirkwood_dma_conf_mbus_windows(void __iomem *base, int win,\n" - "+\t\t\t\t\tunsigned long dma,\n" - "+\t\t\t\t\tstruct mbus_dram_target_info *dram)\n" - "+{\n" - "+\tint i;\n" - "+\n" - "+\t/* First disable and clear windows */\n" - "+\twritel(0, base + KIRKWOOD_AUDIO_WIN_CTRL_REG(win));\n" - "+\twritel(0, base + KIRKWOOD_AUDIO_WIN_BASE_REG(win));\n" - "+\n" - "+\t/* try to find matching cs for current dma address */\n" - "+\tfor (i = 0; i < dram->num_cs; i++) {\n" - "+\t\tstruct mbus_dram_window *cs = dram->cs + i;\n" - "+\t\tif ((cs->base & 0xffff0000) < (dma & 0xffff0000)) {\n" - "+\t\t\twritel(cs->base & 0xffff0000,\n" - "+\t\t\t\tbase + KIRKWOOD_AUDIO_WIN_BASE_REG(win));\n" - "+\t\t\twritel(((cs->size - 1) & 0xffff0000) |\n" - "+\t\t\t\t(cs->mbus_attr << 8) |\n" - "+\t\t\t\t(dram->mbus_dram_target_id << 4) | 1,\n" - "+\t\t\t\tbase + KIRKWOOD_AUDIO_WIN_CTRL_REG(win));\n" - "+\t\t}\n" - "+\t}\n" - "+}\n" - "+\n" - "+static int kirkwood_dma_open(struct snd_pcm_substream *substream)\n" - "+{\n" - "+\tint err;\n" - "+\tstruct snd_pcm_runtime *runtime = substream->runtime;\n" - "+\tstruct snd_soc_pcm_runtime *soc_runtime = substream->private_data;\n" - "+\tstruct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;\n" - "+\tstruct kirkwood_dma_data *priv;\n" - "+\tstruct kirkwood_dma_priv *prdata = cpu_dai->private_data;\n" - "+\tunsigned long addr;\n" - "+\n" - "+\tpriv = snd_soc_dai_get_dma_data(cpu_dai, substream);\n" - "+\tsnd_soc_set_runtime_hwparams(substream, &kirkwood_dma_snd_hw);\n" - "+\n" - "+\t/* Ensure that all constraints linked to dma burst are fullfilled */\n" - "+\terr = snd_pcm_hw_constraint_minmax(runtime,\n" - "+\t\t\tSNDRV_PCM_HW_PARAM_BUFFER_BYTES,\n" - "+\t\t\tpriv->burst * 2,\n" - "+\t\t\tKIRKWOOD_AUDIO_BUF_MAX-1);\n" - "+\tif (err < 0)\n" - "+\t\treturn err;\n" - "+\n" - "+\terr = snd_pcm_hw_constraint_step(runtime, 0,\n" - "+\t\t\tSNDRV_PCM_HW_PARAM_BUFFER_BYTES,\n" - "+\t\t\tpriv->burst);\n" - "+\tif (err < 0)\n" - "+\t\treturn err;\n" - "+\n" - "+\terr = snd_pcm_hw_constraint_step(substream->runtime, 0,\n" - "+\t\t\t SNDRV_PCM_HW_PARAM_PERIOD_BYTES,\n" - "+\t\t\t priv->burst);\n" - "+\tif (err < 0)\n" - "+\t\treturn err;\n" - "+\n" - "+\tif (soc_runtime->dai->cpu_dai->private_data == NULL) {\n" - "+\t\tprdata = kzalloc(sizeof(struct kirkwood_dma_priv), GFP_KERNEL);\n" - "+\t\tif (prdata == NULL)\n" - "+\t\t\treturn -ENOMEM;\n" - "+\n" - "+\t\tprdata->data = priv;\n" - "+\n" - "+\t\terr = request_irq(priv->irq, kirkwood_dma_irq, IRQF_SHARED,\n" - "+\t\t\t\t \"kirkwood-i2s\", prdata);\n" - "+\t\tif (err) {\n" - "+\t\t\tkfree(prdata);\n" - "+\t\t\treturn -EBUSY;\n" - "+\t\t}\n" - "+\n" - "+\t\tsoc_runtime->dai->cpu_dai->private_data = prdata;\n" - "+\n" - "+\t\t/*\n" - "+\t\t * Enable Error interrupts. We're only ack'ing them but\n" - "+\t\t * it's usefull for diagnostics\n" - "+\t\t */\n" - "+\t\twritel((unsigned long)-1, priv->io + KIRKWOOD_ERR_MASK);\n" - "+\t}\n" - "+\n" - "+\taddr = virt_to_phys(substream->dma_buffer.area);\n" - "+\tif (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {\n" - "+\t\tprdata->play_stream = substream;\n" - "+\t\tkirkwood_dma_conf_mbus_windows(priv->io,\n" - "+\t\t\tKIRKWOOD_PLAYBACK_WIN, addr, priv->dram);\n" - "+\t} else {\n" - "+\t\tprdata->rec_stream = substream;\n" - "+\t\tkirkwood_dma_conf_mbus_windows(priv->io,\n" - "+\t\t\tKIRKWOOD_RECORD_WIN, addr, priv->dram);\n" - "+\t}\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_dma_close(struct snd_pcm_substream *substream)\n" - "+{\n" - "+\tstruct snd_soc_pcm_runtime *soc_runtime = substream->private_data;\n" - "+\tstruct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;\n" - "+\tstruct kirkwood_dma_priv *prdata = cpu_dai->private_data;\n" - "+\tstruct kirkwood_dma_data *priv;\n" - "+\n" - "+\tpriv = snd_soc_dai_get_dma_data(cpu_dai, substream);\n" - "+\n" - "+\tif (!prdata || !priv)\n" - "+\t\treturn 0;\n" - "+\n" - "+\tif (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)\n" - "+\t\tprdata->play_stream = NULL;\n" - "+\telse\n" - "+\t\tprdata->rec_stream = NULL;\n" - "+\n" - "+\tif (!prdata->play_stream && !prdata->rec_stream) {\n" - "+\t\twritel(0, priv->io + KIRKWOOD_ERR_MASK);\n" - "+\t\tfree_irq(priv->irq, prdata);\n" - "+\t\tkfree(prdata);\n" - "+\t\tsoc_runtime->dai->cpu_dai->private_data = NULL;\n" - "+\t}\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_dma_hw_params(struct snd_pcm_substream *substream,\n" - "+\t\t\t\tstruct snd_pcm_hw_params *params)\n" - "+{\n" - "+\tstruct snd_pcm_runtime *runtime = substream->runtime;\n" - "+\n" - "+\tsnd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);\n" - "+\truntime->dma_bytes = params_buffer_bytes(params);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_dma_hw_free(struct snd_pcm_substream *substream)\n" - "+{\n" - "+\tsnd_pcm_set_runtime_buffer(substream, NULL);\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_dma_prepare(struct snd_pcm_substream *substream)\n" - "+{\n" - "+\tstruct snd_pcm_runtime *runtime = substream->runtime;\n" - "+\tstruct snd_soc_pcm_runtime *soc_runtime = substream->private_data;\n" - "+\tstruct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;\n" - "+\tstruct kirkwood_dma_data *priv;\n" - "+\tunsigned long size, count;\n" - "+\n" - "+\tpriv = snd_soc_dai_get_dma_data(cpu_dai, substream);\n" - "+\n" - "+\t/* compute buffer size in term of \"words\" as requested in specs */\n" - "+\tsize = frames_to_bytes(runtime, runtime->buffer_size);\n" - "+\tsize = (size>>2)-1;\n" - "+\tcount = snd_pcm_lib_period_bytes(substream);\n" - "+\n" - "+\tif (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {\n" - "+\t\twritel(count, priv->io + KIRKWOOD_PLAY_BYTE_INT_COUNT);\n" - "+\t\twritel(runtime->dma_addr, priv->io + KIRKWOOD_PLAY_BUF_ADDR);\n" - "+\t\twritel(size, priv->io + KIRKWOOD_PLAY_BUF_SIZE);\n" - "+\t} else {\n" - "+\t\twritel(count, priv->io + KIRKWOOD_REC_BYTE_INT_COUNT);\n" - "+\t\twritel(runtime->dma_addr, priv->io + KIRKWOOD_REC_BUF_ADDR);\n" - "+\t\twritel(size, priv->io + KIRKWOOD_REC_BUF_SIZE);\n" - "+\t}\n" - "+\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream\n" - "+\t\t\t\t\t\t*substream)\n" - "+{\n" - "+\tstruct snd_soc_pcm_runtime *soc_runtime = substream->private_data;\n" - "+\tstruct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai;\n" - "+\tstruct kirkwood_dma_data *priv;\n" - "+\tsnd_pcm_uframes_t count;\n" - "+\n" - "+\tpriv = snd_soc_dai_get_dma_data(cpu_dai, substream);\n" - "+\n" - "+\tif (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)\n" - "+\t\tcount = bytes_to_frames(substream->runtime,\n" - "+\t\t\treadl(priv->io + KIRKWOOD_PLAY_BYTE_COUNT));\n" - "+\telse\n" - "+\t\tcount = bytes_to_frames(substream->runtime,\n" - "+\t\t\treadl(priv->io + KIRKWOOD_REC_BYTE_COUNT));\n" - "+\n" - "+\treturn count;\n" - "+}\n" - "+\n" - "+struct snd_pcm_ops kirkwood_dma_ops = {\n" - "+\t.open =\t\tkirkwood_dma_open,\n" - "+\t.close = kirkwood_dma_close,\n" - "+\t.ioctl =\tsnd_pcm_lib_ioctl,\n" - "+\t.hw_params =\tkirkwood_dma_hw_params,\n" - "+\t.hw_free = kirkwood_dma_hw_free,\n" - "+\t.prepare = kirkwood_dma_prepare,\n" - "+\t.pointer =\tkirkwood_dma_pointer,\n" - "+};\n" - "+\n" - "+static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm,\n" - "+\t\tint stream)\n" - "+{\n" - "+\tstruct snd_pcm_substream *substream = pcm->streams[stream].substream;\n" - "+\tstruct snd_dma_buffer *buf = &substream->dma_buffer;\n" - "+\tsize_t size = kirkwood_dma_snd_hw.buffer_bytes_max;\n" - "+\n" - "+\tbuf->dev.type = SNDRV_DMA_TYPE_DEV;\n" - "+\tbuf->dev.dev = pcm->card->dev;\n" - "+\tbuf->area = dma_alloc_coherent(pcm->card->dev, size,\n" - "+\t\t\t&buf->addr, GFP_KERNEL);\n" - "+\tif (!buf->area)\n" - "+\t\treturn -ENOMEM;\n" - "+\tbuf->bytes = size;\n" - "+\tbuf->private_data = NULL;\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_dma_new(struct snd_card *card,\n" - "+\t\tstruct snd_soc_dai *dai, struct snd_pcm *pcm)\n" - "+{\n" - "+\tint ret;\n" - "+\n" - "+\tif (!card->dev->dma_mask)\n" - "+\t\tcard->dev->dma_mask = &kirkwood_dma_dmamask;\n" - "+\tif (!card->dev->coherent_dma_mask)\n" - "+\t\tcard->dev->coherent_dma_mask = 0xffffffff;\n" - "+\n" - "+\tif (dai->playback.channels_min) {\n" - "+\t\tret = kirkwood_dma_preallocate_dma_buffer(pcm,\n" - "+\t\t\t\tSNDRV_PCM_STREAM_PLAYBACK);\n" - "+\t\tif (ret)\n" - "+\t\t\treturn ret;\n" - "+\t}\n" - "+\n" - "+\tif (dai->capture.channels_min) {\n" - "+\t\tret = kirkwood_dma_preallocate_dma_buffer(pcm,\n" - "+\t\t\t\tSNDRV_PCM_STREAM_CAPTURE);\n" - "+\t\tif (ret)\n" - "+\t\t\treturn ret;\n" - "+\t}\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm)\n" - "+{\n" - "+\tstruct snd_pcm_substream *substream;\n" - "+\tstruct snd_dma_buffer *buf;\n" - "+\tint stream;\n" - "+\n" - "+\tfor (stream = 0; stream < 2; stream++) {\n" - "+\t\tsubstream = pcm->streams[stream].substream;\n" - "+\t\tif (!substream)\n" - "+\t\t\tcontinue;\n" - "+\t\tbuf = &substream->dma_buffer;\n" - "+\t\tif (!buf->area)\n" - "+\t\t\tcontinue;\n" - "+\n" - "+\t\tdma_free_coherent(pcm->card->dev, buf->bytes,\n" - "+\t\t\t\tbuf->area, buf->addr);\n" - "+\t\tbuf->area = NULL;\n" - "+\t}\n" - "+}\n" - "+\n" - "+struct snd_soc_platform kirkwood_soc_platform = {\n" - "+\t.name\t\t= \"kirkwood-dma\",\n" - "+\t.pcm_ops\t= &kirkwood_dma_ops,\n" - "+\t.pcm_new\t= kirkwood_dma_new,\n" - "+\t.pcm_free\t= kirkwood_dma_free_dma_buffers,\n" - "+};\n" - "+EXPORT_SYMBOL_GPL(kirkwood_soc_platform);\n" - "+\n" - "+static int __init kirkwood_soc_platform_init(void)\n" - "+{\n" - "+\treturn snd_soc_register_platform(&kirkwood_soc_platform);\n" - "+}\n" - "+module_init(kirkwood_soc_platform_init);\n" - "+\n" - "+static void __exit kirkwood_soc_platform_exit(void)\n" - "+{\n" - "+\tsnd_soc_unregister_platform(&kirkwood_soc_platform);\n" - "+}\n" - "+module_exit(kirkwood_soc_platform_exit);\n" - "+\n" - "+MODULE_AUTHOR(\"Arnaud Patard <apatard@mandriva.com>\");\n" - "+MODULE_DESCRIPTION(\"Marvell Kirkwood Audio DMA module\");\n" - "+MODULE_LICENSE(\"GPL\");\n" - "+\n" - "Index: sound-2.6/sound/soc/kirkwood/kirkwood.h\n" - "===================================================================\n" - "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n" - "+++ sound-2.6/sound/soc/kirkwood/kirkwood.h\t2010-05-27 14:09:55.851714894 +0200\n" - "@@ -0,0 +1,126 @@\n" - "+/*\n" - "+ * kirkwood.h\n" - "+ *\n" - "+ * (c) 2010 Arnaud Patard <apatard@mandriva.com>\n" - "+ *\n" - "+ * This program is free software; you can redistribute it and/or modify it\n" - "+ * under the terms of the GNU General Public License as published by the\n" - "+ * Free Software Foundation; either version 2 of the License, or (at your\n" - "+ * option) any later version.\n" - "+ */\n" - "+\n" - "+#ifndef _KIRKWOOD_AUDIO_H\n" - "+#define _KIRKWOOD_AUDIO_H\n" - "+\n" - "+#define KIRKWOOD_RECORD_WIN\t\t\t0\n" - "+#define KIRKWOOD_PLAYBACK_WIN\t\t\t1\n" - "+#define KIRKWOOD_MAX_AUDIO_WIN\t\t\t2\n" - "+\n" - "+#define KIRKWOOD_AUDIO_WIN_BASE_REG(win)\t(0xA00 + ((win)<<3))\n" - "+#define KIRKWOOD_AUDIO_WIN_CTRL_REG(win)\t(0xA04 + ((win)<<3))\n" - "+\n" - "+\n" - "+#define KIRKWOOD_RECCTL\t\t\t0x1000\n" - "+#define KIRKWOOD_RECCTL_SPDIF_EN\t\t(1<<11)\n" - "+#define KIRKWOOD_RECCTL_I2S_EN\t\t\t(1<<10)\n" - "+#define KIRKWOOD_RECCTL_PAUSE\t\t\t(1<<9)\n" - "+#define KIRKWOOD_RECCTL_MUTE\t\t\t(1<<8)\n" - "+#define KIRKWOOD_RECCTL_BURST_MASK\t\t(3<<5)\n" - "+#define KIRKWOOD_RECCTL_BURST_128\t\t(2<<5)\n" - "+#define KIRKWOOD_RECCTL_BURST_32\t\t(1<<5)\n" - "+#define KIRKWOOD_RECCTL_MONO\t\t\t(1<<4)\n" - "+#define KIRKWOOD_RECCTL_MONO_CHAN_RIGHT\t(1<<3)\n" - "+#define KIRKWOOD_RECCTL_MONO_CHAN_LEFT\t\t(0<<3)\n" - "+#define KIRKWOOD_RECCTL_SIZE_MASK\t\t(7<<0)\n" - "+#define KIRKWOOD_RECCTL_SIZE_16\t\t(7<<0)\n" - "+#define KIRKWOOD_RECCTL_SIZE_16_C\t\t(3<<0)\n" - "+#define KIRKWOOD_RECCTL_SIZE_20\t\t(2<<0)\n" - "+#define KIRKWOOD_RECCTL_SIZE_24\t\t(1<<0)\n" - "+#define KIRKWOOD_RECCTL_SIZE_32\t\t(0<<0)\n" - "+\n" - "+#define KIRKWOOD_REC_BUF_ADDR\t\t\t0x1004\n" - "+#define KIRKWOOD_REC_BUF_SIZE\t\t\t0x1008\n" - "+#define KIRKWOOD_REC_BYTE_COUNT\t\t\t0x100C\n" - "+\n" - "+#define KIRKWOOD_PLAYCTL\t\t\t0x1100\n" - "+#define KIRKWOOD_PLAYCTL_PLAY_BUSY\t\t(1<<16)\n" - "+#define KIRKWOOD_PLAYCTL_BURST_MASK\t\t(3<<11)\n" - "+#define KIRKWOOD_PLAYCTL_BURST_128\t\t(2<<11)\n" - "+#define KIRKWOOD_PLAYCTL_BURST_32\t\t(1<<11)\n" - "+#define KIRKWOOD_PLAYCTL_PAUSE\t\t\t(1<<9)\n" - "+#define KIRKWOOD_PLAYCTL_SPDIF_MUTE\t\t(1<<8)\n" - "+#define KIRKWOOD_PLAYCTL_I2S_MUTE\t\t(1<<7)\n" - "+#define KIRKWOOD_PLAYCTL_SPDIF_EN\t\t(1<<4)\n" - "+#define KIRKWOOD_PLAYCTL_I2S_EN\t\t(1<<3)\n" - "+#define KIRKWOOD_PLAYCTL_SIZE_MASK\t\t(7<<0)\n" - "+#define KIRKWOOD_PLAYCTL_SIZE_16\t\t(7<<0)\n" - "+#define KIRKWOOD_PLAYCTL_SIZE_16_C\t\t(3<<0)\n" - "+#define KIRKWOOD_PLAYCTL_SIZE_20\t\t(2<<0)\n" - "+#define KIRKWOOD_PLAYCTL_SIZE_24\t\t(1<<0)\n" - "+#define KIRKWOOD_PLAYCTL_SIZE_32\t\t(0<<0)\n" - "+\n" - "+#define KIRKWOOD_PLAY_BUF_ADDR\t\t\t0x1104\n" - "+#define KIRKWOOD_PLAY_BUF_SIZE\t\t\t0x1108\n" - "+#define KIRKWOOD_PLAY_BYTE_COUNT\t\t0x110C\n" - "+\n" - "+#define KIRKWOOD_DCO_CTL\t\t\t0x1204\n" - "+#define KIRKWOOD_DCO_CTL_OFFSET_MASK\t\t(0xFFF<<2)\n" - "+#define KIRKWOOD_DCO_CTL_OFFSET_0\t\t(0x800<<2)\n" - "+#define KIRKWOOD_DCO_CTL_FREQ_MASK\t\t(3<<0)\n" - "+#define KIRKWOOD_DCO_CTL_FREQ_11\t\t(0<<0)\n" - "+#define KIRKWOOD_DCO_CTL_FREQ_12\t\t(1<<0)\n" - "+#define KIRKWOOD_DCO_CTL_FREQ_24\t\t(2<<0)\n" - "+\n" - "+#define KIRKWOOD_DCO_SPCR_STATUS\t\t0x120c\n" - "+#define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK\t(1<<16)\n" - "+\n" - "+#define KIRKWOOD_ERR_CAUSE\t\t\t0x1300\n" - "+#define KIRKWOOD_ERR_MASK\t\t\t0x1304\n" - "+\n" - "+#define KIRKWOOD_INT_CAUSE\t\t\t0x1308\n" - "+#define KIRKWOOD_INT_MASK\t\t\t0x130C\n" - "+#define KIRKWOOD_INT_CAUSE_PLAY_BYTES\t\t(1<<14)\n" - "+#define KIRKWOOD_INT_CAUSE_REC_BYTES\t\t(1<<13)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_END\t(1<<7)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_3Q\t\t(1<<6)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_HALF\t(1<<5)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_PLAY_1Q\t\t(1<<4)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_REC_END\t\t(1<<3)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_REC_3Q\t\t(1<<2)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_REC_HALF\t(1<<1)\n" - "+#define KIRKWOOD_INT_CAUSE_DMA_REC_1Q\t\t(1<<0)\n" - "+\n" - "+#define KIRKWOOD_REC_BYTE_INT_COUNT\t\t0x1310\n" - "+#define KIRKWOOD_PLAY_BYTE_INT_COUNT\t\t0x1314\n" - "+#define KIRKWOOD_BYTE_INT_COUNT_MASK\t\t0xffffff\n" - "+\n" - "+#define KIRKWOOD_I2S_PLAYCTL\t\t\t0x2508\n" - "+#define KIRKWOOD_I2S_RECCTL\t\t\t0x2408\n" - "+#define KIRKWOOD_I2S_CTL_JUST_MASK\t\t(0xf<<26)\n" - "+#define KIRKWOOD_I2S_CTL_LJ\t\t\t(0<<26)\n" - "+#define KIRKWOOD_I2S_CTL_I2S\t\t\t(5<<26)\n" - "+#define KIRKWOOD_I2S_CTL_RJ\t\t\t(8<<26)\n" - "+#define KIRKWOOD_I2S_CTL_SIZE_MASK\t\t(3<<30)\n" - "+#define KIRKWOOD_I2S_CTL_SIZE_16\t\t(3<<30)\n" - "+#define KIRKWOOD_I2S_CTL_SIZE_20\t\t(2<<30)\n" - "+#define KIRKWOOD_I2S_CTL_SIZE_24\t\t(1<<30)\n" - "+#define KIRKWOOD_I2S_CTL_SIZE_32\t\t(0<<30)\n" - "+\n" - "+#define KIRKWOOD_AUDIO_BUF_MAX\t\t\t(16*1024*1024)\n" - "+\n" - "+/* Theses values come from the marvell alsa driver */\n" - "+/* need to find where they come from */\n" - "+#define KIRKWOOD_SND_MIN_PERIODS\t\t8\n" - "+#define KIRKWOOD_SND_MAX_PERIODS\t\t16\n" - "+#define KIRKWOOD_SND_MIN_PERIOD_BYTES\t\t0x4000\n" - "+#define KIRKWOOD_SND_MAX_PERIOD_BYTES\t\t0x4000\n" - "+\n" - "+struct kirkwood_dma_data {\n" - "+\tstruct resource *mem;\n" - "+\tvoid __iomem *io;\n" - "+\tint irq;\n" - "+\tint burst;\n" - "+\tstruct mbus_dram_target_info *dram;\n" - "+};\n" - "+\n" - "+#endif\n" - "Index: sound-2.6/sound/soc/kirkwood/kirkwood-i2s.c\n" - "===================================================================\n" - "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n" - "+++ sound-2.6/sound/soc/kirkwood/kirkwood-i2s.c\t2010-05-27 14:09:55.859694735 +0200\n" - "@@ -0,0 +1,485 @@\n" - "+/*\n" - "+ * kirkwood-i2s.c\n" - "+ *\n" - "+ * (c) 2010 Arnaud Patard <apatard@mandriva.com>\n" - "+ *\n" - "+ * This program is free software; you can redistribute it and/or modify it\n" - "+ * under the terms of the GNU General Public License as published by the\n" - "+ * Free Software Foundation; either version 2 of the License, or (at your\n" - "+ * option) any later version.\n" - "+ */\n" - "+\n" - "+#include <linux/init.h>\n" - "+#include <linux/module.h>\n" - "+#include <linux/platform_device.h>\n" - "+#include <linux/io.h>\n" - "+#include <linux/slab.h>\n" - "+#include <linux/mbus.h>\n" - "+#include <linux/delay.h>\n" - "+#include <sound/pcm.h>\n" - "+#include <sound/pcm_params.h>\n" - "+#include <sound/soc.h>\n" - "+#include <plat/audio.h>\n" - "+#include \"kirkwood-i2s.h\"\n" - "+#include \"kirkwood.h\"\n" - "+\n" - "+#define DRV_NAME\t\"kirkwood-i2s\"\n" - "+\n" - "+#define KIRKWOOD_I2S_RATES \\\n" - "+\t(SNDRV_PCM_RATE_44100 | \\\n" - "+\t SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)\n" - "+#define KIRKWOOD_I2S_FORMATS \\\n" - "+\t(SNDRV_PCM_FMTBIT_S16_LE | \\\n" - "+\t SNDRV_PCM_FMTBIT_S24_LE | \\\n" - "+\t SNDRV_PCM_FMTBIT_S32_LE)\n" - "+\n" - "+\n" - "+struct snd_soc_dai kirkwood_i2s_dai;\n" - "+static struct kirkwood_dma_data *priv;\n" - "+\n" - "+static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,\n" - "+\t\tunsigned int fmt)\n" - "+{\n" - "+\tunsigned long mask;\n" - "+\tunsigned long value;\n" - "+\n" - "+\tswitch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {\n" - "+\tcase SND_SOC_DAIFMT_RIGHT_J:\n" - "+\t\tmask = KIRKWOOD_I2S_CTL_RJ;\n" - "+\t\tbreak;\n" - "+\tcase SND_SOC_DAIFMT_LEFT_J:\n" - "+\t\tmask = KIRKWOOD_I2S_CTL_LJ;\n" - "+\t\tbreak;\n" - "+\tcase SND_SOC_DAIFMT_I2S:\n" - "+\t\tmask = KIRKWOOD_I2S_CTL_I2S;\n" - "+\t\tbreak;\n" - "+\tdefault:\n" - "+\t\treturn -EINVAL;\n" - "+\t}\n" - "+\n" - "+\t/*\n" - "+\t * Set same format for playback and record\n" - "+\t * This avoids some troubles.\n" - "+\t */\n" - "+\tvalue = readl(priv->io+KIRKWOOD_I2S_PLAYCTL);\n" - "+\tvalue &= ~KIRKWOOD_I2S_CTL_JUST_MASK;\n" - "+\tvalue |= mask;\n" - "+\twritel(value, priv->io+KIRKWOOD_I2S_PLAYCTL);\n" - "+\n" - "+\tvalue = readl(priv->io+KIRKWOOD_I2S_RECCTL);\n" - "+\tvalue &= ~KIRKWOOD_I2S_CTL_JUST_MASK;\n" - "+\tvalue |= mask;\n" - "+\twritel(value, priv->io+KIRKWOOD_I2S_RECCTL);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)\n" - "+{\n" - "+\tunsigned long value;\n" - "+\n" - "+\tvalue = KIRKWOOD_DCO_CTL_OFFSET_0;\n" - "+\tswitch (rate) {\n" - "+\tdefault:\n" - "+\tcase 44100:\n" - "+\t\tvalue |= KIRKWOOD_DCO_CTL_FREQ_11;\n" - "+\t\tbreak;\n" - "+\tcase 48000:\n" - "+\t\tvalue |= KIRKWOOD_DCO_CTL_FREQ_12;\n" - "+\t\tbreak;\n" - "+\tcase 96000:\n" - "+\t\tvalue |= KIRKWOOD_DCO_CTL_FREQ_24;\n" - "+\t\tbreak;\n" - "+\t}\n" - "+\twritel(value, io + KIRKWOOD_DCO_CTL);\n" - "+\n" - "+\t/* wait for dco locked */\n" - "+\tdo {\n" - "+\t\tcpu_relax();\n" - "+\t\tvalue = readl(io + KIRKWOOD_DCO_SPCR_STATUS);\n" - "+\t\tvalue &= KIRKWOOD_DCO_SPCR_STATUS;\n" - "+\t} while (value == 0);\n" - "+}\n" - "+\n" - "+static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,\n" - "+\t\t\t\t struct snd_pcm_hw_params *params,\n" - "+\t\t\t\t struct snd_soc_dai *dai)\n" - "+{\n" - "+\tunsigned int i2s_reg, reg;\n" - "+\tunsigned long i2s_value, value;\n" - "+\n" - "+\tif (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {\n" - "+\t\ti2s_reg = KIRKWOOD_I2S_PLAYCTL;\n" - "+\t\treg = KIRKWOOD_PLAYCTL;\n" - "+\t} else {\n" - "+\t\ti2s_reg = KIRKWOOD_I2S_RECCTL;\n" - "+\t\treg = KIRKWOOD_RECCTL;\n" - "+\t}\n" - "+\n" - "+\t/* set dco conf */\n" - "+\tkirkwood_set_dco(priv->io, params_rate(params));\n" - "+\n" - "+\ti2s_value = readl(priv->io+i2s_reg);\n" - "+\ti2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;\n" - "+\n" - "+\tvalue = readl(priv->io+reg);\n" - "+\tvalue &= ~KIRKWOOD_PLAYCTL_SIZE_MASK;\n" - "+\n" - "+\t/*\n" - "+\t * Size settings in play/rec i2s control regs and play/rec control\n" - "+\t * regs must be the same.\n" - "+\t */\n" - "+\tswitch (params_format(params)) {\n" - "+\tcase SNDRV_PCM_FORMAT_S16_LE:\n" - "+\t\ti2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_SIZE_16_C;\n" - "+\t\tbreak;\n" - "+\t/*\n" - "+\t * doesn't work... S20_3LE != kirkwood 20bit format ?\n" - "+\t *\n" - "+\tcase SNDRV_PCM_FORMAT_S20_3LE:\n" - "+\t\ti2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_SIZE_20;\n" - "+\t\tbreak;\n" - "+\t*/\n" - "+\tcase SNDRV_PCM_FORMAT_S24_LE:\n" - "+\t\ti2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_SIZE_24;\n" - "+\t\tbreak;\n" - "+\tcase SNDRV_PCM_FORMAT_S32_LE:\n" - "+\t\ti2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_SIZE_32;\n" - "+\t\tbreak;\n" - "+\tdefault:\n" - "+\t\treturn -EINVAL;\n" - "+\t}\n" - "+\twritel(i2s_value, priv->io+i2s_reg);\n" - "+\twritel(value, priv->io+reg);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,\n" - "+\t\t\t\tint cmd, struct snd_soc_dai *dai)\n" - "+{\n" - "+\tunsigned long value;\n" - "+\n" - "+\t/*\n" - "+\t * specs says KIRKWOOD_PLAYCTL must be read 2 times before\n" - "+\t * changing it. So read 1 time here and 1 later.\n" - "+\t */\n" - "+\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\n" - "+\tswitch (cmd) {\n" - "+\tcase SNDRV_PCM_TRIGGER_START:\n" - "+\t\t/* stop audio, enable interrupts */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_PLAYCTL);\n" - "+\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_INT_MASK);\n" - "+\t\tvalue |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_INT_MASK);\n" - "+\n" - "+\t\t/* configure audio & enable i2s playback */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tvalue &= ~KIRKWOOD_PLAYCTL_BURST_MASK;\n" - "+\t\tvalue &= ~(KIRKWOOD_PLAYCTL_PAUSE|KIRKWOOD_PLAYCTL_SPDIF_EN);\n" - "+\n" - "+\t\tif (priv->burst == 32)\n" - "+\t\t\tvalue |= KIRKWOOD_PLAYCTL_BURST_32;\n" - "+\t\telse\n" - "+\t\t\tvalue |= KIRKWOOD_PLAYCTL_BURST_128;\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_I2S_EN;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tcase SNDRV_PCM_TRIGGER_STOP:\n" - "+\t\t/* stop audio, disable interrupts */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_PLAYCTL);\n" - "+\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_INT_MASK);\n" - "+\t\tvalue &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_INT_MASK);\n" - "+\n" - "+\t\t/* disable all playbacks */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tvalue &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);\n" - "+\t\twritel(value, priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tcase SNDRV_PCM_TRIGGER_PAUSE_PUSH:\n" - "+\tcase SNDRV_PCM_TRIGGER_SUSPEND:\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tvalue |= KIRKWOOD_PLAYCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tcase SNDRV_PCM_TRIGGER_RESUME:\n" - "+\tcase SNDRV_PCM_TRIGGER_PAUSE_RELEASE:\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tvalue &= ~KIRKWOOD_PLAYCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_PLAYCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tdefault:\n" - "+\t\treturn -EINVAL;\n" - "+\t}\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,\n" - "+\t\t\t\tint cmd, struct snd_soc_dai *dai)\n" - "+{\n" - "+\tunsigned long value;\n" - "+\n" - "+\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\n" - "+\tswitch (cmd) {\n" - "+\tcase SNDRV_PCM_TRIGGER_START:\n" - "+\t\t/* stop audio, enable interrupts */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tvalue |= KIRKWOOD_RECCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_RECCTL);\n" - "+\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_INT_MASK);\n" - "+\t\tvalue |= KIRKWOOD_INT_CAUSE_REC_BYTES;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_INT_MASK);\n" - "+\n" - "+\t\t/* configure audio & enable i2s record */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tvalue &= ~KIRKWOOD_RECCTL_BURST_MASK;\n" - "+\t\tvalue &= ~KIRKWOOD_RECCTL_MONO;\n" - "+\t\tvalue &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_SPDIF_EN);\n" - "+\n" - "+\t\tif (priv->burst == 32)\n" - "+\t\t\tvalue |= KIRKWOOD_RECCTL_BURST_32;\n" - "+\t\telse\n" - "+\t\t\tvalue |= KIRKWOOD_RECCTL_BURST_128;\n" - "+\t\tvalue |= KIRKWOOD_RECCTL_I2S_EN;\n" - "+\n" - "+\t\twritel(value, priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tcase SNDRV_PCM_TRIGGER_STOP:\n" - "+\t\t/* stop audio, disable interrupts */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tvalue |= KIRKWOOD_RECCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_RECCTL);\n" - "+\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_INT_MASK);\n" - "+\t\tvalue &= ~KIRKWOOD_INT_CAUSE_REC_BYTES;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_INT_MASK);\n" - "+\n" - "+\t\t/* disable all records */\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tvalue &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);\n" - "+\t\twritel(value, priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tcase SNDRV_PCM_TRIGGER_PAUSE_PUSH:\n" - "+\tcase SNDRV_PCM_TRIGGER_SUSPEND:\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tvalue |= KIRKWOOD_RECCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tcase SNDRV_PCM_TRIGGER_RESUME:\n" - "+\tcase SNDRV_PCM_TRIGGER_PAUSE_RELEASE:\n" - "+\t\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tvalue &= ~KIRKWOOD_RECCTL_PAUSE;\n" - "+\t\twritel(value, priv->io + KIRKWOOD_RECCTL);\n" - "+\t\tbreak;\n" - "+\n" - "+\tdefault:\n" - "+\t\treturn -EINVAL;\n" - "+\t\tbreak;\n" - "+\t}\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,\n" - "+\t\t\t struct snd_soc_dai *dai)\n" - "+{\n" - "+\tif (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)\n" - "+\t\treturn kirkwood_i2s_play_trigger(substream, cmd, dai);\n" - "+\telse\n" - "+\t\treturn kirkwood_i2s_rec_trigger(substream, cmd, dai);\n" - "+\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static int kirkwood_i2s_probe(struct platform_device *pdev,\n" - "+\t\t\t struct snd_soc_dai *dai)\n" - "+{\n" - "+\tunsigned long value;\n" - "+\tunsigned int reg_data;\n" - "+\n" - "+\t/* put system in a \"safe\" state : */\n" - "+\t/* disable audio interrupts */\n" - "+\twritel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);\n" - "+\twritel(0, priv->io + KIRKWOOD_INT_MASK);\n" - "+\n" - "+\treg_data = readl(priv->io + 0x1200);\n" - "+\treg_data &= (~(0x333FF8));\n" - "+\treg_data |= 0x111D18;\n" - "+\twritel(reg_data, priv->io + 0x1200);\n" - "+\n" - "+\tmsleep(500);\n" - "+\n" - "+\treg_data = readl(priv->io + 0x1200);\n" - "+\treg_data &= (~(0x333FF8));\n" - "+\treg_data |= 0x111D18;\n" - "+\twritel(reg_data, priv->io + 0x1200);\n" - "+\n" - "+\t/* disable playback/record */\n" - "+\tvalue = readl(priv->io + KIRKWOOD_PLAYCTL);\n" - "+\tvalue &= ~(KIRKWOOD_PLAYCTL_I2S_EN|KIRKWOOD_PLAYCTL_SPDIF_EN);\n" - "+\twritel(value, priv->io + KIRKWOOD_PLAYCTL);\n" - "+\n" - "+\tvalue = readl(priv->io + KIRKWOOD_RECCTL);\n" - "+\tvalue &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);\n" - "+\twritel(value, priv->io + KIRKWOOD_RECCTL);\n" - "+\n" - "+\treturn 0;\n" - "+\n" - "+}\n" - "+\n" - "+static void kirkwood_i2s_remove(struct platform_device *pdev,\n" - "+\t\t\t\tstruct snd_soc_dai *dai)\n" - "+{\n" - "+}\n" - "+\n" - "+static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {\n" - "+\t.trigger\t= kirkwood_i2s_trigger,\n" - "+\t.hw_params = kirkwood_i2s_hw_params,\n" - "+\t.set_fmt = kirkwood_i2s_set_fmt,\n" - "+};\n" - "+\n" - "+\n" - "+struct snd_soc_dai kirkwood_i2s_dai = {\n" - "+\t.name = DRV_NAME,\n" - "+\t.id = 0,\n" - "+\t.probe = kirkwood_i2s_probe,\n" - "+\t.remove = kirkwood_i2s_remove,\n" - "+\t.playback = {\n" - "+\t\t.channels_min = 1,\n" - "+\t\t.channels_max = 2,\n" - "+\t\t.rates = KIRKWOOD_I2S_RATES,\n" - "+\t\t.formats = KIRKWOOD_I2S_FORMATS,},\n" - "+\t.capture = {\n" - "+\t\t.channels_min = 1,\n" - "+\t\t.channels_max = 2,\n" - "+\t\t.rates = KIRKWOOD_I2S_RATES,\n" - "+\t\t.formats = KIRKWOOD_I2S_FORMATS,},\n" - "+\t.ops = &kirkwood_i2s_dai_ops,\n" - "+};\n" - "+EXPORT_SYMBOL_GPL(kirkwood_i2s_dai);\n" - "+\n" - "+static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)\n" - "+{\n" - "+\tstruct resource *mem;\n" - "+\tstruct kirkwood_asoc_platform_data *data =\n" - "+\t\tpdev->dev.platform_data;\n" - "+\tint err;\n" - "+\n" - "+\tpriv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL);\n" - "+\tif (!priv) {\n" - "+\t\tdev_err(&pdev->dev, \"allocation failed\\n\");\n" - "+\t\terr = -ENOMEM;\n" - "+\t\tgoto error;\n" - "+\t}\n" - "+\n" - "+\tmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n" - "+\tif (!mem) {\n" - "+\t\tdev_err(&pdev->dev, \"platform_get_resource failed\\n\");\n" - "+\t\terr = -ENXIO;\n" - "+\t\tgoto err_alloc;\n" - "+\t}\n" - "+\n" - "+\tpriv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME);\n" - "+\tif (!priv->mem) {\n" - "+\t\tdev_err(&pdev->dev, \"request_mem_region failed\\n\");\n" - "+\t\terr = -EBUSY;\n" - "+\t\tgoto error;\n" - "+\t}\n" - "+\n" - "+\tpriv->io = ioremap(priv->mem->start, SZ_16K);\n" - "+\tif (!priv->io) {\n" - "+\t\tdev_err(&pdev->dev, \"ioremap failed\\n\");\n" - "+\t\terr = -ENOMEM;\n" - "+\t\tgoto err_iomem;\n" - "+\t}\n" - "+\n" - "+\tpriv->irq = platform_get_irq(pdev, 0);\n" - "+\tif (priv->irq <= 0) {\n" - "+\t\tdev_err(&pdev->dev, \"platform_get_irq failed\\n\");\n" - "+\t\terr = -ENXIO;\n" - "+\t\tgoto err_ioremap;\n" - "+\t}\n" - "+\n" - "+\tif (!data || !data->dram) {\n" - "+\t\tdev_err(&pdev->dev, \"no platform data ?!\\n\");\n" - "+\t\terr = -EINVAL;\n" - "+\t\tgoto err_ioremap;\n" - "+\t}\n" - "+\n" - "+\tpriv->dram = data->dram;\n" - "+\tpriv->burst = data->burst;\n" - "+\n" - "+\tkirkwood_i2s_dai.capture.dma_data = priv;\n" - "+\tkirkwood_i2s_dai.playback.dma_data = priv;\n" - "+\n" - "+\treturn snd_soc_register_dai(&kirkwood_i2s_dai);\n" - "+\n" - "+err_ioremap:\n" - "+\tiounmap(priv->io);\n" - "+err_iomem:\n" - "+\trelease_mem_region(priv->mem->start, SZ_16K);\n" - "+err_alloc:\n" - "+\tkfree(priv);\n" - "+error:\n" - "+\treturn err;\n" - "+}\n" - "+\n" - "+static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)\n" - "+{\n" - "+\tif (priv) {\n" - "+\t\tiounmap(priv->io);\n" - "+\t\trelease_mem_region(priv->mem->start, SZ_16K);\n" - "+\t\tkfree(priv);\n" - "+\t}\n" - "+\tsnd_soc_unregister_dai(&kirkwood_i2s_dai);\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+static struct platform_driver kirkwood_i2s_driver = {\n" - "+\t.probe = kirkwood_i2s_dev_probe,\n" - "+\t.remove = kirkwood_i2s_dev_remove,\n" - "+\t.driver = {\n" - "+\t\t.name = DRV_NAME,\n" - "+\t\t.owner = THIS_MODULE,\n" - "+\t},\n" - "+};\n" - "+\n" - "+static int __init kirkwood_i2s_init(void)\n" - "+{\n" - "+\treturn platform_driver_register(&kirkwood_i2s_driver);\n" - "+}\n" - "+module_init(kirkwood_i2s_init);\n" - "+\n" - "+static void __exit kirkwood_i2s_exit(void)\n" - "+{\n" - "+\tplatform_driver_unregister(&kirkwood_i2s_driver);\n" - "+}\n" - "+module_exit(kirkwood_i2s_exit);\n" - "+\n" - "+/* Module information */\n" - "+MODULE_AUTHOR(\"Arnaud Patard, <apatard@mandriva.com>\");\n" - "+MODULE_DESCRIPTION(\"Kirkwood I2S SoC Interface\");\n" - "+MODULE_LICENSE(\"GPL\");\n" - "+MODULE_ALIAS(\"platform:kirkwood-i2s\");\n" - "Index: sound-2.6/sound/soc/kirkwood/Makefile\n" - "===================================================================\n" - "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n" - "+++ sound-2.6/sound/soc/kirkwood/Makefile\t2010-05-27 14:09:55.867694480 +0200\n" - "@@ -0,0 +1,6 @@\n" - "+snd-soc-kirkwood-objs := kirkwood-dma.o\n" - "+snd-soc-kirkwood-i2s-objs := kirkwood-i2s.o\n" - "+\n" - "+obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o\n" - "+obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o\n" - "+\n" - "Index: sound-2.6/sound/soc/Makefile\n" - "===================================================================\n" - "--- sound-2.6.orig/sound/soc/Makefile\t2010-05-27 14:09:32.411724822 +0200\n" - "+++ sound-2.6/sound/soc/Makefile\t2010-05-27 14:09:55.875714679 +0200\n" - "@@ -10,6 +10,7 @@ obj-$(CONFIG_SND_SOC)\t+= fsl/\n" - " obj-$(CONFIG_SND_SOC) += imx/\n" - " obj-$(CONFIG_SND_SOC)\t+= nuc900/\n" - " obj-$(CONFIG_SND_SOC)\t+= omap/\n" - "+obj-$(CONFIG_SND_SOC)\t+= kirkwood/\n" - " obj-$(CONFIG_SND_SOC)\t+= pxa/\n" - " obj-$(CONFIG_SND_SOC)\t+= s3c24xx/\n" - " obj-$(CONFIG_SND_SOC)\t+= s6000/\n" - "Index: sound-2.6/sound/soc/kirkwood/kirkwood-dma.h\n" - "===================================================================\n" - "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n" - "+++ sound-2.6/sound/soc/kirkwood/kirkwood-dma.h\t2010-05-27 14:09:55.883714769 +0200\n" - "@@ -0,0 +1,17 @@\n" - "+/*\n" - "+ * kirkwood-dma.h\n" - "+ *\n" - "+ * (c) 2010 Arnaud Patard <apatard@mandriva.com>\n" - "+ *\n" - "+ * This program is free software; you can redistribute it and/or modify it\n" - "+ * under the terms of the GNU General Public License as published by the\n" - "+ * Free Software Foundation; either version 2 of the License, or (at your\n" - "+ * option) any later version.\n" - "+ */\n" - "+\n" - "+#ifndef _KIRKWOOD_DMA_H\n" - "+#define _KIRKWOOD_DMA_H\n" - "+\n" - "+extern struct snd_soc_platform kirkwood_soc_platform;\n" - "+\n" - "+#endif\n" - "Index: sound-2.6/sound/soc/kirkwood/kirkwood-i2s.h\n" - "===================================================================\n" - "--- /dev/null\t1970-01-01 00:00:00.000000000 +0000\n" - "+++ sound-2.6/sound/soc/kirkwood/kirkwood-i2s.h\t2010-05-27 14:09:55.891695033 +0200\n" - "@@ -0,0 +1,17 @@\n" - "+/*\n" - "+ * kirkwood-i2s.h\n" - "+ *\n" - "+ * (c) 2010 Arnaud Patard <apatard@mandriva.com>\n" - "+ *\n" - "+ * This program is free software; you can redistribute it and/or modify it\n" - "+ * under the terms of the GNU General Public License as published by the\n" - "+ * Free Software Foundation; either version 2 of the License, or (at your\n" - "+ * option) any later version.\n" - "+ */\n" - "+\n" - "+#ifndef _KIRKWOOD_I2S_H\n" - "+#define _KIRKWOOD_I2S_H\n" - "+\n" - "+extern struct snd_soc_dai kirkwood_i2s_dai;\n" - "+\n" - "+#endif\n" - "Index: sound-2.6/sound/soc/Kconfig\n" - "===================================================================\n" - "--- sound-2.6.orig/sound/soc/Kconfig\t2010-05-27 14:09:32.303673990 +0200\n" - "+++ sound-2.6/sound/soc/Kconfig\t2010-05-27 14:09:55.899714700 +0200\n" - "@@ -32,6 +32,7 @@ source \"sound/soc/fsl/Kconfig\"\n" - " source \"sound/soc/imx/Kconfig\"\n" - " source \"sound/soc/nuc900/Kconfig\"\n" - " source \"sound/soc/omap/Kconfig\"\n" - "+source \"sound/soc/kirkwood/Kconfig\"\n" - " source \"sound/soc/pxa/Kconfig\"\n" - " source \"sound/soc/s3c24xx/Kconfig\"\n" - " source \"sound/soc/s6000/Kconfig\"" + "An embedded and charset-unspecified text was scrubbed...\n" + "Name: kirkwood_i2s.patch\n" + URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100527/e0e3feaa/attachment.el> -a3105b9c691a3e11f8a3fdc677cf02642874f79e1c8db392d43c055d757c596d +a4073e140c3263c94f623d10ea6eca911334596cd9f1559b1c33c0474389a3c4
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.