/*
* Alchemy Semi Au1000 IrDA driver
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda_device.h>
#include <asm/mach-au1x00/au1000.h>
/* registers */
#define IR_RING_PTR_STATUS 0x00
#define IR_RING_BASE_ADDR_H 0x04
#define IR_RING_BASE_ADDR_L 0x08
#define IR_RING_SIZE 0x0C
#define IR_RING_PROMPT 0x10
#define IR_RING_ADDR_CMPR 0x14
#define IR_INT_CLEAR 0x18
#define IR_CONFIG_1 0x20
#define IR_SIR_FLAGS 0x24
#define IR_STATUS 0x28
#define IR_READ_PHY_CONFIG 0x2C
#define IR_WRITE_PHY_CONFIG 0x30
#define IR_MAX_PKT_LEN 0x34
#define IR_RX_BYTE_CNT 0x38
#define IR_CONFIG_2 0x3C
#define IR_ENABLE 0x40
/* Config1 */
#define IR_RX_INVERT_LED (1 << 0)
#define IR_TX_INVERT_LED (1 << 1)
#define IR_ST (1 << 2)
#define IR_SF (1 << 3)
#define IR_SIR (1 << 4)
#define IR_MIR (1 << 5)
#define IR_FIR (1 << 6)
#define IR_16CRC (1 << 7)
#define IR_TD (1 << 8)
#define IR_RX_ALL (1 << 9)
#define IR_DMA_ENABLE (1 << 10)
#define IR_RX_ENABLE (1 << 11)
#define IR_TX_ENABLE (1 << 12)
#define IR_LOOPBACK (1 << 14)
#define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
IR_RX_ALL | IR_RX_ENABLE | IR_SF | \
IR_16CRC)
/* ir_status */
#define IR_RX_STATUS (1 << 9)
#define IR_TX_STATUS (1 << 10)
#define IR_PHYEN (1 << 15)
/* ir_write_phy_config */
#define IR_BR(x) (((x) & 0x3f) << 10) /* baud rate */
#define IR_PW(x) (((x) & 0x1f) << 5) /* pulse width */
#define IR_P(x) ((x) & 0x1f) /* preamble bits */
/* Config2 */
#define IR_MODE_INV (1 << 0)
#define IR_ONE_PIN (1 << 1)
#define IR_PHYCLK_40MHZ (0 << 2)
#define IR_PHYCLK_48MHZ (1 << 2)
#define IR_PHYCLK_56MHZ (2 << 2)
#define IR_PHYCLK_64MHZ (3 << 2)
#define IR_DP (1 << 4)
#define IR_DA (1 << 5)
#define IR_FLT_HIGH (0 << 6)
#define IR_FLT_MEDHI (1 << 6)
#define IR_FLT_MEDLO (2 << 6)
#define IR_FLT_LO (3 << 6)
#define IR_IEN (1 << 8)
/* ir_enable */
#define IR_HC (1 << 3) /* divide SBUS clock by 2 */
#define IR_CE (1 << 2) /* clock enable */
#define IR_C (1 << 1) /* coherency bit */
#define IR_BE (1 << 0) /* set in big endian mode */
#define NUM_IR_DESC 64
#define RING_SIZE_4 0x0
#define RING_SIZE_16 0x3
#define RING_SIZE_64 0xF
#define MAX_NUM_IR_DESC 64
#define MAX_BUF_SIZE 2048
/* Ring descriptor flags */
#define AU_OWN (1 << 7) /* tx,rx */
#define IR_DIS_CRC (1 << 6) /* tx */
#define IR_BAD_CRC (1 << 5) /* tx */
#define IR_NEED_PULSE (1 << 4) /* tx */
#define IR_FORCE_UNDER (1 << 3) /* tx */
#define IR_DISABLE_TX (1 << 2) /* tx */
#define IR_HW_UNDER (1 << 0) /* tx */
#define IR_TX_ERROR (IR_DIS_CRC | IR_BAD_CRC | IR_HW_UNDER)
#define IR_PHY_ERROR (1 << 6) /* rx */
#define IR_CRC_ERROR (1 << 5) /* rx */
#define IR_MAX_LEN (1 << 4) /* rx */
#define IR_FIFO_OVER (1 << 3) /* rx */
#define IR_SIR_ERROR (1 << 2) /* rx */
#define IR_RX_ERROR (IR_PHY_ERROR | IR_CRC_ERROR | \
IR_MAX_LEN | IR_FIFO_OVER | IR_SIR_ERROR)
struct db_dest {
struct db_dest *pnext;
volatile u32 *vaddr;
dma_addr_t dma_addr;
};
struct ring_dest {
u8 count_0; /* 7:0 */
u8 count_1; /* 12:8 */
u8 reserved;
u8 flags;
u8 addr_0; /* 7:0 */
u8 addr_1; /* 15:8 */
u8 addr_2; /* 23:16 */
u8 addr_3; /* 31:24 */
};
/* Private data for each instance */
struct au1k_private {
void __iomem *iobase;
int irq_rx, irq_tx;
struct db_dest *pDBfree;
struct db_dest db[2 * NUM_IR_DESC];
volatile struct ring_dest *rx_ring[NUM_IR_DESC];
volatile struct ring_dest *tx_ring[NUM_IR_DESC];
struct db_dest *rx_db_inuse[NUM_IR_DESC];
struct db_dest *tx_db_inuse[NUM_IR_DESC];
u32 rx_head;
u32 tx_head;
u32 tx_tail;
u32 tx_full;
iobuff_t rx_buff;
struct net_device *netdev;
struct timeval stamp;
struct timeval now;
struct qos_info qos;
struct irlap_cb *irlap;
u8 open;
u32 speed;
u32 newspeed;
struct timer_list timer;
struct resource *ioarea;
struct au1k_irda_platform_data *platdata;
};
static int qos_mtt_bits = 0x07; /* 1 ms or more */
#define RUN_AT(x) (jiffies + (x))
static void au1k_irda_plat_set_phy_mode(struct au1k_private *p, int mode)
{
if (p->platdata && p->platdata->set_phy_mode)
p->platdata->set_phy_mode(mode);
}
static inline unsigned long irda_read(struct au1k_private *p,
unsigned long ofs)
{
/*
* IrDA peripheral bug. You have to read the register
* twice to get the right value.
*/
(void)__raw_readl(p->iobase + ofs);
return __raw_readl(p->iobase + ofs);
}
static inline void irda_write(struct au1k_private *p, unsigned long ofs,
unsigned long val)
{
__raw_writel(val, p->iobase + ofs);
wmb();
}
/*
* 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 struct db_dest *GetFreeDB(struct au1k_private *aup)
{
struct db_dest *db;
db = aup->pDBfree;
if (db)
aup->pDBfree = db->pnext;
return db;
}
/*
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 struct ring_dest *)
(rx_base + sizeof(struct ring_dest) * i);
}
for (i = 0; i < NUM_IR_DESC; i++) {
aup->tx_ring[i] = (volatile struct ring_dest *)
(tx_base + sizeof(struct ring_dest) * i);
}
}
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;
}
/*
* Set the IrDA communications speed.
*/
static int au1k_irda_set_speed(struct net_device *dev, int speed)
{
struct au1k_private *aup = netdev_priv(dev);
volatile struct ring_dest *ptxd;
unsigned long control;
int ret = 0, timeout = 10, i;
if (speed == aup->speed)
return ret;
/* disable PHY first */
au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
/* disable RX/TX */
irda_write(aup, IR_CONFIG_1,
irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE));
msleep(20);
while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) {
msleep(20);
if (!timeout--) {
printk(KERN_ERR "%s: rx/tx disable timeout\n",
dev->name);
break;
}
}
/* disable DMA */
irda_write(aup, IR_CONFIG_1,
irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE);
msleep(20);
/* 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)
au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR);
else
au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);
switch (speed) {
case 9600:
irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12));
irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
break;
case 19200:
irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR