/*
* linux/drivers/net/irda/sa1100_ir.c
*
* Copyright (C) 2000-2001 Russell King
*
* 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.
*
* Infra-red driver for the StrongARM SA1100 embedded microprocessor
*
* Note that we don't have to worry about the SA1111's DMA bugs in here,
* so we use the straight forward dma_map_* functions with a null pointer.
*
* This driver takes one kernel command line parameter, sa1100ir=, with
* the following options:
* max_rate:baudrate - set the maximum baud rate
* power_level:level - set the transmitter power level
* tx_lpm:0|1 - set transmit low power mode
*/
#include <linux/module.h>
#include <linux/moduleparam.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/delay.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/sa11x0-dma.h>
#include <net/irda/irda.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda_device.h>
#include <mach/hardware.h>
#include <asm/mach/irda.h>
static int power_level = 3;
static int tx_lpm;
static int max_rate = 4000000;
struct sa1100_buf {
struct device *dev;
struct sk_buff *skb;
struct scatterlist sg;
struct dma_chan *chan;
dma_cookie_t cookie;
};
struct sa1100_irda {
unsigned char utcr4;
unsigned char power;
unsigned char open;
int speed;
int newspeed;
struct sa1100_buf dma_rx;
struct sa1100_buf dma_tx;
struct device *dev;
struct irda_platform_data *pdata;
struct irlap_cb *irlap;
struct qos_info qos;
iobuff_t tx_buff;
iobuff_t rx_buff;
int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *);
irqreturn_t (*irq)(struct net_device *, struct sa1100_irda *);
};
static int sa1100_irda_set_speed(struct sa1100_irda *, int);
#define IS_FIR(si) ((si)->speed >= 4000000)
#define HPSIR_MAX_RXLEN 2047
static struct dma_slave_config sa1100_irda_sir_tx = {
.direction = DMA_TO_DEVICE,
.dst_addr = __PREG(Ser2UTDR),
.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.dst_maxburst = 4,
};
static struct dma_slave_config sa1100_irda_fir_rx = {
.direction = DMA_FROM_DEVICE,
.src_addr = __PREG(Ser2HSDR),
.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.src_maxburst = 8,
};
static struct dma_slave_config sa1100_irda_fir_tx = {
.direction = DMA_TO_DEVICE,
.dst_addr = __PREG(Ser2HSDR),
.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.dst_maxburst = 8,
};
static unsigned sa1100_irda_dma_xferred(struct sa1100_buf *buf)
{
struct dma_chan *chan = buf->chan;
struct dma_tx_state state;
enum dma_status status;
status = chan->device->device_tx_status(chan, buf->cookie, &state);
if (status != DMA_PAUSED)
return 0;
return sg_dma_len(&buf->sg) - state.residue;
}
static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf,
const char *name, struct dma_slave_config *cfg)
{
dma_cap_mask_t m;
int ret;
dma_cap_zero(m);
dma_cap_set(DMA_SLAVE, m);
buf->chan = dma_request_channel(m