/*
 * bf6xx_sport.c Analog Devices BF6XX SPORT driver
 *
 * Copyright (c) 2012 Analog Devices Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <asm/blackfin.h>
#include <asm/dma.h>
#include <asm/portmux.h>

#include "bf6xx-sport.h"

int sport_set_tx_params(struct sport_device *sport,
			struct sport_params *params)
{
	if (sport->tx_regs->spctl & SPORT_CTL_SPENPRI)
		return -EBUSY;
	sport->tx_regs->spctl = params->spctl | SPORT_CTL_SPTRAN;
	sport->tx_regs->div = params->div;
	SSYNC();
	return 0;
}
EXPORT_SYMBOL(sport_set_tx_params);

int sport_set_rx_params(struct sport_device *sport,
			struct sport_params *params)
{
	if (sport->rx_regs->spctl & SPORT_CTL_SPENPRI)
		return -EBUSY;
	sport->rx_regs->spctl = params->spctl & ~SPORT_CTL_SPTRAN;
	sport->rx_regs->div = params->div;
	SSYNC();
	return 0;
}
EXPORT_SYMBOL(sport_set_rx_params);

static int compute_wdsize(size_t wdsize)
{
	switch (wdsize) {
	case 1:
		return WDSIZE_8 | PSIZE_8;
	case 2:
		return WDSIZE_16 | PSIZE_16;
	default:
		return WDSIZE_32 | PSIZE_32;
	}
}

void sport_tx_start(struct sport_device *sport)
{
	set_dma_next_desc_addr(sport->tx_dma_chan, sport->tx_desc);
	set_dma_config(sport->tx_dma_chan, DMAFLOW_LIST | DI_EN
			| compute_wdsize(sport->wdsize) | NDSIZE_6);
	enable_dma(sport->tx_dma_chan);
	sport->tx_regs->spctl |= SPORT_CTL_SPENPRI;
	SSYNC();
}
EXPORT_SYMBOL(sport_tx_start);

void sport_rx_start(struct sport_device *sport)
{
	set_dma_next_desc_addr(sport->rx_dma_chan, sport->rx_desc);
	set_dma_config(sport->rx_dma_chan, DMAFLOW_LIST | DI_EN | WNR
			| compute_wdsize(sport->wdsize) | NDSIZE_6);
	enable_dma(sport->rx_dma_chan);
	sport->rx_regs->spctl |= SPORT_CTL_SPENPRI;
	SSYNC();
}
EXPORT_SYMBOL(sport_rx_start);

void sport_tx_stop(struct sport_device *sport)
{
	sport->tx_regs->spctl &= ~SPORT_CTL_SPENPRI;
	SSYNC();
	disable_dma(sport->tx_dma_chan);
}
EXPORT_SYMBOL(sport_tx_stop);

void sport_rx_stop(struct sport_device *sport)
{
	sport->rx_regs->spctl &= ~SPORT_CTL_SPENPRI;
	SSYNC();
	disable_dma(sport->rx_dma_chan);
}
EXPORT_SYMBOL(sport_rx_stop);

void sport_set_tx_callback(struct sport_device *sport,
		void (*tx_callback)(void *), void *tx_data)
{
	sport->tx_callback = tx_callback;
	sport->tx_data = tx_data;
}
EXPORT_SYMBOL(sport_set_tx_callback);

void sport_set_rx_callback(struct sport_device *sport,
		void (*rx_callback)(void *), void *rx_data)
{
	sport->rx_callback = rx_callback;
	sport->rx_data = rx_data;
}
EXPORT_SYMBOL(sport_set_rx_callback);

static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
		size_t fragsize, unsigned int cfg,
		unsigned int count, 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 = count;
		desc[i].x_modify = wdsize;
		desc[i].y_count = 0;
		desc[i].y_modify = 0;
	}

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

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

	count = fragsize / sport->wdsize;

	if (sport->tx_desc)
		dma_free_coherent(NULL, sport->tx_desc_size,
				sport->tx_desc, 0);

	sport->tx_desc = dma_alloc_coherent(NULL,
			fragcount * sizeof(struct dmasg), &addr, 0);
	sport->tx_desc_size = fragcount * sizeof(struct dmasg);
	if (!sport->tx_desc)
		return -ENOMEM;

	sport->tx_buf = buf;
	sport->tx_fragsize = fragsize;
	sport->tx_frags = fragcount;
	cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6;

	setup_desc(sport->tx_desc, buf, fragcount, fragsize,
		   cfg | DMAEN, count, sport->wdsize);
	return 0;
}
EXPORT_SYMBOL(sport_config_tx_dma);

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

	count = fragsize / sport->wdsize;

	if (sport->rx_desc)
		dma_free_coherent(NULL, sport->rx_desc_size,
				sport->rx_desc, 0);

	sport->rx_desc = dma_alloc_coherent(NULL,
			fragcount * sizeof(struct dmasg), &addr, 0);
	sport->rx_desc_size = fragcount * sizeof(struct dmasg);
	if (!sport->rx_desc)
		return -ENOMEM;

	sport->rx_buf = buf;
	sport->rx_fragsize = fragsize;
	sport->rx_frags = fragcount;
	cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize)
		| WNR | NDSIZE_6;

	setup_desc(sport->rx_desc, buf, fragcount, fragsize,
		   cfg | DMAEN, count, sport->wdsize);
	return 0;
}
EXPORT_SYMBOL(sport_config_rx_dma);

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

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

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

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

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

	status = get_dma_curr_irqstat(sport->tx_dma_chan);
	if (status & (DMA_DONE | DMA_ERR)) {
		clear_dma_irqstat(sport->tx_dma_chan);
		SSYNC();
	}
	if (sport->tx_callback)
		sport->tx_callback(sport->tx_data);
	return IRQ_HANDLED;
}

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

	status = get_dma_curr_irqstat(sport->rx_dma_chan);
	if (status & (DMA_DONE | DMA_ERR)) {
		clear_dma_irqstat(sport->rx_dma_chan);
		SSYNC();
	}
	if (sport->rx_callback)
		sport->rx_callback(sport->rx_data);
	return IRQ_HANDLED;
}

static irqreturn_t sport_err_irq(int irq, void *dev_id)
{
	struct sport_device *sport = dev_id;
	struct device *dev = &sport->pdev->dev;

	if (sport->tx_regs->spctl & SPORT_CTL_DERRPRI)
		dev_err(dev, "sport error: TUVF\n");
	if (sport->rx_regs->spctl & SPORT_CTL_DERRPRI)
		dev_err(dev, "sport error: ROVF\n");

	return IRQ_HANDLED;
}

static int sport_get_resource(struct sport_device *sport)
{
	struct platform_device *pdev = sport->pdev;
	struct device *dev = &pdev->dev;
	struct bfin_snd_platform_data *pdata = dev->platform_data;
	struct resource *res;

	if (!pdata) {
		dev_err(dev, "No platform data\n");
		return -ENODEV;
	}
	sport->pin_req = pdata->pin_req;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res) {
		dev_err(dev, "No rx MEM resource\n");
		return -ENODEV;
	}
	sport->rx_regs = (struct sport_register *)res->start;

	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!res) {
		dev_err(dev, "No tx DMA resource\n");
		return -ENODEV;
	}
	sport->tx_dma_chan = res->start;

	res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
	if (!res) {
		dev_err(dev, "No rx DMA resource\n");
		return -ENODEV;
	}
	sport->rx_dma_chan = res->start;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(dev, "No tx error irq resource\n");
		return -ENODEV;
	}
	sport->tx_err_irq = res->start;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (!res) {
		dev_err(dev, "No rx error irq resource\n");
		return -ENODEV;
	}
	sport->rx_err_irq = res->start;

	return 0;
}

static int sport_request_resource(struct sport_device *sport)
{
	struct device *dev = &sport->pdev->dev;
	int ret;

	ret = peripheral_request_list(sport->pin_req, "soc-audio");
	if (ret) {
		dev_err(dev, "Unable to request sport pin\n");
		return ret;
	}

	ret = request_dma(sport->tx_dma_chan, "SPORT TX Data");
	if (ret) {
		dev_err(dev, "Unable to allocate DMA channel for sport tx\n");
		goto err_tx_dma;
	}
	set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport);

	ret = request_dma(sport->rx_dma_chan, "SPORT RX Data");
	if (ret) {
		dev_err(dev, "Unable to allocate DMA channel for sport rx\n");
		goto err_rx_dma;
	}
	set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport);

	ret = request_irq(sport->tx_err_irq, sport_err_irq,
			0, "SPORT TX ERROR", sport);
	if (ret) {
		dev_err(dev, "Unable to allocate tx error IRQ for sport\n");
		goto err_tx_irq;
	}

	ret = request_irq(sport->rx_err_irq, sport_err_irq,
			0, "SPORT RX ERROR", sport);
	if (ret) {
		dev_err(dev, "Unable to allocate rx error IRQ for sport\n");
		goto err_rx_irq;
	}

	return 0;
err_rx_irq:
	free_irq(sport->tx_err_irq, sport);
err_tx_irq:
	free_dma(sport->rx_dma_chan);
err_rx_dma:
	free_dma(sport->tx_dma_chan);
err_tx_dma:
	peripheral_free_list(sport->pin_req);
	return ret;
}

static void sport_free_resource(struct sport_device *sport)
{
	free_irq(sport->rx_err_irq, sport);
	free_irq(sport->tx_err_irq, sport);
	free_dma(sport->rx_dma_chan);
	free_dma(sport->tx_dma_chan);
	peripheral_free_list(sport->pin_req);
}

struct sport_device *sport_create(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct sport_device *sport;
	int ret;

	sport = kzalloc(sizeof(*sport), GFP_KERNEL);
	if (!sport)
		return NULL;

	sport->pdev = pdev;

	ret = sport_get_resource(sport);
	if (ret)
		goto free_data;

	ret = sport_request_resource(sport);
	if (ret)
		goto free_data;

	dev_dbg(dev, "SPORT create success\n");
	return sport;
free_data:
	kfree(sport);
	return NULL;
}
EXPORT_SYMBOL(sport_create);

void sport_delete(struct sport_device *sport)
{
	if (sport->tx_desc)
		dma_free_coherent(NULL, sport->tx_desc_size,
				sport->tx_desc, 0);
	if (sport->rx_desc)
		dma_free_coherent(NULL, sport->rx_desc_size,
				sport->rx_desc, 0);
	sport_free_resource(sport);
	kfree(sport);
}
EXPORT_SYMBOL(sport_delete);

MODULE_DESCRIPTION("Analog Devices BF6XX SPORT driver");
MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
MODULE_LICENSE("GPL v2");
