irda smc patch

From: Stefani Seibold (stefani@seibold.net)
Date: Fri Jul 20 2001 - 05:21:56 EST


Hi folks,

this patch make the linux irda smc-ircc driver working the newer LPC47xxx smc chips,
with are mostly used in notebook computers.

I added also support for all smc super i/o chips, which i had found a reference manual
on the smc webpage:

FDC37C44
FDC37C665GT
FDC37C669
FDC37C669
FDC37C78
FDC37N769
FDC37N869
FDC37B72X
FDC37B77X
FDC37B78X
FDC37B80X
FDC37C67X
FDC37C93X
FDC37C93XAPM
FDC37C93XFR
FDC37M707
FDC37M81X
FDC37N958FR
FDC37N972
LPC47N227
LPC47N267
LPC47B27X
LPC47B37X
LPC47M10X
LPC47M120
LPC47M13X
LPC47M14X
LPC47N252
LPC47S42X

It was tested currently on my INSPIRON 8000, so feedbacks are welcome

I hope this patch will go in to the 2.4 tree...

Greetings

diff -u --recursive --new-file linux-2.4.6-ac5/drivers/net/irda/smc-ircc.c.save linux-2.4.6-ac5/drivers/net/irda/smc-ircc.c
--- linux-2.4.6-ac5/drivers/net/irda/smc-ircc.c.save Fri Jul 20 10:32:05 2001
+++ linux-2.4.6-ac5/drivers/net/irda/smc-ircc.c Fri Jul 20 11:52:27 2001
@@ -8,7 +8,10 @@
  * Created at:
  * Modified at: Tue Feb 22 10:05:06 2000
  * Modified by: Dag Brattli <dag@brattli.net>
+ * Modified at: Tue Jun 26 2001
+ * Modified by: Stefani Seibold <stefani@seibold.net>
  *
+ * Copyright (c) 2001 Stefani Seibold
  * Copyright (c) 1999-2000 Dag Brattli
  * Copyright (c) 1998-1999 Thomas Davis,
  * All Rights Reserved.
@@ -28,8 +31,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  *
- * SIO's: SMC FDC37N869, FDC37C669, FDC37N958
- * Applicable Models : Fujitsu Lifebook 635t, Sony PCG-505TX
+ * SIO's: all SIO documentet by SMC (June, 2001)
+ * Applicable Models : Fujitsu Lifebook 635t, Sony PCG-505TX,
+ * Dell Inspiron 8000
  *
  ********************************************************************/
 
@@ -60,23 +64,27 @@
 #include <net/irda/smc-ircc.h>
 #include <net/irda/irport.h>
 
+struct smc_chip {
+ char *name;
+ u16 flags;
+ u8 devid;
+ u8 rev;
+};
+typedef struct smc_chip smc_chip_t;
+
 static char *driver_name = "smc-ircc";
 
-#define CHIP_IO_EXTENT 8
+#define DIM(x) (sizeof(x)/(sizeof(*(x))))
 
-static unsigned int io[] = { ~0, ~0 };
-static unsigned int io2[] = { 0, 0 };
+#define CHIP_IO_EXTENT 8
 
 static struct ircc_cb *dev_self[] = { NULL, NULL};
 
 /* Some prototypes */
-static int ircc_open(int i, unsigned int iobase, unsigned int board_addr);
+static int ircc_open(unsigned int iobase, unsigned int board_addr);
 #ifdef MODULE
 static int ircc_close(struct ircc_cb *self);
 #endif /* MODULE */
-static int ircc_probe(int iobase, int board_addr);
-static int ircc_probe_58(smc_chip_t *chip, chipio_t *info);
-static int ircc_probe_69(smc_chip_t *chip, chipio_t *info);
 static int ircc_dma_receive(struct ircc_cb *self, int iobase);
 static void ircc_dma_receive_complete(struct ircc_cb *self, int iobase);
 static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -91,20 +99,73 @@
 static int ircc_net_close(struct net_device *dev);
 static int ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data);
 
