/*
 * Alchemy Semi Au1000 IrDA driver
 *
 * Copyright 2001 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *         	ppopov@mvista.com or source@mvista.com
 *
 *  This program is free software; you can distribute 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 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.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/bitops.h>

#include <asm/irq.h>
#include <asm/io.h>
#include <asm/au1000.h>
#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100)
#include <asm/pb1000.h>
#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
#include <asm/db1x00.h>
#else 
#error au1k_ir: unsupported board
#endif

#include <net/irda/irda.h>
#include <net/irda/irmod.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda_device.h>
#include "au1000_ircc.h"

static int au1k_irda_net_init(struct net_device *);
static int au1k_irda_start(struct net_device *);
static int au1k_irda_stop(struct net_device *dev);
static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *);
static int au1k_irda_rx(struct net_device *);
static void au1k_irda_interrupt(int, void *, struct pt_regs *);
static void au1k_tx_timeout(struct net_device *);
static struct net_device_stats *au1k_irda_stats(struct net_device *);
static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int);
static int au1k_irda_set_speed(struct net_device *dev, int speed);

static void *dma_alloc(size_t, dma_addr_t *);
static void dma_free(void *, size_t);

static int qos_mtt_bits = 0x07;  /* 1 ms or more */
static struct net_device *ir_devs[NUM_IR_IFF];
static char version[] __devinitdata =
    "au1k_ircc:1.2 ppopov@mvista.com\n";

#define RUN_AT(x) (jiffies + (x))

#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
static BCSR * const bcsr = (BCSR *)0xAE000000;
#endif

static DEFINE_SPINLOCK(ir_lock);

/*
 * IrDA peripheral bug. You have to read the register
 * twice to get the right value.
 */
u32 read_ir_reg(u32 addr) 
{ 
	readl(addr);
	return readl(addr);
}


/*
 * Buffer allocation/deallocation routines. The buffer descriptor returned
 * has the virtual and dma address of a buffer suitable for 
 * both, receive and transmit operations.
 */
static db_dest_t *GetFreeDB(struct au1k_private *aup)
{
	db_dest_t *pDB;
	pDB = aup->pDBfree;

	if (pDB) {
		aup->pDBfree = pDB->pnext;
	}
	return pDB;
}

static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB)
{
	db_dest_t *pDBfree = aup->pDBfree;
	if (pDBfree)
		pDBfree->pnext = pDB;
	aup->pDBfree = pDB;
}


/*
  DMA memory allocation, derived from pci_alloc_consistent.
  However, the Au1000 data cache is coherent (when programmed
  so), therefore we return KSEG0 address, not KSEG1.
*/
static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
{
	void *ret;
	int gfp = GFP_ATOMIC | GFP_DMA;

	ret = (void *) __get_free_pages(gfp, get_order(size));

	if (ret != NULL) {
		memset(ret, 0, size);
		*dma_handle = virt_to_bus(ret);
		ret = (void *)KSEG0ADDR(ret);
	}
	return ret;
}


static void dma_free(void *vaddr, size_t size)
{
	vaddr = (void *)KSEG0ADDR(vaddr);
	free_pages((unsigned long) vaddr, get_order(size));
}


static void 
setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
{
	int i;
	for (i=0; i<NUM_IR_DESC; i++) {
		aup->rx_ring[i] = (volatile ring_dest_t *) 
			(rx_base + sizeof(ring_dest_t)*i);
	}
	for (i=0; i<NUM_IR_DESC; i++) {
		aup->tx_ring[i] = (volatile ring_dest_t *) 
			(tx_base + sizeof(ring_dest_t)*i);
	}
}

