/*
 * File:         bf5xx_sport.c
 * Based on:
 * Author:       Roy Huang <roy.huang@analog.com>
 *
 * Created:      Tue Sep 21 10:52:42 CEST 2004
 * Description:
 *               Blackfin SPORT Driver
 *
 *               Copyright 2004-2007 Analog Devices Inc.
 *
 * Bugs:         Enter bugs at http://blackfin.uclinux.org/
 *
 * 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
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see the file COPYING, or write
 * to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/bug.h>
#include <asm/portmux.h>
#include <asm/dma.h>
#include <asm/blackfin.h>
#include <asm/cacheflush.h>

#include "bf5xx-sport.h"
/* delay between frame sync pulse and first data bit in multichannel mode */
#define FRAME_DELAY (1<<12)

/* note: multichannel is in units of 8 channels,
 * tdm_count is # channels NOT / 8 ! */
int sport_set_multichannel(struct sport_device *sport,
		int tdm_count, u32 mask, int packed)
{
	pr_debug("%s tdm_count=%d mask:0x%08x packed=%d\n", __func__,
			tdm_count, mask, packed);

	if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
		return -EBUSY;

	if (tdm_count & 0x7)
		return -EINVAL;

	if (tdm_count > 32)
		return -EINVAL; /* Only support less than 32 channels now */

	if (tdm_count) {
		sport->regs->mcmc1 = ((tdm_count>>3)-1) << 12;
		sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
				(packed ? (MCDTXPE|MCDRXPE) : 0);

		sport->regs->mtcs0 = mask;
		sport->regs->mrcs0 = mask;
		sport->regs->mtcs1 = 0;
		sport->regs->mrcs1 = 0;
		sport->regs->mtcs2 = 0;
		sport->regs->mrcs2 = 0;
		sport->regs->mtcs3 = 0;
		sport->regs->mrcs3 = 0;
	} else {
		sport->regs->mcmc1 = 0;
		sport->regs->mcmc2 = 0;

		sport->regs->mtcs0 = 0;
		sport->regs->mrcs0 = 0;
	}

	sport->regs->mtcs1 = 0; sport->regs->mtcs2 = 0; sport->regs->mtcs3 = 0;
	sport->regs->mrcs1 = 0; sport->regs->mrcs2 = 0; sport->regs->mrcs3 = 0;

	SSYNC();

	return 0;
}
EXPORT_SYMBOL(sport_set_multichannel);

int sport_config_rx(struct sport_device *sport, unsigned int rcr1,
		unsigned int rcr2, unsigned int clkdiv, unsigned int fsdiv)
{
	if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
		return -EBUSY;

	sport->regs->rcr1 = rcr1;
	sport->regs->rcr2 = rcr2;
	sport->regs->rclkdiv = clkdiv;
	sport->regs->rfsdiv = fsdiv;

	SSYNC();

	return 0;
}
EXPORT_SYMBOL(sport_config_rx);

int sport_config_tx(struct sport_device *sport, unsigned int tcr1,
		unsigned int tcr2, unsigned int clkdiv, unsigned int fsdiv)
{
	if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
		return -EBUSY;

	sport->regs->tcr1 = tcr1;
	sport->regs->tcr2 = tcr2;
	sport->regs->tclkdiv = clkdiv;
	sport->regs->tfsdiv = fsdiv;

	SSYNC();

	return 0;
}
EXPORT_SYMBOL(sport_config_tx);

static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
		size_t fragsize, unsigned int cfg,
		unsigned int x_count, unsigned int ycount, size_t wdsize)
{

	int i;

	for (i = 0; i < fragcount; ++i) {
		desc[i].next_desc_addr  = &(desc[i + 1]);
		desc[i].start_addr = (unsigned long)buf + i*fragsize;
		desc[i].cfg = cfg;
		desc[i].x_count = x_count;
		desc[i].x_modify = wdsize;
		desc[i].y_count = ycount;
		desc[i].y_modify = wdsize;
	}

	/* make circular */
	desc[fragcount-1].next_desc_addr = desc;

	pr_debug("setup desc: desc0=%p, next0=%p, desc1=%p,"
		"next1=%p\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
		desc, desc[0].next_desc_addr,
		desc+1, desc[1].next_desc_addr,
		desc[0].x_count, desc[0].y_count,
		desc[0].start_addr, desc[0].cfg);
}