-/* These are the currently known SMC chipsets */
-static smc_chip_t chips[] =
+#define KEY55_1 0 // SuperIO Configuration mode with Key <0x55>
+#define KEY55_2 1 // SuperIO Configuration mode with Key <0x55,0x55>
+#define NoIRDA 2 // SuperIO Chip has no IRDA Port
+#define SIR 0 // SuperIO Chip has only slow IRDA
+#define FIR 4 // SuperIO Chip has fast IRDA
+#define SERx4 8 // SuperIO Chip supports 115,2 KBaud * 4=460,8 KBaud
+
+/* These are the currently known SMC SuperIO chipsets */
+static smc_chip_t fdc_chips_flat[]=
+{
+ // Base address 0x3f0 or 0x370
+ { "37C44", KEY55_1|NoIRDA, 0x00, 0x00 }, /* This chip can not detected */
+ { "37C665GT", KEY55_2|NoIRDA, 0x65, 0x01 },
+ { "37C665GT", KEY55_2|NoIRDA, 0x66, 0x01 },
+ { "37C669", KEY55_2|SIR|SERx4, 0x03, 0x02 },
+ { "37C669", KEY55_2|SIR|SERx4, 0x04, 0x02 }, /* ID? */
+ { "37C78", KEY55_2|NoIRDA, 0x78, 0x00 },
+ { "37N769", KEY55_1|FIR|SERx4, 0x28, 0x00 },
+ { "37N869", KEY55_1|FIR|SERx4, 0x29, 0x00 },
+ { NULL }
+};
+
+static smc_chip_t fdc_chips_paged[]=
+{
+ { "37B72X", KEY55_1|SIR|SERx4, 0x4c, 0x00 },
+ { "37B77X", KEY55_1|SIR|SERx4, 0x43, 0x00 },
+ { "37B78X", KEY55_1|SIR|SERx4, 0x44, 0x00 },
+ { "37B80X", KEY55_1|SIR|SERx4, 0x42, 0x00 },
+ { "37C67X", KEY55_1|FIR|SERx4, 0x40, 0x00 },
+ { "37C93X", KEY55_2|SIR|SERx4, 0x02, 0x01 },
+ { "37C93XAPM", KEY55_1|SIR|SERx4, 0x30, 0x01 },
+ { "37C93XFR", KEY55_2|FIR|SERx4, 0x03, 0x01 },
+ { "37M707", KEY55_1|SIR|SERx4, 0x42, 0x00 },
+ { "37M81X", KEY55_1|SIR|SERx4, 0x4d, 0x00 },
+ { "37N958FR", KEY55_1|FIR|SERx4, 0x09, 0x04 },
+ { "37N972", KEY55_1|FIR|SERx4, 0x0a, 0x00 },
+ { "37N972", KEY55_1|FIR|SERx4, 0x0b, 0x00 },
+ { NULL }
+};
+
+static smc_chip_t lpc_chips_flat[]=
 {
- { "FDC37C669", 0x55, 0x55, 0x0d, 0x04, ircc_probe_69 },
- { "FDC37N769", 0x55, 0x55, 0x0d, 0x28, ircc_probe_69 },
- { "FDC37N869", 0x55, 0x00, 0x0d, 0x29, ircc_probe_69 },
- { "FDC37N958", 0x55, 0x55, 0x20, 0x09, ircc_probe_58 },
- { "FDC37N971", 0x55, 0x55, 0x20, 0x0a, ircc_probe_58 },
- { "FDC37N972", 0x55, 0x55, 0x20, 0x0b, ircc_probe_58 },
+ // Base address 0x2E or 0x4E
+ { "47N227", KEY55_1|FIR|SERx4, 0x5a, 0x00 },
+ { "47N267", KEY55_1|FIR|SERx4, 0x5e, 0x00 },
+ { NULL }
+};
+
+static smc_chip_t lpc_chips_paged[]=
+{
+ { "47B27X", KEY55_1|SIR|SERx4, 0x51, 0x00 },
+ { "47B37X", KEY55_1|SIR|SERx4, 0x52, 0x00 },
+ { "47M10X", KEY55_1|SIR|SERx4, 0x59, 0x00 },
+ { "47M120", KEY55_1|NoIRDA|SERx4, 0x5c, 0x00 },
+ { "47M13X", KEY55_1|SIR|SERx4, 0x59, 0x00 },
+ { "47M14X", KEY55_1|SIR|SERx4, 0x5f, 0x00 },
+ { "47N252", KEY55_1|FIR|SERx4, 0x0e, 0x00 },
+ { "47S42X", KEY55_1|SIR|SERx4, 0x57, 0x00 },
         { NULL }
 };
 
 static int ircc_irq=255;
 static int ircc_dma=255;
