/*
* linux/arch/arm/plat-omap/mcbsp.c
*
* Copyright (C) 2004 Nokia Corporation
* Author: Samuel Ortiz <samuel.ortiz@nokia.com>
*
*
* 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.
*
* Multichannel mode not supported.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <mach/dma.h>
#include <mach/mcbsp.h>
struct omap_mcbsp **mcbsp_ptr;
int omap_mcbsp_count;
void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
{
if (cpu_class_is_omap1() || cpu_is_omap2420())
__raw_writew((u16)val, io_base + reg);
else
__raw_writel(val, io_base + reg);
}
int omap_mcbsp_read(void __iomem *io_base, u16 reg)
{
if (cpu_class_is_omap1() || cpu_is_omap2420())
return __raw_readw(io_base + reg);
else
return __raw_readl(io_base + reg);
}
#define OMAP_MCBSP_READ(base, reg) \
omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg)
#define OMAP_MCBSP_WRITE(base, reg, val) \
omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val)
#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
static void omap_mcbsp_dump_reg(u8 id)
{
struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, DRR2));
dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, DRR1));
dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, DXR2));
dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, DXR1));
dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, SPCR2));
dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, SPCR1));
dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, RCR2));
dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, RCR1));
dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, XCR2));
dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, XCR1));
dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, SRGR2));
dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, SRGR1));
dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
OMAP_MCBSP_READ(mcbsp->io_base, PCR0));
dev_dbg(mcbsp->dev, "***********************\n");
}
static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
{
struct omap_mcbsp *mcbsp_tx = dev_id;
dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n",
OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
complete(&mcbsp_tx->tx_irq_completion);
return IRQ_HANDLED;
}
static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
{
struct omap_mcbsp *mcbsp_rx = dev_id;
dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n",
OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
complete(&mcbsp_rx->rx_irq_completion);
return IRQ_HANDLED;
}
static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_mcbsp *mcbsp_dma_tx = data;
dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
/* We can free the channels */
omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
mcbsp_dma_tx->dma_tx_lch = -1;
complete(&mcbsp_dma_tx->tx_dma_completion);
}
static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
{
struct omap_mcbsp *mcbsp_dma_rx = data;
dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
/* We can free the channels */
omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
mcbsp_dma_rx->dma_rx_lch = -1;
complete(&mcbsp_dma_rx->rx_dma_completion);