n.
 *
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/atmel_pdc.h>

#include <sound/driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <sound/soc.h>

#include <asm/arch/hardware.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/at91_ssc.h>

#include "at91-pcm.h"
#include "at91-ssc.h"

#if 0
#define	DBG(x...)	printk(KERN_DEBUG "at91-ssc:" x)
#else
#define	DBG(x...)
#endif

#if defined(CONFIG_ARCH_AT91SAM9260)
#define NUM_SSC_DEVICES		1
#else
#define NUM_SSC_DEVICES		3
#endif


/*
 * SSC PDC registers required by the PCM DMA engine.
 */
static struct at91_pdc_regs pdc_tx_reg = {
	.xpr		= ATMEL_PDC_TPR,
	.xcr		= ATMEL_PDC_TCR,
	.xnpr		= ATMEL_PDC_TNPR,
	.xncr		= ATMEL_PDC_TNCR,
};

static struct at91_pdc_regs pdc_rx_reg = {
	.xpr		= ATMEL_PDC_RPR,
	.xcr		= ATMEL_PDC_RCR,
	.xnpr		= ATMEL_PDC_RNPR,
	.xncr		= ATMEL_PDC_RNCR,
};

/*
 * SSC & PDC status bits for transmit and receive.
 */
static struct at91_ssc_mask ssc_tx_mask = {
	.ssc_enable	= AT91_SSC_TXEN,
	.ssc_disable	= AT91_SSC_TXDIS,
	.ssc_endx	= AT91_SSC_ENDTX,
	.ssc_endbuf	= AT91_SSC_TXBUFE,
	.pdc_enable	= ATMEL_PDC_TXTEN,
	.pdc_disable	= ATMEL_PDC_TXTDIS,
};

static struct at91_ssc_mask ssc_rx_mask = {
	.ssc_enable	= AT91_SSC_RXEN,
	.ssc_disable	= AT91_SSC_RXDIS,
	.ssc_endx	= AT91_SSC_ENDRX,
	.ssc_endbuf	= AT91_SSC_RXBUFF,
	.pdc_enable	= ATMEL_PDC_RXTEN,
	.pdc_disable	= ATMEL_PDC_RXTDIS,
};


/*
 * DMA parameters.
 */
static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
	{{
	.name		= "SSC0 PCM out",
	.pdc		= &pdc_tx_reg,
	.mask		= &ssc_tx_mask,
	},
	{
	.name		= "SSC0 PCM in",
	.pdc		= &pdc_rx_reg,
	.mask		= &ssc_rx_mask,
	}},
#if NUM_SSC_DEVICES == 3
	{{
	.name		= "SSC1 PCM out",
	.pdc		= &pdc_tx_reg,
	.mask		= &ssc_tx_mask,
	},
	{
	.name		= "SSC1 PCM in",
	.pdc		= &pdc_rx_reg,
	.mask		= &ssc_rx_mask,
	}},
	{{
	.name		= "SSC2 PCM out",
	.pdc		