+static int ircc_fir=0;
+static int ircc_sir=0;
+
+static unsigned short dev_count=0;
 
 static inline void register_bank(int iobase, int bank)
 {
@@ -112,6 +173,209 @@
                iobase+IRCC_MASTER);
 }
 
+static int smc_access(unsigned short cfg_base,unsigned char reg)
+{
+ IRDA_DEBUG(0, __FUNCTION__ "()\n");
+
+ outb(reg, cfg_base);
+
+ if (inb(cfg_base)!=reg)
+ return -1;
+
+ return 0;
+}
+
+static smc_chip_t * smc_probe(unsigned short cfg_base,u8 reg,smc_chip_t *chip,char *type)
+{
+ u8 devid,xdevid;
+ u8 rev;
+
+ IRDA_DEBUG(0, __FUNCTION__ "()\n");
+
+ /* Leave configuration */
+
+ outb(0xaa, cfg_base);
+
+ if (inb(cfg_base)==0xaa) /* not a smc superio chip */
+ return NULL;
+
+ outb(reg, cfg_base);
+
+ xdevid=inb(cfg_base+1);
+
+ /* Enter configuration */
+
+ outb(0x55, cfg_base);
+
+ if (smc_access(cfg_base,0x55)) /* send second key and check */
+ return NULL;
+
+ /* probe device ID */
+
+ if (smc_access(cfg_base,reg))
+ return NULL;
+
+ devid=inb(cfg_base+1);
+
+ if (devid==0) /* typical value for unused port */
+ return NULL;
+
+ if (devid==0xff) /* typical value for unused port */
+ return NULL;
+
+ /* probe revision ID */
+
+ if (smc_access(cfg_base,reg+1))
+ return NULL;
+
+ rev=inb(cfg_base+1);
+
+ if (rev>=128) /* i think this will make no sense */
+ return NULL;
+
+ if (devid==xdevid) /* protection against false positives */
+ return NULL;
+
+ /* Check for expected device ID; are there others? */
+
+ while(chip->devid!=devid) {
+
+ chip++;
+
+ if (chip->name==NULL)
+ return NULL;
+ }
+ if (chip->rev>rev)
+ return NULL;
+
+ MESSAGE("found SMC SuperIO Chip (devid=0x%02x rev=%02X base=0x%04x): %s%s\n",devid,rev,cfg_base,type,chip->name);
+
+ if (chip->flags&NoIRDA)
+ MESSAGE("chipset does not support IRDA\n");
+
+ return chip;
+}
+
+/*
+ * Function smc_superio_flat (chip, base, type)
+ *
+ * Try get configuration of a smc SuperIO chip with flat register model
+ *
+ */
+static int smc_superio_flat(smc_chip_t *chips, unsigned short cfg_base, char *type)
+{
+ unsigned short fir_io;
+ unsigned short sir_io;
+ __u8 mode;
+ int ret = -ENODEV;
+
+ IRDA_DEBUG(0, __FUNCTION__ "()\n");
+
+ if (smc_probe(cfg_base,0xD,chips,type)==NULL)
+ return ret;
+
+ outb(0x0c, cfg_base);
+
+ mode = inb(cfg_base+1);
+ mode = (mode & 0x38) >> 3;
+
+ /* Value for IR port */
+ if (mode && mode < 4) {
+ /* SIR iobase */
+ outb(0x25, cfg_base);
+ sir_io = inb(cfg_base+1) << 2;
+
+ /* FIR iobase */
+ outb(0x2b, cfg_base);
+ fir_io = inb(cfg_base+1) << 3;
+
+ if (fir_io) {
+ if (ircc_open(fir_io, sir_io) == 0)
+ ret=0;
+ }
+ }
+
+ /* Exit configuration */
+ outb(0xaa, cfg_base);
+
+ return ret;
+}
+
+/*
+ * Function smc_superio_paged (chip, base, type)
+ *
+ * Try get configuration of a smc SuperIO chip with paged register model
+ *
+ */
+static int smc_superio_paged(smc_chip_t *chips, unsigned short cfg_base, char *type)
+{
+ unsigned short fir_io;
+ unsigned short sir_io;
+ int ret = -ENODEV;
+
+ IRDA_DEBUG(0, __FUNCTION__ "()\n");
+
+ if (smc_probe(cfg_base,0x20,chips,type)==NULL)
+ return ret;
+
+ /* Select logical device (UART2) */
+ outb(0x07, cfg_base);
+ outb(0x05, cfg_base + 1);
+
+ /* SIR iobase */
+ outb(0x60, cfg_base);
+ sir_io = inb(cfg_base + 1) << 8;
+ outb(0x61, cfg_base);
+ sir_io |= inb(cfg_base + 1);
+
+ /* Read FIR base */
+ outb(0x62, cfg_base);
+ fir_io = inb(cfg_base + 1) << 8;
+ outb(0x63, cfg_base);
+ fir_io |= inb(cfg_base + 1);
+ outb(0x2b, cfg_base); // ???
+
+ if (fir_io) {
+ if (ircc_open(fir_io, sir_io) == 0)
+ ret=0;
+ }
+
+ /* Exit configuration */
+ outb(0xaa, cfg_base);
+
+ return ret;
+}
+
+static int smc_superio_fdc(unsigned short cfg_base)
+{
+ if (check_region(cfg_base, 2) < 0) {
+ IRDA_DEBUG(0, __FUNCTION__ ": can't get cfg_base of 0x%03x\n",
+ cfg_base);
+ return -1;
+ }
+
+ if (!smc_superio_flat(fdc_chips_flat,cfg_base,"FDC")||!smc_superio_paged(fdc_chips_paged,cfg_base,"FDC"))
+ return 0;
+
+ return -1;
+}
+
+static int smc_superio_lpc(unsigned short cfg_base)
+{
+#if 0
+ if (check_region(cfg_base, 2) < 0) {
+ IRDA_DEBUG(0, __FUNCTION__ ": can't get cfg_base of 0x%03x\n",
+ cfg_base);
+ return -1;
+ }
+#endif
+
+ if (!smc_superio_flat(lpc_chips_flat,cfg_base,"LPC")||!smc_superio_paged(lpc_chips_paged,cfg_base,"LPC"))
+ return 0;
+
+ return -1;
+}
+
 /*
  * Function ircc_init ()
  *
@@ -120,37 +384,36 @@
  */
 int __init ircc_init(void)
 {
- static int smcreg[] = { 0x3f0, 0x370 };
- smc_chip_t *chip;
- chipio_t info;
- int ret = -ENODEV;
- int i;
+ int ret=-ENODEV;
 
         IRDA_DEBUG(0, __FUNCTION__ "\n");
 
- /* Probe for all the NSC chipsets we know about */
- for (chip=chips; chip->name ; chip++) {
- for (i=0; i<2; i++) {
- info.cfg_base = smcreg[i];
-
- /*
- * First we check if the user has supplied any
- * parameters which we should use instead of probed
- * values
- */
- if (io[i] < 0x2000) {
- info.fir_base = io[i];
- info.sir_base = io2[i];
- } else if (chip->probe(chip, &info) < 0)
- continue;
- if (check_region(info.fir_base, CHIP_IO_EXTENT) < 0)
- continue;
- if (check_region(info.sir_base, CHIP_IO_EXTENT) < 0)
- continue;
- if (ircc_open(i, info.fir_base, info.sir_base) == 0)
- ret = 0;
- }
+ dev_count=0;
+
+ if ((ircc_fir>0)&&(ircc_sir>0)) {
+ MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir);
+ MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir);
+
+ if (ircc_open(ircc_fir, ircc_sir) == 0)
+ return 0;
+
+ return -ENODEV;
         }