static int au1k_irda_init(void)
{
	static unsigned version_printed = 0;
	struct au1k_private *aup;
	struct net_device *dev;
	int err;

	if (version_printed++ == 0) printk(version);

	dev = alloc_irdadev(sizeof(struct au1k_private));
	if (!dev)
		return -ENOMEM;

	dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */
	err = au1k_irda_net_init(dev);
	if (err)
		goto out;
	err = register_netdev(dev);
	if (err)
		goto out1;
	ir_devs[0] = dev;
	printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
	return 0;

out1:
	aup = netdev_priv(dev);
	dma_free((void *)aup->db[0].vaddr,
		MAX_BUF_SIZE * 2*NUM_IR_DESC);
	dma_free((void *)aup->rx_ring[0],
		2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
	kfree(aup->rx_buff.head);
out:
	free_netdev(dev);
	return err;
}

static int au1k_irda_init_iobuf(iobuff_t *io, int size)
{
	io->head = kmalloc(size, GFP_KERNEL);
	if (io->head != NULL) {
		io->truesize = size;
		io->in_frame = FALSE;
		io->state    = OUTSIDE_FRAME;
		io->data     = io->head;
	}
	return io->head ? 0 : -ENOMEM;
}

static int au1k_irda_net_init(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	int i, retval = 0, err;
	db_dest_t *pDB, *pDBfree;
	dma_addr_t temp;

	err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
	if (err)
		goto out1;

	dev->open = au1k_irda_start;
	dev->hard_start_xmit = au1k_irda_hard_xmit;
	dev->stop = au1k_irda_stop;
	dev->get_stats = au1k_irda_stats;
	dev->do_ioctl = au1k_irda_ioctl;
	dev->tx_timeout = au1k_tx_timeout;

	irda_init_max_qos_capabilies(&aup->qos);

	/* The only value we must override it the baudrate */
	aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200|IR_576000 |(IR_4000000 << 8);
	
	aup->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&aup->qos);

	retval = -ENOMEM;

	/* Tx ring follows rx ring + 512 bytes */
	/* we need a 1k aligned buffer */
	aup->rx_ring[0] = (ring_dest_t *)
		dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);
	if (!aup->rx_ring[0])
		goto out2;

	/* allocate the data buffers */
	aup->db[0].vaddr = 
		(void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
	if (!aup->db[0].vaddr)
		goto out3;

	setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);

	pDBfree = NULL;
	pDB = aup->db;
	for (i=0; i<(2*NUM_IR_DESC); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = 
			(u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	/* attach a data buffer to each descriptor */
	for (i=0; i<NUM_IR_DESC; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto out;
		aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
		aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
		aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
		aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
		aup->rx_db_inuse[i] = pDB;
	}
	for (i=0; i<NUM_IR_DESC; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto out;
		aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
		aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
		aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
		aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
		aup->tx_ring[i]->count_0 = 0;
		aup->tx_ring[i]->count_1 = 0;
		aup->tx_ring[i]->flags = 0;
		aup->tx_db_inuse[i] = pDB;
	}

#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
	/* power on */
	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
	bcsr->resets |= BCSR_RESETS_IRDA_MODE_FULL;
	au_sync();
#endif

	return 0;

out3:
	dma_free((void *)aup->rx_ring[0],
		2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
out2:
	kfree(aup->rx_buff.head);
out1:
	printk(KERN_ERR "au1k_init_module failed.  Returns %d\n", retval);
	return retval;
}


static int au1k_init(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	int i;
	u32 control;
	u32 ring_address;

	/* bring the device out of reset */
	control = 0xe; /* coherent, clock enable, one half system clock */
			  
#ifndef CONFIG_CPU_LITTLE_ENDIAN
	control |= 1;
#endif
	aup->tx_head = 0;
	aup->tx_tail = 0;
	aup->rx_head = 0;

	for (i=0; i<NUM_IR_DESC; i++) {
		aup->rx_ring[i]->flags = AU_OWN;
	}

	writel(control, IR_INTERFACE_CONFIG);
	au_sync_delay(10);

	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
	au_sync_delay(1);

	writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);

	ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
	writel(ring_address >> 26, IR_RING_BASE_ADDR_H);
	writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);

	writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);

	writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
	writel(0, IR_RING_ADDR_CMPR);

	au1k_irda_set_speed(dev, 9600);
	return 0;
}

