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 + * Modified at: Tue Jun 26 2001 + * Modified by: Stefani Seibold * + * 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 #include +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 */