+
+ /* Trys to open for all the SMC chipsets we know about */
+
+ IRDA_DEBUG(0, __FUNCTION__
+ " Try to open all known SMC chipsets\n");
+
+ if (smc_superio_fdc(0x3f0))
+ ret=0;
+ if (smc_superio_fdc(0x370))
+ ret=0;
+ if (smc_superio_lpc(0x2e))
+ ret=0;
+ if (smc_superio_lpc(0x4e))
+ ret=0;
+
         return ret;
 }
 
@@ -177,24 +440,57 @@
 /*
  * Function ircc_open (iobase, irq)
  *
- * Open driver instance
+ * Try to open driver instance
  *
  */
-static int ircc_open(int i, unsigned int fir_base, unsigned int sir_base)
+static int ircc_open(unsigned int fir_base, unsigned int sir_base)
 {
         struct ircc_cb *self;
         struct irport_cb *irport;
- int config;
- int ret;
+ unsigned char low, high, chip, config, dma, irq, version;
+
 
         IRDA_DEBUG(0, __FUNCTION__ "\n");
 
- if ((config = ircc_probe(fir_base, sir_base)) == -1) {
+ if (check_region(fir_base, CHIP_IO_EXTENT) < 0) {
+ IRDA_DEBUG(0, __FUNCTION__ ": can't get fir_base of 0x%03x\n",
+ fir_base);
+ return -ENODEV;
+ }
+#if POSSIBLE_USED_BY_SERIAL_DRIVER
+ if (check_region(sir_base, CHIP_IO_EXTENT) < 0) {
+ IRDA_DEBUG(0, __FUNCTION__ ": can't get sir_base of 0x%03x\n",
+ sir_base);
+ return -ENODEV;
+ }
+#endif
+
+ register_bank(fir_base, 3);
+
+ high = inb(fir_base+IRCC_ID_HIGH);
+ low = inb(fir_base+IRCC_ID_LOW);
+ chip = inb(fir_base+IRCC_CHIP_ID);
+ version = inb(fir_base+IRCC_VERSION);
+ config = inb(fir_base+IRCC_INTERFACE);
+
+ irq = config >> 4 & 0x0f;
+ dma = config & 0x0f;
+
+ if (high != 0x10 || low != 0xb8 || (chip != 0xf1 && chip != 0xf2)) {
                 IRDA_DEBUG(0, __FUNCTION__
                            "(), addr 0x%04x - no device found!\n", fir_base);
- return -1;
+ return -ENODEV;
         }
-
+ MESSAGE("SMC IrDA Controller found\n IrCC version %d.%d, "
+ "firport 0x%03x, sirport 0x%03x dma=%d, irq=%d\n",
+ chip & 0x0f, version, fir_base, sir_base, dma, irq);
+
+ if (dev_count>DIM(dev_self)) {
+ IRDA_DEBUG(0, __FUNCTION__
+ "(), to many devices!\n");
+ return -ENOMEM;
+ }
+
         /*
          * Allocate new instance of the driver
          */
@@ -206,46 +502,74 @@
         }
         memset(self, 0, sizeof(struct ircc_cb));
         spin_lock_init(&self->lock);
-
- /* Need to store self somewhere */
- dev_self[i] = self;
 
- irport = irport_open(i, sir_base, config >> 4 & 0x0f);
- if (!irport)
+ /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
+ self->rx_buff.truesize = 4000;
+ self->tx_buff.truesize = 4000;
+
+ self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+ GFP_KERNEL|GFP_DMA);
+ if (self->rx_buff.head == NULL) {
+ ERROR("%s, Can't allocate memory for receive buffer!\n",
+ driver_name);
+ kfree(self);
+ return -ENOMEM;
+ }
+
+ self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
+ GFP_KERNEL|GFP_DMA);
+ if (self->tx_buff.head == NULL) {
+ ERROR("%s, Can't allocate memory for transmit buffer!\n",
+ driver_name);
+ kfree(self->rx_buff.head);
+ kfree(self);
+ return -ENOMEM;
+ }
+
+ irport = irport_open(dev_count, sir_base, irq);
+ if (!irport) {
+ kfree(self->tx_buff.head);
+ kfree(self->rx_buff.head);
+ kfree(self);
                 return -ENODEV;
+ }
+
+ memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+ memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+
+ /* Need to store self somewhere */
+ dev_self[dev_count++] = self;
 
         /* Steal the network device from irport */
         self->netdev = irport->netdev;
         self->irport = irport;
