patch-2.3.35 linux/drivers/net/irda/w83977af_ir.c
Next file: linux/drivers/net/myri_sbus.c
Previous file: linux/drivers/net/irda/toshoboe.c
Back to the patch index
Back to the overall index
- Lines: 441
- Date:
Tue Dec 21 10:17:31 1999
- Orig file:
v2.3.34/linux/drivers/net/irda/w83977af_ir.c
- Orig date:
Tue Nov 23 22:42:20 1999
diff -u --recursive --new-file v2.3.34/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Paul VanderSpek
* Created at: Wed Nov 4 11:46:16 1998
- * Modified at: Mon Nov 8 10:05:48 1999
+ * Modified at: Thu Dec 16 00:52:53 1999
* Modified by: Dag Brattli <[email protected]>
*
* Copyright (c) 1998-1999 Dag Brattli <[email protected]>
@@ -22,7 +22,7 @@
* and at no charge.
*
* If you find bugs in this file, its very likely that the same bug
- * will also be in pc87108.c since the implementations is quite
+ * will also be in pc87108.c since the implementations are quite
* similar.
*
* Notice that all functions that needs to access the chip in _any_
@@ -62,22 +62,28 @@
#include <net/irda/w83977af.h>
#include <net/irda/w83977af_ir.h>
-#define CONFIG_NETWINDER /* Adjust to NetWinder differences */
-#undef CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */
-#define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */
-#undef CONFIG_USE_INTERNAL_TIMER /* Just cannot make that timer work */
-#define CONFIG_USE_W977_PNP /* Currently needed */
+#ifdef CONFIG_ARCH_VNC /* Adjust to NetWinder differences */
+#undef CONFIG_VNC_TX_DMA_PROBLEMS /* Not needed */
+#define CONFIG_VNC_RX_DMA_PROBLEMS /* Must have this one! */
+#endif
+#undef CONFIG_USE_INTERNAL_TIMER /* Just cannot make that timer work */
+#define CONFIG_USE_W977_PNP /* Currently needed */
#define PIO_MAX_SPEED 115200
static char *driver_name = "w83977af_ir";
-static int qos_mtt_bits = 0x07; /* 1 ms or more */
+static int qos_mtt_bits = 0x07; /* 1 ms or more */
#define CHIP_IO_EXTENT 8
static unsigned int io[] = { 0x180, ~0, ~0, ~0 };
+#ifdef CONFIG_ARCH_VNC /* Adjust to NetWinder differences */
static unsigned int irq[] = { 6, 0, 0, 0 };
-static unsigned int dma[] =
-{ 1, 0, 0, 0 };
+#else
+static unsigned int irq[] = { 11, 0, 0, 0 };
+#endif
+static unsigned int dma[] = { 1, 0, 0, 0 };
+static unsigned int efbase[] = { W977_EFIO_BASE, W977_EFIO2_BASE };
+static unsigned int efio = W977_EFIO_BASE;
static struct w83977af_ir *dev_self[] = { NULL, NULL, NULL, NULL};
@@ -98,6 +104,7 @@
static int w83977af_net_init(struct net_device *dev);
static int w83977af_net_open(struct net_device *dev);
static int w83977af_net_close(struct net_device *dev);
+static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
/*
* Function w83977af_init ()
@@ -248,6 +255,7 @@
dev->hard_start_xmit = w83977af_hard_xmit;
dev->open = w83977af_net_open;
dev->stop = w83977af_net_close;
+ dev->do_ioctl = w83977af_net_ioctl;
rtnl_lock();
err = register_netdev(dev);
@@ -278,21 +286,23 @@
#ifdef CONFIG_USE_W977_PNP
/* enter PnP configuration mode */
- w977_efm_enter();
+ w977_efm_enter(efio);
- w977_select_device(W977_DEVICE_IR);
+ w977_select_device(W977_DEVICE_IR, efio);
/* Deactivate device */
- w977_write_reg(0x30, 0x00);
+ w977_write_reg(0x30, 0x00, efio);
- w977_efm_exit();
+ w977_efm_exit(efio);
#endif /* CONFIG_USE_W977_PNP */
/* Remove netdevice */
if (self->netdev) {
rtnl_lock();
- unregister_netdev(self->netdev);
+ unregister_netdevice(self->netdev);
rtnl_unlock();
+ /* Must free the old-style 2.2.x device */
+ kfree(self->netdev);
}
/* Release the PORT that this driver is using */
@@ -311,100 +321,103 @@
return 0;
}
-/*
- * Function w83977af_probe (iobase, irq, dma)
- *
- * Returns non-negative on success.
- *
- */
int w83977af_probe( int iobase, int irq, int dma)
{
- int version;
-
- IRDA_DEBUG( 0, __FUNCTION__ "()\n");
+ int version;
+ int i;
+
+ for (i=0; i < 2; i++) {
+ IRDA_DEBUG( 0, __FUNCTION__ "()\n");
#ifdef CONFIG_USE_W977_PNP
- /* Enter PnP configuration mode */
- w977_efm_enter();
-
- w977_select_device(W977_DEVICE_IR);
-
- /* Configure PnP port, IRQ, and DMA channel */
- w977_write_reg(0x60, (iobase >> 8) & 0xff);
- w977_write_reg(0x61, (iobase) & 0xff);
-
- w977_write_reg(0x70, irq);
-#ifdef CONFIG_NETWINDER
- w977_write_reg(0x74, dma+1); /* Netwinder uses 1 higher than Linux */
+ /* Enter PnP configuration mode */
+ w977_efm_enter(efbase[i]);
+
+ w977_select_device(W977_DEVICE_IR, efbase[i]);
+
+ /* Configure PnP port, IRQ, and DMA channel */
+ w977_write_reg(0x60, (iobase >> 8) & 0xff, efbase[i]);
+ w977_write_reg(0x61, (iobase) & 0xff, efbase[i]);
+
+ w977_write_reg(0x70, irq, efbase[i]);
+#ifdef CONFIG_ARCH_VNC
+ /* Netwinder uses 1 higher than Linux */
+ w977_write_reg(0x74, dma+1, efbase[i]);
#else
- w977_write_reg(0x74, dma);
-#endif
- w977_write_reg(0x75, 0x04); /* Disable Tx DMA */
-
- /* Set append hardware CRC, enable IR bank selection */
- w977_write_reg(0xf0, APEDCRC|ENBNKSEL);
-
- /* Activate device */
- w977_write_reg(0x30, 0x01);
-
- w977_efm_exit();
-#endif
- /* Disable Advanced mode */
- switch_bank(iobase, SET2);
- outb(iobase+2, 0x00);
-
- /* Turn on UART (global) interrupts */
- switch_bank(iobase, SET0);
- outb(HCR_EN_IRQ, iobase+HCR);
-
- /* Switch to advanced mode */
- switch_bank(iobase, SET2);
- outb(inb(iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
-
- /* Set default IR-mode */
- switch_bank(iobase, SET0);
- outb(HCR_SIR, iobase+HCR);
-
- /* Read the Advanced IR ID */
- switch_bank(iobase, SET3);
- version = inb(iobase+AUID);
-
- /* Should be 0x1? */
- if (0x10 != (version & 0xf0)) {
- IRDA_DEBUG( 0, __FUNCTION__ "(), Wrong chip version");
- return -1;
- }
-
- /* Set FIFO size to 32 */
- switch_bank(iobase, SET2);
- outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);
-
- /* Set FIFO threshold to TX17, RX16 */
- switch_bank(iobase, SET0);
- outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|UFR_EN_FIFO,iobase+UFR);
-
- /* Receiver frame length */
- switch_bank(iobase, SET4);
- outb(2048 & 0xff, iobase+6);
- outb((2048 >> 8) & 0x1f, iobase+7);
-
- /*
- * Init HP HSDL-1100 transceiver.
- *
- * Set IRX_MSL since we have 2 * receive paths IRRX, and
- * IRRXH. Clear IRSL0D since we want IRSL0 * to be a input pin used
- * for IRRXH
- *
- * IRRX pin 37 connected to receiver
- * IRTX pin 38 connected to transmitter
- * FIRRX pin 39 connected to receiver (IRSL0)
- * CIRRX pin 40 connected to pin 37
- */
- switch_bank(iobase, SET7);
- outb(0x40, iobase+7);
-
- IRDA_DEBUG(0, "W83977AF (IR) driver loaded. Version: 0x%02x\n", version);
-
- return 0;
+ w977_write_reg(0x74, dma, efbase[i]);
+#endif /*CONFIG_ARCH_VNC */
+ w977_write_reg(0x75, 0x04, efbase[i]); /* Disable Tx DMA */
+
+ /* Set append hardware CRC, enable IR bank selection */
+ w977_write_reg(0xf0, APEDCRC|ENBNKSEL, efbase[i]);
+
+ /* Activate device */
+ w977_write_reg(0x30, 0x01, efbase[i]);
+
+ w977_efm_exit(efbase[i]);
+#endif /* CONFIG_USE_W977_PNP */
+ /* Disable Advanced mode */
+ switch_bank(iobase, SET2);
+ outb(iobase+2, 0x00);
+
+ /* Turn on UART (global) interrupts */
+ switch_bank(iobase, SET0);
+ outb(HCR_EN_IRQ, iobase+HCR);
+
+ /* Switch to advanced mode */
+ switch_bank(iobase, SET2);
+ outb(inb(iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
+
+ /* Set default IR-mode */
+ switch_bank(iobase, SET0);
+ outb(HCR_SIR, iobase+HCR);
+
+ /* Read the Advanced IR ID */
+ switch_bank(iobase, SET3);
+ version = inb(iobase+AUID);
+
+ /* Should be 0x1? */
+ if (0x10 == (version & 0xf0)) {
+ efio = efbase[i];
+
+ /* Set FIFO size to 32 */
+ switch_bank(iobase, SET2);
+ outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);
+
+ /* Set FIFO threshold to TX17, RX16 */
+ switch_bank(iobase, SET0);
+ outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|
+ UFR_EN_FIFO,iobase+UFR);
+
+ /* Receiver frame length */
+ switch_bank(iobase, SET4);
+ outb(2048 & 0xff, iobase+6);
+ outb((2048 >> 8) & 0x1f, iobase+7);
+
+ /*
+ * Init HP HSDL-1100 transceiver.
+ *
+ * Set IRX_MSL since we have 2 * receive paths IRRX,
+ * and IRRXH. Clear IRSL0D since we want IRSL0 * to
+ * be a input pin used for IRRXH
+ *
+ * IRRX pin 37 connected to receiver
+ * IRTX pin 38 connected to transmitter
+ * FIRRX pin 39 connected to receiver (IRSL0)
+ * CIRRX pin 40 connected to pin 37
+ */
+ switch_bank(iobase, SET7);
+ outb(0x40, iobase+7);
+
+ MESSAGE("W83977AF (IR) driver loaded. "
+ "Version: 0x%02x\n", version);
+
+ return 0;
+ } else {
+ /* Try next extented function register address */
+ IRDA_DEBUG( 0, __FUNCTION__ "(), Wrong chip version");
+ }
+ }
+ return -1;
}
void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
@@ -576,7 +589,7 @@
static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
{
__u8 set;
-#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+#ifdef CONFIG_VNC_TX_DMA_PROBLEMS
unsigned long flags;
__u8 hcr;
#endif
@@ -592,7 +605,7 @@
/* Choose transmit DMA channel */
switch_bank(iobase, SET2);
outb(ADCR1_D_CHSW|/*ADCR1_DMA_F|*/ADCR1_ADV_SL, iobase+ADCR1);
-#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+#ifdef CONFIG_VNC_TX_DMA_PROBLEMS
save_flags(flags);
cli();
@@ -609,7 +622,7 @@
/* Enable DMA */
switch_bank(iobase, SET0);
-#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+#ifdef CONFIG_VNC_TX_DMA_PROBLEMS
hcr = inb(iobase+HCR);
outb(hcr | HCR_EN_DMA, iobase+HCR);
enable_dma(self->io.dma);
@@ -653,7 +666,7 @@
}
IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n",
- fifo_size, actual, len);
+ fifo_size, actual, len);
/* Restore bank */
outb(set, iobase+SSR);
@@ -725,7 +738,7 @@
{
int iobase;
__u8 set;
-#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
+#ifdef CONFIG_VNC_RX_DMA_PROBLEMS
unsigned long flags;
__u8 hcr;
#endif
@@ -751,7 +764,7 @@
self->io.direction = IO_RECV;
self->rx_buff.data = self->rx_buff.head;
-#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
+#ifdef CONFIG_VNC_RX_DMA_PROBLEMS
save_flags(flags);
cli();
@@ -775,7 +788,7 @@
/* Enable DMA */
switch_bank(iobase, SET0);
-#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
+#ifdef CONFIG_VNC_RX_DMA_PROBLEMS
hcr = inb(iobase+HCR);
outb(hcr | HCR_EN_DMA, iobase+HCR);
enable_dma(self->io.dma);
@@ -985,6 +998,14 @@
self->netdev->tbusy = 0; /* Unlock */
self->stats.tx_packets++;
+ /* Check if we need to change the speed? */
+ if (self->new_speed) {
+ IRDA_DEBUG(2, __FUNCTION__
+ "(), Changing speed!\n");
+ w83977af_change_speed(self, self->new_speed);
+ self->new_speed = 0;
+ }
+
/* Schedule network layer */
mark_bh(NET_BH);
@@ -1207,7 +1228,7 @@
iobase = self->io.iobase;
if (request_irq(self->io.irq, w83977af_interrupt, 0, dev->name,
- (void *) dev)) {
+ (void *) dev)) {
return -EAGAIN;
}
/*
@@ -1289,7 +1310,7 @@
switch_bank(iobase, SET0);
outb(0, iobase+ICR);
- free_irq(self->io.irq, self);
+ free_irq(self->io.irq, dev);
free_dma(self->io.dma);
/* Restore bank register */
@@ -1298,6 +1319,50 @@
MOD_DEC_USE_COUNT;
return 0;
+}
+
+/*
+ * Function w83977af_net_ioctl (dev, rq, cmd)
+ *
+ * Process IOCTL commands for this device
+ *
+ */
+static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct if_irda_req *irq = (struct if_irda_req *) rq;
+ struct w83977af_ir *self;
+ unsigned long flags;
+ int ret = 0;
+
+ ASSERT(dev != NULL, return -1;);
+
+ self = dev->priv;
+
+ ASSERT(self != NULL, return -1;);
+
+ IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+
+ /* Disable interrupts & save flags */
+ save_flags(flags);
+ cli();
+
+ switch (cmd) {
+ case SIOCSBANDWIDTH: /* Set bandwidth */
+ w83977af_change_speed(self, irq->ifr_baudrate);
+ break;
+ case SIOCSMEDIABUSY: /* Set media busy */
+ irda_device_set_media_busy(self->netdev, TRUE);
+ break;
+ case SIOCGRECEIVING: /* Check if we are receiving right now */
+ irq->ifr_receiving = w83977af_is_receiving(self);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ restore_flags(flags);
+
+ return ret;
}
#ifdef MODULE
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen (who was at: [email protected])