static int au1k_irda_start(struct net_device *dev)
{
	int retval;
	char hwname[32];
	struct au1k_private *aup = netdev_priv(dev);

	if ((retval = au1k_init(dev))) {
		printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
		return retval;
	}

	if ((retval = request_irq(AU1000_IRDA_TX_INT, &au1k_irda_interrupt, 
					0, dev->name, dev))) {
		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
				dev->name, dev->irq);
		return retval;
	}
	if ((retval = request_irq(AU1000_IRDA_RX_INT, &au1k_irda_interrupt, 
					0, dev->name, dev))) {
		free_irq(AU1000_IRDA_TX_INT, dev);
		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
				dev->name, dev->irq);
		return retval;
	}

	/* Give self a hardware name */
	sprintf(hwname, "Au1000 SIR/FIR");
	aup->irlap = irlap_open(dev, &aup->qos, hwname);
	netif_start_queue(dev);

	writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */

	aup->timer.expires = RUN_AT((3*HZ)); 
	aup->timer.data = (unsigned long)dev;
	return 0;
}

static int au1k_irda_stop(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);

	/* disable interrupts */
	writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2);
	writel(0, IR_CONFIG_1); 
	writel(0, IR_INTERFACE_CONFIG); /* disable clock */
	au_sync();

	if (aup->irlap) {
		irlap_close(aup->irlap);
		aup->irlap = NULL;
	}

	netif_stop_queue(dev);
	del_timer(&aup->timer);

	/* disable the interrupt */
	free_irq(AU1000_IRDA_TX_INT, dev);
	free_irq(AU1000_IRDA_RX_INT, dev);
	return 0;
}

static void __exit au1k_irda_exit(void)
{
	struct net_device *dev = ir_devs[0];
	struct au1k_private *aup = netdev_priv(dev);

	unregister_netdev(dev);

	dma_free((void *)aup->db[0].vaddr,
		MAX_BUF_SIZE * 2*NUM_IR_DESC);
	dma_free((void *)aup->rx_ring[0],
		2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
	kfree(aup->rx_buff.head);
	free_netdev(dev);
}


static inline void 
update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
{
	struct au1k_private *aup = netdev_priv(dev);
	struct net_device_stats *ps = &aup->stats;

	ps->tx_packets++;
	ps->tx_bytes += pkt_len;

	if (status & IR_TX_ERROR) {
		ps->tx_errors++;
		ps->tx_aborted_errors++;
	}
}


static void au1k_tx_ack(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	volatile ring_dest_t *ptxd;

	ptxd = aup->tx_ring[aup->tx_tail];
	while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
		update_tx_stats(dev, ptxd->flags, 
				ptxd->count_1<<8 | ptxd->count_0);
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
		au_sync();

		aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
		ptxd = aup->tx_ring[aup->tx_tail];

		if (aup->tx_full) {
			aup->tx_full = 0;
			netif_wake_queue(dev);
		}
	}

	if (aup->tx_tail == aup->tx_head) {
		if (aup->newspeed) {
			au1k_irda_set_speed(dev, aup->newspeed);
			aup->newspeed = 0;
		}
		else {
			writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, 
					IR_CONFIG_1); 
			au_sync();
			writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, 
					IR_CONFIG_1); 
			writel(0, IR_RING_PROMPT);
			au_sync();
		}
	}
}


/*
 * Au1000 transmit routine.
 */
static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	int speed = irda_get_next_speed(skb);
	volatile ring_dest_t *ptxd;
	u32 len;

	u32 flags;
	db_dest_t *pDB;

	if (speed != aup->speed && speed != -1) {
		aup->newspeed = speed;
	}

	if ((skb->len == 0) && (aup->newspeed)) {
		if (aup->tx_tail == aup->tx_head) {
			au1k_irda_set_speed(dev, speed);
			aup->newspeed = 0;
		}
		dev_kfree_skb(skb);
		return 0;
	}

	ptxd = aup->tx_ring[aup->tx_head];
	flags = ptxd->flags;

	if (flags & AU_OWN) {
		printk(KERN_DEBUG "%s: tx_full\n", dev->name);
		netif_stop_queue(dev);
		aup->tx_full = 1;
		return 1;
	}
	else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
		printk(KERN_DEBUG "%s: tx_full\n", dev->name);
		netif_stop_queue(dev);
		aup->tx_full = 1;
		return 1;
	}

	pDB = aup->tx_db_inuse[aup->tx_head];

#if 0
	if (read_ir_reg(IR_RX_BYTE_CNT) != 0) {
		printk("tx warning: rx byte cnt %x\n", 
				read_ir_reg(IR_RX_BYTE_CNT));
	}
