From 98e15babf1e25868d22c024dac6133cc29059d39 Mon Sep 17 00:00:00 2001 From: Kurt Mahan 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 --- 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 #include +#ifdef CONFIG_M54455 #include #include #include +#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<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");