static int sport_start(struct sport_device *sport)
{
	enable_dma(sport->dma_rx_chan);
	enable_dma(sport->dma_tx_chan);
	sport->regs->rcr1 |= RSPEN;
	sport->regs->tcr1 |= TSPEN;
	SSYNC();

	return 0;
}

static int sport_stop(struct sport_device *sport)
{
	sport->regs->tcr1 &= ~TSPEN;
	sport->regs->rcr1 &= ~RSPEN;
	SSYNC();

	disable_dma(sport->dma_rx_chan);
	disable_dma(sport->dma_tx_chan);
	return 0;
}

static inline int sport_hook_rx_dummy(struct sport_device *sport)
{
	struct dmasg *desc, temp_desc;
	unsigned long flags;

	BUG_ON(sport->dummy_rx_desc == NULL);
	BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc);

	/* Maybe the dummy buffer descriptor ring is damaged */
	sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc + 1;

	local_irq_save(flags);
	desc = get_dma_next_desc_ptr(sport->dma_rx_chan);
	/* Copy the descriptor which will be damaged to backup */
	temp_desc = *desc;
	desc->x_count = sport->dummy_count / 2;
	desc->y_count = 0;
	desc->next_desc_addr = sport->dummy_rx_desc;
	local_irq_restore(flags);
	/* Waiting for dummy buffer descriptor is already hooked*/
	while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
			sizeof(struct dmasg)) != sport->dummy_rx_desc)
		continue;
	sport->curr_rx_desc = sport->dummy_rx_desc;
	/* Restore the damaged descriptor */
	*desc = temp_desc;

	return 0;
}

static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
{
	if (dummy) {
		sport->dummy_rx_desc->next_desc_addr = sport->dummy_rx_desc;
		sport->curr_rx_desc = sport->dummy_rx_desc;
	} else
		sport->curr_rx_desc = sport->dma_rx_desc;

	set_dma_next_desc_addr(sport->dma_rx_chan, sport->curr_rx_desc);
	set_dma_x_count(sport->dma_rx_chan, 0);
	set_dma_x_modify(sport->dma_rx_chan, 0);
	set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
				WDSIZE_32 | WNR));
	set_dma_curr_addr(sport->dma_rx_chan, sport->curr_rx_desc->start_addr);
	SSYNC();

	return 0;
}

static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
{
	if (dummy) {
		sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc;
		sport->curr_tx_desc = sport->dummy_tx_desc;
	} else
		sport->curr_tx_desc = sport->dma_tx_desc;

	set_dma_next_desc_addr(sport->dma_tx_chan, sport->curr_tx_desc);
	set_dma_x_count(sport->dma_tx_chan, 0);
	set_dma_x_modify(sport->dma_tx_chan, 0);
	set_dma_config(sport->dma_tx_chan,
			(DMAFLOW_LARGE | NDSIZE_9 | WDSIZE_32));
	set_dma_curr_addr(sport->dma_tx_chan, sport->curr_tx_desc->start_addr);
	SSYNC();

	return 0;
}

int sport_rx_start(struct sport_device *sport)
{
	unsigned long flags;
	pr_debug("%s enter\n", __func__);
	if (sport->rx_run)
		return -EBUSY;
	if (sport->tx_run) {
		/* tx is running, rx is not running */
		BUG_ON(sport->dma_rx_desc == NULL);
		BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc);
		local_irq_save(flags);
		while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
			sizeof(struct dmasg)) != sport->dummy_rx_desc)
			continue;
		sport->dummy_rx_desc->next_desc_addr = sport->dma_rx_desc;
		local_irq_restore(flags);
		sport->curr_rx_desc = sport->dma_rx_desc;
	} else {
		sport_tx_dma_start(sport, 1);
		sport_rx_dma_start(sport, 0);
		sport_start(sport);
	}

	sport->rx_run = 1;

	return 0;
}
EXPORT_SYMBOL(sport_rx_start);