#endif
	
	if (aup->speed == 4000000) {
		/* FIR */
		memcpy((void *)pDB->vaddr, skb->data, skb->len);
		ptxd->count_0 = skb->len & 0xff;
		ptxd->count_1 = (skb->len >> 8) & 0xff;

	}
	else {
		/* SIR */
		len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE);
		ptxd->count_0 = len & 0xff;
		ptxd->count_1 = (len >> 8) & 0xff;
		ptxd->flags |= IR_DIS_CRC;
		au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c);
	}
	ptxd->flags |= AU_OWN;
	au_sync();

	writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1); 
	writel(0, IR_RING_PROMPT);
	au_sync();

	dev_kfree_skb(skb);
	aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1);
	dev->trans_start = jiffies;
	return 0;
}


static inline void 
update_rx_stats(struct net_device *dev, u32 status, u32 count)
{
	struct au1k_private *aup = netdev_priv(dev);
	struct net_device_stats *ps = &aup->stats;

	ps->rx_packets++;

	if (status & IR_RX_ERROR) {
		ps->rx_errors++;
		if (status & (IR_PHY_ERROR|IR_FIFO_OVER))
			ps->rx_missed_errors++;
		if (status & IR_MAX_LEN)
			ps->rx_length_errors++;
		if (status & IR_CRC_ERROR)
			ps->rx_crc_errors++;
	}
	else 
		ps->rx_bytes += count;
}

/*
 * Au1000 receive routine.
 */
static int au1k_irda_rx(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	struct sk_buff *skb;
	volatile ring_dest_t *prxd;
	u32 flags, count;
	db_dest_t *pDB;

	prxd = aup->rx_ring[aup->rx_head];
	flags = prxd->flags;

	while (!(flags & AU_OWN))  {
		pDB = aup->rx_db_inuse[aup->rx_head];
		count = prxd->count_1<<8 | prxd->count_0;
		if (!(flags & IR_RX_ERROR))  {
			/* good frame */
			update_rx_stats(dev, flags, count);
			skb=alloc_skb(count+1,GFP_ATOMIC);
			if (skb == NULL) {
				aup->stats.rx_dropped++;
				continue;
			}
			skb_reserve(skb, 1);
			if (aup->speed == 4000000)
				skb_put(skb, count);
			else
				skb_put(skb, count-2);
			memcpy(skb->data, (void *)pDB->vaddr, count-2);
			skb->dev = dev;
			skb->mac.raw = skb->data;
			skb->protocol = htons(ETH_P_IRDA);
			netif_rx(skb);
			prxd->count_0 = 0;
			prxd->count_1 = 0;
		}
		prxd->flags |= AU_OWN;
		aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
		writel(0, IR_RING_PROMPT);
		au_sync();

		/* next descriptor */
		prxd = aup->rx_ring[aup->rx_head];
		flags = prxd->flags;
		dev->last_rx = jiffies;

	}
	return 0;
}


void au1k_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	struct net_device *dev = (struct net_device *) dev_id;

	if (dev == NULL) {
		printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
		return;
	}

	writel(0, IR_INT_CLEAR); /* ack irda interrupts */

	au1k_irda_rx(dev);
	au1k_tx_ack(dev);
}


/*
 * The Tx ring has been full longer than the watchdog timeout
 * value. The transmitter must be hung?
 */
static void au1k_tx_timeout(struct net_device *dev)
{
	u32 speed;
	struct au1k_private *aup = netdev_priv(dev);

	printk(KERN_ERR "%s: tx timeout\n", dev->name);
	speed = aup->speed;
	aup->speed = 0;
	au1k_irda_set_speed(dev, speed);
	aup->tx_full = 0;
	netif_wake_queue(dev);
}


/*
 * Set the IrDA communications speed.
 */
