diff options
Diffstat (limited to 'target/linux/coldfire/patches/033-m5445x_ssi_cleanup.patch')
-rw-r--r-- | target/linux/coldfire/patches/033-m5445x_ssi_cleanup.patch | 437 |
1 files changed, 437 insertions, 0 deletions
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 index 0000000..068323b --- /dev/null +++ b/target/linux/coldfire/patches/033-m5445x_ssi_cleanup.patch @@ -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"); |