int sport_rx_stop(struct sport_device *sport)
{
	pr_debug("%s enter\n", __func__);

	if (!sport->rx_run)
		return 0;
	if (sport->tx_run) {
		/* TX dma is still running, hook the dummy buffer */
		sport_hook_rx_dummy(sport);
	} else {
		/* Both rx and tx dma will be stopped */
		sport_stop(sport);
		sport->curr_rx_desc = NULL;
		sport->curr_tx_desc = NULL;
	}

	sport->rx_run = 0;

	return 0;
}
EXPORT_SYMBOL(sport_rx_stop);

static inline int sport_hook_tx_dummy(struct sport_device *sport)
{
	struct dmasg *desc, temp_desc;
	unsigned long flags;

	BUG_ON(sport->dummy_tx_desc == NULL);
	BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc);

	sport->dummy_tx_desc->next_desc_addr = sport->dummy_tx_desc + 1;

	/* Shorten the time on last normal descriptor */
	local_irq_save(flags);
	desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
	/* Store the descriptor which will be damaged */
	temp_desc = *desc;
	desc->x_count = sport->dummy_count / 2;
	desc->y_count = 0;
	desc->next_desc_addr = sport->dummy_tx_desc;
	local_irq_restore(flags);
	/* Waiting for dummy buffer descriptor is already hooked*/
	while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
			sizeof(struct dmasg)) != sport->dummy_tx_desc)
		continue;
	sport->curr_tx_desc = sport->dummy_tx_desc;
	/* Restore the damaged descriptor */
	*desc = temp_desc;

	return 0;
}

int sport_tx_start(struct sport_device *sport)
{
	unsigned long flags;
	pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
			sport->tx_run, sport->rx_run);
	if (sport->tx_run)
		return -EBUSY;
	if (sport->rx_run) {
		BUG_ON(sport->dma_tx_desc == NULL);
		BUG_ON(sport->curr_tx_desc != sport->dummy_tx_desc);
		/* Hook the normal buffer descriptor */
		local_irq_save(flags);
		while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
			sizeof(struct dmasg)) != sport->dummy_tx_desc)
			continue;
		sport->dummy_tx_desc->next_desc_addr = sport->dma_tx_desc;
		local_irq_restore(flags);
		sport->curr_tx_desc = sport->dma_tx_desc;
	} else {

		sport_tx_dma_start(sport, 0);
		/* Let rx dma run the dummy buffer */
		sport_rx_dma_start(sport, 1);
		sport_start(sport);
	}
	sport->tx_run = 1;
	return 0;
}
EXPORT_SYMBOL(sport_tx_start);

int sport_tx_stop(struct sport_device *sport)
{
	if (!sport->tx_run)
		return 0;
	if (sport->rx_run) {
		/* RX is still running, hook the dummy buffer */
		sport_hook_tx_dummy(sport);
	} else {
		/* Both rx and tx dma stopped */
		sport_stop(sport);
		sport->curr_rx_desc = NULL;
		sport->curr_tx_desc = NULL;
	}

	sport->tx_run = 0;

	return 0;
}
EXPORT_SYMBOL(sport_tx_stop);

static inline int compute_wdsize(size_t wdsize)
{
	switch (wdsize) {
	case 1:
		return WDSIZE_8;
	case 2:
		return WDSIZE_16;
	case 4:
	default:
		return WDSIZE_32;
	}
}