static int 
au1k_irda_set_speed(struct net_device *dev, int speed)
{
	unsigned long flags;
	struct au1k_private *aup = netdev_priv(dev);
	u32 control;
	int ret = 0, timeout = 10, i;
	volatile ring_dest_t *ptxd;
#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
	unsigned long irda_resets;
#endif

	if (speed == aup->speed)
		return ret;

	spin_lock_irqsave(&ir_lock, flags);

	/* disable PHY first */
	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE);

	/* disable RX/TX */
	writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE), 
			IR_CONFIG_1);
	au_sync_delay(1);
	while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) {
		mdelay(1);
		if (!timeout--) {
			printk(KERN_ERR "%s: rx/tx disable timeout\n",
					dev->name);
			break;
		}
	}

	/* disable DMA */
	writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1);
	au_sync_delay(1);

	/* 
	 *  After we disable tx/rx. the index pointers
 	 * go back to zero.
	 */
	aup->tx_head = aup->tx_tail = aup->rx_head = 0;
	for (i=0; i<NUM_IR_DESC; i++) {
		ptxd = aup->tx_ring[i];
		ptxd->flags = 0;
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
	}

	for (i=0; i<NUM_IR_DESC; i++) {
		ptxd = aup->rx_ring[i];
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
		ptxd->flags = AU_OWN;
	}

	if (speed == 4000000) {
#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
		bcsr->resets |= BCSR_RESETS_FIR_SEL;
#else /* Pb1000 and Pb1100 */
		writel(1<<13, CPLD_AUX1);
#endif
	}
	else {
#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
		bcsr->resets &= ~BCSR_RESETS_FIR_SEL;
#else /* Pb1000 and Pb1100 */
		writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
#endif
	}

	switch (speed) {
	case 9600:	
		writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
		writel(IR_SIR_MODE, IR_CONFIG_1); 
		break;
	case 19200:	
		writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
		writel(IR_SIR_MODE, IR_CONFIG_1); 
		break;
	case 38400:
		writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
		writel(IR_SIR_MODE, IR_CONFIG_1); 
		break;
	case 57600:	
		writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
		writel(IR_SIR_MODE, IR_CONFIG_1); 
		break;
	case 115200: 
		writel(12<<5, IR_WRITE_PHY_CONFIG); 
		writel(IR_SIR_MODE, IR_CONFIG_1); 
		break;
	case 4000000:
		writel(0xF, IR_WRITE_PHY_CONFIG);
		writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1); 
		break;
	default:
		printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
		ret = -EINVAL;
		break;
	}

	aup->speed = speed;
	writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE);
	au_sync();

	control = read_ir_reg(IR_ENABLE);
	writel(0, IR_RING_PROMPT);
	au_sync();

	if (control & (1<<14)) {
		printk(KERN_ERR "%s: configuration error\n", dev->name);
	}
	else {
		if (control & (1<<11))
			printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
		if (control & (1<<12))
			printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
		if (control & (1<<13))
			printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
		if (control & (1<<10))
			printk(KERN_DEBUG "%s TX enabled\n", dev->name);
		if (control & (1<<9))
			printk(KERN_DEBUG "%s RX enabled\n", dev->name);
	}

	spin_unlock_irqrestore(&ir_lock, flags);
	return ret;
}

static int 
au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
{
	struct if_irda_req *rq = (struct if_irda_req *)ifreq;
	struct au1k_private *aup = netdev_priv(dev);
	int ret = -EOPNOTSUPP;

	switch (cmd) {
	case SIOCSBANDWIDTH:
		if (capable(CAP_NET_ADMIN)) {
			/*
			 * We are unable to set the speed if the
			 * device is not running.
			 */
			if (aup->open)
				ret = au1k_irda_set_speed(dev,
						rq->ifr_baudrate);
			else {
				printk(KERN_ERR "%s ioctl: !netif_running\n",
						dev->name);
				ret = 0;
			}
		}
		break;

	case SIOCSMEDIABUSY:
		ret = -EPERM;
		if (capable(CAP_NET_ADMIN)) {
			irda_device_set_media_busy(dev, TRUE);
			ret = 0;
		}
		break;

	case SIOCGRECEIVING:
		rq->ifr_receiving = 0;
		break;
	default:
		break;
	}
	return ret;
}


static struct net_device_stats *au1k_irda_stats(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	return &aup->stats;
}

MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
MODULE_DESCRIPTION("Au1000 IrDA Device Driver");

module_init(au1k_irda_init);
module_exit(au1k_irda_exit);
