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");