/*
 * 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)

struct sport_device *sport_handle;
EXPORT_SYMBOL(sport_handle);
/* 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 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);

struct sport_device *sport_init(struct sport_param *param, unsigned wdsize,
		unsigned dummy_count, void *private_data)
{
	int ret;
	struct sport_device *sport;
	pr_debug("%s enter\n", __func__);
	BUG_ON(param == NULL);
	BUG_ON(wdsize == 0 || dummy_count == 0);
	sport = kmalloc(sizeof(struct sport_device), GFP_KERNEL);
	if (!sport) {
		pr_err("Failed to allocate for sport device\n");
		return NULL;
	}

	memset(sport, 0, sizeof(struct sport_device));
	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->private_data = private_data;

	if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
		pr_err("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) {
		pr_err("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) {
		pr_err("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) {
		pr_err("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) {
		pr_err("Failed to request err irq:%d\n", \
				sport->err_irq);
		goto __init_err3;
	}

	pr_err("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 = wdsize;
	sport->dummy_count = dummy_count;

	if (L1_DATA_A_LENGTH)
		sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2);
	else
		sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL);
	if (sport->dummy_buf == NULL) {
		pr_err("Failed to allocate dummy buffer\n");
		goto __error;
	}

	ret = sport_config_rx_dummy(sport);
	if (ret) {
		pr_err("Failed to config rx dummy ring\n");
		goto __error;
	}
	ret = sport_config_tx_dummy(sport);
	if (ret) {
		pr_err("Failed to config tx dummy ring\n");
		goto __error;
	}

	return sport;
__error:
	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);
	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);
		sport = NULL;
}
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");
