use broken-out patches for the coldfire to make it easier to follow differences again...
[openwrt/svn-archive/archive.git] / target / linux / coldfire / patches / 033-m5445x_ssi_cleanup.patch
diff --git a/target/linux/coldfire/patches/033-m5445x_ssi_cleanup.patch b/target/linux/coldfire/patches/033-m5445x_ssi_cleanup.patch
new file mode 100644 (file)
index 0000000..068323b
--- /dev/null
@@ -0,0 +1,437 @@
+From 98e15babf1e25868d22c024dac6133cc29059d39 Mon Sep 17 00:00:00 2001
+From: Kurt Mahan <kmahan@freescale.com>
+Date: Sun, 9 Dec 2007 02:24:13 -0700
+Subject: [PATCH] Fix DMA mode and cleanup driver.
+
+LTIBName: m5445x-ssi-cleanup
+Signed-off-by: Kurt Mahan <kmahan@freescale.com>
+---
+ drivers/spi/ssi_audio.c |  207 ++++++++++++++++++++++++-----------------------
+ 1 files changed, 104 insertions(+), 103 deletions(-)
+
+--- a/drivers/spi/ssi_audio.c
++++ b/drivers/spi/ssi_audio.c
+@@ -2,7 +2,7 @@
+  * MCF5445x audio driver.
+  *
+  * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
+- * Copyright Freescale Semiconductor, Inc. 2006
++ * Copyright Freescale Semiconductor, Inc. 2006, 2007
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -25,9 +25,11 @@
+ #include <asm/coldfire.h>
+ #include <asm/coldfire_edma.h>
++#ifdef CONFIG_M54455
+ #include <asm/mcf5445x_ssi.h>
+ #include <asm/mcf5445x_ccm.h>
+ #include <asm/mcf5445x_gpio.h>
++#endif
+ #define SOUND_DEVICE_NAME "sound"
+ #define DRIVER_NAME "ssi_audio"
+@@ -47,8 +49,8 @@
+ /* TLV320DAC23 audio chip registers */
+-#define CODEC_LEFT_IN_REG                     (0x00)
+-#define CODEC_RIGHT_IN_REG                    (0x01)
++#define CODEC_LEFT_IN_REG             (0x00)
++#define CODEC_RIGHT_IN_REG            (0x01)
+ #define CODEC_LEFT_HP_VOL_REG         (0x02)
+ #define CODEC_RIGHT_HP_VOL_REG                (0x03)
+ #define CODEC_ANALOG_APATH_REG                (0x04)
+@@ -57,7 +59,7 @@
+ #define CODEC_DIGITAL_IF_FMT_REG      (0x07)
+ #define CODEC_SAMPLE_RATE_REG         (0x08)
+ #define CODEC_DIGITAL_IF_ACT_REG      (0x09)
+-#define CODEC_RESET_REG                               (0x0f)
++#define CODEC_RESET_REG                       (0x0f)
+ #define CODEC_SAMPLE_8KHZ             (0x0C)
+ #define CODEC_SAMPLE_16KHZ            (0x58)
+@@ -71,21 +73,21 @@
+ /* DMA transfer size */
+ #define DMASIZE               (16*1024)
+-/* transmit eDMA channel for SSI channel 0 */
+-#define DMA_TCD       10
+-/* transmit eDMA channel for SSI channel 1 */
+-#define DMA_TCD2      11
++/* eDMA channel for SSI channel 0 TX */
++#define DMA_TCD       MCF_EDMA_CHAN_TIMER2
++/* eDMA channel for SSI channel 1 TX */
++#define DMA_TCD2      MCF_EDMA_CHAN_TIMER3
+ struct ssi_audio {
+-      struct spi_device       *spi;
++      struct spi_device *spi;
+       u32 speed;
+       u32 stereo;
+       u32 bits;
+       u32 format;
+-      u8  isopen;
+-      u8  dmaing;
+-      u8  ssi_enabled;
+-      u8  channel;
++      u8 isopen;
++      u8 dmaing;
++      u8 ssi_enabled;
++      u8 channel;
+       spinlock_t lock;
+       u8* audio_buf;
+ };
+@@ -129,7 +131,8 @@ static void ssi_audio_setsamplesize(int 
+       }
+ #ifdef AUDIO_DEBUG
+-      printk(DRIVER_NAME ":ssi_audio_setsamplesize %d %d\n", audio_device->format, audio_device->bits);
++      printk(DRIVER_NAME ":ssi_audio_setsamplesize %d %d\n",
++             audio_device->format, audio_device->bits);
+ #endif
+ }
+@@ -157,62 +160,57 @@ void __inline__ ssi_audio_dmarun(void)
+ {
+       set_edma_params(DMA_TCD,
+ #ifdef USE_MMU
+-                                      virt_to_phys(&(audio_device->audio_buf[audio_start])),
++                      virt_to_phys(&(audio_device->audio_buf[audio_start])),
+ #else
+-                                      (u32)&(audio_device->audio_buf[audio_start]),
++                      (u32)&(audio_device->audio_buf[audio_start]),
+ #endif
+-                                      (u32)&MCF_SSI_TX0,
+-                                      MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
+-                                      8,
+-                                      4,
+-                                      0,
+-                                      audio_count/8,
+-                                      audio_count/8,
+-                                      0,
+-                                      0,
+-                                      0, // major_int
+-                                      0  // disable_req
+-                                      );
++                      (u32)&MCF_SSI_TX0,
++                      MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
++                      8,
++                      4,
++                      0,
++                      audio_count/8,
++                      audio_count/8,
++                      0,
++                      0,
++                      0, // major_int
++                      0  // disable_req
++                      );
+       set_edma_params(DMA_TCD2,
+ #ifdef USE_MMU
+-                                      virt_to_phys(&(audio_device->audio_buf[audio_start+4])),
++                      virt_to_phys(&(audio_device->audio_buf[audio_start+4])),
+ #else
+-                                      (u32)&(audio_device->audio_buf[audio_start+4]),
++                      (u32)&(audio_device->audio_buf[audio_start+4]),
+ #endif
+-                                      (u32)&MCF_SSI_TX1,
+-                                      MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
+-                                      8,
+-                                      4,
+-                                      0,
+-                                      audio_count/8,
+-                                      audio_count/8,
+-                                      0,
+-                                      0,
+-                                      1, // major_int
+-                    0  // disable_req
+-                                      );
++                      (u32)&MCF_SSI_TX1,
++                      MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT,
++                      8,
++                      4,
++                      0,
++                      audio_count/8,
++                      audio_count/8,
++                      0,
++                      0,
++                      1, // major_int
++                      0  // disable_req
++                      );
+       audio_device->dmaing = 1;
+       audio_txbusy = 1;
+       start_edma_transfer(DMA_TCD);
+       start_edma_transfer(DMA_TCD2);
+-#if 0
+-      MCF_EDMA_ERQ |= (1<<DMA_TCD) | (1<<DMA_TCD2);
+-      MCF_EDMA_SSRT = DMA_TCD;
+-      MCF_EDMA_SSRT = DMA_TCD2;
+-#endif
+-
+ }
+-/*
+- *    Start DMA'ing a new buffer of data if any available.
++/**
++ * ssi_audio_dmabuf - Start DMA'ing a new buffer of data if any available.
+  */
+ static void ssi_audio_dmabuf(void)
+ {
+ #ifdef AUDIO_DEBUG
+-      printk(DRIVER_NAME ":ssi_audio_dmabuf(): append=%x start=%x\n", audio_append, audio_appstart);
++      printk(DRIVER_NAME ":ssi_audio_dmabuf(): append=%x start=%x\n",
++             audio_append, audio_appstart);
+ #endif
+       /* If already running then nothing to do... */
+@@ -241,7 +239,8 @@ static void ssi_audio_dmabuf(void)
+       }
+ }
+-void __inline__ stop_dma(void) {
++void __inline__ stop_dma(void)
++{
+       stop_edma_transfer(DMA_TCD);
+       stop_edma_transfer(DMA_TCD2);
+ }
+@@ -283,7 +282,6 @@ static void init_dma(void)
+ #endif        /* CONFIG_SSIAUDIO_USE_EDMA */
+-
+ /* Write CODEC register using SPI
+  *   address - CODEC register address
+  *   data - data to be written into register
+@@ -296,7 +294,8 @@ static int codec_write(u8 addr, u16 data
+               return -ENODEV;
+       spi_word = ((addr & 0x7F)<<9)|(data & 0x1FF);
+-      return spi_write(audio_device->spi, (const u8*)&spi_word, sizeof(spi_word));
++      return spi_write(audio_device->spi, (const u8*)&spi_word,
++                       sizeof(spi_word));
+ }
+ static inline void enable_ssi(void)
+@@ -359,7 +358,7 @@ static void init_audio_codec(void)
+       codec_write(CODEC_DIGITAL_APATH_REG, 0x007); /* Set A path */
+       /* set sample rate */
+-    adjust_codec_speed();
++      adjust_codec_speed();
+       codec_write(CODEC_LEFT_HP_VOL_REG, 0x075); /* set volume */
+       codec_write(CODEC_RIGHT_HP_VOL_REG, 0x075); /* set volume */
+@@ -375,13 +374,12 @@ static void chip_init(void)
+ #endif
+       /* Enable the SSI pins */
+-      MCF_GPIO_PAR_SSI = ( 0
+-                                                      | MCF_GPIO_PAR_SSI_MCLK
+-                                                      | MCF_GPIO_PAR_SSI_STXD(3)
+-                                                      | MCF_GPIO_PAR_SSI_SRXD(3)
+-                                                      | MCF_GPIO_PAR_SSI_FS(3)
+-                                                      | MCF_GPIO_PAR_SSI_BCLK(3) );
+-
++      MCF_GPIO_PAR_SSI = (0
++                          | MCF_GPIO_PAR_SSI_MCLK
++                          | MCF_GPIO_PAR_SSI_STXD(3)
++                          | MCF_GPIO_PAR_SSI_SRXD(3)
++                          | MCF_GPIO_PAR_SSI_FS(3)
++                          | MCF_GPIO_PAR_SSI_BCLK(3) );
+ }
+ static void init_ssi(void)
+@@ -430,8 +428,8 @@ static void init_ssi(void)
+                       ;
+       MCF_SSI_FCSR = 0
+-                      | MCF_SSI_FCSR_TFWM0(0)
+-                      | MCF_SSI_FCSR_TFWM1(0)
++                      | MCF_SSI_FCSR_TFWM0(2)
++                      | MCF_SSI_FCSR_TFWM1(2)
+                       ;
+       MCF_SSI_IER =   0 // interrupts
+@@ -459,9 +457,8 @@ static int ssi_audio_isr(int irq, void *
+ {
+       unsigned long   *bp;
+-      if (audio_txbusy==0) {
++      if (audio_txbusy==0)
+               return IRQ_HANDLED;
+-      }
+       spin_lock(&(audio_device->lock));
+@@ -560,7 +557,8 @@ static int ssi_audio_close(struct inode 
+ }
+ /* write to audio device */
+-static ssize_t ssi_audio_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
++static ssize_t ssi_audio_write(struct file *filp, const char *buf,
++      size_t count, loff_t *ppos)
+ {
+       unsigned long   *dp, *buflp;
+       unsigned short  *bufwp;
+@@ -568,10 +566,12 @@ static ssize_t ssi_audio_write(struct fi
+       unsigned int    slen, bufcnt, i, s, e;
+ #ifdef AUDIO_DEBUG
+-      printk(DRIVER_NAME ":ssi_audio_write(buf=%x,count=%d)\n", (int) buf, count);
++      printk(DRIVER_NAME ":ssi_audio_write(buf=%x,count=%d)\n",
++             (int)buf, count);
+ #endif
+-      if (audio_device==NULL) return (-ENODEV);
++      if (audio_device==NULL)
++              return (-ENODEV);
+       if (count <= 0)
+               return 0;
+@@ -592,8 +592,8 @@ static ssize_t ssi_audio_write(struct fi
+ tryagain:
+       /*
+-       *      Get a snapshot of buffer, so we can figure out how
+-       *      much data we can fit in...
++       * Get a snapshot of buffer, so we can figure out how
++       * much data we can fit in...
+        */
+       s = audio_start;
+       e = audio_append;
+@@ -613,11 +613,12 @@ tryagain:
+               goto tryagain;
+       }
+-      /* For DMA we need to have data as 32 bit
+-         values (since SSI TX register is 32 bit).
+-         So, the incomming 16 bit data must be put to buffer as 32 bit values.
+-         Also, the endianess is converted if needed
+-      */
++      /*
++       * For DMA we need to have data as 32 bit
++       * values (since SSI TX register is 32 bit).
++       * So, the incoming 16 bit data must be put to buffer as 32 bit values.
++       * Also, the endianess is converted if needed
++       */
+       if (audio_device->stereo) {
+               if (audio_device->bits == 16) {
+                       if (audio_device->format==AFMT_S16_LE) {
+@@ -678,16 +679,19 @@ tryagain:
+ }
+ /* ioctl: control the driver */
+-static int ssi_audio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
++static int ssi_audio_ioctl(struct inode *inode, struct file *filp,
++      unsigned int cmd, unsigned long arg)
+ {
+-      long    val;
+-      int     rc = 0;
++      long val;
++      int rc = 0;
+ #ifdef AUDIO_DEBUG
+-    printk(DRIVER_NAME ":ssi_audio_ioctl(cmd=%x,arg=%x)\n", (int) cmd, (int) arg);
++    printk(DRIVER_NAME ":ssi_audio_ioctl(cmd=%x,arg=%x)\n",
++         (int)cmd, (int)arg);
+ #endif
+-      if (audio_device==NULL) return (-ENODEV);
++      if (audio_device==NULL)
++              return (-ENODEV);
+       switch (cmd) {
+@@ -744,8 +748,6 @@ static int ssi_audio_ioctl(struct inode 
+       return rc;
+ }
+-/****************************************************************************/
+-
+ struct file_operations        ssi_audio_fops = {
+       open: ssi_audio_open,           /* open */
+       release: ssi_audio_close,       /* close */
+@@ -756,8 +758,8 @@ struct file_operations     ssi_audio_fops = 
+ /* initialize audio driver */
+ static int __devinit ssi_audio_probe(struct spi_device *spi)
+ {
+-      struct ssi_audio        *audio;
+-      int     err;
++      struct ssi_audio *audio;
++      int err;
+ #ifdef AUDIO_DEBUG
+       printk(DRIVER_NAME": probe\n");
+@@ -804,7 +806,7 @@ static int __devinit ssi_audio_probe(str
+       audio->spi = spi;
+ #ifndef CONFIG_SSIAUDIO_USE_EDMA
+-      if (request_irq(spi->irq, ssi_audio_isr, SA_INTERRUPT,  spi->dev.bus_id, audio)) {
++      if (request_irq(spi->irq, ssi_audio_isr, IRQF_DISABLED, spi->dev.bus_id, audio)) {
+               dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
+               err = -EBUSY;
+               goto err_free_mem;
+@@ -813,25 +815,21 @@ static int __devinit ssi_audio_probe(str
+ #else
+       /* request 2 eDMA channels since two channel output mode is used */
+       if (request_edma_channel(DMA_TCD,
+-                                                      ssi_audio_dma_handler_empty,
+-                                                      NULL,
+-                                                      audio,
+-                                                      &(audio_device->lock),
+-                                                      DRIVER_NAME
+-                                                      )!=0)
+-      {
++                               ssi_audio_dma_handler_empty,
++                               NULL,
++                               audio,
++                               &(audio_device->lock),
++                               DRIVER_NAME)!=0) {
+               dev_dbg(&spi->dev, "DMA channel %d busy?\n", DMA_TCD);
+               err = -EBUSY;
+               goto err_free_mem;
+       }
+       if (request_edma_channel(DMA_TCD2,
+-                                                      ssi_audio_dma_handler,
+-                                                      NULL,
+-                                                      audio,
+-                                                      &(audio_device->lock),
+-                                                      DRIVER_NAME
+-                                                      )!=0)
+-      {
++                               ssi_audio_dma_handler,
++                               NULL,
++                               audio,
++                               &(audio_device->lock),
++                               DRIVER_NAME)!=0) {
+               dev_dbg(&spi->dev, "DMA channel %d busy?\n", DMA_TCD2);
+               err = -EBUSY;
+               goto err_free_mem;
+@@ -870,11 +868,13 @@ static int __devexit ssi_audio_remove(st
+       return 0;
+ }
+-static int ssi_audio_suspend(struct spi_device *spi, pm_message_t message) {
++static int ssi_audio_suspend(struct spi_device *spi, pm_message_t message)
++{
+       return 0;
+ }
+-static int ssi_audio_resume(struct spi_device *spi) {
++static int ssi_audio_resume(struct spi_device *spi)
++{
+       return 0;
+ }
+@@ -902,5 +902,6 @@ static void __exit ssi_audio_exit(void)
+ }
+ module_exit(ssi_audio_exit);
+-MODULE_DESCRIPTION("SSI/I2S Audio Driver");
+ MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Freescale Semiconductor, Inc.");
++MODULE_DESCRIPTION("SSI/I2S Audio Driver");