+
         irport->priv = self;
 
         /* Initialize IO */
         self->io.fir_base = fir_base;
         self->io.sir_base = sir_base; /* Used by irport */
- self->io.irq = config >> 4 & 0x0f;
+ self->io.fir_ext = CHIP_IO_EXTENT;
+ self->io.sir_ext = 8; /* Used by irport */
+
         if (ircc_irq < 255) {
- MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
- driver_name, self->io.irq, ircc_irq);
+ if (ircc_irq!=irq)
+ MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
+ driver_name, self->io.irq, ircc_irq);
                 self->io.irq = ircc_irq;
         }
- self->io.fir_ext = CHIP_IO_EXTENT;
- self->io.sir_ext = 8; /* Used by irport */
- self->io.dma = config & 0x0f;
+ else
+ self->io.irq = irq;
         if (ircc_dma < 255) {
- MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
- driver_name, self->io.dma, ircc_dma);
+ if (ircc_dma!=dma)
+ MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
+ driver_name, self->io.dma, ircc_dma);
                 self->io.dma = ircc_dma;
         }
+ else
+ self->io.dma = dma;
 
- /* Lock the port that we need */
- ret = check_region(self->io.fir_base, self->io.fir_ext);
- if (ret < 0) {
- IRDA_DEBUG(0, __FUNCTION__ ": can't get fir_base of 0x%03x\n",
- self->io.fir_base);
- kfree(self);
- return -ENODEV;
- }
- request_region(self->io.fir_base, self->io.fir_ext, driver_name);
+ request_region(fir_base, CHIP_IO_EXTENT, driver_name);
 
         /* Initialize QoS for this device */
         irda_init_max_qos_capabilies(&irport->qos);
