summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/sound/soc/fsl
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/sound/soc/fsl')
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/Kconfig67
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/Makefile22
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c91
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c999
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h129
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c800
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h200
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c534
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h84
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c333
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h13
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c230
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c595
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c601
-rw-r--r--ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c91
15 files changed, 0 insertions, 4789 deletions
diff --git a/ANDROID_3.4.5/sound/soc/fsl/Kconfig b/ANDROID_3.4.5/sound/soc/fsl/Kconfig
deleted file mode 100644
index d754d34d..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/Kconfig
+++ /dev/null
@@ -1,67 +0,0 @@
-config SND_MPC52xx_DMA
- tristate
-
-# ASoC platform support for the Freescale PowerPC SOCs that have an SSI and
-# an Elo DMA controller, such as the MPC8610 and P1022. You will still need to
-# select a platform driver and a codec driver.
-config SND_SOC_POWERPC_SSI
- tristate
- depends on FSL_SOC
-
-config SND_SOC_MPC8610_HPCD
- tristate "ALSA SoC support for the Freescale MPC8610 HPCD board"
- # I2C is necessary for the CS4270 driver
- depends on MPC8610_HPCD && I2C
- select SND_SOC_POWERPC_SSI
- select SND_SOC_CS4270
- select SND_SOC_CS4270_VD33_ERRATA
- default y if MPC8610_HPCD
- help
- Say Y if you want to enable audio on the Freescale MPC8610 HPCD.
-
-config SND_SOC_P1022_DS
- tristate "ALSA SoC support for the Freescale P1022 DS board"
- # I2C is necessary for the WM8776 driver
- depends on P1022_DS && I2C
- select SND_SOC_POWERPC_SSI
- select SND_SOC_WM8776
- default y if P1022_DS
- help
- Say Y if you want to enable audio on the Freescale P1022 DS board.
- This will also include the Wolfson Microelectronics WM8776 codec
- driver.
-
-config SND_SOC_MPC5200_I2S
- tristate "Freescale MPC5200 PSC in I2S mode driver"
- depends on PPC_MPC52xx && PPC_BESTCOMM
- select SND_MPC52xx_DMA
- select PPC_BESTCOMM_GEN_BD
- help
- Say Y here to support the MPC5200 PSCs in I2S mode.
-
-config SND_SOC_MPC5200_AC97
- tristate "Freescale MPC5200 PSC in AC97 mode driver"
- depends on PPC_MPC52xx && PPC_BESTCOMM
- select SND_SOC_AC97_BUS
- select SND_MPC52xx_DMA
- select PPC_BESTCOMM_GEN_BD
- help
- Say Y here to support the MPC5200 PSCs in AC97 mode.
-
-config SND_MPC52xx_SOC_PCM030
- tristate "SoC AC97 Audio support for Phytec pcm030 and WM9712"
- depends on PPC_MPC5200_SIMPLE
- select SND_SOC_MPC5200_AC97
- select SND_SOC_WM9712
- help
- Say Y if you want to add support for sound on the Phytec pcm030
- baseboard.
-
-config SND_MPC52xx_SOC_EFIKA
- tristate "SoC AC97 Audio support for bbplan Efika and STAC9766"
- depends on PPC_EFIKA
- select SND_SOC_MPC5200_AC97
- select SND_SOC_STAC9766
- help
- Say Y if you want to add support for sound on the Efika.
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/Makefile b/ANDROID_3.4.5/sound/soc/fsl/Makefile
deleted file mode 100644
index b4a38c0a..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# MPC8610 HPCD Machine Support
-snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o
-obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o
-
-# P1022 DS Machine Support
-snd-soc-p1022-ds-objs := p1022_ds.o
-obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o
-
-# Freescale PowerPC SSI/DMA Platform Support
-snd-soc-fsl-ssi-objs := fsl_ssi.o
-snd-soc-fsl-dma-objs := fsl_dma.o
-obj-$(CONFIG_SND_SOC_POWERPC_SSI) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o
-
-# MPC5200 Platform Support
-obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
-obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o
-obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
-
-# MPC5200 Machine Support
-obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
-obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c b/ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c
deleted file mode 100644
index b2acd329..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/efika-audio-fabric.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Efika driver for the PSC of the Freescale MPC52xx
- * configured as AC97 interface
- *
- * Copyright 2008 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/stac9766.h"
-
-#define DRV_NAME "efika-audio-fabric"
-
-static struct snd_soc_dai_link efika_fabric_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 Analog",
- .codec_dai_name = "stac9766-hifi-analog",
- .cpu_dai_name = "mpc5200-psc-ac97.0",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "stac9766-codec",
-},
-{
- .name = "AC97",
- .stream_name = "AC97 IEC958",
- .codec_dai_name = "stac9766-hifi-IEC958",
- .cpu_dai_name = "mpc5200-psc-ac97.1",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "stac9766-codec",
-},
-};
-
-static struct snd_soc_card card = {
- .name = "Efika",
- .owner = THIS_MODULE,
- .dai_link = efika_fabric_dai,
- .num_links = ARRAY_SIZE(efika_fabric_dai),
-};
-
-static __init int efika_fabric_init(void)
-{
- struct platform_device *pdev;
- int rc;
-
- if (!of_machine_is_compatible("bplan,efika"))
- return -ENODEV;
-
- pdev = platform_device_alloc("soc-audio", 1);
- if (!pdev) {
- pr_err("efika_fabric_init: platform_device_alloc() failed\n");
- return -ENODEV;
- }
-
- platform_set_drvdata(pdev, &card);
-
- rc = platform_device_add(pdev);
- if (rc) {
- pr_err("efika_fabric_init: platform_device_add() failed\n");
- platform_device_put(pdev);
- return -ENODEV;
- }
- return 0;
-}
-
-module_init(efika_fabric_init);
-
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION(DRV_NAME ": mpc5200 Efika fabric driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c b/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c
deleted file mode 100644
index 96bb92dd..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * Freescale DMA ALSA SoC PCM driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- * This driver implements ASoC support for the Elo DMA controller, which is
- * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms,
- * the PCM driver is what handles the DMA buffer.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <linux/of_platform.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/io.h>
-
-#include "fsl_dma.h"
-#include "fsl_ssi.h" /* For the offset of stx0 and srx0 */
-
-/*
- * The formats that the DMA controller supports, which is anything
- * that is 8, 16, or 32 bits.
- */
-#define FSLDMA_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
- SNDRV_PCM_FMTBIT_U8 | \
- SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_U16_LE | \
- SNDRV_PCM_FMTBIT_U16_BE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S24_BE | \
- SNDRV_PCM_FMTBIT_U24_LE | \
- SNDRV_PCM_FMTBIT_U24_BE | \
- SNDRV_PCM_FMTBIT_S32_LE | \
- SNDRV_PCM_FMTBIT_S32_BE | \
- SNDRV_PCM_FMTBIT_U32_LE | \
- SNDRV_PCM_FMTBIT_U32_BE)
-
-#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
- SNDRV_PCM_RATE_CONTINUOUS)
-
-struct dma_object {
- struct snd_soc_platform_driver dai;
- dma_addr_t ssi_stx_phys;
- dma_addr_t ssi_srx_phys;
- unsigned int ssi_fifo_depth;
- struct ccsr_dma_channel __iomem *channel;
- unsigned int irq;
- bool assigned;
- char path[1];
-};
-
-/*
- * The number of DMA links to use. Two is the bare minimum, but if you
- * have really small links you might need more.
- */
-#define NUM_DMA_LINKS 2
-
-/** fsl_dma_private: p-substream DMA data
- *
- * Each substream has a 1-to-1 association with a DMA channel.
- *
- * The link[] array is first because it needs to be aligned on a 32-byte
- * boundary, so putting it first will ensure alignment without padding the
- * structure.
- *
- * @link[]: array of link descriptors
- * @dma_channel: pointer to the DMA channel's registers
- * @irq: IRQ for this DMA channel
- * @substream: pointer to the substream object, needed by the ISR
- * @ssi_sxx_phys: bus address of the STX or SRX register to use
- * @ld_buf_phys: physical address of the LD buffer
- * @current_link: index into link[] of the link currently being processed
- * @dma_buf_phys: physical address of the DMA buffer
- * @dma_buf_next: physical address of the next period to process
- * @dma_buf_end: physical address of the byte after the end of the DMA
- * @buffer period_size: the size of a single period
- * @num_periods: the number of periods in the DMA buffer
- */
-struct fsl_dma_private {
- struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
- struct ccsr_dma_channel __iomem *dma_channel;
- unsigned int irq;
- struct snd_pcm_substream *substream;
- dma_addr_t ssi_sxx_phys;
- unsigned int ssi_fifo_depth;
- dma_addr_t ld_buf_phys;
- unsigned int current_link;
- dma_addr_t dma_buf_phys;
- dma_addr_t dma_buf_next;
- dma_addr_t dma_buf_end;
- size_t period_size;
- unsigned int num_periods;
-};
-
-/**
- * fsl_dma_hardare: define characteristics of the PCM hardware.
- *
- * The PCM hardware is the Freescale DMA controller. This structure defines
- * the capabilities of that hardware.
- *
- * Since the sampling rate and data format are not controlled by the DMA
- * controller, we specify no limits for those values. The only exception is
- * period_bytes_min, which is set to a reasonably low value to prevent the
- * DMA controller from generating too many interrupts per second.
- *
- * Since each link descriptor has a 32-bit byte count field, we set
- * period_bytes_max to the largest 32-bit number. We also have no maximum
- * number of periods.
- *
- * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a
- * limitation in the SSI driver requires the sample rates for playback and
- * capture to be the same.
- */
-static const struct snd_pcm_hardware fsl_dma_hardware = {
-
- .info = SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_JOINT_DUPLEX |
- SNDRV_PCM_INFO_PAUSE,
- .formats = FSLDMA_PCM_FORMATS,
- .rates = FSLDMA_PCM_RATES,
- .rate_min = 5512,
- .rate_max = 192000,
- .period_bytes_min = 512, /* A reasonable limit */
- .period_bytes_max = (u32) -1,
- .periods_min = NUM_DMA_LINKS,
- .periods_max = (unsigned int) -1,
- .buffer_bytes_max = 128 * 1024, /* A reasonable limit */
-};
-
-/**
- * fsl_dma_abort_stream: tell ALSA that the DMA transfer has aborted
- *
- * This function should be called by the ISR whenever the DMA controller
- * halts data transfer.
- */
-static void fsl_dma_abort_stream(struct snd_pcm_substream *substream)
-{
- unsigned long flags;
-
- snd_pcm_stream_lock_irqsave(substream, flags);
-
- if (snd_pcm_running(substream))
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
-
- snd_pcm_stream_unlock_irqrestore(substream, flags);
-}
-
-/**
- * fsl_dma_update_pointers - update LD pointers to point to the next period
- *
- * As each period is completed, this function changes the the link
- * descriptor pointers for that period to point to the next period.
- */
-static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private)
-{
- struct fsl_dma_link_descriptor *link =
- &dma_private->link[dma_private->current_link];
-
- /* Update our link descriptors to point to the next period. On a 36-bit
- * system, we also need to update the ESAD bits. We also set (keep) the
- * snoop bits. See the comments in fsl_dma_hw_params() about snooping.
- */
- if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- link->source_addr = cpu_to_be32(dma_private->dma_buf_next);
-#ifdef CONFIG_PHYS_64BIT
- link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(dma_private->dma_buf_next));
-#endif
- } else {
- link->dest_addr = cpu_to_be32(dma_private->dma_buf_next);
-#ifdef CONFIG_PHYS_64BIT
- link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(dma_private->dma_buf_next));
-#endif
- }
-
- /* Update our variables for next time */
- dma_private->dma_buf_next += dma_private->period_size;
-
- if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
- dma_private->dma_buf_next = dma_private->dma_buf_phys;
-
- if (++dma_private->current_link >= NUM_DMA_LINKS)
- dma_private->current_link = 0;
-}
-
-/**
- * fsl_dma_isr: interrupt handler for the DMA controller
- *
- * @irq: IRQ of the DMA channel
- * @dev_id: pointer to the dma_private structure for this DMA channel
- */
-static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
-{
- struct fsl_dma_private *dma_private = dev_id;
- struct snd_pcm_substream *substream = dma_private->substream;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
- irqreturn_t ret = IRQ_NONE;
- u32 sr, sr2 = 0;
-
- /* We got an interrupt, so read the status register to see what we
- were interrupted for.
- */
- sr = in_be32(&dma_channel->sr);
-
- if (sr & CCSR_DMA_SR_TE) {
- dev_err(dev, "dma transmit error\n");
- fsl_dma_abort_stream(substream);
- sr2 |= CCSR_DMA_SR_TE;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_CH)
- ret = IRQ_HANDLED;
-
- if (sr & CCSR_DMA_SR_PE) {
- dev_err(dev, "dma programming error\n");
- fsl_dma_abort_stream(substream);
- sr2 |= CCSR_DMA_SR_PE;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_EOLNI) {
- sr2 |= CCSR_DMA_SR_EOLNI;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_CB)
- ret = IRQ_HANDLED;
-
- if (sr & CCSR_DMA_SR_EOSI) {
- /* Tell ALSA we completed a period. */
- snd_pcm_period_elapsed(substream);
-
- /*
- * Update our link descriptors to point to the next period. We
- * only need to do this if the number of periods is not equal to
- * the number of links.
- */
- if (dma_private->num_periods != NUM_DMA_LINKS)
- fsl_dma_update_pointers(dma_private);
-
- sr2 |= CCSR_DMA_SR_EOSI;
- ret = IRQ_HANDLED;
- }
-
- if (sr & CCSR_DMA_SR_EOLSI) {
- sr2 |= CCSR_DMA_SR_EOLSI;
- ret = IRQ_HANDLED;
- }
-
- /* Clear the bits that we set */
- if (sr2)
- out_be32(&dma_channel->sr, sr2);
-
- return ret;
-}
-
-/**
- * fsl_dma_new: initialize this PCM driver.
- *
- * This function is called when the codec driver calls snd_soc_new_pcms(),
- * once for each .dai_link in the machine driver's snd_soc_card
- * structure.
- *
- * snd_dma_alloc_pages() is just a front-end to dma_alloc_coherent(), which
- * (currently) always allocates the DMA buffer in lowmem, even if GFP_HIGHMEM
- * is specified. Therefore, any DMA buffers we allocate will always be in low
- * memory, but we support for 36-bit physical addresses anyway.
- *
- * Regardless of where the memory is actually allocated, since the device can
- * technically DMA to any 36-bit address, we do need to set the DMA mask to 36.
- */
-static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_pcm *pcm = rtd->pcm;
- static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
- int ret;
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &fsl_dma_dmamask;
-
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = fsl_dma_dmamask;
-
- /* Some codecs have separate DAIs for playback and capture, so we
- * should allocate a DMA buffer only for the streams that are valid.
- */
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
- fsl_dma_hardware.buffer_bytes_max,
- &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
- if (ret) {
- dev_err(card->dev, "can't alloc playback dma buffer\n");
- return ret;
- }
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
- fsl_dma_hardware.buffer_bytes_max,
- &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
- if (ret) {
- dev_err(card->dev, "can't alloc capture dma buffer\n");
- snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
- return ret;
- }
- }
-
- return 0;
-}
-
-/**
- * fsl_dma_open: open a new substream.
- *
- * Each substream has its own DMA buffer.
- *
- * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link
- * descriptors that ping-pong from one period to the next. For example, if
- * there are six periods and two link descriptors, this is how they look
- * before playback starts:
- *
- * The last link descriptor
- * ____________ points back to the first
- * | |
- * V |
- * ___ ___ |
- * | |->| |->|
- * |___| |___|
- * | |
- * | |
- * V V
- * _________________________________________
- * | | | | | | | The DMA buffer is
- * | | | | | | | divided into 6 parts
- * |______|______|______|______|______|______|
- *
- * and here's how they look after the first period is finished playing:
- *
- * ____________
- * | |
- * V |
- * ___ ___ |
- * | |->| |->|
- * |___| |___|
- * | |
- * |______________
- * | |
- * V V
- * _________________________________________
- * | | | | | | |
- * | | | | | | |
- * |______|______|______|______|______|______|
- *
- * The first link descriptor now points to the third period. The DMA
- * controller is currently playing the second period. When it finishes, it
- * will jump back to the first descriptor and play the third period.
- *
- * There are four reasons we do this:
- *
- * 1. The only way to get the DMA controller to automatically restart the
- * transfer when it gets to the end of the buffer is to use chaining
- * mode. Basic direct mode doesn't offer that feature.
- * 2. We need to receive an interrupt at the end of every period. The DMA
- * controller can generate an interrupt at the end of every link transfer
- * (aka segment). Making each period into a DMA segment will give us the
- * interrupts we need.
- * 3. By creating only two link descriptors, regardless of the number of
- * periods, we do not need to reallocate the link descriptors if the
- * number of periods changes.
- * 4. All of the audio data is still stored in a single, contiguous DMA
- * buffer, which is what ALSA expects. We're just dividing it into
- * contiguous parts, and creating a link descriptor for each one.
- */
-static int fsl_dma_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct dma_object *dma =
- container_of(rtd->platform->driver, struct dma_object, dai);
- struct fsl_dma_private *dma_private;
- struct ccsr_dma_channel __iomem *dma_channel;
- dma_addr_t ld_buf_phys;
- u64 temp_link; /* Pointer to next link descriptor */
- u32 mr;
- unsigned int channel;
- int ret = 0;
- unsigned int i;
-
- /*
- * Reject any DMA buffer whose size is not a multiple of the period
- * size. We need to make sure that the DMA buffer can be evenly divided
- * into periods.
- */
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (ret < 0) {
- dev_err(dev, "invalid buffer size\n");
- return ret;
- }
-
- channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-
- if (dma->assigned) {
- dev_err(dev, "dma channel already assigned\n");
- return -EBUSY;
- }
-
- dma_private = dma_alloc_coherent(dev, sizeof(struct fsl_dma_private),
- &ld_buf_phys, GFP_KERNEL);
- if (!dma_private) {
- dev_err(dev, "can't allocate dma private data\n");
- return -ENOMEM;
- }
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dma_private->ssi_sxx_phys = dma->ssi_stx_phys;
- else
- dma_private->ssi_sxx_phys = dma->ssi_srx_phys;
-
- dma_private->ssi_fifo_depth = dma->ssi_fifo_depth;
- dma_private->dma_channel = dma->channel;
- dma_private->irq = dma->irq;
- dma_private->substream = substream;
- dma_private->ld_buf_phys = ld_buf_phys;
- dma_private->dma_buf_phys = substream->dma_buffer.addr;
-
- ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "fsldma-audio",
- dma_private);
- if (ret) {
- dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
- dma_private->irq, ret);
- dma_free_coherent(dev, sizeof(struct fsl_dma_private),
- dma_private, dma_private->ld_buf_phys);
- return ret;
- }
-
- dma->assigned = 1;
-
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
- snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
- runtime->private_data = dma_private;
-
- /* Program the fixed DMA controller parameters */
-
- dma_channel = dma_private->dma_channel;
-
- temp_link = dma_private->ld_buf_phys +
- sizeof(struct fsl_dma_link_descriptor);
-
- for (i = 0; i < NUM_DMA_LINKS; i++) {
- dma_private->link[i].next = cpu_to_be64(temp_link);
-
- temp_link += sizeof(struct fsl_dma_link_descriptor);
- }
- /* The last link descriptor points to the first */
- dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
-
- /* Tell the DMA controller where the first link descriptor is */
- out_be32(&dma_channel->clndar,
- CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
- out_be32(&dma_channel->eclndar,
- CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
-
- /* The manual says the BCR must be clear before enabling EMP */
- out_be32(&dma_channel->bcr, 0);
-
- /*
- * Program the mode register for interrupts, external master control,
- * and source/destination hold. Also clear the Channel Abort bit.
- */
- mr = in_be32(&dma_channel->mr) &
- ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
-
- /*
- * We want External Master Start and External Master Pause enabled,
- * because the SSI is controlling the DMA controller. We want the DMA
- * controller to be set up in advance, and then we signal only the SSI
- * to start transferring.
- *
- * We want End-Of-Segment Interrupts enabled, because this will generate
- * an interrupt at the end of each segment (each link descriptor
- * represents one segment). Each DMA segment is the same thing as an
- * ALSA period, so this is how we get an interrupt at the end of every
- * period.
- *
- * We want Error Interrupt enabled, so that we can get an error if
- * the DMA controller is mis-programmed somehow.
- */
- mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
- CCSR_DMA_MR_EMS_EN;
-
- /* For playback, we want the destination address to be held. For
- capture, set the source address to be held. */
- mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
-
- out_be32(&dma_channel->mr, mr);
-
- return 0;
-}
-
-/**
- * fsl_dma_hw_params: continue initializing the DMA links
- *
- * This function obtains hardware parameters about the opened stream and
- * programs the DMA controller accordingly.
- *
- * One drawback of big-endian is that when copying integers of different
- * sizes to a fixed-sized register, the address to which the integer must be
- * copied is dependent on the size of the integer.
- *
- * For example, if P is the address of a 32-bit register, and X is a 32-bit
- * integer, then X should be copied to address P. However, if X is a 16-bit
- * integer, then it should be copied to P+2. If X is an 8-bit register,
- * then it should be copied to P+3.
- *
- * So for playback of 8-bit samples, the DMA controller must transfer single
- * bytes from the DMA buffer to the last byte of the STX0 register, i.e.
- * offset by 3 bytes. For 16-bit samples, the offset is two bytes.
- *
- * For 24-bit samples, the offset is 1 byte. However, the DMA controller
- * does not support 3-byte copies (the DAHTS register supports only 1, 2, 4,
- * and 8 bytes at a time). So we do not support packed 24-bit samples.
- * 24-bit data must be padded to 32 bits.
- */
-static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
-
- /* Number of bits per sample */
- unsigned int sample_bits =
- snd_pcm_format_physical_width(params_format(hw_params));
-
- /* Number of bytes per frame */
- unsigned int sample_bytes = sample_bits / 8;
-
- /* Bus address of SSI STX register */
- dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys;
-
- /* Size of the DMA buffer, in bytes */
- size_t buffer_size = params_buffer_bytes(hw_params);
-
- /* Number of bytes per period */
- size_t period_size = params_period_bytes(hw_params);
-
- /* Pointer to next period */
- dma_addr_t temp_addr = substream->dma_buffer.addr;
-
- /* Pointer to DMA controller */
- struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
-
- u32 mr; /* DMA Mode Register */
-
- unsigned int i;
-
- /* Initialize our DMA tracking variables */
- dma_private->period_size = period_size;
- dma_private->num_periods = params_periods(hw_params);
- dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size;
- dma_private->dma_buf_next = dma_private->dma_buf_phys +
- (NUM_DMA_LINKS * period_size);
-
- if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
- /* This happens if the number of periods == NUM_DMA_LINKS */
- dma_private->dma_buf_next = dma_private->dma_buf_phys;
-
- mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK |
- CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK);
-
- /* Due to a quirk of the SSI's STX register, the target address
- * for the DMA operations depends on the sample size. So we calculate
- * that offset here. While we're at it, also tell the DMA controller
- * how much data to transfer per sample.
- */
- switch (sample_bits) {
- case 8:
- mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1;
- ssi_sxx_phys += 3;
- break;
- case 16:
- mr |= CCSR_DMA_MR_DAHTS_2 | CCSR_DMA_MR_SAHTS_2;
- ssi_sxx_phys += 2;
- break;
- case 32:
- mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4;
- break;
- default:
- /* We should never get here */
- dev_err(dev, "unsupported sample size %u\n", sample_bits);
- return -EINVAL;
- }
-
- /*
- * BWC determines how many bytes are sent/received before the DMA
- * controller checks the SSI to see if it needs to stop. BWC should
- * always be a multiple of the frame size, so that we always transmit
- * whole frames. Each frame occupies two slots in the FIFO. The
- * parameter for CCSR_DMA_MR_BWC() is rounded down the next power of two
- * (MR[BWC] can only represent even powers of two).
- *
- * To simplify the process, we set BWC to the largest value that is
- * less than or equal to the FIFO watermark. For playback, this ensures
- * that we transfer the maximum amount without overrunning the FIFO.
- * For capture, this ensures that we transfer the maximum amount without
- * underrunning the FIFO.
- *
- * f = SSI FIFO depth
- * w = SSI watermark value (which equals f - 2)
- * b = DMA bandwidth count (in bytes)
- * s = sample size (in bytes, which equals frame_size * 2)
- *
- * For playback, we never transmit more than the transmit FIFO
- * watermark, otherwise we might write more data than the FIFO can hold.
- * The watermark is equal to the FIFO depth minus two.
- *
- * For capture, two equations must hold:
- * w > f - (b / s)
- * w >= b / s
- *
- * So, b > 2 * s, but b must also be <= s * w. To simplify, we set
- * b = s * w, which is equal to
- * (dma_private->ssi_fifo_depth - 2) * sample_bytes.
- */
- mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes);
-
- out_be32(&dma_channel->mr, mr);
-
- for (i = 0; i < NUM_DMA_LINKS; i++) {
- struct fsl_dma_link_descriptor *link = &dma_private->link[i];
-
- link->count = cpu_to_be32(period_size);
-
- /* The snoop bit tells the DMA controller whether it should tell
- * the ECM to snoop during a read or write to an address. For
- * audio, we use DMA to transfer data between memory and an I/O
- * device (the SSI's STX0 or SRX0 register). Snooping is only
- * needed if there is a cache, so we need to snoop memory
- * addresses only. For playback, that means we snoop the source
- * but not the destination. For capture, we snoop the
- * destination but not the source.
- *
- * Note that failing to snoop properly is unlikely to cause
- * cache incoherency if the period size is larger than the
- * size of L1 cache. This is because filling in one period will
- * flush out the data for the previous period. So if you
- * increased period_bytes_min to a large enough size, you might
- * get more performance by not snooping, and you'll still be
- * okay. You'll need to update fsl_dma_update_pointers() also.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- link->source_addr = cpu_to_be32(temp_addr);
- link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(temp_addr));
-
- link->dest_addr = cpu_to_be32(ssi_sxx_phys);
- link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
- upper_32_bits(ssi_sxx_phys));
- } else {
- link->source_addr = cpu_to_be32(ssi_sxx_phys);
- link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
- upper_32_bits(ssi_sxx_phys));
-
- link->dest_addr = cpu_to_be32(temp_addr);
- link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
- upper_32_bits(temp_addr));
- }
-
- temp_addr += period_size;
- }
-
- return 0;
-}
-
-/**
- * fsl_dma_pointer: determine the current position of the DMA transfer
- *
- * This function is called by ALSA when ALSA wants to know where in the
- * stream buffer the hardware currently is.
- *
- * For playback, the SAR register contains the physical address of the most
- * recent DMA transfer. For capture, the value is in the DAR register.
- *
- * The base address of the buffer is stored in the source_addr field of the
- * first link descriptor.
- */
-static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
- dma_addr_t position;
- snd_pcm_uframes_t frames;
-
- /* Obtain the current DMA pointer, but don't read the ESAD bits if we
- * only have 32-bit DMA addresses. This function is typically called
- * in interrupt context, so we need to optimize it.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- position = in_be32(&dma_channel->sar);
-#ifdef CONFIG_PHYS_64BIT
- position |= (u64)(in_be32(&dma_channel->satr) &
- CCSR_DMA_ATR_ESAD_MASK) << 32;
-#endif
- } else {
- position = in_be32(&dma_channel->dar);
-#ifdef CONFIG_PHYS_64BIT
- position |= (u64)(in_be32(&dma_channel->datr) &
- CCSR_DMA_ATR_ESAD_MASK) << 32;
-#endif
- }
-
- /*
- * When capture is started, the SSI immediately starts to fill its FIFO.
- * This means that the DMA controller is not started until the FIFO is
- * full. However, ALSA calls this function before that happens, when
- * MR.DAR is still zero. In this case, just return zero to indicate
- * that nothing has been received yet.
- */
- if (!position)
- return 0;
-
- if ((position < dma_private->dma_buf_phys) ||
- (position > dma_private->dma_buf_end)) {
- dev_err(dev, "dma pointer is out of range, halting stream\n");
- return SNDRV_PCM_POS_XRUN;
- }
-
- frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
-
- /*
- * If the current address is just past the end of the buffer, wrap it
- * around.
- */
- if (frames == runtime->buffer_size)
- frames = 0;
-
- return frames;
-}
-
-/**
- * fsl_dma_hw_free: release resources allocated in fsl_dma_hw_params()
- *
- * Release the resources allocated in fsl_dma_hw_params() and de-program the
- * registers.
- *
- * This function can be called multiple times.
- */
-static int fsl_dma_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
-
- if (dma_private) {
- struct ccsr_dma_channel __iomem *dma_channel;
-
- dma_channel = dma_private->dma_channel;
-
- /* Stop the DMA */
- out_be32(&dma_channel->mr, CCSR_DMA_MR_CA);
- out_be32(&dma_channel->mr, 0);
-
- /* Reset all the other registers */
- out_be32(&dma_channel->sr, -1);
- out_be32(&dma_channel->clndar, 0);
- out_be32(&dma_channel->eclndar, 0);
- out_be32(&dma_channel->satr, 0);
- out_be32(&dma_channel->sar, 0);
- out_be32(&dma_channel->datr, 0);
- out_be32(&dma_channel->dar, 0);
- out_be32(&dma_channel->bcr, 0);
- out_be32(&dma_channel->nlndar, 0);
- out_be32(&dma_channel->enlndar, 0);
- }
-
- return 0;
-}
-
-/**
- * fsl_dma_close: close the stream.
- */
-static int fsl_dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct fsl_dma_private *dma_private = runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct device *dev = rtd->platform->dev;
- struct dma_object *dma =
- container_of(rtd->platform->driver, struct dma_object, dai);
-
- if (dma_private) {
- if (dma_private->irq)
- free_irq(dma_private->irq, dma_private);
-
- if (dma_private->ld_buf_phys) {
- dma_unmap_single(dev, dma_private->ld_buf_phys,
- sizeof(dma_private->link),
- DMA_TO_DEVICE);
- }
-
- /* Deallocate the fsl_dma_private structure */
- dma_free_coherent(dev, sizeof(struct fsl_dma_private),
- dma_private, dma_private->ld_buf_phys);
- substream->runtime->private_data = NULL;
- }
-
- dma->assigned = 0;
-
- return 0;
-}
-
-/*
- * Remove this PCM driver.
- */
-static void fsl_dma_free_dma_buffers(struct snd_pcm *pcm)
-{
- struct snd_pcm_substream *substream;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
- substream = pcm->streams[i].substream;
- if (substream) {
- snd_dma_free_pages(&substream->dma_buffer);
- substream->dma_buffer.area = NULL;
- substream->dma_buffer.addr = 0;
- }
- }
-}
-
-/**
- * find_ssi_node -- returns the SSI node that points to his DMA channel node
- *
- * Although this DMA driver attempts to operate independently of the other
- * devices, it still needs to determine some information about the SSI device
- * that it's working with. Unfortunately, the device tree does not contain
- * a pointer from the DMA channel node to the SSI node -- the pointer goes the
- * other way. So we need to scan the device tree for SSI nodes until we find
- * the one that points to the given DMA channel node. It's ugly, but at least
- * it's contained in this one function.
- */
-static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
-{
- struct device_node *ssi_np, *np;
-
- for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") {
- /* Check each DMA phandle to see if it points to us. We
- * assume that device_node pointers are a valid comparison.
- */
- np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
- of_node_put(np);
- if (np == dma_channel_np)
- return ssi_np;
-
- np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
- of_node_put(np);
- if (np == dma_channel_np)
- return ssi_np;
- }
-
- return NULL;
-}
-
-static struct snd_pcm_ops fsl_dma_ops = {
- .open = fsl_dma_open,
- .close = fsl_dma_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = fsl_dma_hw_params,
- .hw_free = fsl_dma_hw_free,
- .pointer = fsl_dma_pointer,
-};
-
-static int __devinit fsl_soc_dma_probe(struct platform_device *pdev)
- {
- struct dma_object *dma;
- struct device_node *np = pdev->dev.of_node;
- struct device_node *ssi_np;
- struct resource res;
- const uint32_t *iprop;
- int ret;
-
- /* Find the SSI node that points to us. */
- ssi_np = find_ssi_node(np);
- if (!ssi_np) {
- dev_err(&pdev->dev, "cannot find parent SSI node\n");
- return -ENODEV;
- }
-
- ret = of_address_to_resource(ssi_np, 0, &res);
- if (ret) {
- dev_err(&pdev->dev, "could not determine resources for %s\n",
- ssi_np->full_name);
- of_node_put(ssi_np);
- return ret;
- }
-
- dma = kzalloc(sizeof(*dma) + strlen(np->full_name), GFP_KERNEL);
- if (!dma) {
- dev_err(&pdev->dev, "could not allocate dma object\n");
- of_node_put(ssi_np);
- return -ENOMEM;
- }
-
- strcpy(dma->path, np->full_name);
- dma->dai.ops = &fsl_dma_ops;
- dma->dai.pcm_new = fsl_dma_new;
- dma->dai.pcm_free = fsl_dma_free_dma_buffers;
-
- /* Store the SSI-specific information that we need */
- dma->ssi_stx_phys = res.start + offsetof(struct ccsr_ssi, stx0);
- dma->ssi_srx_phys = res.start + offsetof(struct ccsr_ssi, srx0);
-
- iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
- if (iprop)
- dma->ssi_fifo_depth = be32_to_cpup(iprop);
- else
- /* Older 8610 DTs didn't have the fifo-depth property */
- dma->ssi_fifo_depth = 8;
-
- of_node_put(ssi_np);
-
- ret = snd_soc_register_platform(&pdev->dev, &dma->dai);
- if (ret) {
- dev_err(&pdev->dev, "could not register platform\n");
- kfree(dma);
- return ret;
- }
-
- dma->channel = of_iomap(np, 0);
- dma->irq = irq_of_parse_and_map(np, 0);
-
- dev_set_drvdata(&pdev->dev, dma);
-
- return 0;
-}
-
-static int __devexit fsl_soc_dma_remove(struct platform_device *pdev)
-{
- struct dma_object *dma = dev_get_drvdata(&pdev->dev);
-
- snd_soc_unregister_platform(&pdev->dev);
- iounmap(dma->channel);
- irq_dispose_mapping(dma->irq);
- kfree(dma);
-
- return 0;
-}
-
-static const struct of_device_id fsl_soc_dma_ids[] = {
- { .compatible = "fsl,ssi-dma-channel", },
- {}
-};
-MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids);
-
-static struct platform_driver fsl_soc_dma_driver = {
- .driver = {
- .name = "fsl-pcm-audio",
- .owner = THIS_MODULE,
- .of_match_table = fsl_soc_dma_ids,
- },
- .probe = fsl_soc_dma_probe,
- .remove = __devexit_p(fsl_soc_dma_remove),
-};
-
-module_platform_driver(fsl_soc_dma_driver);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h b/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h
deleted file mode 100644
index 78fee97e..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_dma.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * mpc8610-pcm.h - ALSA PCM interface for the Freescale MPC8610 SoC
- *
- * 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 _MPC8610_PCM_H
-#define _MPC8610_PCM_H
-
-struct ccsr_dma {
- u8 res0[0x100];
- struct ccsr_dma_channel {
- __be32 mr; /* Mode register */
- __be32 sr; /* Status register */
- __be32 eclndar; /* Current link descriptor extended addr reg */
- __be32 clndar; /* Current link descriptor address register */
- __be32 satr; /* Source attributes register */
- __be32 sar; /* Source address register */
- __be32 datr; /* Destination attributes register */
- __be32 dar; /* Destination address register */
- __be32 bcr; /* Byte count register */
- __be32 enlndar; /* Next link descriptor extended address reg */
- __be32 nlndar; /* Next link descriptor address register */
- u8 res1[4];
- __be32 eclsdar; /* Current list descriptor extended addr reg */
- __be32 clsdar; /* Current list descriptor address register */
- __be32 enlsdar; /* Next list descriptor extended address reg */
- __be32 nlsdar; /* Next list descriptor address register */
- __be32 ssr; /* Source stride register */
- __be32 dsr; /* Destination stride register */
- u8 res2[0x38];
- } channel[4];
- __be32 dgsr;
-};
-
-#define CCSR_DMA_MR_BWC_DISABLED 0x0F000000
-#define CCSR_DMA_MR_BWC_SHIFT 24
-#define CCSR_DMA_MR_BWC_MASK 0x0F000000
-#define CCSR_DMA_MR_BWC(x) \
- ((ilog2(x) << CCSR_DMA_MR_BWC_SHIFT) & CCSR_DMA_MR_BWC_MASK)
-#define CCSR_DMA_MR_EMP_EN 0x00200000
-#define CCSR_DMA_MR_EMS_EN 0x00040000
-#define CCSR_DMA_MR_DAHTS_MASK 0x00030000
-#define CCSR_DMA_MR_DAHTS_1 0x00000000
-#define CCSR_DMA_MR_DAHTS_2 0x00010000
-#define CCSR_DMA_MR_DAHTS_4 0x00020000
-#define CCSR_DMA_MR_DAHTS_8 0x00030000
-#define CCSR_DMA_MR_SAHTS_MASK 0x0000C000
-#define CCSR_DMA_MR_SAHTS_1 0x00000000
-#define CCSR_DMA_MR_SAHTS_2 0x00004000
-#define CCSR_DMA_MR_SAHTS_4 0x00008000
-#define CCSR_DMA_MR_SAHTS_8 0x0000C000
-#define CCSR_DMA_MR_DAHE 0x00002000
-#define CCSR_DMA_MR_SAHE 0x00001000
-#define CCSR_DMA_MR_SRW 0x00000400
-#define CCSR_DMA_MR_EOSIE 0x00000200
-#define CCSR_DMA_MR_EOLNIE 0x00000100
-#define CCSR_DMA_MR_EOLSIE 0x00000080
-#define CCSR_DMA_MR_EIE 0x00000040
-#define CCSR_DMA_MR_XFE 0x00000020
-#define CCSR_DMA_MR_CDSM_SWSM 0x00000010
-#define CCSR_DMA_MR_CA 0x00000008
-#define CCSR_DMA_MR_CTM 0x00000004
-#define CCSR_DMA_MR_CC 0x00000002
-#define CCSR_DMA_MR_CS 0x00000001
-
-#define CCSR_DMA_SR_TE 0x00000080
-#define CCSR_DMA_SR_CH 0x00000020
-#define CCSR_DMA_SR_PE 0x00000010
-#define CCSR_DMA_SR_EOLNI 0x00000008
-#define CCSR_DMA_SR_CB 0x00000004
-#define CCSR_DMA_SR_EOSI 0x00000002
-#define CCSR_DMA_SR_EOLSI 0x00000001
-
-/* ECLNDAR takes bits 32-36 of the CLNDAR register */
-static inline u32 CCSR_DMA_ECLNDAR_ADDR(u64 x)
-{
- return (x >> 32) & 0xf;
-}
-
-#define CCSR_DMA_CLNDAR_ADDR(x) ((x) & 0xFFFFFFFE)
-#define CCSR_DMA_CLNDAR_EOSIE 0x00000008
-
-/* SATR and DATR, combined */
-#define CCSR_DMA_ATR_PBATMU 0x20000000
-#define CCSR_DMA_ATR_TFLOWLVL_0 0x00000000
-#define CCSR_DMA_ATR_TFLOWLVL_1 0x06000000
-#define CCSR_DMA_ATR_TFLOWLVL_2 0x08000000
-#define CCSR_DMA_ATR_TFLOWLVL_3 0x0C000000
-#define CCSR_DMA_ATR_PCIORDER 0x02000000
-#define CCSR_DMA_ATR_SME 0x01000000
-#define CCSR_DMA_ATR_NOSNOOP 0x00040000
-#define CCSR_DMA_ATR_SNOOP 0x00050000
-#define CCSR_DMA_ATR_ESAD_MASK 0x0000000F
-
-/**
- * List Descriptor for extended chaining mode DMA operations.
- *
- * The CLSDAR register points to the first (in a linked-list) List
- * Descriptor. Each object must be aligned on a 32-byte boundary. Each
- * list descriptor points to a linked-list of link Descriptors.
- */
-struct fsl_dma_list_descriptor {
- __be64 next; /* Address of next list descriptor */
- __be64 first_link; /* Address of first link descriptor */
- __be32 source; /* Source stride */
- __be32 dest; /* Destination stride */
- u8 res[8]; /* Reserved */
-} __attribute__ ((aligned(32), packed));
-
-/**
- * Link Descriptor for basic and extended chaining mode DMA operations.
- *
- * A Link Descriptor points to a single DMA buffer. Each link descriptor
- * must be aligned on a 32-byte boundary.
- */
-struct fsl_dma_link_descriptor {
- __be32 source_attr; /* Programmed into SATR register */
- __be32 source_addr; /* Programmed into SAR register */
- __be32 dest_attr; /* Programmed into DATR register */
- __be32 dest_addr; /* Programmed into DAR register */
- __be64 next; /* Address of next link descriptor */
- __be32 count; /* Byte count */
- u8 res[4]; /* Reserved */
-} __attribute__ ((aligned(32), packed));
-
-#endif
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c b/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c
deleted file mode 100644
index 2eb407fa..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.c
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/of_platform.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "fsl_ssi.h"
-
-/**
- * FSLSSI_I2S_RATES: sample rates supported by the I2S
- *
- * This driver currently only supports the SSI running in I2S slave mode,
- * which means the codec determines the sample rate. Therefore, we tell
- * ALSA that we support all rates and let the codec driver decide what rates
- * are really supported.
- */
-#define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
- SNDRV_PCM_RATE_CONTINUOUS)
-
-/**
- * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
- *
- * This driver currently only supports the SSI running in I2S slave mode.
- *
- * The SSI has a limitation in that the samples must be in the same byte
- * order as the host CPU. This is because when multiple bytes are written
- * to the STX register, the bytes and bits must be written in the same
- * order. The STX is a shift register, so all the bits need to be aligned
- * (bit-endianness must match byte-endianness). Processors typically write
- * the bits within a byte in the same order that the bytes of a word are
- * written in. So if the host CPU is big-endian, then only big-endian
- * samples will be written to STX properly.
- */
-#ifdef __BIG_ENDIAN
-#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_S20_3BE | \
- SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_S24_BE)
-#else
-#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
-#endif
-
-/* SIER bitflag of interrupts to enable */
-#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \
- CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \
- CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \
- CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \
- CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN)
-
-/**
- * fsl_ssi_private: per-SSI private data
- *
- * @ssi: pointer to the SSI's registers
- * @ssi_phys: physical address of the SSI registers
- * @irq: IRQ of this SSI
- * @first_stream: pointer to the stream that was opened first
- * @second_stream: pointer to second stream
- * @playback: the number of playback streams opened
- * @capture: the number of capture streams opened
- * @cpu_dai: the CPU DAI for this device
- * @dev_attr: the sysfs device attribute structure
- * @stats: SSI statistics
- * @name: name for this device
- */
-struct fsl_ssi_private {
- struct ccsr_ssi __iomem *ssi;
- dma_addr_t ssi_phys;
- unsigned int irq;
- struct snd_pcm_substream *first_stream;
- struct snd_pcm_substream *second_stream;
- unsigned int fifo_depth;
- struct snd_soc_dai_driver cpu_dai_drv;
- struct device_attribute dev_attr;
- struct platform_device *pdev;
-
- struct {
- unsigned int rfrc;
- unsigned int tfrc;
- unsigned int cmdau;
- unsigned int cmddu;
- unsigned int rxt;
- unsigned int rdr1;
- unsigned int rdr0;
- unsigned int tde1;
- unsigned int tde0;
- unsigned int roe1;
- unsigned int roe0;
- unsigned int tue1;
- unsigned int tue0;
- unsigned int tfs;
- unsigned int rfs;
- unsigned int tls;
- unsigned int rls;
- unsigned int rff1;
- unsigned int rff0;
- unsigned int tfe1;
- unsigned int tfe0;
- } stats;
-
- char name[1];
-};
-
-/**
- * fsl_ssi_isr: SSI interrupt handler
- *
- * Although it's possible to use the interrupt handler to send and receive
- * data to/from the SSI, we use the DMA instead. Programming is more
- * complicated, but the performance is much better.
- *
- * This interrupt handler is used only to gather statistics.
- *
- * @irq: IRQ of the SSI device
- * @dev_id: pointer to the ssi_private structure for this SSI device
- */
-static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
-{
- struct fsl_ssi_private *ssi_private = dev_id;
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
- irqreturn_t ret = IRQ_NONE;
- __be32 sisr;
- __be32 sisr2 = 0;
-
- /* We got an interrupt, so read the status register to see what we
- were interrupted for. We mask it with the Interrupt Enable register
- so that we only check for events that we're interested in.
- */
- sisr = in_be32(&ssi->sisr) & SIER_FLAGS;
-
- if (sisr & CCSR_SSI_SISR_RFRC) {
- ssi_private->stats.rfrc++;
- sisr2 |= CCSR_SSI_SISR_RFRC;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFRC) {
- ssi_private->stats.tfrc++;
- sisr2 |= CCSR_SSI_SISR_TFRC;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_CMDAU) {
- ssi_private->stats.cmdau++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_CMDDU) {
- ssi_private->stats.cmddu++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RXT) {
- ssi_private->stats.rxt++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RDR1) {
- ssi_private->stats.rdr1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RDR0) {
- ssi_private->stats.rdr0++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TDE1) {
- ssi_private->stats.tde1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TDE0) {
- ssi_private->stats.tde0++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_ROE1) {
- ssi_private->stats.roe1++;
- sisr2 |= CCSR_SSI_SISR_ROE1;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_ROE0) {
- ssi_private->stats.roe0++;
- sisr2 |= CCSR_SSI_SISR_ROE0;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TUE1) {
- ssi_private->stats.tue1++;
- sisr2 |= CCSR_SSI_SISR_TUE1;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TUE0) {
- ssi_private->stats.tue0++;
- sisr2 |= CCSR_SSI_SISR_TUE0;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFS) {
- ssi_private->stats.tfs++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RFS) {
- ssi_private->stats.rfs++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TLS) {
- ssi_private->stats.tls++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RLS) {
- ssi_private->stats.rls++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RFF1) {
- ssi_private->stats.rff1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_RFF0) {
- ssi_private->stats.rff0++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFE1) {
- ssi_private->stats.tfe1++;
- ret = IRQ_HANDLED;
- }
-
- if (sisr & CCSR_SSI_SISR_TFE0) {
- ssi_private->stats.tfe0++;
- ret = IRQ_HANDLED;
- }
-
- /* Clear the bits that we set */
- if (sisr2)
- out_be32(&ssi->sisr, sisr2);
-
- return ret;
-}
-
-/**
- * fsl_ssi_startup: create a new substream
- *
- * This is the first function called when a stream is opened.
- *
- * If this is the first stream open, then grab the IRQ and program most of
- * the SSI registers.
- */
-static int fsl_ssi_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct fsl_ssi_private *ssi_private =
- snd_soc_dai_get_drvdata(rtd->cpu_dai);
- int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
-
- /*
- * If this is the first stream opened, then request the IRQ
- * and initialize the SSI registers.
- */
- if (!ssi_private->first_stream) {
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
- ssi_private->first_stream = substream;
-
- /*
- * Section 16.5 of the MPC8610 reference manual says that the
- * SSI needs to be disabled before updating the registers we set
- * here.
- */
- clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
-
- /*
- * Program the SSI into I2S Slave Non-Network Synchronous mode.
- * Also enable the transmit and receive FIFO.
- *
- * FIXME: Little-endian samples require a different shift dir
- */
- clrsetbits_be32(&ssi->scr,
- CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
- CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
- | (synchronous ? CCSR_SSI_SCR_SYN : 0));
-
- out_be32(&ssi->stcr,
- CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
- CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
- CCSR_SSI_STCR_TSCKP);
-
- out_be32(&ssi->srcr,
- CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
- CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
- CCSR_SSI_SRCR_RSCKP);
-
- /*
- * The DC and PM bits are only used if the SSI is the clock
- * master.
- */
-
- /* Enable the interrupts and DMA requests */
- out_be32(&ssi->sier, SIER_FLAGS);
-
- /*
- * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
- * don't use FIFO 1. We program the transmit water to signal a
- * DMA transfer if there are only two (or fewer) elements left
- * in the FIFO. Two elements equals one frame (left channel,
- * right channel). This value, however, depends on the depth of
- * the transmit buffer.
- *
- * We program the receive FIFO to notify us if at least two
- * elements (one frame) have been written to the FIFO. We could
- * make this value larger (and maybe we should), but this way
- * data will be written to memory as soon as it's available.
- */
- out_be32(&ssi->sfcsr,
- CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
- CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2));
-
- /*
- * We keep the SSI disabled because if we enable it, then the
- * DMA controller will start. It's not supposed to start until
- * the SCR.TE (or SCR.RE) bit is set, but it does anyway. The
- * DMA controller will transfer one "BWC" of data (i.e. the
- * amount of data that the MR.BWC bits are set to). The reason
- * this is bad is because at this point, the PCM driver has not
- * finished initializing the DMA controller.
- */
- } else {
- if (synchronous) {
- struct snd_pcm_runtime *first_runtime =
- ssi_private->first_stream->runtime;
- /*
- * This is the second stream open, and we're in
- * synchronous mode, so we need to impose sample
- * sample size constraints. This is because STCCR is
- * used for playback and capture in synchronous mode,
- * so there's no way to specify different word
- * lengths.
- *
- * Note that this can cause a race condition if the
- * second stream is opened before the first stream is
- * fully initialized. We provide some protection by
- * checking to make sure the first stream is
- * initialized, but it's not perfect. ALSA sometimes
- * re-initializes the driver with a different sample
- * rate or size. If the second stream is opened
- * before the first stream has received its final
- * parameters, then the second stream may be
- * constrained to the wrong sample rate or size.
- */
- if (!first_runtime->sample_bits) {
- dev_err(substream->pcm->card->dev,
- "set sample size in %s stream first\n",
- substream->stream ==
- SNDRV_PCM_STREAM_PLAYBACK
- ? "capture" : "playback");
- return -EAGAIN;
- }
-
- snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
- first_runtime->sample_bits,
- first_runtime->sample_bits);
- }
-
- ssi_private->second_stream = substream;
- }
-
- return 0;
-}
-
-/**
- * fsl_ssi_hw_params - program the sample size
- *
- * Most of the SSI registers have been programmed in the startup function,
- * but the word length must be programmed here. Unfortunately, programming
- * the SxCCR.WL bits requires the SSI to be temporarily disabled. This can
- * cause a problem with supporting simultaneous playback and capture. If
- * the SSI is already playing a stream, then that stream may be temporarily
- * stopped when you start capture.
- *
- * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
- * clock master.
- */
-static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
-{
- struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
- unsigned int sample_size =
- snd_pcm_format_width(params_format(hw_params));
- u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
- int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
-
- /*
- * If we're in synchronous mode, and the SSI is already enabled,
- * then STCCR is already set properly.
- */
- if (enabled && ssi_private->cpu_dai_drv.symmetric_rates)
- return 0;
-
- /*
- * FIXME: The documentation says that SxCCR[WL] should not be
- * modified while the SSI is enabled. The only time this can
- * happen is if we're trying to do simultaneous playback and
- * capture in asynchronous mode. Unfortunately, I have been enable
- * to get that to work at all on the P1022DS. Therefore, we don't
- * bother to disable/enable the SSI when setting SxCCR[WL], because
- * the SSI will stop anyway. Maybe one day, this will get fixed.
- */
-
- /* In synchronous mode, the SSI uses STCCR for capture */
- if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
- ssi_private->cpu_dai_drv.symmetric_rates)
- clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
- else
- clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
-
- return 0;
-}
-
-/**
- * fsl_ssi_trigger: start and stop the DMA transfer.
- *
- * This function is called by ALSA to start, stop, pause, and resume the DMA
- * transfer of data.
- *
- * The DMA channel is in external master start and pause mode, which
- * means the SSI completely controls the flow of data.
- */
-static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- setbits32(&ssi->scr,
- CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
- else
- setbits32(&ssi->scr,
- CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- clrbits32(&ssi->scr, CCSR_SSI_SCR_TE);
- else
- clrbits32(&ssi->scr, CCSR_SSI_SCR_RE);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**
- * fsl_ssi_shutdown: shutdown the SSI
- *
- * Shutdown the SSI if there are no other substreams open.
- */
-static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
-
- if (ssi_private->first_stream == substream)
- ssi_private->first_stream = ssi_private->second_stream;
-
- ssi_private->second_stream = NULL;
-
- /*
- * If this is the last active substream, disable the SSI.
- */
- if (!ssi_private->first_stream) {
- struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
-
- clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN);
- }
-}
-
-static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
- .startup = fsl_ssi_startup,
- .hw_params = fsl_ssi_hw_params,
- .shutdown = fsl_ssi_shutdown,
- .trigger = fsl_ssi_trigger,
-};
-
-/* Template for the CPU dai driver structure */
-static struct snd_soc_dai_driver fsl_ssi_dai_template = {
- .playback = {
- /* The SSI does not support monaural audio. */
- .channels_min = 2,
- .channels_max = 2,
- .rates = FSLSSI_I2S_RATES,
- .formats = FSLSSI_I2S_FORMATS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = FSLSSI_I2S_RATES,
- .formats = FSLSSI_I2S_FORMATS,
- },
- .ops = &fsl_ssi_dai_ops,
-};
-
-/* Show the statistics of a flag only if its interrupt is enabled. The
- * compiler will optimze this code to a no-op if the interrupt is not
- * enabled.
- */
-#define SIER_SHOW(flag, name) \
- do { \
- if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
- length += sprintf(buf + length, #name "=%u\n", \
- ssi_private->stats.name); \
- } while (0)
-
-
-/**
- * fsl_sysfs_ssi_show: display SSI statistics
- *
- * Display the statistics for the current SSI device. To avoid confusion,
- * we only show those counts that are enabled.
- */
-static ssize_t fsl_sysfs_ssi_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct fsl_ssi_private *ssi_private =
- container_of(attr, struct fsl_ssi_private, dev_attr);
- ssize_t length = 0;
-
- SIER_SHOW(RFRC_EN, rfrc);
- SIER_SHOW(TFRC_EN, tfrc);
- SIER_SHOW(CMDAU_EN, cmdau);
- SIER_SHOW(CMDDU_EN, cmddu);
- SIER_SHOW(RXT_EN, rxt);
- SIER_SHOW(RDR1_EN, rdr1);
- SIER_SHOW(RDR0_EN, rdr0);
- SIER_SHOW(TDE1_EN, tde1);
- SIER_SHOW(TDE0_EN, tde0);
- SIER_SHOW(ROE1_EN, roe1);
- SIER_SHOW(ROE0_EN, roe0);
- SIER_SHOW(TUE1_EN, tue1);
- SIER_SHOW(TUE0_EN, tue0);
- SIER_SHOW(TFS_EN, tfs);
- SIER_SHOW(RFS_EN, rfs);
- SIER_SHOW(TLS_EN, tls);
- SIER_SHOW(RLS_EN, rls);
- SIER_SHOW(RFF1_EN, rff1);
- SIER_SHOW(RFF0_EN, rff0);
- SIER_SHOW(TFE1_EN, tfe1);
- SIER_SHOW(TFE0_EN, tfe0);
-
- return length;
-}
-
-/**
- * Make every character in a string lower-case
- */
-static void make_lowercase(char *s)
-{
- char *p = s;
- char c;
-
- while ((c = *p)) {
- if ((c >= 'A') && (c <= 'Z'))
- *p = c + ('a' - 'A');
- p++;
- }
-}
-
-static int __devinit fsl_ssi_probe(struct platform_device *pdev)
-{
- struct fsl_ssi_private *ssi_private;
- int ret = 0;
- struct device_attribute *dev_attr = NULL;
- struct device_node *np = pdev->dev.of_node;
- const char *p, *sprop;
- const uint32_t *iprop;
- struct resource res;
- char name[64];
-
- /* SSIs that are not connected on the board should have a
- * status = "disabled"
- * property in their device tree nodes.
- */
- if (!of_device_is_available(np))
- return -ENODEV;
-
- /* Check for a codec-handle property. */
- if (!of_get_property(np, "codec-handle", NULL)) {
- dev_err(&pdev->dev, "missing codec-handle property\n");
- return -ENODEV;
- }
-
- /* We only support the SSI in "I2S Slave" mode */
- sprop = of_get_property(np, "fsl,mode", NULL);
- if (!sprop || strcmp(sprop, "i2s-slave")) {
- dev_notice(&pdev->dev, "mode %s is unsupported\n", sprop);
- return -ENODEV;
- }
-
- /* The DAI name is the last part of the full name of the node. */
- p = strrchr(np->full_name, '/') + 1;
- ssi_private = kzalloc(sizeof(struct fsl_ssi_private) + strlen(p),
- GFP_KERNEL);
- if (!ssi_private) {
- dev_err(&pdev->dev, "could not allocate DAI object\n");
- return -ENOMEM;
- }
-
- strcpy(ssi_private->name, p);
-
- /* Initialize this copy of the CPU DAI driver structure */
- memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
- sizeof(fsl_ssi_dai_template));
- ssi_private->cpu_dai_drv.name = ssi_private->name;
-
- /* Get the addresses and IRQ */
- ret = of_address_to_resource(np, 0, &res);
- if (ret) {
- dev_err(&pdev->dev, "could not determine device resources\n");
- goto error_kmalloc;
- }
- ssi_private->ssi = of_iomap(np, 0);
- if (!ssi_private->ssi) {
- dev_err(&pdev->dev, "could not map device resources\n");
- ret = -ENOMEM;
- goto error_kmalloc;
- }
- ssi_private->ssi_phys = res.start;
-
- ssi_private->irq = irq_of_parse_and_map(np, 0);
- if (ssi_private->irq == NO_IRQ) {
- dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
- ret = -ENXIO;
- goto error_iomap;
- }
-
- /* The 'name' should not have any slashes in it. */
- ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
- ssi_private);
- if (ret < 0) {
- dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
- goto error_irqmap;
- }
-
- /* Are the RX and the TX clocks locked? */
- if (!of_find_property(np, "fsl,ssi-asynchronous", NULL))
- ssi_private->cpu_dai_drv.symmetric_rates = 1;
-
- /* Determine the FIFO depth. */
- iprop = of_get_property(np, "fsl,fifo-depth", NULL);
- if (iprop)
- ssi_private->fifo_depth = be32_to_cpup(iprop);
- else
- /* Older 8610 DTs didn't have the fifo-depth property */
- ssi_private->fifo_depth = 8;
-
- /* Initialize the the device_attribute structure */
- dev_attr = &ssi_private->dev_attr;
- sysfs_attr_init(&dev_attr->attr);
- dev_attr->attr.name = "statistics";
- dev_attr->attr.mode = S_IRUGO;
- dev_attr->show = fsl_sysfs_ssi_show;
-
- ret = device_create_file(&pdev->dev, dev_attr);
- if (ret) {
- dev_err(&pdev->dev, "could not create sysfs %s file\n",
- ssi_private->dev_attr.attr.name);
- goto error_irq;
- }
-
- /* Register with ASoC */
- dev_set_drvdata(&pdev->dev, ssi_private);
-
- ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv);
- if (ret) {
- dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
- goto error_dev;
- }
-
- /* Trigger the machine driver's probe function. The platform driver
- * name of the machine driver is taken from /compatible property of the
- * device tree. We also pass the address of the CPU DAI driver
- * structure.
- */
- sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL);
- /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */
- p = strrchr(sprop, ',');
- if (p)
- sprop = p + 1;
- snprintf(name, sizeof(name), "snd-soc-%s", sprop);
- make_lowercase(name);
-
- ssi_private->pdev =
- platform_device_register_data(&pdev->dev, name, 0, NULL, 0);
- if (IS_ERR(ssi_private->pdev)) {
- ret = PTR_ERR(ssi_private->pdev);
- dev_err(&pdev->dev, "failed to register platform: %d\n", ret);
- goto error_dai;
- }
-
- return 0;
-
-error_dai:
- snd_soc_unregister_dai(&pdev->dev);
-
-error_dev:
- dev_set_drvdata(&pdev->dev, NULL);
- device_remove_file(&pdev->dev, dev_attr);
-
-error_irq:
- free_irq(ssi_private->irq, ssi_private);
-
-error_irqmap:
- irq_dispose_mapping(ssi_private->irq);
-
-error_iomap:
- iounmap(ssi_private->ssi);
-
-error_kmalloc:
- kfree(ssi_private);
-
- return ret;
-}
-
-static int fsl_ssi_remove(struct platform_device *pdev)
-{
- struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
-
- platform_device_unregister(ssi_private->pdev);
- snd_soc_unregister_dai(&pdev->dev);
- device_remove_file(&pdev->dev, &ssi_private->dev_attr);
-
- free_irq(ssi_private->irq, ssi_private);
- irq_dispose_mapping(ssi_private->irq);
-
- kfree(ssi_private);
- dev_set_drvdata(&pdev->dev, NULL);
-
- return 0;
-}
-
-static const struct of_device_id fsl_ssi_ids[] = {
- { .compatible = "fsl,mpc8610-ssi", },
- {}
-};
-MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
-
-static struct platform_driver fsl_ssi_driver = {
- .driver = {
- .name = "fsl-ssi-dai",
- .owner = THIS_MODULE,
- .of_match_table = fsl_ssi_ids,
- },
- .probe = fsl_ssi_probe,
- .remove = fsl_ssi_remove,
-};
-
-module_platform_driver(fsl_ssi_driver);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h b/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h
deleted file mode 100644
index 21730002..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/fsl_ssi.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * fsl_ssi.h - ALSA SSI interface for the Freescale MPC8610 SoC
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed
- * under the terms of the GNU General Public License version 2. This
- * program is licensed "as is" without any warranty of any kind, whether
- * express or implied.
- */
-
-#ifndef _MPC8610_I2S_H
-#define _MPC8610_I2S_H
-
-/* SSI Register Map */
-struct ccsr_ssi {
- __be32 stx0; /* 0x.0000 - SSI Transmit Data Register 0 */
- __be32 stx1; /* 0x.0004 - SSI Transmit Data Register 1 */
- __be32 srx0; /* 0x.0008 - SSI Receive Data Register 0 */
- __be32 srx1; /* 0x.000C - SSI Receive Data Register 1 */
- __be32 scr; /* 0x.0010 - SSI Control Register */
- __be32 sisr; /* 0x.0014 - SSI Interrupt Status Register Mixed */
- __be32 sier; /* 0x.0018 - SSI Interrupt Enable Register */
- __be32 stcr; /* 0x.001C - SSI Transmit Configuration Register */
- __be32 srcr; /* 0x.0020 - SSI Receive Configuration Register */
- __be32 stccr; /* 0x.0024 - SSI Transmit Clock Control Register */
- __be32 srccr; /* 0x.0028 - SSI Receive Clock Control Register */
- __be32 sfcsr; /* 0x.002C - SSI FIFO Control/Status Register */
- __be32 str; /* 0x.0030 - SSI Test Register */
- __be32 sor; /* 0x.0034 - SSI Option Register */
- __be32 sacnt; /* 0x.0038 - SSI AC97 Control Register */
- __be32 sacadd; /* 0x.003C - SSI AC97 Command Address Register */
- __be32 sacdat; /* 0x.0040 - SSI AC97 Command Data Register */
- __be32 satag; /* 0x.0044 - SSI AC97 Tag Register */
- __be32 stmsk; /* 0x.0048 - SSI Transmit Time Slot Mask Register */
- __be32 srmsk; /* 0x.004C - SSI Receive Time Slot Mask Register */
- __be32 saccst; /* 0x.0050 - SSI AC97 Channel Status Register */
- __be32 saccen; /* 0x.0054 - SSI AC97 Channel Enable Register */
- __be32 saccdis; /* 0x.0058 - SSI AC97 Channel Disable Register */
-};
-
-#define CCSR_SSI_SCR_RFR_CLK_DIS 0x00000800
-#define CCSR_SSI_SCR_TFR_CLK_DIS 0x00000400
-#define CCSR_SSI_SCR_TCH_EN 0x00000100
-#define CCSR_SSI_SCR_SYS_CLK_EN 0x00000080
-#define CCSR_SSI_SCR_I2S_MODE_MASK 0x00000060
-#define CCSR_SSI_SCR_I2S_MODE_NORMAL 0x00000000
-#define CCSR_SSI_SCR_I2S_MODE_MASTER 0x00000020
-#define CCSR_SSI_SCR_I2S_MODE_SLAVE 0x00000040
-#define CCSR_SSI_SCR_SYN 0x00000010
-#define CCSR_SSI_SCR_NET 0x00000008
-#define CCSR_SSI_SCR_RE 0x00000004
-#define CCSR_SSI_SCR_TE 0x00000002
-#define CCSR_SSI_SCR_SSIEN 0x00000001
-
-#define CCSR_SSI_SISR_RFRC 0x01000000
-#define CCSR_SSI_SISR_TFRC 0x00800000
-#define CCSR_SSI_SISR_CMDAU 0x00040000
-#define CCSR_SSI_SISR_CMDDU 0x00020000
-#define CCSR_SSI_SISR_RXT 0x00010000
-#define CCSR_SSI_SISR_RDR1 0x00008000
-#define CCSR_SSI_SISR_RDR0 0x00004000
-#define CCSR_SSI_SISR_TDE1 0x00002000
-#define CCSR_SSI_SISR_TDE0 0x00001000
-#define CCSR_SSI_SISR_ROE1 0x00000800
-#define CCSR_SSI_SISR_ROE0 0x00000400
-#define CCSR_SSI_SISR_TUE1 0x00000200
-#define CCSR_SSI_SISR_TUE0 0x00000100
-#define CCSR_SSI_SISR_TFS 0x00000080
-#define CCSR_SSI_SISR_RFS 0x00000040
-#define CCSR_SSI_SISR_TLS 0x00000020
-#define CCSR_SSI_SISR_RLS 0x00000010
-#define CCSR_SSI_SISR_RFF1 0x00000008
-#define CCSR_SSI_SISR_RFF0 0x00000004
-#define CCSR_SSI_SISR_TFE1 0x00000002
-#define CCSR_SSI_SISR_TFE0 0x00000001
-
-#define CCSR_SSI_SIER_RFRC_EN 0x01000000
-#define CCSR_SSI_SIER_TFRC_EN 0x00800000
-#define CCSR_SSI_SIER_RDMAE 0x00400000
-#define CCSR_SSI_SIER_RIE 0x00200000
-#define CCSR_SSI_SIER_TDMAE 0x00100000
-#define CCSR_SSI_SIER_TIE 0x00080000
-#define CCSR_SSI_SIER_CMDAU_EN 0x00040000
-#define CCSR_SSI_SIER_CMDDU_EN 0x00020000
-#define CCSR_SSI_SIER_RXT_EN 0x00010000
-#define CCSR_SSI_SIER_RDR1_EN 0x00008000
-#define CCSR_SSI_SIER_RDR0_EN 0x00004000
-#define CCSR_SSI_SIER_TDE1_EN 0x00002000
-#define CCSR_SSI_SIER_TDE0_EN 0x00001000
-#define CCSR_SSI_SIER_ROE1_EN 0x00000800
-#define CCSR_SSI_SIER_ROE0_EN 0x00000400
-#define CCSR_SSI_SIER_TUE1_EN 0x00000200
-#define CCSR_SSI_SIER_TUE0_EN 0x00000100
-#define CCSR_SSI_SIER_TFS_EN 0x00000080
-#define CCSR_SSI_SIER_RFS_EN 0x00000040
-#define CCSR_SSI_SIER_TLS_EN 0x00000020
-#define CCSR_SSI_SIER_RLS_EN 0x00000010
-#define CCSR_SSI_SIER_RFF1_EN 0x00000008
-#define CCSR_SSI_SIER_RFF0_EN 0x00000004
-#define CCSR_SSI_SIER_TFE1_EN 0x00000002
-#define CCSR_SSI_SIER_TFE0_EN 0x00000001
-
-#define CCSR_SSI_STCR_TXBIT0 0x00000200
-#define CCSR_SSI_STCR_TFEN1 0x00000100
-#define CCSR_SSI_STCR_TFEN0 0x00000080
-#define CCSR_SSI_STCR_TFDIR 0x00000040
-#define CCSR_SSI_STCR_TXDIR 0x00000020
-#define CCSR_SSI_STCR_TSHFD 0x00000010
-#define CCSR_SSI_STCR_TSCKP 0x00000008
-#define CCSR_SSI_STCR_TFSI 0x00000004
-#define CCSR_SSI_STCR_TFSL 0x00000002
-#define CCSR_SSI_STCR_TEFS 0x00000001
-
-#define CCSR_SSI_SRCR_RXEXT 0x00000400
-#define CCSR_SSI_SRCR_RXBIT0 0x00000200
-#define CCSR_SSI_SRCR_RFEN1 0x00000100
-#define CCSR_SSI_SRCR_RFEN0 0x00000080
-#define CCSR_SSI_SRCR_RFDIR 0x00000040
-#define CCSR_SSI_SRCR_RXDIR 0x00000020
-#define CCSR_SSI_SRCR_RSHFD 0x00000010
-#define CCSR_SSI_SRCR_RSCKP 0x00000008
-#define CCSR_SSI_SRCR_RFSI 0x00000004
-#define CCSR_SSI_SRCR_RFSL 0x00000002
-#define CCSR_SSI_SRCR_REFS 0x00000001
-
-/* STCCR and SRCCR */
-#define CCSR_SSI_SxCCR_DIV2 0x00040000
-#define CCSR_SSI_SxCCR_PSR 0x00020000
-#define CCSR_SSI_SxCCR_WL_SHIFT 13
-#define CCSR_SSI_SxCCR_WL_MASK 0x0001E000
-#define CCSR_SSI_SxCCR_WL(x) \
- (((((x) / 2) - 1) << CCSR_SSI_SxCCR_WL_SHIFT) & CCSR_SSI_SxCCR_WL_MASK)
-#define CCSR_SSI_SxCCR_DC_SHIFT 8
-#define CCSR_SSI_SxCCR_DC_MASK 0x00001F00
-#define CCSR_SSI_SxCCR_DC(x) \
- ((((x) - 1) << CCSR_SSI_SxCCR_DC_SHIFT) & CCSR_SSI_SxCCR_DC_MASK)
-#define CCSR_SSI_SxCCR_PM_SHIFT 0
-#define CCSR_SSI_SxCCR_PM_MASK 0x000000FF
-#define CCSR_SSI_SxCCR_PM(x) \
- ((((x) - 1) << CCSR_SSI_SxCCR_PM_SHIFT) & CCSR_SSI_SxCCR_PM_MASK)
-
-/*
- * The xFCNT bits are read-only, and the xFWM bits are read/write. Use the
- * CCSR_SSI_SFCSR_xFCNTy() macros to read the FIFO counters, and use the
- * CCSR_SSI_SFCSR_xFWMy() macros to set the watermarks.
- */
-#define CCSR_SSI_SFCSR_RFCNT1_SHIFT 28
-#define CCSR_SSI_SFCSR_RFCNT1_MASK 0xF0000000
-#define CCSR_SSI_SFCSR_RFCNT1(x) \
- (((x) & CCSR_SSI_SFCSR_RFCNT1_MASK) >> CCSR_SSI_SFCSR_RFCNT1_SHIFT)
-#define CCSR_SSI_SFCSR_TFCNT1_SHIFT 24
-#define CCSR_SSI_SFCSR_TFCNT1_MASK 0x0F000000
-#define CCSR_SSI_SFCSR_TFCNT1(x) \
- (((x) & CCSR_SSI_SFCSR_TFCNT1_MASK) >> CCSR_SSI_SFCSR_TFCNT1_SHIFT)
-#define CCSR_SSI_SFCSR_RFWM1_SHIFT 20
-#define CCSR_SSI_SFCSR_RFWM1_MASK 0x00F00000
-#define CCSR_SSI_SFCSR_RFWM1(x) \
- (((x) << CCSR_SSI_SFCSR_RFWM1_SHIFT) & CCSR_SSI_SFCSR_RFWM1_MASK)
-#define CCSR_SSI_SFCSR_TFWM1_SHIFT 16
-#define CCSR_SSI_SFCSR_TFWM1_MASK 0x000F0000
-#define CCSR_SSI_SFCSR_TFWM1(x) \
- (((x) << CCSR_SSI_SFCSR_TFWM1_SHIFT) & CCSR_SSI_SFCSR_TFWM1_MASK)
-#define CCSR_SSI_SFCSR_RFCNT0_SHIFT 12
-#define CCSR_SSI_SFCSR_RFCNT0_MASK 0x0000F000
-#define CCSR_SSI_SFCSR_RFCNT0(x) \
- (((x) & CCSR_SSI_SFCSR_RFCNT0_MASK) >> CCSR_SSI_SFCSR_RFCNT0_SHIFT)
-#define CCSR_SSI_SFCSR_TFCNT0_SHIFT 8
-#define CCSR_SSI_SFCSR_TFCNT0_MASK 0x00000F00
-#define CCSR_SSI_SFCSR_TFCNT0(x) \
- (((x) & CCSR_SSI_SFCSR_TFCNT0_MASK) >> CCSR_SSI_SFCSR_TFCNT0_SHIFT)
-#define CCSR_SSI_SFCSR_RFWM0_SHIFT 4
-#define CCSR_SSI_SFCSR_RFWM0_MASK 0x000000F0
-#define CCSR_SSI_SFCSR_RFWM0(x) \
- (((x) << CCSR_SSI_SFCSR_RFWM0_SHIFT) & CCSR_SSI_SFCSR_RFWM0_MASK)
-#define CCSR_SSI_SFCSR_TFWM0_SHIFT 0
-#define CCSR_SSI_SFCSR_TFWM0_MASK 0x0000000F
-#define CCSR_SSI_SFCSR_TFWM0(x) \
- (((x) << CCSR_SSI_SFCSR_TFWM0_SHIFT) & CCSR_SSI_SFCSR_TFWM0_MASK)
-
-#define CCSR_SSI_STR_TEST 0x00008000
-#define CCSR_SSI_STR_RCK2TCK 0x00004000
-#define CCSR_SSI_STR_RFS2TFS 0x00002000
-#define CCSR_SSI_STR_RXSTATE(x) (((x) >> 8) & 0x1F)
-#define CCSR_SSI_STR_TXD2RXD 0x00000080
-#define CCSR_SSI_STR_TCK2RCK 0x00000040
-#define CCSR_SSI_STR_TFS2RFS 0x00000020
-#define CCSR_SSI_STR_TXSTATE(x) ((x) & 0x1F)
-
-#define CCSR_SSI_SOR_CLKOFF 0x00000040
-#define CCSR_SSI_SOR_RX_CLR 0x00000020
-#define CCSR_SSI_SOR_TX_CLR 0x00000010
-#define CCSR_SSI_SOR_INIT 0x00000008
-#define CCSR_SSI_SOR_WAIT_SHIFT 1
-#define CCSR_SSI_SOR_WAIT_MASK 0x00000006
-#define CCSR_SSI_SOR_WAIT(x) (((x) & 3) << CCSR_SSI_SOR_WAIT_SHIFT)
-#define CCSR_SSI_SOR_SYNRST 0x00000001
-
-#endif
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c
deleted file mode 100644
index 9a3f7c5a..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Freescale MPC5200 PSC DMA
- * ALSA SoC Platform driver
- *
- * Copyright (C) 2008 Secret Lab Technologies Ltd.
- * Copyright (C) 2009 Jon Smirl, Digispeaker
- */
-
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/of_platform.h>
-
-#include <sound/soc.h>
-
-#include <sysdev/bestcomm/bestcomm.h>
-#include <sysdev/bestcomm/gen_bd.h>
-#include <asm/mpc52xx_psc.h>
-
-#include "mpc5200_dma.h"
-
-/*
- * Interrupt handlers
- */
-static irqreturn_t psc_dma_status_irq(int irq, void *_psc_dma)
-{
- struct psc_dma *psc_dma = _psc_dma;
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
- u16 isr;
-
- isr = in_be16(&regs->mpc52xx_psc_isr);
-
- /* Playback underrun error */
- if (psc_dma->playback.active && (isr & MPC52xx_PSC_IMR_TXEMP))
- psc_dma->stats.underrun_count++;
-
- /* Capture overrun error */
- if (psc_dma->capture.active && (isr & MPC52xx_PSC_IMR_ORERR))
- psc_dma->stats.overrun_count++;
-
- out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
-
- return IRQ_HANDLED;
-}
-
-/**
- * psc_dma_bcom_enqueue_next_buffer - Enqueue another audio buffer
- * @s: pointer to stream private data structure
- *
- * Enqueues another audio period buffer into the bestcomm queue.
- *
- * Note: The routine must only be called when there is space available in
- * the queue. Otherwise the enqueue will fail and the audio ring buffer
- * will get out of sync
- */
-static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s)
-{
- struct bcom_bd *bd;
-
- /* Prepare and enqueue the next buffer descriptor */
- bd = bcom_prepare_next_buffer(s->bcom_task);
- bd->status = s->period_bytes;
- bd->data[0] = s->runtime->dma_addr + (s->period_next * s->period_bytes);
- bcom_submit_next_buffer(s->bcom_task, NULL);
-
- /* Update for next period */
- s->period_next = (s->period_next + 1) % s->runtime->periods;
-}
-
-/* Bestcomm DMA irq handler */
-static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream)
-{
- struct psc_dma_stream *s = _psc_dma_stream;
-
- spin_lock(&s->psc_dma->lock);
- /* For each finished period, dequeue the completed period buffer
- * and enqueue a new one in it's place. */
- while (bcom_buffer_done(s->bcom_task)) {
- bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
-
- s->period_current = (s->period_current+1) % s->runtime->periods;
- s->period_count++;
-
- psc_dma_bcom_enqueue_next_buffer(s);
- }
- spin_unlock(&s->psc_dma->lock);
-
- /* If the stream is active, then also inform the PCM middle layer
- * of the period finished event. */
- if (s->active)
- snd_pcm_period_elapsed(s->stream);
-
- return IRQ_HANDLED;
-}
-
-static int psc_dma_hw_free(struct snd_pcm_substream *substream)
-{
- snd_pcm_set_runtime_buffer(substream, NULL);
- return 0;
-}
-
-/**
- * psc_dma_trigger: start and stop the DMA transfer.
- *
- * This function is called by ALSA to start, stop, pause, and resume the DMA
- * transfer of data.
- */
-static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
- u16 imr;
- unsigned long flags;
- int i;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dev_dbg(psc_dma->dev, "START: stream=%i fbits=%u ps=%u #p=%u\n",
- substream->pstr->stream, runtime->frame_bits,
- (int)runtime->period_size, runtime->periods);
- s->period_bytes = frames_to_bytes(runtime,
- runtime->period_size);
- s->period_next = 0;
- s->period_current = 0;
- s->active = 1;
- s->period_count = 0;
- s->runtime = runtime;
-
- /* Fill up the bestcomm bd queue and enable DMA.
- * This will begin filling the PSC's fifo.
- */
- spin_lock_irqsave(&psc_dma->lock, flags);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- bcom_gen_bd_rx_reset(s->bcom_task);
- else
- bcom_gen_bd_tx_reset(s->bcom_task);
-
- for (i = 0; i < runtime->periods; i++)
- if (!bcom_queue_full(s->bcom_task))
- psc_dma_bcom_enqueue_next_buffer(s);
-
- bcom_enable(s->bcom_task);
- spin_unlock_irqrestore(&psc_dma->lock, flags);
-
- out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
-
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- dev_dbg(psc_dma->dev, "STOP: stream=%i periods_count=%i\n",
- substream->pstr->stream, s->period_count);
- s->active = 0;
-
- spin_lock_irqsave(&psc_dma->lock, flags);
- bcom_disable(s->bcom_task);
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- bcom_gen_bd_rx_reset(s->bcom_task);
- else
- bcom_gen_bd_tx_reset(s->bcom_task);
- spin_unlock_irqrestore(&psc_dma->lock, flags);
-
- break;
-
- default:
- dev_dbg(psc_dma->dev, "unhandled trigger: stream=%i cmd=%i\n",
- substream->pstr->stream, cmd);
- return -EINVAL;
- }
-
- /* Update interrupt enable settings */
- imr = 0;
- if (psc_dma->playback.active)
- imr |= MPC52xx_PSC_IMR_TXEMP;
- if (psc_dma->capture.active)
- imr |= MPC52xx_PSC_IMR_ORERR;
- out_be16(&regs->isr_imr.imr, psc_dma->imr | imr);
-
- return 0;
-}
-
-
-/* ---------------------------------------------------------------------
- * The PSC DMA 'ASoC platform' driver
- *
- * Can be referenced by an 'ASoC machine' driver
- * This driver only deals with the audio bus; it doesn't have any
- * interaction with the attached codec
- */
-
-static const struct snd_pcm_hardware psc_dma_hardware = {
- .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_BATCH,
- .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
- SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 2,
- .period_bytes_max = 1024 * 1024,
- .period_bytes_min = 32,
- .periods_min = 2,
- .periods_max = 256,
- .buffer_bytes_max = 2 * 1024 * 1024,
- .fifo_size = 512,
-};
-
-static int psc_dma_open(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct psc_dma_stream *s;
- int rc;
-
- dev_dbg(psc_dma->dev, "psc_dma_open(substream=%p)\n", substream);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- s = &psc_dma->capture;
- else
- s = &psc_dma->playback;
-
- snd_soc_set_runtime_hwparams(substream, &psc_dma_hardware);
-
- rc = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
- if (rc < 0) {
- dev_err(substream->pcm->card->dev, "invalid buffer size\n");
- return rc;
- }
-
- s->stream = substream;
- return 0;
-}
-
-static int psc_dma_close(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct psc_dma_stream *s;
-
- dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream);
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- s = &psc_dma->capture;
- else
- s = &psc_dma->playback;
-
- if (!psc_dma->playback.active &&
- !psc_dma->capture.active) {
-
- /* Disable all interrupts and reset the PSC */
- out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
- out_8(&psc_dma->psc_regs->command, 4 << 4); /* reset error */
- }
- s->stream = NULL;
- return 0;
-}
-
-static snd_pcm_uframes_t
-psc_dma_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct psc_dma_stream *s;
- dma_addr_t count;
-
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- s = &psc_dma->capture;
- else
- s = &psc_dma->playback;
-
- count = s->period_current * s->period_bytes;
-
- return bytes_to_frames(substream->runtime, count);
-}
-
-static int
-psc_dma_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-
- return 0;
-}
-
-static struct snd_pcm_ops psc_dma_ops = {
- .open = psc_dma_open,
- .close = psc_dma_close,
- .hw_free = psc_dma_hw_free,
- .ioctl = snd_pcm_lib_ioctl,
- .pointer = psc_dma_pointer,
- .trigger = psc_dma_trigger,
- .hw_params = psc_dma_hw_params,
-};
-
-static u64 psc_dma_dmamask = DMA_BIT_MASK(32);
-static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_card *card = rtd->card->snd_card;
- struct snd_soc_dai *dai = rtd->cpu_dai;
- struct snd_pcm *pcm = rtd->pcm;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- size_t size = psc_dma_hardware.buffer_bytes_max;
- int rc = 0;
-
- dev_dbg(rtd->platform->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
- card, dai, pcm);
-
- if (!card->dev->dma_mask)
- card->dev->dma_mask = &psc_dma_dmamask;
- if (!card->dev->coherent_dma_mask)
- card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
- rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
- size, &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
- if (rc)
- goto playback_alloc_err;
- }
-
- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
- rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
- size, &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
- if (rc)
- goto capture_alloc_err;
- }
-
- if (rtd->codec->ac97)
- rtd->codec->ac97->private_data = psc_dma;
-
- return 0;
-
- capture_alloc_err:
- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
- snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
-
- playback_alloc_err:
- dev_err(card->dev, "Cannot allocate buffer(s)\n");
-
- return -ENOMEM;
-}
-
-static void psc_dma_free(struct snd_pcm *pcm)
-{
- struct snd_soc_pcm_runtime *rtd = pcm->private_data;
- struct snd_pcm_substream *substream;
- int stream;
-
- dev_dbg(rtd->platform->dev, "psc_dma_free(pcm=%p)\n", pcm);
-
- for (stream = 0; stream < 2; stream++) {
- substream = pcm->streams[stream].substream;
- if (substream) {
- snd_dma_free_pages(&substream->dma_buffer);
- substream->dma_buffer.area = NULL;
- substream->dma_buffer.addr = 0;
- }
- }
-}
-
-static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
- .ops = &psc_dma_ops,
- .pcm_new = &psc_dma_new,
- .pcm_free = &psc_dma_free,
-};
-
-static int mpc5200_hpcd_probe(struct platform_device *op)
-{
- phys_addr_t fifo;
- struct psc_dma *psc_dma;
- struct resource res;
- int size, irq, rc;
- const __be32 *prop;
- void __iomem *regs;
- int ret;
-
- /* Fetch the registers and IRQ of the PSC */
- irq = irq_of_parse_and_map(op->dev.of_node, 0);
- if (of_address_to_resource(op->dev.of_node, 0, &res)) {
- dev_err(&op->dev, "Missing reg property\n");
- return -ENODEV;
- }
- regs = ioremap(res.start, resource_size(&res));
- if (!regs) {
- dev_err(&op->dev, "Could not map registers\n");
- return -ENODEV;
- }
-
- /* Allocate and initialize the driver private data */
- psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL);
- if (!psc_dma) {
- ret = -ENOMEM;
- goto out_unmap;
- }
-
- /* Get the PSC ID */
- prop = of_get_property(op->dev.of_node, "cell-index", &size);
- if (!prop || size < sizeof *prop) {
- ret = -ENODEV;
- goto out_free;
- }
-
- spin_lock_init(&psc_dma->lock);
- mutex_init(&psc_dma->mutex);
- psc_dma->id = be32_to_cpu(*prop);
- psc_dma->irq = irq;
- psc_dma->psc_regs = regs;
- psc_dma->fifo_regs = regs + sizeof *psc_dma->psc_regs;
- psc_dma->dev = &op->dev;
- psc_dma->playback.psc_dma = psc_dma;
- psc_dma->capture.psc_dma = psc_dma;
- snprintf(psc_dma->name, sizeof psc_dma->name, "PSC%u", psc_dma->id);
-
- /* Find the address of the fifo data registers and setup the
- * DMA tasks */
- fifo = res.start + offsetof(struct mpc52xx_psc, buffer.buffer_32);
- psc_dma->capture.bcom_task =
- bcom_psc_gen_bd_rx_init(psc_dma->id, 10, fifo, 512);
- psc_dma->playback.bcom_task =
- bcom_psc_gen_bd_tx_init(psc_dma->id, 10, fifo);
- if (!psc_dma->capture.bcom_task ||
- !psc_dma->playback.bcom_task) {
- dev_err(&op->dev, "Could not allocate bestcomm tasks\n");
- ret = -ENODEV;
- goto out_free;
- }
-
- /* Disable all interrupts and reset the PSC */
- out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
- /* reset receiver */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_RX);
- /* reset transmitter */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_TX);
- /* reset error */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_ERR_STAT);
- /* reset mode */
- out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_SEL_MODE_REG_1);
-
- /* Set up mode register;
- * First write: RxRdy (FIFO Alarm) generates rx FIFO irq
- * Second write: register Normal mode for non loopback
- */
- out_8(&psc_dma->psc_regs->mode, 0);
- out_8(&psc_dma->psc_regs->mode, 0);
-
- /* Set the TX and RX fifo alarm thresholds */
- out_be16(&psc_dma->fifo_regs->rfalarm, 0x100);
- out_8(&psc_dma->fifo_regs->rfcntl, 0x4);
- out_be16(&psc_dma->fifo_regs->tfalarm, 0x100);
- out_8(&psc_dma->fifo_regs->tfcntl, 0x7);
-
- /* Lookup the IRQ numbers */
- psc_dma->playback.irq =
- bcom_get_task_irq(psc_dma->playback.bcom_task);
- psc_dma->capture.irq =
- bcom_get_task_irq(psc_dma->capture.bcom_task);
-
- rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED,
- "psc-dma-status", psc_dma);
- rc |= request_irq(psc_dma->capture.irq, &psc_dma_bcom_irq, IRQF_SHARED,
- "psc-dma-capture", &psc_dma->capture);
- rc |= request_irq(psc_dma->playback.irq, &psc_dma_bcom_irq, IRQF_SHARED,
- "psc-dma-playback", &psc_dma->playback);
- if (rc) {
- ret = -ENODEV;
- goto out_irq;
- }
-
- /* Save what we've done so it can be found again later */
- dev_set_drvdata(&op->dev, psc_dma);
-
- /* Tell the ASoC OF helpers about it */
- return snd_soc_register_platform(&op->dev, &mpc5200_audio_dma_platform);
-out_irq:
- free_irq(psc_dma->irq, psc_dma);
- free_irq(psc_dma->capture.irq, &psc_dma->capture);
- free_irq(psc_dma->playback.irq, &psc_dma->playback);
-out_free:
- kfree(psc_dma);
-out_unmap:
- iounmap(regs);
- return ret;
-}
-
-static int mpc5200_hpcd_remove(struct platform_device *op)
-{
- struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
-
- dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n");
-
- snd_soc_unregister_platform(&op->dev);
-
- bcom_gen_bd_rx_release(psc_dma->capture.bcom_task);
- bcom_gen_bd_tx_release(psc_dma->playback.bcom_task);
-
- /* Release irqs */
- free_irq(psc_dma->irq, psc_dma);
- free_irq(psc_dma->capture.irq, &psc_dma->capture);
- free_irq(psc_dma->playback.irq, &psc_dma->playback);
-
- iounmap(psc_dma->psc_regs);
- kfree(psc_dma);
- dev_set_drvdata(&op->dev, NULL);
-
- return 0;
-}
-
-static struct of_device_id mpc5200_hpcd_match[] = {
- { .compatible = "fsl,mpc5200-pcm", },
- {}
-};
-MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
-
-static struct platform_driver mpc5200_hpcd_of_driver = {
- .probe = mpc5200_hpcd_probe,
- .remove = mpc5200_hpcd_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "mpc5200-pcm-audio",
- .of_match_table = mpc5200_hpcd_match,
- }
-};
-
-module_platform_driver(mpc5200_hpcd_of_driver);
-
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h
deleted file mode 100644
index a3c0cd53..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_dma.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Freescale MPC5200 Audio DMA driver
- */
-
-#ifndef __SOUND_SOC_FSL_MPC5200_DMA_H__
-#define __SOUND_SOC_FSL_MPC5200_DMA_H__
-
-#define PSC_STREAM_NAME_LEN 32
-
-/**
- * psc_ac97_stream - Data specific to a single stream (playback or capture)
- * @active: flag indicating if the stream is active
- * @psc_dma: pointer back to parent psc_dma data structure
- * @bcom_task: bestcomm task structure
- * @irq: irq number for bestcomm task
- * @period_end: physical address of end of DMA region
- * @period_next_pt: physical address of next DMA buffer to enqueue
- * @period_bytes: size of DMA period in bytes
- * @ac97_slot_bits: Enable bits for turning on the correct AC97 slot
- */
-struct psc_dma_stream {
- struct snd_pcm_runtime *runtime;
- int active;
- struct psc_dma *psc_dma;
- struct bcom_task *bcom_task;
- int irq;
- struct snd_pcm_substream *stream;
- int period_next;
- int period_current;
- int period_bytes;
- int period_count;
-
- /* AC97 state */
- u32 ac97_slot_bits;
-};
-
-/**
- * psc_dma - Private driver data
- * @name: short name for this device ("PSC0", "PSC1", etc)
- * @psc_regs: pointer to the PSC's registers
- * @fifo_regs: pointer to the PSC's FIFO registers
- * @irq: IRQ of this PSC
- * @dev: struct device pointer
- * @dai: the CPU DAI for this device
- * @sicr: Base value used in serial interface control register; mode is ORed
- * with this value.
- * @playback: Playback stream context data
- * @capture: Capture stream context data
- */
-struct psc_dma {
- char name[32];
- struct mpc52xx_psc __iomem *psc_regs;
- struct mpc52xx_psc_fifo __iomem *fifo_regs;
- unsigned int irq;
- struct device *dev;
- spinlock_t lock;
- struct mutex mutex;
- u32 sicr;
- uint sysclk;
- int imr;
- int id;
- unsigned int slots;
-
- /* per-stream data */
- struct psc_dma_stream playback;
- struct psc_dma_stream capture;
-
- /* Statistics */
- struct {
- unsigned long overrun_count;
- unsigned long underrun_count;
- } stats;
-};
-
-/* Utility for retrieving psc_dma_stream structure from a substream */
-static inline struct psc_dma_stream *
-to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
-{
- if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
- return &psc_dma->capture;
- return &psc_dma->playback;
-}
-
-#endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c
deleted file mode 100644
index ffa00a2e..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * linux/sound/mpc5200-ac97.c -- AC97 support for the Freescale MPC52xx chip.
- *
- * Copyright (C) 2009 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * 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/module.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/delay.h>
-
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/time.h>
-#include <asm/delay.h>
-#include <asm/mpc52xx.h>
-#include <asm/mpc52xx_psc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-
-#define DRV_NAME "mpc5200-psc-ac97"
-
-/* ALSA only supports a single AC97 device so static is recommend here */
-static struct psc_dma *psc_dma;
-
-static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
-{
- int status;
- unsigned int val;
-
- mutex_lock(&psc_dma->mutex);
-
- /* Wait for command send status zero = ready */
- status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
- MPC52xx_PSC_SR_CMDSEND), 100, 0);
- if (status == 0) {
- pr_err("timeout on ac97 bus (rdy)\n");
- mutex_unlock(&psc_dma->mutex);
- return -ENODEV;
- }
-
- /* Force clear the data valid bit */
- in_be32(&psc_dma->psc_regs->ac97_data);
-
- /* Send the read */
- out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24));
-
- /* Wait for the answer */
- status = spin_event_timeout((in_be16(&psc_dma->psc_regs->sr_csr.status) &
- MPC52xx_PSC_SR_DATA_VAL), 100, 0);
- if (status == 0) {
- pr_err("timeout on ac97 read (val) %x\n",
- in_be16(&psc_dma->psc_regs->sr_csr.status));
- mutex_unlock(&psc_dma->mutex);
- return -ENODEV;
- }
- /* Get the data */
- val = in_be32(&psc_dma->psc_regs->ac97_data);
- if (((val >> 24) & 0x7f) != reg) {
- pr_err("reg echo error on ac97 read\n");
- mutex_unlock(&psc_dma->mutex);
- return -ENODEV;
- }
- val = (val >> 8) & 0xffff;
-
- mutex_unlock(&psc_dma->mutex);
- return (unsigned short) val;
-}
-
-static void psc_ac97_write(struct snd_ac97 *ac97,
- unsigned short reg, unsigned short val)
-{
- int status;
-
- mutex_lock(&psc_dma->mutex);
-
- /* Wait for command status zero = ready */
- status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) &
- MPC52xx_PSC_SR_CMDSEND), 100, 0);
- if (status == 0) {
- pr_err("timeout on ac97 bus (write)\n");
- goto out;
- }
- /* Write data */
- out_be32(&psc_dma->psc_regs->ac97_cmd,
- ((reg & 0x7f) << 24) | (val << 8));
-
- out:
- mutex_unlock(&psc_dma->mutex);
-}
-
-static void psc_ac97_warm_reset(struct snd_ac97 *ac97)
-{
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
-
- mutex_lock(&psc_dma->mutex);
-
- out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR);
- udelay(3);
- out_be32(&regs->sicr, psc_dma->sicr);
-
- mutex_unlock(&psc_dma->mutex);
-}
-
-static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
-{
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
-
- mutex_lock(&psc_dma->mutex);
- dev_dbg(psc_dma->dev, "cold reset\n");
-
- mpc5200_psc_ac97_gpio_reset(psc_dma->id);
-
- /* Notify the PSC that a reset has occurred */
- out_be32(&regs->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB);
-
- /* Re-enable RX and TX */
- out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
-
- mutex_unlock(&psc_dma->mutex);
-
- msleep(1);
- psc_ac97_warm_reset(ac97);
-}
-
-struct snd_ac97_bus_ops soc_ac97_ops = {
- .read = psc_ac97_read,
- .write = psc_ac97_write,
- .reset = psc_ac97_cold_reset,
- .warm_reset = psc_ac97_warm_reset,
-};
-EXPORT_SYMBOL_GPL(soc_ac97_ops);
-
-static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
-
- dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
- " periods=%i buffer_size=%i buffer_bytes=%i channels=%i"
- " rate=%i format=%i\n",
- __func__, substream, params_period_size(params),
- params_period_bytes(params), params_periods(params),
- params_buffer_size(params), params_buffer_bytes(params),
- params_channels(params), params_rate(params),
- params_format(params));
-
- /* Determine the set of enable bits to turn on */
- s->ac97_slot_bits = (params_channels(params) == 1) ? 0x100 : 0x300;
- if (substream->pstr->stream != SNDRV_PCM_STREAM_CAPTURE)
- s->ac97_slot_bits <<= 16;
- return 0;
-}
-
-static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *cpu_dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
-
- dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream);
-
- if (params_channels(params) == 1)
- out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000);
- else
- out_be32(&psc_dma->psc_regs->ac97_slots, 0x03000000);
-
- return 0;
-}
-
-static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(dai);
- struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- dev_dbg(psc_dma->dev, "AC97 START: stream=%i\n",
- substream->pstr->stream);
-
- /* Set the slot enable bits */
- psc_dma->slots |= s->ac97_slot_bits;
- out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- dev_dbg(psc_dma->dev, "AC97 STOP: stream=%i\n",
- substream->pstr->stream);
-
- /* Clear the slot enable bits */
- psc_dma->slots &= ~(s->ac97_slot_bits);
- out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
- break;
- }
- return 0;
-}
-
-static int psc_ac97_probe(struct snd_soc_dai *cpu_dai)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
-
- /* Go */
- out_8(&regs->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
- return 0;
-}
-
-/* ---------------------------------------------------------------------
- * ALSA SoC Bindings
- *
- * - Digital Audio Interface (DAI) template
- * - create/destroy dai hooks
- */
-
-/**
- * psc_ac97_dai_template: template CPU Digital Audio Interface
- */
-static const struct snd_soc_dai_ops psc_ac97_analog_ops = {
- .hw_params = psc_ac97_hw_analog_params,
- .trigger = psc_ac97_trigger,
-};
-
-static const struct snd_soc_dai_ops psc_ac97_digital_ops = {
- .hw_params = psc_ac97_hw_digital_params,
-};
-
-static struct snd_soc_dai_driver psc_ac97_dai[] = {
-{
- .ac97_control = 1,
- .probe = psc_ac97_probe,
- .playback = {
- .channels_min = 1,
- .channels_max = 6,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_BE,
- },
- .capture = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_8000_48000,
- .formats = SNDRV_PCM_FMTBIT_S32_BE,
- },
- .ops = &psc_ac97_analog_ops,
-},
-{
- .ac97_control = 1,
- .playback = {
- .channels_min = 1,
- .channels_max = 2,
- .rates = SNDRV_PCM_RATE_32000 | \
- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE,
- },
- .ops = &psc_ac97_digital_ops,
-} };
-
-
-
-/* ---------------------------------------------------------------------
- * OF platform bus binding code:
- * - Probe/remove operations
- * - OF device match table
- */
-static int __devinit psc_ac97_of_probe(struct platform_device *op)
-{
- int rc;
- struct snd_ac97 ac97;
- struct mpc52xx_psc __iomem *regs;
-
- rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
- if (rc != 0) {
- dev_err(&op->dev, "Failed to register DAI\n");
- return rc;
- }
-
- psc_dma = dev_get_drvdata(&op->dev);
- regs = psc_dma->psc_regs;
- ac97.private_data = psc_dma;
-
- psc_dma->imr = 0;
- out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
-
- /* Configure the serial interface mode to AC97 */
- psc_dma->sicr = MPC52xx_PSC_SICR_SIM_AC97 | MPC52xx_PSC_SICR_ENAC97;
- out_be32(&regs->sicr, psc_dma->sicr);
-
- /* No slots active */
- out_be32(&regs->ac97_slots, 0x00000000);
-
- return 0;
-}
-
-static int __devexit psc_ac97_of_remove(struct platform_device *op)
-{
- snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai));
- return 0;
-}
-
-/* Match table for of_platform binding */
-static struct of_device_id psc_ac97_match[] __devinitdata = {
- { .compatible = "fsl,mpc5200-psc-ac97", },
- { .compatible = "fsl,mpc5200b-psc-ac97", },
- {}
-};
-MODULE_DEVICE_TABLE(of, psc_ac97_match);
-
-static struct platform_driver psc_ac97_driver = {
- .probe = psc_ac97_of_probe,
- .remove = __devexit_p(psc_ac97_of_remove),
- .driver = {
- .name = "mpc5200-psc-ac97",
- .owner = THIS_MODULE,
- .of_match_table = psc_ac97_match,
- },
-};
-
-module_platform_driver(psc_ac97_driver);
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION("mpc5200 AC97 module");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h
deleted file mode 100644
index e881e784..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_ac97.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Freescale MPC5200 PSC in AC97 mode
- * ALSA SoC Digital Audio Interface (DAI) driver
- *
- */
-
-#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
-#define __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
-
-#define MPC5200_AC97_NORMAL 0
-#define MPC5200_AC97_SPDIF 1
-
-#endif /* __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ */
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c b/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c
deleted file mode 100644
index 7b530327..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc5200_psc_i2s.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Freescale MPC5200 PSC in I2S mode
- * ALSA SoC Digital Audio Interface (DAI) driver
- *
- * Copyright (C) 2008 Secret Lab Technologies Ltd.
- * Copyright (C) 2009 Jon Smirl, Digispeaker
- */
-
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <asm/mpc52xx_psc.h>
-
-#include "mpc5200_dma.h"
-
-/**
- * PSC_I2S_RATES: sample rates supported by the I2S
- *
- * This driver currently only supports the PSC running in I2S slave mode,
- * which means the codec determines the sample rate. Therefore, we tell
- * ALSA that we support all rates and let the codec driver decide what rates
- * are really supported.
- */
-#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
- SNDRV_PCM_RATE_CONTINUOUS)
-
-/**
- * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode
- */
-#define PSC_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
- SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
-
-static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- u32 mode;
-
- dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
- " periods=%i buffer_size=%i buffer_bytes=%i\n",
- __func__, substream, params_period_size(params),
- params_period_bytes(params), params_periods(params),
- params_buffer_size(params), params_buffer_bytes(params));
-
- switch (params_format(params)) {
- case SNDRV_PCM_FORMAT_S8:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_8;
- break;
- case SNDRV_PCM_FORMAT_S16_BE:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_16;
- break;
- case SNDRV_PCM_FORMAT_S24_BE:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_24;
- break;
- case SNDRV_PCM_FORMAT_S32_BE:
- mode = MPC52xx_PSC_SICR_SIM_CODEC_32;
- break;
- default:
- dev_dbg(psc_dma->dev, "invalid format\n");
- return -EINVAL;
- }
- out_be32(&psc_dma->psc_regs->sicr, psc_dma->sicr | mode);
-
- return 0;
-}
-
-/**
- * psc_i2s_set_sysclk: set the clock frequency and direction
- *
- * This function is called by the machine driver to tell us what the clock
- * frequency and direction are.
- *
- * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
- * and we don't care about the frequency. Return an error if the direction
- * is not SND_SOC_CLOCK_IN.
- *
- * @clk_id: reserved, should be zero
- * @freq: the frequency of the given clock ID, currently ignored
- * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
- */
-static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n",
- cpu_dai, dir);
- return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
-}
-
-/**
- * psc_i2s_set_fmt: set the serial format.
- *
- * This function is called by the machine driver to tell us what serial
- * format to use.
- *
- * This driver only supports I2S mode. Return an error if the format is
- * not SND_SOC_DAIFMT_I2S.
- *
- * @format: one of SND_SOC_DAIFMT_xxx
- */
-static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
-{
- struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
- dev_dbg(psc_dma->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n",
- cpu_dai, format);
- return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
-}
-
-/* ---------------------------------------------------------------------
- * ALSA SoC Bindings
- *
- * - Digital Audio Interface (DAI) template
- * - create/destroy dai hooks
- */
-
-/**
- * psc_i2s_dai_template: template CPU Digital Audio Interface
- */
-static const struct snd_soc_dai_ops psc_i2s_dai_ops = {
- .hw_params = psc_i2s_hw_params,
- .set_sysclk = psc_i2s_set_sysclk,
- .set_fmt = psc_i2s_set_fmt,
-};
-
-static struct snd_soc_dai_driver psc_i2s_dai[] = {{
- .playback = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = PSC_I2S_RATES,
- .formats = PSC_I2S_FORMATS,
- },
- .capture = {
- .channels_min = 2,
- .channels_max = 2,
- .rates = PSC_I2S_RATES,
- .formats = PSC_I2S_FORMATS,
- },
- .ops = &psc_i2s_dai_ops,
-} };
-
-/* ---------------------------------------------------------------------
- * OF platform bus binding code:
- * - Probe/remove operations
- * - OF device match table
- */
-static int __devinit psc_i2s_of_probe(struct platform_device *op)
-{
- int rc;
- struct psc_dma *psc_dma;
- struct mpc52xx_psc __iomem *regs;
-
- rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
- if (rc != 0) {
- pr_err("Failed to register DAI\n");
- return rc;
- }
-
- psc_dma = dev_get_drvdata(&op->dev);
- regs = psc_dma->psc_regs;
-
- /* Configure the serial interface mode; defaulting to CODEC8 mode */
- psc_dma->sicr = MPC52xx_PSC_SICR_DTS1 | MPC52xx_PSC_SICR_I2S |
- MPC52xx_PSC_SICR_CLKPOL;
- out_be32(&psc_dma->psc_regs->sicr,
- psc_dma->sicr | MPC52xx_PSC_SICR_SIM_CODEC_8);
-
- /* Check for the codec handle. If it is not present then we
- * are done */
- if (!of_get_property(op->dev.of_node, "codec-handle", NULL))
- return 0;
-
- /* Due to errata in the dma mode; need to line up enabling
- * the transmitter with a transition on the frame sync
- * line */
-
- /* first make sure it is low */
- while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) != 0)
- ;
- /* then wait for the transition to high */
- while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) == 0)
- ;
- /* Finally, enable the PSC.
- * Receiver must always be enabled; even when we only want
- * transmit. (see 15.3.2.3 of MPC5200B User's Guide) */
-
- /* Go */
- out_8(&psc_dma->psc_regs->command,
- MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
-
- return 0;
-
-}
-
-static int __devexit psc_i2s_of_remove(struct platform_device *op)
-{
- snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
- return 0;
-}
-
-/* Match table for of_platform binding */
-static struct of_device_id psc_i2s_match[] __devinitdata = {
- { .compatible = "fsl,mpc5200-psc-i2s", },
- { .compatible = "fsl,mpc5200b-psc-i2s", },
- {}
-};
-MODULE_DEVICE_TABLE(of, psc_i2s_match);
-
-static struct platform_driver psc_i2s_driver = {
- .probe = psc_i2s_of_probe,
- .remove = __devexit_p(psc_i2s_of_remove),
- .driver = {
- .name = "mpc5200-psc-i2s",
- .owner = THIS_MODULE,
- .of_match_table = psc_i2s_match,
- },
-};
-
-module_platform_driver(psc_i2s_driver);
-
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver");
-MODULE_LICENSE("GPL");
-
diff --git a/ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c b/ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c
deleted file mode 100644
index 3fea5a15..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/mpc8610_hpcd.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/**
- * Freescale MPC8610HPCD ALSA SoC Machine driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007-2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/of_i2c.h>
-#include <sound/soc.h>
-#include <asm/fsl_guts.h>
-
-#include "fsl_dma.h"
-#include "fsl_ssi.h"
-
-/* There's only one global utilities register */
-static phys_addr_t guts_phys;
-
-#define DAI_NAME_SIZE 32
-
-/**
- * mpc8610_hpcd_data: machine-specific ASoC device data
- *
- * This structure contains data for a single sound platform device on an
- * MPC8610 HPCD. Some of the data is taken from the device tree.
- */
-struct mpc8610_hpcd_data {
- struct snd_soc_dai_link dai[2];
- struct snd_soc_card card;
- unsigned int dai_format;
- unsigned int codec_clk_direction;
- unsigned int cpu_clk_direction;
- unsigned int clk_frequency;
- unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
- unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
- unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
- char codec_dai_name[DAI_NAME_SIZE];
- char codec_name[DAI_NAME_SIZE];
- char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
-};
-
-/**
- * mpc8610_hpcd_machine_probe: initialize the board
- *
- * This function is used to initialize the board-specific hardware.
- *
- * Here we program the DMACR and PMUXCR registers.
- */
-static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card)
-{
- struct mpc8610_hpcd_data *machine_data =
- container_of(card, struct mpc8610_hpcd_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Program the signal routing between the SSI and the DMA */
- guts_set_dmacr(guts, machine_data->dma_id[0],
- machine_data->dma_channel_id[0],
- CCSR_GUTS_DMACR_DEV_SSI);
- guts_set_dmacr(guts, machine_data->dma_id[1],
- machine_data->dma_channel_id[1],
- CCSR_GUTS_DMACR_DEV_SSI);
-
- guts_set_pmuxcr_dma(guts, machine_data->dma_id[0],
- machine_data->dma_channel_id[0], 0);
- guts_set_pmuxcr_dma(guts, machine_data->dma_id[1],
- machine_data->dma_channel_id[1], 0);
-
- switch (machine_data->ssi_id) {
- case 0:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_SSI);
- break;
- case 1:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_SSI);
- break;
- }
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_startup: program the board with various hardware parameters
- *
- * This function takes board-specific information, like clock frequencies
- * and serial data formats, and passes that information to the codec and
- * transport drivers.
- */
-static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct mpc8610_hpcd_data *machine_data =
- container_of(rtd->card, struct mpc8610_hpcd_data, card);
- struct device *dev = rtd->card->dev;
- int ret = 0;
-
- /* Tell the codec driver what the serial protocol is. */
- ret = snd_soc_dai_set_fmt(rtd->codec_dai, machine_data->dai_format);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver audio format\n");
- return ret;
- }
-
- /*
- * Tell the codec driver what the MCLK frequency is, and whether it's
- * a slave or master.
- */
- ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0,
- machine_data->clk_frequency,
- machine_data->codec_clk_direction);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver clock params\n");
- return ret;
- }
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_machine_remove: Remove the sound device
- *
- * This function is called to remove the sound device for one SSI. We
- * de-program the DMACR and PMUXCR register.
- */
-static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
-{
- struct mpc8610_hpcd_data *machine_data =
- container_of(card, struct mpc8610_hpcd_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Restore the signal routing */
-
- guts_set_dmacr(guts, machine_data->dma_id[0],
- machine_data->dma_channel_id[0], 0);
- guts_set_dmacr(guts, machine_data->dma_id[1],
- machine_data->dma_channel_id[1], 0);
-
- switch (machine_data->ssi_id) {
- case 0:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_LA);
- break;
- case 1:
- clrsetbits_be32(&guts->pmuxcr,
- CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_LA);
- break;
- }
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_ops: ASoC machine driver operations
- */
-static struct snd_soc_ops mpc8610_hpcd_ops = {
- .startup = mpc8610_hpcd_startup,
-};
-
-/**
- * get_node_by_phandle_name - get a node by its phandle name
- *
- * This function takes a node, the name of a property in that node, and a
- * compatible string. Assuming the property is a phandle to another node,
- * it returns that node, (optionally) if that node is compatible.
- *
- * If the property is not a phandle, or the node it points to is not compatible
- * with the specific string, then NULL is returned.
- */
-static struct device_node *get_node_by_phandle_name(struct device_node *np,
- const char *name,
- const char *compatible)
-{
- const phandle *ph;
- int len;
-
- ph = of_get_property(np, name, &len);
- if (!ph || (len != sizeof(phandle)))
- return NULL;
-
- np = of_find_node_by_phandle(*ph);
- if (!np)
- return NULL;
-
- if (compatible && !of_device_is_compatible(np, compatible)) {
- of_node_put(np);
- return NULL;
- }
-
- return np;
-}
-
-/**
- * get_parent_cell_index -- return the cell-index of the parent of a node
- *
- * Return the value of the cell-index property of the parent of the given
- * node. This is used for DMA channel nodes that need to know the DMA ID
- * of the controller they are on.
- */
-static int get_parent_cell_index(struct device_node *np)
-{
- struct device_node *parent = of_get_parent(np);
- const u32 *iprop;
-
- if (!parent)
- return -1;
-
- iprop = of_get_property(parent, "cell-index", NULL);
- of_node_put(parent);
-
- if (!iprop)
- return -1;
-
- return be32_to_cpup(iprop);
-}
-
-/**
- * codec_node_dev_name - determine the dev_name for a codec node
- *
- * This function determines the dev_name for an I2C node. This is the name
- * that would be returned by dev_name() if this device_node were part of a
- * 'struct device' It's ugly and hackish, but it works.
- *
- * The dev_name for such devices include the bus number and I2C address. For
- * example, "cs4270.0-004f".
- */
-static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
-{
- const u32 *iprop;
- int addr;
- char temp[DAI_NAME_SIZE];
- struct i2c_client *i2c;
-
- of_modalias_node(np, temp, DAI_NAME_SIZE);
-
- iprop = of_get_property(np, "reg", NULL);
- if (!iprop)
- return -EINVAL;
-
- addr = be32_to_cpup(iprop);
-
- /* We need the adapter number */
- i2c = of_find_i2c_device_by_node(np);
- if (!i2c)
- return -ENODEV;
-
- snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
-
- return 0;
-}
-
-static int get_dma_channel(struct device_node *ssi_np,
- const char *name,
- struct snd_soc_dai_link *dai,
- unsigned int *dma_channel_id,
- unsigned int *dma_id)
-{
- struct resource res;
- struct device_node *dma_channel_np;
- const u32 *iprop;
- int ret;
-
- dma_channel_np = get_node_by_phandle_name(ssi_np, name,
- "fsl,ssi-dma-channel");
- if (!dma_channel_np)
- return -EINVAL;
-
- /* Determine the dev_name for the device_node. This code mimics the
- * behavior of of_device_make_bus_id(). We need this because ASoC uses
- * the dev_name() of the device to match the platform (DMA) device with
- * the CPU (SSI) device. It's all ugly and hackish, but it works (for
- * now).
- *
- * dai->platform name should already point to an allocated buffer.
- */
- ret = of_address_to_resource(dma_channel_np, 0, &res);
- if (ret)
- return ret;
- snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
- (unsigned long long) res.start, dma_channel_np->name);
-
- iprop = of_get_property(dma_channel_np, "cell-index", NULL);
- if (!iprop) {
- of_node_put(dma_channel_np);
- return -EINVAL;
- }
-
- *dma_channel_id = be32_to_cpup(iprop);
- *dma_id = get_parent_cell_index(dma_channel_np);
- of_node_put(dma_channel_np);
-
- return 0;
-}
-
-/**
- * mpc8610_hpcd_probe: platform probe function for the machine driver
- *
- * Although this is a machine driver, the SSI node is the "master" node with
- * respect to audio hardware connections. Therefore, we create a new ASoC
- * device for each new SSI node that has a codec attached.
- */
-static int mpc8610_hpcd_probe(struct platform_device *pdev)
-{
- struct device *dev = pdev->dev.parent;
- /* ssi_pdev is the platform device for the SSI node that probed us */
- struct platform_device *ssi_pdev =
- container_of(dev, struct platform_device, dev);
- struct device_node *np = ssi_pdev->dev.of_node;
- struct device_node *codec_np = NULL;
- struct platform_device *sound_device = NULL;
- struct mpc8610_hpcd_data *machine_data;
- int ret = -ENODEV;
- const char *sprop;
- const u32 *iprop;
-
- /* Find the codec node for this SSI. */
- codec_np = of_parse_phandle(np, "codec-handle", 0);
- if (!codec_np) {
- dev_err(dev, "invalid codec node\n");
- return -EINVAL;
- }
-
- machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
- if (!machine_data) {
- ret = -ENOMEM;
- goto error_alloc;
- }
-
- machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
- machine_data->dai[0].ops = &mpc8610_hpcd_ops;
-
- /* Determine the codec name, it will be used as the codec DAI name */
- ret = codec_node_dev_name(codec_np, machine_data->codec_name,
- DAI_NAME_SIZE);
- if (ret) {
- dev_err(&pdev->dev, "invalid codec node %s\n",
- codec_np->full_name);
- ret = -EINVAL;
- goto error;
- }
- machine_data->dai[0].codec_name = machine_data->codec_name;
-
- /* The DAI name from the codec (snd_soc_dai_driver.name) */
- machine_data->dai[0].codec_dai_name = "cs4270-hifi";
-
- /* We register two DAIs per SSI, one for playback and the other for
- * capture. Currently, we only support codecs that have one DAI for
- * both playback and capture.
- */
- memcpy(&machine_data->dai[1], &machine_data->dai[0],
- sizeof(struct snd_soc_dai_link));
-
- /* Get the device ID */
- iprop = of_get_property(np, "cell-index", NULL);
- if (!iprop) {
- dev_err(&pdev->dev, "cell-index property not found\n");
- ret = -EINVAL;
- goto error;
- }
- machine_data->ssi_id = be32_to_cpup(iprop);
-
- /* Get the serial format and clock direction. */
- sprop = of_get_property(np, "fsl,mode", NULL);
- if (!sprop) {
- dev_err(&pdev->dev, "fsl,mode property not found\n");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcasecmp(sprop, "i2s-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
-
- /* In i2s-slave mode, the codec has its own clock source, so we
- * need to get the frequency from the device tree and pass it to
- * the codec driver.
- */
- iprop = of_get_property(codec_np, "clock-frequency", NULL);
- if (!iprop || !*iprop) {
- dev_err(&pdev->dev, "codec bus-frequency "
- "property is missing or invalid\n");
- ret = -EINVAL;
- goto error;
- }
- machine_data->clk_frequency = be32_to_cpup(iprop);
- } else if (strcasecmp(sprop, "i2s-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "lj-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "lj-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "rj-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "rj-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "ac97-slave") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "ac97-master") == 0) {
- machine_data->dai_format =
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS;
- machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
- machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else {
- dev_err(&pdev->dev,
- "unrecognized fsl,mode property '%s'\n", sprop);
- ret = -EINVAL;
- goto error;
- }
-
- if (!machine_data->clk_frequency) {
- dev_err(&pdev->dev, "unknown clock frequency\n");
- ret = -EINVAL;
- goto error;
- }
-
- /* Find the playback DMA channel to use. */
- machine_data->dai[0].platform_name = machine_data->platform_name[0];
- ret = get_dma_channel(np, "fsl,playback-dma", &machine_data->dai[0],
- &machine_data->dma_channel_id[0],
- &machine_data->dma_id[0]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
- goto error;
- }
-
- /* Find the capture DMA channel to use. */
- machine_data->dai[1].platform_name = machine_data->platform_name[1];
- ret = get_dma_channel(np, "fsl,capture-dma", &machine_data->dai[1],
- &machine_data->dma_channel_id[1],
- &machine_data->dma_id[1]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
- goto error;
- }
-
- /* Initialize our DAI data structure. */
- machine_data->dai[0].stream_name = "playback";
- machine_data->dai[1].stream_name = "capture";
- machine_data->dai[0].name = machine_data->dai[0].stream_name;
- machine_data->dai[1].name = machine_data->dai[1].stream_name;
-
- machine_data->card.probe = mpc8610_hpcd_machine_probe;
- machine_data->card.remove = mpc8610_hpcd_machine_remove;
- machine_data->card.name = pdev->name; /* The platform driver name */
- machine_data->card.num_links = 2;
- machine_data->card.dai_link = machine_data->dai;
-
- /* Allocate a new audio platform device structure */
- sound_device = platform_device_alloc("soc-audio", -1);
- if (!sound_device) {
- dev_err(&pdev->dev, "platform device alloc failed\n");
- ret = -ENOMEM;
- goto error;
- }
-
- /* Associate the card data with the sound device */
- platform_set_drvdata(sound_device, &machine_data->card);
-
- /* Register with ASoC */
- ret = platform_device_add(sound_device);
- if (ret) {
- dev_err(&pdev->dev, "platform device add failed\n");
- goto error_sound;
- }
- dev_set_drvdata(&pdev->dev, sound_device);
-
- of_node_put(codec_np);
-
- return 0;
-
-error_sound:
- platform_device_put(sound_device);
-error:
- kfree(machine_data);
-error_alloc:
- of_node_put(codec_np);
- return ret;
-}
-
-/**
- * mpc8610_hpcd_remove: remove the platform device
- *
- * This function is called when the platform device is removed.
- */
-static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev)
-{
- struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
- struct snd_soc_card *card = platform_get_drvdata(sound_device);
- struct mpc8610_hpcd_data *machine_data =
- container_of(card, struct mpc8610_hpcd_data, card);
-
- platform_device_unregister(sound_device);
-
- kfree(machine_data);
- sound_device->dev.platform_data = NULL;
-
- dev_set_drvdata(&pdev->dev, NULL);
-
- return 0;
-}
-
-static struct platform_driver mpc8610_hpcd_driver = {
- .probe = mpc8610_hpcd_probe,
- .remove = __devexit_p(mpc8610_hpcd_remove),
- .driver = {
- /* The name must match 'compatible' property in the device tree,
- * in lowercase letters.
- */
- .name = "snd-soc-mpc8610hpcd",
- .owner = THIS_MODULE,
- },
-};
-
-/**
- * mpc8610_hpcd_init: machine driver initialization.
- *
- * This function is called when this module is loaded.
- */
-static int __init mpc8610_hpcd_init(void)
-{
- struct device_node *guts_np;
- struct resource res;
-
- pr_info("Freescale MPC8610 HPCD ALSA SoC machine driver\n");
-
- /* Get the physical address of the global utilities registers */
- guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts");
- if (of_address_to_resource(guts_np, 0, &res)) {
- pr_err("mpc8610-hpcd: missing/invalid global utilities node\n");
- return -EINVAL;
- }
- guts_phys = res.start;
-
- return platform_driver_register(&mpc8610_hpcd_driver);
-}
-
-/**
- * mpc8610_hpcd_exit: machine driver exit
- *
- * This function is called when this driver is unloaded.
- */
-static void __exit mpc8610_hpcd_exit(void)
-{
- platform_driver_unregister(&mpc8610_hpcd_driver);
-}
-
-module_init(mpc8610_hpcd_init);
-module_exit(mpc8610_hpcd_exit);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale MPC8610 HPCD ALSA SoC machine driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c b/ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c
deleted file mode 100644
index 982a1c94..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/p1022_ds.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/**
- * Freescale P1022DS ALSA SoC Machine driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2010 Freescale Semiconductor, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/of_i2c.h>
-#include <sound/soc.h>
-#include <asm/fsl_guts.h>
-
-#include "fsl_dma.h"
-#include "fsl_ssi.h"
-
-/* P1022-specific PMUXCR and DMUXCR bit definitions */
-
-#define CCSR_GUTS_PMUXCR_UART0_I2C1_MASK 0x0001c000
-#define CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI 0x00010000
-#define CCSR_GUTS_PMUXCR_UART0_I2C1_SSI 0x00018000
-
-#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK 0x00000c00
-#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI 0x00000000
-
-#define CCSR_GUTS_DMUXCR_PAD 1 /* DMA controller/channel set to pad */
-#define CCSR_GUTS_DMUXCR_SSI 2 /* DMA controller/channel set to SSI */
-
-/*
- * Set the DMACR register in the GUTS
- *
- * The DMACR register determines the source of initiated transfers for each
- * channel on each DMA controller. Rather than have a bunch of repetitive
- * macros for the bit patterns, we just have a function that calculates
- * them.
- *
- * guts: Pointer to GUTS structure
- * co: The DMA controller (0 or 1)
- * ch: The channel on the DMA controller (0, 1, 2, or 3)
- * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx)
- */
-static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts,
- unsigned int co, unsigned int ch, unsigned int device)
-{
- unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
-
- clrsetbits_be32(&guts->dmuxcr, 3 << shift, device << shift);
-}
-
-/* There's only one global utilities register */
-static phys_addr_t guts_phys;
-
-#define DAI_NAME_SIZE 32
-
-/**
- * machine_data: machine-specific ASoC device data
- *
- * This structure contains data for a single sound platform device on an
- * P1022 DS. Some of the data is taken from the device tree.
- */
-struct machine_data {
- struct snd_soc_dai_link dai[2];
- struct snd_soc_card card;
- unsigned int dai_format;
- unsigned int codec_clk_direction;
- unsigned int cpu_clk_direction;
- unsigned int clk_frequency;
- unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
- unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
- unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
- char codec_name[DAI_NAME_SIZE];
- char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
-};
-
-/**
- * p1022_ds_machine_probe: initialize the board
- *
- * This function is used to initialize the board-specific hardware.
- *
- * Here we program the DMACR and PMUXCR registers.
- */
-static int p1022_ds_machine_probe(struct snd_soc_card *card)
-{
- struct machine_data *mdata =
- container_of(card, struct machine_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Enable SSI Tx signal */
- clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK,
- CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI);
-
- /* Enable SSI Rx signal */
- clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK,
- CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI);
-
- /* Enable DMA Channel for SSI */
- guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0],
- CCSR_GUTS_DMUXCR_SSI);
-
- guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1],
- CCSR_GUTS_DMUXCR_SSI);
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * p1022_ds_startup: program the board with various hardware parameters
- *
- * This function takes board-specific information, like clock frequencies
- * and serial data formats, and passes that information to the codec and
- * transport drivers.
- */
-static int p1022_ds_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct machine_data *mdata =
- container_of(rtd->card, struct machine_data, card);
- struct device *dev = rtd->card->dev;
- int ret = 0;
-
- /* Tell the codec driver what the serial protocol is. */
- ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver audio format\n");
- return ret;
- }
-
- /*
- * Tell the codec driver what the MCLK frequency is, and whether it's
- * a slave or master.
- */
- ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0, mdata->clk_frequency,
- mdata->codec_clk_direction);
- if (ret < 0) {
- dev_err(dev, "could not set codec driver clock params\n");
- return ret;
- }
-
- return 0;
-}
-
-/**
- * p1022_ds_machine_remove: Remove the sound device
- *
- * This function is called to remove the sound device for one SSI. We
- * de-program the DMACR and PMUXCR register.
- */
-static int p1022_ds_machine_remove(struct snd_soc_card *card)
-{
- struct machine_data *mdata =
- container_of(card, struct machine_data, card);
- struct ccsr_guts __iomem *guts;
-
- guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
- if (!guts) {
- dev_err(card->dev, "could not map global utilities\n");
- return -ENOMEM;
- }
-
- /* Restore the signal routing */
- clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK);
- clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK);
- guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], 0);
- guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], 0);
-
- iounmap(guts);
-
- return 0;
-}
-
-/**
- * p1022_ds_ops: ASoC machine driver operations
- */
-static struct snd_soc_ops p1022_ds_ops = {
- .startup = p1022_ds_startup,
-};
-
-/**
- * get_node_by_phandle_name - get a node by its phandle name
- *
- * This function takes a node, the name of a property in that node, and a
- * compatible string. Assuming the property is a phandle to another node,
- * it returns that node, (optionally) if that node is compatible.
- *
- * If the property is not a phandle, or the node it points to is not compatible
- * with the specific string, then NULL is returned.
- */
-static struct device_node *get_node_by_phandle_name(struct device_node *np,
- const char *name, const char *compatible)
-{
- np = of_parse_phandle(np, name, 0);
- if (!np)
- return NULL;
-
- if (!of_device_is_compatible(np, compatible)) {
- of_node_put(np);
- return NULL;
- }
-
- return np;
-}
-
-/**
- * get_parent_cell_index -- return the cell-index of the parent of a node
- *
- * Return the value of the cell-index property of the parent of the given
- * node. This is used for DMA channel nodes that need to know the DMA ID
- * of the controller they are on.
- */
-static int get_parent_cell_index(struct device_node *np)
-{
- struct device_node *parent = of_get_parent(np);
- const u32 *iprop;
- int ret = -1;
-
- if (!parent)
- return -1;
-
- iprop = of_get_property(parent, "cell-index", NULL);
- if (iprop)
- ret = be32_to_cpup(iprop);
-
- of_node_put(parent);
-
- return ret;
-}
-
-/**
- * codec_node_dev_name - determine the dev_name for a codec node
- *
- * This function determines the dev_name for an I2C node. This is the name
- * that would be returned by dev_name() if this device_node were part of a
- * 'struct device' It's ugly and hackish, but it works.
- *
- * The dev_name for such devices include the bus number and I2C address. For
- * example, "cs4270-codec.0-004f".
- */
-static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
-{
- const u32 *iprop;
- int addr;
- char temp[DAI_NAME_SIZE];
- struct i2c_client *i2c;
-
- of_modalias_node(np, temp, DAI_NAME_SIZE);
-
- iprop = of_get_property(np, "reg", NULL);
- if (!iprop)
- return -EINVAL;
-
- addr = be32_to_cpup(iprop);
-
- /* We need the adapter number */
- i2c = of_find_i2c_device_by_node(np);
- if (!i2c)
- return -ENODEV;
-
- snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
-
- return 0;
-}
-
-static int get_dma_channel(struct device_node *ssi_np,
- const char *name,
- struct snd_soc_dai_link *dai,
- unsigned int *dma_channel_id,
- unsigned int *dma_id)
-{
- struct resource res;
- struct device_node *dma_channel_np;
- const u32 *iprop;
- int ret;
-
- dma_channel_np = get_node_by_phandle_name(ssi_np, name,
- "fsl,ssi-dma-channel");
- if (!dma_channel_np)
- return -EINVAL;
-
- /* Determine the dev_name for the device_node. This code mimics the
- * behavior of of_device_make_bus_id(). We need this because ASoC uses
- * the dev_name() of the device to match the platform (DMA) device with
- * the CPU (SSI) device. It's all ugly and hackish, but it works (for
- * now).
- *
- * dai->platform name should already point to an allocated buffer.
- */
- ret = of_address_to_resource(dma_channel_np, 0, &res);
- if (ret) {
- of_node_put(dma_channel_np);
- return ret;
- }
- snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
- (unsigned long long) res.start, dma_channel_np->name);
-
- iprop = of_get_property(dma_channel_np, "cell-index", NULL);
- if (!iprop) {
- of_node_put(dma_channel_np);
- return -EINVAL;
- }
-
- *dma_channel_id = be32_to_cpup(iprop);
- *dma_id = get_parent_cell_index(dma_channel_np);
- of_node_put(dma_channel_np);
-
- return 0;
-}
-
-/**
- * p1022_ds_probe: platform probe function for the machine driver
- *
- * Although this is a machine driver, the SSI node is the "master" node with
- * respect to audio hardware connections. Therefore, we create a new ASoC
- * device for each new SSI node that has a codec attached.
- */
-static int p1022_ds_probe(struct platform_device *pdev)
-{
- struct device *dev = pdev->dev.parent;
- /* ssi_pdev is the platform device for the SSI node that probed us */
- struct platform_device *ssi_pdev =
- container_of(dev, struct platform_device, dev);
- struct device_node *np = ssi_pdev->dev.of_node;
- struct device_node *codec_np = NULL;
- struct platform_device *sound_device = NULL;
- struct machine_data *mdata;
- int ret = -ENODEV;
- const char *sprop;
- const u32 *iprop;
-
- /* Find the codec node for this SSI. */
- codec_np = of_parse_phandle(np, "codec-handle", 0);
- if (!codec_np) {
- dev_err(dev, "could not find codec node\n");
- return -EINVAL;
- }
-
- mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL);
- if (!mdata) {
- ret = -ENOMEM;
- goto error_put;
- }
-
- mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
- mdata->dai[0].ops = &p1022_ds_ops;
-
- /* Determine the codec name, it will be used as the codec DAI name */
- ret = codec_node_dev_name(codec_np, mdata->codec_name, DAI_NAME_SIZE);
- if (ret) {
- dev_err(&pdev->dev, "invalid codec node %s\n",
- codec_np->full_name);
- ret = -EINVAL;
- goto error;
- }
- mdata->dai[0].codec_name = mdata->codec_name;
-
- /* We register two DAIs per SSI, one for playback and the other for
- * capture. We support codecs that have separate DAIs for both playback
- * and capture.
- */
- memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link));
-
- /* The DAI names from the codec (snd_soc_dai_driver.name) */
- mdata->dai[0].codec_dai_name = "wm8776-hifi-playback";
- mdata->dai[1].codec_dai_name = "wm8776-hifi-capture";
-
- /* Get the device ID */
- iprop = of_get_property(np, "cell-index", NULL);
- if (!iprop) {
- dev_err(&pdev->dev, "cell-index property not found\n");
- ret = -EINVAL;
- goto error;
- }
- mdata->ssi_id = be32_to_cpup(iprop);
-
- /* Get the serial format and clock direction. */
- sprop = of_get_property(np, "fsl,mode", NULL);
- if (!sprop) {
- dev_err(&pdev->dev, "fsl,mode property not found\n");
- ret = -EINVAL;
- goto error;
- }
-
- if (strcasecmp(sprop, "i2s-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
-
- /* In i2s-slave mode, the codec has its own clock source, so we
- * need to get the frequency from the device tree and pass it to
- * the codec driver.
- */
- iprop = of_get_property(codec_np, "clock-frequency", NULL);
- if (!iprop || !*iprop) {
- dev_err(&pdev->dev, "codec bus-frequency "
- "property is missing or invalid\n");
- ret = -EINVAL;
- goto error;
- }
- mdata->clk_frequency = be32_to_cpup(iprop);
- } else if (strcasecmp(sprop, "i2s-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "lj-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "lj-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "rj-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "rj-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else if (strcasecmp(sprop, "ac97-slave") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM;
- mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
- } else if (strcasecmp(sprop, "ac97-master") == 0) {
- mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS;
- mdata->codec_clk_direction = SND_SOC_CLOCK_IN;
- mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT;
- } else {
- dev_err(&pdev->dev,
- "unrecognized fsl,mode property '%s'\n", sprop);
- ret = -EINVAL;
- goto error;
- }
-
- if (!mdata->clk_frequency) {
- dev_err(&pdev->dev, "unknown clock frequency\n");
- ret = -EINVAL;
- goto error;
- }
-
- /* Find the playback DMA channel to use. */
- mdata->dai[0].platform_name = mdata->platform_name[0];
- ret = get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0],
- &mdata->dma_channel_id[0],
- &mdata->dma_id[0]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
- goto error;
- }
-
- /* Find the capture DMA channel to use. */
- mdata->dai[1].platform_name = mdata->platform_name[1];
- ret = get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1],
- &mdata->dma_channel_id[1],
- &mdata->dma_id[1]);
- if (ret) {
- dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
- goto error;
- }
-
- /* Initialize our DAI data structure. */
- mdata->dai[0].stream_name = "playback";
- mdata->dai[1].stream_name = "capture";
- mdata->dai[0].name = mdata->dai[0].stream_name;
- mdata->dai[1].name = mdata->dai[1].stream_name;
-
- mdata->card.probe = p1022_ds_machine_probe;
- mdata->card.remove = p1022_ds_machine_remove;
- mdata->card.name = pdev->name; /* The platform driver name */
- mdata->card.num_links = 2;
- mdata->card.dai_link = mdata->dai;
-
- /* Allocate a new audio platform device structure */
- sound_device = platform_device_alloc("soc-audio", -1);
- if (!sound_device) {
- dev_err(&pdev->dev, "platform device alloc failed\n");
- ret = -ENOMEM;
- goto error;
- }
-
- /* Associate the card data with the sound device */
- platform_set_drvdata(sound_device, &mdata->card);
-
- /* Register with ASoC */
- ret = platform_device_add(sound_device);
- if (ret) {
- dev_err(&pdev->dev, "platform device add failed\n");
- goto error;
- }
- dev_set_drvdata(&pdev->dev, sound_device);
-
- of_node_put(codec_np);
-
- return 0;
-
-error:
- if (sound_device)
- platform_device_put(sound_device);
-
- kfree(mdata);
-error_put:
- of_node_put(codec_np);
- return ret;
-}
-
-/**
- * p1022_ds_remove: remove the platform device
- *
- * This function is called when the platform device is removed.
- */
-static int __devexit p1022_ds_remove(struct platform_device *pdev)
-{
- struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
- struct snd_soc_card *card = platform_get_drvdata(sound_device);
- struct machine_data *mdata =
- container_of(card, struct machine_data, card);
-
- platform_device_unregister(sound_device);
-
- kfree(mdata);
- sound_device->dev.platform_data = NULL;
-
- dev_set_drvdata(&pdev->dev, NULL);
-
- return 0;
-}
-
-static struct platform_driver p1022_ds_driver = {
- .probe = p1022_ds_probe,
- .remove = __devexit_p(p1022_ds_remove),
- .driver = {
- /*
- * The name must match 'compatible' property in the device tree,
- * in lowercase letters.
- */
- .name = "snd-soc-p1022ds",
- .owner = THIS_MODULE,
- },
-};
-
-/**
- * p1022_ds_init: machine driver initialization.
- *
- * This function is called when this module is loaded.
- */
-static int __init p1022_ds_init(void)
-{
- struct device_node *guts_np;
- struct resource res;
-
- /* Get the physical address of the global utilities registers */
- guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
- if (of_address_to_resource(guts_np, 0, &res)) {
- pr_err("snd-soc-p1022ds: missing/invalid global utils node\n");
- of_node_put(guts_np);
- return -EINVAL;
- }
- guts_phys = res.start;
- of_node_put(guts_np);
-
- return platform_driver_register(&p1022_ds_driver);
-}
-
-/**
- * p1022_ds_exit: machine driver exit
- *
- * This function is called when this driver is unloaded.
- */
-static void __exit p1022_ds_exit(void)
-{
- platform_driver_unregister(&p1022_ds_driver);
-}
-
-module_init(p1022_ds_init);
-module_exit(p1022_ds_exit);
-
-MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
-MODULE_DESCRIPTION("Freescale P1022 DS ALSA SoC machine driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c b/ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c
deleted file mode 100644
index b3af55dc..00000000
--- a/ANDROID_3.4.5/sound/soc/fsl/pcm030-audio-fabric.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Phytec pcm030 driver for the PSC of the Freescale MPC52xx
- * configured as AC97 interface
- *
- * Copyright 2008 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/wm9712.h"
-
-#define DRV_NAME "pcm030-audio-fabric"
-
-static struct snd_soc_dai_link pcm030_fabric_dai[] = {
-{
- .name = "AC97",
- .stream_name = "AC97 Analog",
- .codec_dai_name = "wm9712-hifi",
- .cpu_dai_name = "mpc5200-psc-ac97.0",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "wm9712-codec",
-},
-{
- .name = "AC97",
- .stream_name = "AC97 IEC958",
- .codec_dai_name = "wm9712-aux",
- .cpu_dai_name = "mpc5200-psc-ac97.1",
- .platform_name = "mpc5200-pcm-audio",
- .codec_name = "wm9712-codec",
-},
-};
-
-static struct snd_soc_card card = {
- .name = "pcm030",
- .owner = THIS_MODULE,
- .dai_link = pcm030_fabric_dai,
- .num_links = ARRAY_SIZE(pcm030_fabric_dai),
-};
-
-static __init int pcm030_fabric_init(void)
-{
- struct platform_device *pdev;
- int rc;
-
- if (!of_machine_is_compatible("phytec,pcm030"))
- return -ENODEV;
-
- pdev = platform_device_alloc("soc-audio", 1);
- if (!pdev) {
- pr_err("pcm030_fabric_init: platform_device_alloc() failed\n");
- return -ENODEV;
- }
-
- platform_set_drvdata(pdev, &card);
-
- rc = platform_device_add(pdev);
- if (rc) {
- pr_err("pcm030_fabric_init: platform_device_add() failed\n");
- platform_device_put(pdev);
- return -ENODEV;
- }
- return 0;
-}
-
-module_init(pcm030_fabric_init);
-
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION(DRV_NAME ": mpc5200 pcm030 fabric driver");
-MODULE_LICENSE("GPL");
-