int sport_config_rx_dma(struct sport_device *sport, void *buf,
		int fragcount, size_t fragsize)
{
	unsigned int x_count;
	unsigned int y_count;
	unsigned int cfg;
	dma_addr_t addr;

	pr_debug("%s buf:%p, frag:%d, fragsize:0x%lx\n", __func__, \
			buf, fragcount, fragsize);

	x_count = fragsize / sport->wdsize;
	y_count = 0;

	/* for fragments larger than 64k words we use 2d dma,
	 * denote fragecount as two numbers' mutliply and both of them
	 * are less than 64k.*/
	if (x_count >= 0x10000) {
		int i, count = x_count;

		for (i = 16; i > 0; i--) {
			x_count = 1 << i;
			if ((count & (x_count - 1)) == 0) {
				y_count = count >> i;
				if (y_count < 0x10000)
					break;
			}
		}
		if (i == 0)
			return -EINVAL;
	}
	pr_debug("%s(x_count:0x%x, y_count:0x%x)\n", __func__,
			x_count, y_count);

	if (sport->dma_rx_desc)
		dma_free_coherent(NULL, sport->rx_desc_bytes,
					sport->dma_rx_desc, 0);

	/* Allocate a new descritor ring as current one. */
	sport->dma_rx_desc = dma_alloc_coherent(NULL, \
			fragcount * sizeof(struct dmasg), &addr, 0);
	sport->rx_desc_bytes = fragcount * sizeof(struct dmasg);

	if (!sport->dma_rx_desc) {
		pr_err("Failed to allocate memory for rx desc\n");
		return -ENOMEM;
	}

	sport->rx_buf = buf;
	sport->rx_fragsize = fragsize;
	sport->rx_frags = fragcount;

	cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | WNR | \
		  (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */

	if (y_count != 0)
		cfg |= DMA2D;

	setup_desc(sport->dma_rx_desc, buf, fragcount, fragsize,
			cfg|DMAEN, x_count, y_count, sport->wdsize);

	return 0;
}
EXPORT_SYMBOL(sport_config_rx_dma);

int sport_config_tx_dma(struct sport_device *sport, void *buf, \
		int fragcount, size_t fragsize)
{
	unsigned int x_count;
	unsigned int y_count;
	unsigned int cfg;
	dma_addr_t addr;

	pr_debug("%s buf:%p, fragcount:%d, fragsize:0x%lx\n",
			__func__, buf, fragcount, fragsize);

	x_count = fragsize/sport->wdsize;
	y_count = 0;

	/* for fragments larger than 64k words we use 2d dma,
	 * denote fragecount as two numbers' mutliply and both of them
	 * are less than 64k.*/
	if (x_count >= 0x10000) {
		int i, count = x_count;

		for (i = 16; i > 0; i--) {
			x_count = 1 << i;
			if ((count & (x_count - 1)) == 0) {
				y_count = count >> i;
				if (y_count < 0x10000)
					break;
			}
		}
		if (i == 0)
			return -EINVAL;
	}
	pr_debug("%s x_count:0x%x, y_count:0x%x\n", __func__,
			x_count, y_count);


	if (sport->dma_tx_desc) {
		dma_free_coherent(NULL, sport->tx_desc_bytes, \
				sport->dma_tx_desc, 0);
	}

	sport->dma_tx_desc = dma_alloc_coherent(NULL, \
			fragcount * sizeof(struct dmasg), &addr, 0);
	sport->tx_desc_bytes = fragcount * sizeof(struct dmasg);
	if (!sport->dma_tx_desc) {
		pr_err("Failed to allocate memory for tx desc\n");
		return -ENOMEM;
	}

	sport->tx_buf = buf;
	sport->tx_fragsize = fragsize;
	sport->tx_frags = fragcount;
	cfg     = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | \
		  (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */

	if (y_count != 0)
		cfg |= DMA2D;

	setup_desc(sport->dma_tx_desc, buf, fragcount, fragsize,
			cfg|DMAEN, x_count, y_count, sport->wdsize);

	return 0;
}
EXPORT_SYMBOL(sport_config_tx_dma);

/* setup dummy dma descriptor ring, which don't generate interrupts,
 * the x_modify is set to 0 */
static int sport_config_rx_dummy(struct sport_device *sport)
{
	struct dmasg *desc;
	unsigned config;

	pr_debug("%s entered\n", __func__);
	if (L1_DATA_A_LENGTH)
		desc = l1_data_sram_zalloc(2 * sizeof(*desc));
	else {
		dma_addr_t addr;
		desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
		memset(desc, 0, 2 * sizeof(*desc));
	}
	if (desc == NULL) {
		pr_err("Failed to allocate memory for dummy rx desc\n");
		return -ENOMEM;
	}
	sport->dummy_rx_desc = desc;
	desc->start_addr = (unsigned long)sport->dummy_buf;
	config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
		 | WNR | DMAEN;
	desc->cfg = config;
	desc->x_count = sport->dummy_count/sport->wdsize;
	desc->x_modify = sport->wdsize;
	desc->y_count = 0;
	desc->y_modify = 0;
	memcpy(desc+1, desc, sizeof(*desc));
	desc->next_desc_addr = desc + 1;
	desc[1].next_desc_addr = desc;
	return 0;
}

static int sport_config_tx_dummy(struct sport_device *sport)
{
	struct dmasg *desc;
	unsigned int config;

	pr_debug("%s entered\n", __func__);

	if (L1_DATA_A_LENGTH)
		desc = l1_data_sram_zalloc(2 * sizeof(*desc));
	else {
		dma_addr_t addr;
		desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
		memset(desc, 0, 2 * sizeof(*desc));
	}
	if (!desc) {
		pr_err("Failed to allocate memory for dummy tx desc\n");
		return -ENOMEM;
	}
	sport->dummy_tx_desc = desc;
	desc->start_addr = (unsigned long)sport->dummy_buf + \
		sport->dummy_count;
	config = DMAFLOW_LARGE | NDSIZE_9 |
		 compute_wdsize(sport->wdsize) | DMAEN;
	desc->cfg = config;
	desc->x_count = sport->dummy_count/sport->wdsize;
	desc->x_modify = sport->wdsize;
	desc->y_count = 0;
	desc->y_modify = 0;
	memcpy(desc+1, desc, sizeof(*desc));
	desc->next_desc_addr = desc + 1;
	desc[1].next_desc_addr = desc;
	return 0;
}

unsigned long sport_curr_offset_rx(struct sport_device *sport)
{
	unsigned long curr = get_dma_curr_addr(sport->dma_rx_chan);

	return (unsigned char *)curr - sport->rx_buf;
}
EXPORT_SYMBOL(sport_curr_offset_rx);

unsigned long sport_curr_offset_tx(struct sport_device *sport)
{
	unsigned long curr = get_dma_curr_addr(sport->dma_tx_chan);

	return (unsigned char *)curr - sport->tx_buf;
}
EXPORT_SYMBOL(sport_curr_offset_tx);

void sport_incfrag(struct sport_device *sport, int *frag, int tx)
{
	++(*frag);
	if (tx == 1 && *frag == sport->tx_frags)
		*frag = 0;

	if (tx == 0 && *frag == sport->rx_frags)
		*frag = 0;
}
EXPORT_SYMBOL(sport_incfrag);

void sport_decfrag(struct sport_device *sport, int *frag, int tx)
{
	--(*frag);
	if (tx == 1 && *frag == 0)
		*frag = sport->tx_frags;

	if (tx == 0 && *frag == 0)
		*frag = sport->rx_frags;
}
EXPORT_SYMBOL(sport_decfrag);

static int sport_check_status(struct sport_device *sport,
		unsigned int *sport_stat,
		unsigned int *rx_stat,
		unsigned int *tx_stat)
{
	int status = 0;

	if (sport_stat) {
		SSYNC();
		status = sport->regs->stat;
		if (status & (TOVF|TUVF|ROVF|RUVF))
			sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
		SSYNC();
		*sport_stat = status;
	}

	if (rx_stat) {
		SSYNC();
		status = get_dma_curr_irqstat(sport->dma_rx_chan);
		if (status & (DMA_DONE|DMA_ERR))
			clear_dma_irqstat(sport->dma_rx_chan);
		SSYNC();
		*rx_stat = status;
	}

	if (tx_stat) {
		SSYNC();
		status = get_dma_curr_irqstat(sport->dma_tx_chan);
		if (status & (DMA_DONE|DMA_ERR))
			clear_dma_irqstat(sport->dma_tx_chan);
		SSYNC();
		*tx_stat = status;
	}

	return 0;
}

int  sport_dump_stat(struct sport_device *sport, char *buf, size_t len)
{
	int ret;

	ret = snprintf(buf, len,
			"sts: 0x%04x\n"
			"rx dma %d sts: 0x%04x tx dma %d sts: 0x%04x\n",
			sport->regs->stat,
			sport->dma_rx_chan,
			get_dma_curr_irqstat(sport->dma_rx_chan),
			sport->dma_tx_chan,
			get_dma_curr_irqstat(sport->dma_tx_chan));
	buf += ret;
	len -= ret;

	ret += snprintf(buf, len,
			"curr_rx_desc:0x%p, curr_tx_desc:0x%p\n"
			"dma_rx_desc:0x%p, dma_tx_desc:0x%p\n"
			"dummy_rx_desc:0x%p, dummy_tx_desc:0x%p\n",
			sport->curr_rx_desc, sport->curr_tx_desc,
			sport->dma_rx_desc, sport->dma_tx_desc,
			sport->dummy_rx_desc, sport->dummy_tx_desc);

	return ret;
}

static irqreturn_t rx_handler(int irq, void *dev_id)
{
	unsigned int rx_stat;
	struct sport_device *sport = dev_id;

	pr_debug("%s enter\n", __func__);
	sport_check_status(sport, NULL, &rx_stat, NULL);
	if (!(rx_stat & DMA_DONE))
		pr_err("rx dma is already stopped\n");

	if (sport->rx_callback) {
		sport->rx_callback(sport->rx_data);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

static irqreturn_t tx_handler(int irq, void *dev_id)
{
	unsigned int tx_stat;
	struct sport_device *sport = dev_id;
	pr_debug("%s enter\n", __func__);
	sport_check_status(sport, NULL, NULL, &tx_stat);
	if (!(tx_stat & DMA_DONE)) {
		pr_err("tx dma is already stopped\n");
		return IRQ_HANDLED;
	}
	if (sport->tx_callback) {
		sport->tx_callback(sport->tx_data);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

static irqreturn_t err_handler(int irq, void *dev_id)
{
	unsigned int status = 0;
	struct sport_device *sport = dev_id;

	pr_debug("%s\n", __func__);
	if (sport_check_status(sport, &status, NULL, NULL)) {
		pr_err("error checking status ??");
		return IRQ_NONE;
	}

	if (status & (TOVF|TUVF|ROVF|RUVF)) {
		pr_info("sport status error:%s%s%s%s\n",
				status & TOVF ? " TOVF" : "",
				status & TUVF ? " TUVF" : "",
				status & ROVF ? " ROVF" : "",
				status & RUVF ? " RUVF" : "");
		if (status & TOVF || status & TUVF) {
			disable_dma(sport->dma_tx_chan);
			if (sport->tx_run)
				sport_tx_dma_start(sport, 0);
			else
				sport_tx_dma_start(sport, 1);
			enable_dma(sport->dma_tx_chan);
		} else {
			disable_dma(sport->dma_rx_chan);
			if (sport->rx_run)
				sport_rx_dma_start(sport, 0);
			else
				sport_rx_dma_start(sport, 1);
			enable_dma(sport->dma_rx_chan);
		}
	}
	status = sport->regs->stat;
	if (status & (TOVF|TUVF|ROVF|RUVF))
		sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
	SSYNC();

	if (sport->err_callback)
		sport->err_callback(sport->err_data);

	return IRQ_HANDLED;
}

int sport_set_rx_callback(struct sport_device *sport,
		       void (*rx_callback)(void *), void *rx_data)
{
	BUG_ON(rx_callback == NULL);
	sport->rx_callback = rx_callback;
	sport->rx_data = rx_data;

	return 0;
}
EXPORT_SYMBOL(sport_set_rx_callback);

int sport_set_tx_callback(struct sport_device *sport,
		void (*tx_callback)(void *), void *tx_data)
{
	BUG_ON(tx_callback == NULL);
	sport->tx_callback = tx_callback;
	sport->tx_data = tx_data;

	return 0;
}
EXPORT_SYMBOL(sport_set_tx_callback);

int sport_set_err_callback(struct sport_device *sport,
		void (*err_callback)(void *), void *err_data)
{
	BUG_ON(err_callback == NULL);
	sport->err_callback = err_callback;
	sport->err_data = err_data;

	return 0;
}
EXPORT_SYMBOL(sport_set_err_callback);

static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
{
	/* Extract settings from platform data */
	struct device *dev = &pdev->dev;
	struct bfin_snd_platform_data *pdata = dev->platform_data;
	struct resource *res;

	param->num = pdev->id;

	if (!pdata) {
		dev_err(dev, "no platform_data\n");
		return -ENODEV;
	}
	param->pin_req = pdata->pin_req;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "no MEM resource\n");
		return -ENODEV;
	}
	param->regs = (struct sport_register *)res->start;

	/* first RX, then TX */
	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!res) {
		dev_err(dev, "no rx DMA resource\n");
		return -ENODEV;
	}
	param->dma_rx_chan = res->start;

	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
	if (!res) {
		dev_err(dev, "no tx DMA resource\n");
		return -ENODEV;
	}
	param->dma_tx_chan = res->start;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(dev, "no irq resource\n");
		return -ENODEV;
	}
	param->err_irq = res->start;

	return 0;
}

struct sport_device *sport_init(struct platform_device *pdev,
	unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
{
	struct device *dev = &pdev->dev;
	struct sport_param param;
	struct sport_device *sport;
	int ret;

	dev_dbg(dev, "%s enter\n", __func__);

	param.wdsize = wdsize;
	param.dummy_count = dummy_count;
	BUG_ON(param.wdsize == 0 || param.dummy_count == 0);

	ret = sport_config_pdev(pdev, &param);
	if (ret)
		return NULL;

	if (peripheral_request_list(param.pin_req, "soc-audio")) {
		dev_err(dev, "requesting Peripherals failed\n");
		return NULL;
	}

	sport = kzalloc(sizeof(*sport), GFP_KERNEL);
	if (!sport) {
		dev_err(dev, "failed to allocate for sport device\n");
		goto __init_err0;
	}

	sport->num = param.num;
	sport->dma_rx_chan = param.dma_rx_chan;
	sport->dma_tx_chan = param.dma_tx_chan;
	sport->err_irq = param.err_irq;
	sport->regs = param.regs;
	sport->pin_req = param.pin_req;

	if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
		dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
		goto __init_err1;
	}
	if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
		dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
		goto __init_err2;
	}

	if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
		dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
		goto __init_err2;
	}

	if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
		dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
		goto __init_err3;
	}

	if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
			sport) < 0) {
		dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
		goto __init_err3;
	}

	dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
			sport->dma_rx_chan, sport->dma_tx_chan,
			sport->err_irq, sport->regs);

	sport->wdsize = param.wdsize;
	sport->dummy_count = param.dummy_count;

	sport->private_data = kzalloc(priv_size, GFP_KERNEL);
	if (!sport->private_data) {
		dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
		goto __init_err4;
	}

	if (L1_DATA_A_LENGTH)
		sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
	else
		sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
	if (sport->dummy_buf == NULL) {
		dev_err(dev, "failed to allocate dummy buffer\n");
		goto __error1;
	}

	ret = sport_config_rx_dummy(sport);
	if (ret) {
		dev_err(dev, "failed to config rx dummy ring\n");
		goto __error2;
	}
	ret = sport_config_tx_dummy(sport);
	if (ret) {
		dev_err(dev, "failed to config tx dummy ring\n");
		goto __error3;
	}

	platform_set_drvdata(pdev, sport);

	return sport;