@@ -260,23 +584,6 @@
 
         irport->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO;
         
- /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
- self->rx_buff.truesize = 4000;
- self->tx_buff.truesize = 4000;
-
- self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
- if (self->rx_buff.head == NULL)
- return -ENOMEM;
- memset(self->rx_buff.head, 0, self->rx_buff.truesize);
-
- self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
- if (self->tx_buff.head == NULL) {
- kfree(self->rx_buff.head);
- return -ENOMEM;
- }
- memset(self->tx_buff.head, 0, self->tx_buff.truesize);
 
         self->rx_buff.in_frame = FALSE;
         self->rx_buff.state = OUTSIDE_FRAME;
@@ -295,6 +602,10 @@
         if (self->pmdev)
                 self->pmdev->data = self;
 
+ /* Power on device */
+
+ outb(0x00, fir_base+IRCC_MASTER);
+
         return 0;
 }
 
@@ -347,146 +658,6 @@
 #endif /* MODULE */
 
 /*
- * Function ircc_probe_69 (chip, info)
- *
- * Probes for the SMC FDC37C669 and FDC37N869
- *
- */
-static int ircc_probe_69(smc_chip_t *chip, chipio_t *info)
-{
- int cfg_base = info->cfg_base;
- __u8 devid, mode;
- int ret = -ENODEV;
- int fir_io;
-
- IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
- /* Enter configuration */
- outb(chip->entr1, cfg_base);
- outb(chip->entr2, cfg_base);
-
- outb(chip->cid_index, cfg_base);
- devid = inb(cfg_base+1);
- IRDA_DEBUG(0, __FUNCTION__ "(), devid=0x%02x\n",devid);
-
- /* Check for expected device ID; are there others? */
- if (devid == chip->cid_value) {
- outb(0x0c, cfg_base);
- mode = inb(cfg_base+1);
- mode = (mode & 0x38) >> 3;
-
- /* Value for IR port */
- if (mode && mode < 4) {
- /* SIR iobase */
- outb(0x25, cfg_base);
- info->sir_base = inb(cfg_base+1) << 2;
-
- /* FIR iobase */
- outb(0x2b, cfg_base);
- fir_io = inb(cfg_base+1) << 3;
- if (fir_io) {
- ret = 0;
- info->fir_base = fir_io;
- }
- }
- }
-
- /* Exit configuration */
- outb(0xaa, cfg_base);
-
- return ret;
-}
-
-/*
- * Function ircc_probe_58 (chip, info)
- *
- * Probes for the SMC FDC37N958
- *
- */
-static int ircc_probe_58(smc_chip_t *chip, chipio_t *info)
-{
- int cfg_base = info->cfg_base;
- __u8 devid;
- int ret = -ENODEV;
- int fir_io;
-
- IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
- /* Enter configuration */
- outb(chip->entr1, cfg_base);
- outb(chip->entr2, cfg_base);
-
- outb(chip->cid_index, cfg_base);
- devid = inb(cfg_base+1);
- IRDA_DEBUG(0, __FUNCTION__ "(), devid=0x%02x\n",devid);
-
- /* Check for expected device ID; are there others? */
- if (devid == chip->cid_value) {
- /* Select logical device (UART2) */
- outb(0x07, cfg_base);
- outb(0x05, cfg_base + 1);
-
- /* SIR iobase */
- outb(0x60, cfg_base);
- info->sir_base = inb(cfg_base + 1) << 8;
- outb(0x61, cfg_base);
- info->sir_base |= inb(cfg_base + 1);
-
- /* Read FIR base */
- outb(0x62, cfg_base);
- fir_io = inb(cfg_base + 1) << 8;
- outb(0x63, cfg_base);
- fir_io |= inb(cfg_base + 1);
- outb(0x2b, cfg_base);
- if (fir_io) {
- ret = 0;
- info->fir_base = fir_io;
- }
- }
-
- /* Exit configuration */
- outb(0xaa, cfg_base);
-
- return ret;
-}
-
-/*
- * Function ircc_probe (iobase, board_addr, irq, dma)
- *
- * Returns non-negative on success.
- *
- */
-static int ircc_probe(int fir_base, int sir_base)
-{
- int low, high, chip, config, dma, irq;
- int iobase = fir_base;
- int version = 1;
-
- IRDA_DEBUG(0, __FUNCTION__ "\n");
-
- register_bank(iobase, 3);
- high = inb(iobase+IRCC_ID_HIGH);
- low = inb(iobase+IRCC_ID_LOW);
- chip = inb(iobase+IRCC_CHIP_ID);
- version = inb(iobase+IRCC_VERSION);
- config = inb(iobase+IRCC_INTERFACE);
- irq = config >> 4 & 0x0f;
- dma = config & 0x0f;
-
- if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) {
- MESSAGE("SMC IrDA Controller found; IrCC version %d.%d, "
- "port 0x%03x, dma=%d, irq=%d\n",
- chip & 0x0f, version, iobase, dma, irq);
- } else
- return -ENODEV;
-
- /* Power on device */
- outb(0x00, iobase+IRCC_MASTER);
-
- return config;
-}
-
-/*
  * Function ircc_change_speed (self, baud)
  *
  * Change the speed of the device
@@ -1055,6 +1226,10 @@
 MODULE_PARM_DESC(ircc_dma, "DMA channel");
 MODULE_PARM(ircc_irq, "1i");
 MODULE_PARM_DESC(ircc_irq, "IRQ line");
+MODULE_PARM(ircc_fir, "1-4i");
+MODULE_PARM_DESC(ircc_fir, "FIR Base Adress");
+MODULE_PARM(ircc_sir, "1-4i");
+MODULE_PARM_DESC(ircc_sir, "SIR Base Adress");
 
 int init_module(void)
 {
diff -u --recursive --new-file linux-2.4.6-ac5/include/net/irda/smc-ircc.h.save linux-2.4.6-ac5/include/net/irda/smc-ircc.h
--- linux-2.4.6-ac5/include/net/irda/smc-ircc.h.save Fri Jul 20 10:59:58 2001
+++ linux-2.4.6-ac5/include/net/irda/smc-ircc.h Fri Jul 20 11:00:25 2001
@@ -154,16 +154,6 @@
 #define IRCC_1152 0x80
 #define IRCC_CRC 0x40
 
-struct smc_chip {
- char *name;
- unsigned char entr1;
- unsigned char entr2;
- unsigned char cid_index;
- unsigned char cid_value;
- int (*probe)(struct smc_chip *chip, chipio_t *info);
-};
-typedef struct smc_chip smc_chip_t;
-
 /* Private data for each instance */
 struct ircc_cb {
         struct net_device *netdev; /* Yes! we are some kind of netdevice */



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jul 23 2001 - 21:00:13 EST