__error3:
	if (L1_DATA_A_LENGTH)
		l1_data_sram_free(sport->dummy_rx_desc);
	else
		dma_free_coherent(NULL, 2*sizeof(struct dmasg),
				sport->dummy_rx_desc, 0);
__error2:
	if (L1_DATA_A_LENGTH)
		l1_data_sram_free(sport->dummy_buf);
	else
		kfree(sport->dummy_buf);
__error1:
	kfree(sport->private_data);
__init_err4:
	free_irq(sport->err_irq, sport);
__init_err3:
	free_dma(sport->dma_tx_chan);
__init_err2:
	free_dma(sport->dma_rx_chan);
__init_err1:
	kfree(sport);
__init_err0:
	peripheral_free_list(param.pin_req);
	return NULL;
}
EXPORT_SYMBOL(sport_init);

void sport_done(struct sport_device *sport)
{
	if (sport == NULL)
		return;

	sport_stop(sport);
	if (sport->dma_rx_desc)
		dma_free_coherent(NULL, sport->rx_desc_bytes,
			sport->dma_rx_desc, 0);
	if (sport->dma_tx_desc)
		dma_free_coherent(NULL, sport->tx_desc_bytes,
			sport->dma_tx_desc, 0);

#if L1_DATA_A_LENGTH != 0
	l1_data_sram_free(sport->dummy_rx_desc);
	l1_data_sram_free(sport->dummy_tx_desc);
	l1_data_sram_free(sport->dummy_buf);
#else
	dma_free_coherent(NULL, 2*sizeof(struct dmasg),
		sport->dummy_rx_desc, 0);
	dma_free_coherent(NULL, 2*sizeof(struct dmasg),
		sport->dummy_tx_desc, 0);
	kfree(sport->dummy_buf);
#endif
	free_dma(sport->dma_rx_chan);
	free_dma(sport->dma_tx_chan);
	free_irq(sport->err_irq, sport);

	kfree(sport->private_data);
	peripheral_free_list(sport->pin_req);
	kfree(sport);
}
EXPORT_SYMBOL(sport_done);

/*
* It is only used to send several bytes when dma is not enabled
 * sport controller is configured but not enabled.
 * Multichannel cannot works with pio mode */
/* Used by ac97 to write and read codec register */
int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
		u8 *in_data, int len)
{
	unsigned short dma_config;
	unsigned short status;
	unsigned long flags;
	unsigned long wait = 0;

	pr_debug("%s enter, out_data:%p, in_data:%p len:%d\n", \
			__func__, out_data, in_data, len);
	pr_debug("tcr1:0x%04x, tcr2:0x%04x, tclkdiv:0x%04x, tfsdiv:0x%04x\n"
			"mcmc1:0x%04x, mcmc2:0x%04x\n",
			sport->regs->tcr1, sport->regs->tcr2,
			sport->regs->tclkdiv, sport->regs->tfsdiv,
			sport->regs->mcmc1, sport->regs->mcmc2);
	flush_dcache_range((unsigned)out_data, (unsigned)(out_data + len));

	/* Enable tx dma */
	dma_config = (RESTART | WDSIZE_16 | DI_EN);
	set_dma_start_addr(sport->dma_tx_chan, (unsigned long)out_data);
	set_dma_x_count(sport->dma_tx_chan, len/2);
	set_dma_x_modify(sport->dma_tx_chan, 2);
	set_dma_config(sport->dma_tx_chan, dma_config);
	enable_dma(sport->dma_tx_chan);

	if (in_data != NULL) {
		invalidate_dcache_range((unsigned)in_data, \
				(unsigned)(in_data + len));
		/* Enable rx dma */
		dma_config = (RESTART | WDSIZE_16 | WNR | DI_EN);
		set_dma_start_addr(sport->dma_rx_chan, (unsigned long)in_data);
		set_dma_x_count(sport->dma_rx_chan, len/2);
		set_dma_x_modify(sport->dma_rx_chan, 2);
		set_dma_config(sport->dma_rx_chan, dma_config);
		enable_dma(sport->dma_rx_chan);
	}

	local_irq_save(flags);
	sport->regs->tcr1 |= TSPEN;
	sport->regs->rcr1 |= RSPEN;
	SSYNC();

	status = get_dma_curr_irqstat(sport->dma_tx_chan);
	while (status & DMA_RUN) {
		udelay(1);
		status = get_dma_curr_irqstat(sport->dma_tx_chan);
		pr_debug("DMA status:0x%04x\n", status);
		if (wait++ > 100)
			goto __over;
	}
	status = sport->regs->stat;
	wait = 0;

	while (!(status & TXHRE)) {
		pr_debug("sport status:0x%04x\n", status);
		udelay(1);
		status = *(unsigned short *)&sport->regs->stat;
		if (wait++ > 1000)
			goto __over;
	}
	/* Wait for the last byte sent out */
	udelay(20);
	pr_debug("sport status:0x%04x\n", status);

__over:
	sport->regs->tcr1 &= ~TSPEN;
	sport->regs->rcr1 &= ~RSPEN;
	SSYNC();
	disable_dma(sport->dma_tx_chan);
	/* Clear the status */
	clear_dma_irqstat(sport->dma_tx_chan);
	if (in_data != NULL) {
		disable_dma(sport->dma_rx_chan);
		clear_dma_irqstat(sport->dma_rx_chan);
	}
	SSYNC();
	local_irq_restore(flags);

	return 0;
}
EXPORT_SYMBOL(sport_send_and_recv);

MODULE_AUTHOR("Roy Huang");
MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
MODULE_LICENSE("GPL");
