Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

smc-ircc.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *                
00003  * Filename:      smc-ircc.c
00004  * Version:       0.4
00005  * Description:   Driver for the SMC Infrared Communications Controller
00006  * Status:        Experimental.
00007  * Author:        Thomas Davis (tadavis@jps.net)
00008  * Created at:    
00009  * Modified at:   Fri Jan 21 09:41:08 2000
00010  * Modified by:   Dag Brattli <dagb@cs.uit.no>
00011  * 
00012  *     Copyright (c) 1999-2000 Dag Brattli
00013  *     Copyright (c) 1998-1999 Thomas Davis, 
00014  *     All Rights Reserved.
00015  *      
00016  *     This program is free software; you can redistribute it and/or 
00017  *     modify it under the terms of the GNU General Public License as 
00018  *     published by the Free Software Foundation; either version 2 of 
00019  *     the License, or (at your option) any later version.
00020  * 
00021  *     This program is distributed in the hope that it will be useful,
00022  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00024  *     GNU General Public License for more details.
00025  * 
00026  *     You should have received a copy of the GNU General Public License 
00027  *     along with this program; if not, write to the Free Software 
00028  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
00029  *     MA 02111-1307 USA
00030  *
00031  *     SIO's: SMC FDC37N869, FDC37C669, FDC37N958
00032  *     Applicable Models : Fujitsu Lifebook 635t, Sony PCG-505TX
00033  *
00034  ********************************************************************/
00035 
00036 #include <linux/module.h>
00037 
00038 #include <linux/kernel.h>
00039 #include <linux/types.h>
00040 #include <linux/skbuff.h>
00041 #include <linux/netdevice.h>
00042 #include <linux/ioport.h>
00043 #include <linux/delay.h>
00044 #include <linux/malloc.h>
00045 #include <linux/init.h>
00046 #include <linux/rtnetlink.h>
00047 #include <linux/serial_reg.h>
00048 
00049 #include <asm/io.h>
00050 #include <asm/dma.h>
00051 #include <asm/byteorder.h>
00052 
00053 #ifdef CONFIG_APM
00054 #include <linux/apm_bios.h>
00055 #endif
00056 
00057 #include <net/irda/wrapper.h>
00058 #include <net/irda/irda.h>
00059 #include <net/irda/irmod.h>
00060 #include <net/irda/irlap_frame.h>
00061 #include <net/irda/irda_device.h>
00062 
00063 #include <net/irda/smc-ircc.h>
00064 #include <net/irda/irport.h>
00065 
00066 static char *driver_name = "smc-ircc";
00067 
00068 #define CHIP_IO_EXTENT 8
00069 
00070 static unsigned int io[]  = { ~0, ~0 }; 
00071 static unsigned int io2[] = { 0, 0 };
00072 
00073 static struct ircc_cb *dev_self[] = { NULL, NULL};
00074 
00075 /* Some prototypes */
00076 static int  ircc_open(int i, unsigned int iobase, unsigned int board_addr);
00077 #ifdef MODULE
00078 static int  ircc_close(struct ircc_cb *self);
00079 #endif /* MODULE */
00080 static int  ircc_probe(int iobase, int board_addr);
00081 static int  ircc_probe_58(smc_chip_t *chip, chipio_t *info);
00082 static int  ircc_probe_69(smc_chip_t *chip, chipio_t *info);
00083 static int  ircc_dma_receive(struct ircc_cb *self, int iobase); 
00084 static void ircc_dma_receive_complete(struct ircc_cb *self, int iobase);
00085 static int  ircc_hard_xmit(struct sk_buff *skb, struct device *dev);
00086 static void ircc_dma_xmit(struct ircc_cb *self, int iobase, int bofs);
00087 static void ircc_change_speed(void *priv, __u32 speed);
00088 static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
00089 static int  ircc_is_receiving(struct ircc_cb *self);
00090 
00091 static int  ircc_net_open(struct device *dev);
00092 static int  ircc_net_close(struct device *dev);
00093 #ifdef CONFIG_APM
00094 static int  ircc_apmproc(apm_event_t event);
00095 #endif /* CONFIG_APM */
00096 
00097 /* These are the currently known SMC chipsets */
00098 static smc_chip_t chips[] =
00099 {
00100         { "FDC37C669", 0x55, 0x55, 0x0d, 0x04, ircc_probe_69 },
00101         { "FDC37N869", 0x55, 0x00, 0x0d, 0x29, ircc_probe_69 },
00102         { "FDC37N958", 0x55, 0x55, 0x20, 0x09, ircc_probe_58 },
00103         { NULL }
00104 };
00105 
00106 static int ircc_irq=255;
00107 static int ircc_dma=255;
00108 
00109 static inline void register_bank(int iobase, int bank)
00110 {
00111         outb(((inb(iobase+IRCC_MASTER) & 0xf0) | (bank & 0x07)),
00112                iobase+IRCC_MASTER);
00113 }
00114 
00115 /*
00116  * Function ircc_init ()
00117  *
00118  *    Initialize chip. Just try to find out how many chips we are dealing with
00119  *    and where they are
00120  */
00121 int __init ircc_init(void)
00122 {
00123         static int smcreg[] = { 0x3f0, 0x370 };
00124         smc_chip_t *chip;
00125         chipio_t info;
00126         int ret = -ENODEV;
00127         int i;
00128 
00129         IRDA_DEBUG(0, __FUNCTION__ "\n");
00130 
00131         /* Probe for all the NSC chipsets we know about */
00132         for (chip=chips; chip->name ; chip++,i++) {
00133                 for (i=0; i<2; i++) {
00134                         info.cfg_base = smcreg[i];
00135                         
00136                         /* 
00137                          * First we check if the user has supplied any
00138                          * parameters which we should use instead of probed
00139                          * values
00140                          */
00141                         if (io[i] < 2000) {
00142                                 info.fir_base = io[i];
00143                                 info.sir_base = io2[i];
00144                         } else if (chip->probe(chip, &info) < 0)
00145                                 continue;
00146                         if (check_region(info.fir_base, CHIP_IO_EXTENT) < 0)
00147                                 continue;
00148                         if (check_region(info.sir_base, CHIP_IO_EXTENT) < 0)
00149                                 continue;
00150                         if (ircc_open(i, info.fir_base, info.sir_base) == 0)
00151                                 ret = 0; 
00152                 }
00153         }
00154         return ret;
00155 }
00156 
00157 /*
00158  * Function ircc_cleanup ()
00159  *
00160  *    Close all configured chips
00161  *
00162  */
00163 #ifdef MODULE
00164 static void ircc_cleanup(void)
00165 {
00166         int i;
00167 
00168         IRDA_DEBUG(0, __FUNCTION__ "\n");
00169 
00170         for (i=0; i < 2; i++) {
00171                 if (dev_self[i])
00172                         ircc_close(dev_self[i]);
00173         }
00174 }
00175 #endif /* MODULE */
00176 
00177 /*
00178  * Function ircc_open (iobase, irq)
00179  *
00180  *    Open driver instance
00181  *
00182  */
00183 static int ircc_open(int i, unsigned int fir_base, unsigned int sir_base)
00184 {
00185         struct ircc_cb *self;
00186         struct irport_cb *irport;
00187         int config;
00188         int ret;
00189 
00190         IRDA_DEBUG(0, __FUNCTION__ "\n");
00191 
00192         if ((config = ircc_probe(fir_base, sir_base)) == -1) {
00193                 IRDA_DEBUG(0, __FUNCTION__ 
00194                            "(), addr 0x%04x - no device found!\n", fir_base);
00195                 return -1;
00196         }
00197         
00198         /*
00199          *  Allocate new instance of the driver
00200          */
00201         self = kmalloc(sizeof(struct ircc_cb), GFP_KERNEL);
00202         if (self == NULL) {
00203                 ERROR("%s, Can't allocate memory for control block!\n",
00204                       driver_name);
00205                 return -ENOMEM;
00206         }
00207         memset(self, 0, sizeof(struct ircc_cb));
00208         spin_lock_init(&self->lock);
00209    
00210         /* Need to store self somewhere */
00211         dev_self[i] = self;
00212 
00213         irport = irport_open(i, sir_base, config >> 4 & 0x0f);
00214         if (!irport)
00215                 return -ENODEV;
00216 
00217         /* Steal the network device from irport */
00218         self->netdev = irport->netdev;
00219         self->irport = irport;
00220         irport->priv = self;
00221 
00222         /* Initialize IO */
00223         self->io.fir_base  = fir_base;
00224         self->io.sir_base  = sir_base; /* Used by irport */
00225         self->io.irq       = config >> 4 & 0x0f;
00226         if (ircc_irq < 255) {
00227                 MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
00228                         driver_name, self->io.irq, ircc_irq);
00229                 self->io.irq = ircc_irq;
00230         }
00231         self->io.fir_ext   = CHIP_IO_EXTENT;
00232         self->io.sir_ext   = 8;       /* Used by irport */
00233         self->io.dma       = config & 0x0f;
00234         if (ircc_dma < 255) {
00235                 MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
00236                         driver_name, self->io.dma, ircc_dma);
00237                 self->io.dma = ircc_dma;
00238         }
00239 
00240         /* Lock the port that we need */
00241         ret = check_region(self->io.fir_base, self->io.fir_ext);
00242         if (ret < 0) { 
00243                 IRDA_DEBUG(0, __FUNCTION__ ": can't get fir_base of 0x%03x\n",
00244                            self->io.fir_base);
00245                 kfree(self);
00246                 return -ENODEV;
00247         }
00248         request_region(self->io.fir_base, self->io.fir_ext, driver_name);
00249 
00250         /* Initialize QoS for this device */
00251         irda_init_max_qos_capabilies(&irport->qos);
00252         
00253         /* The only value we must override it the baudrate */
00254         irport->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
00255                 IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
00256 
00257         irport->qos.min_turn_time.bits = 0x07;
00258         irda_qos_bits_to_value(&irport->qos);
00259 
00260         irport->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO;
00261         
00262         /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
00263         self->rx_buff.truesize = 4000; 
00264         self->tx_buff.truesize = 4000;
00265 
00266         self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
00267                                               GFP_KERNEL|GFP_DMA);
00268         if (self->rx_buff.head == NULL)
00269                 return -ENOMEM;
00270         memset(self->rx_buff.head, 0, self->rx_buff.truesize);
00271         
00272         self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
00273                                               GFP_KERNEL|GFP_DMA);
00274         if (self->tx_buff.head == NULL) {
00275                 kfree(self->rx_buff.head);
00276                 return -ENOMEM;
00277         }
00278         memset(self->tx_buff.head, 0, self->tx_buff.truesize);
00279 
00280         self->rx_buff.in_frame = FALSE;
00281         self->rx_buff.state = OUTSIDE_FRAME;
00282         self->tx_buff.data = self->tx_buff.head;
00283         self->rx_buff.data = self->rx_buff.head;
00284         
00285         /* Override the speed change function, since we must control it now */
00286         irport->change_speed = &ircc_change_speed;
00287         irport->interrupt    = &ircc_interrupt;
00288         self->netdev->open   = &ircc_net_open;
00289         self->netdev->stop   = &ircc_net_close;
00290 
00291         irport_start(self->irport);
00292 
00293         return 0;
00294 }
00295 
00296 /*
00297  * Function ircc_close (self)
00298  *
00299  *    Close driver instance
00300  *
00301  */
00302 #ifdef MODULE
00303 static int ircc_close(struct ircc_cb *self)
00304 {
00305         int iobase;
00306 
00307         IRDA_DEBUG(0, __FUNCTION__ "\n");
00308 
00309         ASSERT(self != NULL, return -1;);
00310 
00311         iobase = self->io.fir_base;
00312 
00313         irport_close(self->irport);
00314 
00315         /* Stop interrupts */
00316         register_bank(iobase, 0);
00317         outb(0, iobase+IRCC_IER);
00318         outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER);
00319         outb(0x00, iobase+IRCC_MASTER);
00320 #if 0
00321         /* Reset to SIR mode */
00322         register_bank(iobase, 1);
00323         outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase+IRCC_SCE_CFGA);
00324         outb(IRCC_CFGB_IR, iobase+IRCC_SCE_CFGB);
00325 #endif
00326         /* Release the PORT that this driver is using */
00327         IRDA_DEBUG(0, __FUNCTION__ "(), releasing 0x%03x\n", 
00328                    self->io.fir_base);
00329 
00330         release_region(self->io.fir_base, self->io.fir_ext);
00331 
00332         if (self->tx_buff.head)
00333                 kfree(self->tx_buff.head);
00334         
00335         if (self->rx_buff.head)
00336                 kfree(self->rx_buff.head);
00337 
00338         kfree(self);
00339 
00340         return 0;
00341 }
00342 #endif /* MODULE */
00343 
00344 /*
00345  * Function ircc_probe_69 (chip, info)
00346  *
00347  *    Probes for the SMC FDC37C669 and FDC37N869
00348  *
00349  */
00350 static int ircc_probe_69(smc_chip_t *chip, chipio_t *info)
00351 {
00352         int cfg_base = info->cfg_base;
00353         __u8 devid, mode;
00354         int ret = -ENODEV;
00355         int fir_io;
00356         
00357         IRDA_DEBUG(0, __FUNCTION__ "()\n");
00358 
00359         /* Enter configuration */
00360         outb(chip->entr1, cfg_base);
00361         outb(chip->entr2, cfg_base);
00362         
00363         outb(chip->cid_index, cfg_base);
00364         devid = inb(cfg_base+1);
00365         IRDA_DEBUG(0, __FUNCTION__ "(), devid=0x%02x\n",devid);
00366         
00367         /* Check for expected device ID; are there others? */
00368         if (devid == chip->cid_value) {
00369                 outb(0x0c, cfg_base);
00370                 mode = inb(cfg_base+1);
00371                 mode = (mode & 0x38) >> 3;
00372                 
00373                 /* Value for IR port */
00374                 if (mode && mode < 4) {
00375                         /* SIR iobase */
00376                         outb(0x25, cfg_base);
00377                         info->sir_base = inb(cfg_base+1) << 2;
00378 
00379                         /* FIR iobase */
00380                         outb(0x2b, cfg_base);
00381                         fir_io = inb(cfg_base+1) << 3;
00382                         if (fir_io) {
00383                                 ret = 0;
00384                                 info->fir_base = fir_io;
00385                         }
00386                 }
00387         }
00388         
00389         /* Exit configuration */
00390         outb(0xaa, cfg_base);
00391 
00392         return ret;
00393 }
00394 
00395 /*
00396  * Function ircc_probe_58 (chip, info)
00397  *
00398  *    Probes for the SMC FDC37N958
00399  *
00400  */
00401 static int ircc_probe_58(smc_chip_t *chip, chipio_t *info)
00402 {
00403         int cfg_base = info->cfg_base;
00404         __u8 devid;
00405         int ret = -ENODEV;
00406         int fir_io;
00407         
00408         IRDA_DEBUG(0, __FUNCTION__ "()\n");
00409 
00410         /* Enter configuration */
00411         outb(chip->entr1, cfg_base);
00412         outb(chip->entr2, cfg_base);
00413         
00414         outb(chip->cid_index, cfg_base);
00415         devid = inb(cfg_base+1);
00416         IRDA_DEBUG(0, __FUNCTION__ "(), devid=0x%02x\n",devid);
00417         
00418         /* Check for expected device ID; are there others? */
00419         if (devid == chip->cid_value) {
00420                 /* Select logical device (UART2) */
00421                 outb(0x07, cfg_base);
00422                 outb(0x05, cfg_base + 1);
00423                 
00424                 /* SIR iobase */
00425                 outb(0x60, cfg_base);
00426                 info->sir_base = inb(cfg_base + 1) << 8;
00427                 outb(0x61, cfg_base);
00428                 info->sir_base |= inb(cfg_base + 1);
00429                 
00430                 /* Read FIR base */
00431                 outb(0x62, cfg_base);
00432                 fir_io = inb(cfg_base + 1) << 8;
00433                 outb(0x63, cfg_base);
00434                 fir_io |= inb(cfg_base + 1);
00435                 outb(0x2b, cfg_base);
00436                 if (fir_io) {
00437                         ret = 0;
00438                         info->fir_base = fir_io;
00439                 }
00440         }
00441         
00442         /* Exit configuration */
00443         outb(0xaa, cfg_base);
00444 
00445         return ret;
00446 }
00447 
00448 /*
00449  * Function ircc_probe (iobase, board_addr, irq, dma)
00450  *
00451  *    Returns non-negative on success.
00452  *
00453  */
00454 static int ircc_probe(int fir_base, int sir_base) 
00455 {
00456         int low, high, chip, config, dma, irq;
00457         int iobase = fir_base;
00458         int version = 1;
00459 
00460         IRDA_DEBUG(0, __FUNCTION__ "\n");
00461 
00462         register_bank(iobase, 3);
00463         high    = inb(iobase+IRCC_ID_HIGH);
00464         low     = inb(iobase+IRCC_ID_LOW);
00465         chip    = inb(iobase+IRCC_CHIP_ID);
00466         version = inb(iobase+IRCC_VERSION);
00467         config  = inb(iobase+IRCC_INTERFACE);
00468         irq     = config >> 4 & 0x0f;
00469         dma     = config & 0x0f;
00470 
00471         if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) { 
00472                 MESSAGE("SMC IrDA Controller found; IrCC version %d.%d, "
00473                         "port 0x%03x, dma=%d, irq=%d\n",
00474                         chip & 0x0f, version, iobase, dma, irq);
00475         } else
00476                 return -ENODEV;
00477 
00478         /* Power on device */
00479         outb(0x00, iobase+IRCC_MASTER);
00480 
00481         return config;
00482 }
00483 
00484 /*
00485  * Function ircc_change_speed (self, baud)
00486  *
00487  *    Change the speed of the device
00488  *
00489  */
00490 static void ircc_change_speed(void *priv, __u32 speed)
00491 {
00492         int iobase, ir_mode, ctrl, fast; 
00493         struct ircc_cb *self = (struct ircc_cb *) priv;
00494         struct device *dev;
00495 
00496         IRDA_DEBUG(0, __FUNCTION__ "\n");
00497 
00498         ASSERT(self != NULL, return;);
00499 
00500         dev = self->netdev;
00501         iobase = self->io.fir_base;
00502 
00503         /* Update accounting for new speed */
00504         self->io.speed = speed;
00505 
00506         outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER);
00507         outb(0x00, iobase+IRCC_MASTER);
00508 
00509         switch (speed) {
00510         case 9600:
00511         case 19200:
00512         case 38400:
00513         case 57600:
00514         case 115200:            
00515                 ir_mode = IRCC_CFGA_IRDA_SIR_A;
00516                 ctrl = 0;
00517                 fast = 0;
00518                 break;
00519         case 576000:            
00520                 ir_mode = IRCC_CFGA_IRDA_HDLC;
00521                 ctrl = IRCC_CRC;
00522                 fast = 0;
00523                 IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
00524                 break;
00525         case 1152000:
00526                 ir_mode = IRCC_CFGA_IRDA_HDLC;
00527                 ctrl = IRCC_1152 | IRCC_CRC;
00528                 fast = 0;
00529                 IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
00530                 break;
00531         case 4000000:
00532                 ir_mode = IRCC_CFGA_IRDA_4PPM;
00533                 ctrl = IRCC_CRC;
00534                 fast = IRCC_LCR_A_FAST;
00535                 IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
00536                 break;
00537         default:
00538                 IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", 
00539                            speed);
00540                 return;
00541         }
00542         
00543         register_bank(iobase, 0);
00544         outb(0, iobase+IRCC_IER);
00545         outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER);
00546 
00547         /* Make special FIR init if necessary */
00548         if (speed > 115200) {
00549                 irport_stop(self->irport);
00550 
00551                 /* Install FIR transmit handler */
00552                 dev->hard_start_xmit = &ircc_hard_xmit;
00553 
00554                 /* 
00555                  * Don't know why we have to do this, but FIR interrupts 
00556                  * stops working if we remove it.
00557                  */
00558                 /* outb(UART_MCR_OUT2, self->io.sir_base + UART_MCR); */
00559 
00560                 /* Be ready for incomming frames */
00561                 ircc_dma_receive(self, iobase);
00562         } else {
00563                 /* Install SIR transmit handler */
00564                 dev->hard_start_xmit = &irport_hard_xmit;
00565                 irport_start(self->irport);
00566                 
00567                 IRDA_DEBUG(0, __FUNCTION__ 
00568                            "(), using irport to change speed to %d\n", speed);
00569                 irport_change_speed(self->irport, speed);
00570         }       
00571         dev->tbusy = 0;
00572 
00573         register_bank(iobase, 1);
00574         outb(((inb(iobase+IRCC_SCE_CFGA) & 0x87) | ir_mode), 
00575              iobase+IRCC_SCE_CFGA);
00576 
00577 #ifdef SMC_669 /* Uses pin 88/89 for Rx/Tx */
00578         outb(((inb(iobase+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_COM), 
00579              iobase+IRCC_SCE_CFGB);
00580 #else   
00581         outb(((inb(iobase+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_MUX_IR),
00582              iobase+IRCC_SCE_CFGB);
00583 #endif  
00584         (void) inb(iobase+IRCC_FIFO_THRESHOLD);
00585         outb(64, iobase+IRCC_FIFO_THRESHOLD);
00586         
00587         register_bank(iobase, 4);
00588         outb((inb(iobase+IRCC_CONTROL) & 0x30) | ctrl, iobase+IRCC_CONTROL);
00589         
00590         register_bank(iobase, 0);
00591         outb(fast, iobase+IRCC_LCR_A);
00592 }
00593 
00594 /*
00595  * Function ircc_hard_xmit (skb, dev)
00596  *
00597  *    Transmit the frame!
00598  *
00599  */
00600 static int ircc_hard_xmit(struct sk_buff *skb, struct device *dev)
00601 {
00602         struct irport_cb *irport;
00603         struct ircc_cb *self;
00604         unsigned long flags;
00605         __u32 speed;
00606         int iobase;
00607         int mtt;
00608 
00609         irport = (struct irport_cb *) dev->priv;
00610         self = (struct ircc_cb *) irport->priv;
00611         ASSERT(self != NULL, return 0;);
00612 
00613         iobase = self->io.fir_base;
00614 
00615         spin_lock_irqsave(&self->lock, flags);
00616 
00617         /* Check if we need to change the speed after this frame */
00618         if ((speed = irda_get_speed(skb)) != self->io.speed)
00619                 self->new_speed = speed;
00620         
00621         /* Lock transmit buffer */
00622         if (irda_lock((void *) &dev->tbusy) == FALSE)
00623                 return -EBUSY;
00624 
00625         memcpy(self->tx_buff.head, skb->data, skb->len);
00626 
00627         self->tx_buff.len = skb->len;
00628         self->tx_buff.data = self->tx_buff.head;
00629         
00630         mtt = irda_get_mtt(skb);        
00631         if (mtt) {
00632                 int bofs;
00633 
00634                 /* 
00635                  * Compute who many BOFS (STA or PA's) we need to waste the
00636                  * min turn time given the speed of the link.
00637                  */
00638                 bofs = mtt * (self->io.speed / 1000) / 8000;
00639                 if (bofs > 4095)
00640                         bofs = 4095;
00641 
00642                 ircc_dma_xmit(self, iobase, bofs);
00643         } else {
00644                 /* Transmit frame */
00645                 ircc_dma_xmit(self, iobase, 0);
00646         }
00647         
00648         spin_unlock_irqrestore(&self->lock, flags);
00649         dev_kfree_skb(skb);
00650 
00651         return 0;
00652 }
00653 
00654 /*
00655  * Function ircc_dma_xmit (self, iobase)
00656  *
00657  *    Transmit data using DMA
00658  *
00659  */
00660 static void ircc_dma_xmit(struct ircc_cb *self, int iobase, int bofs)
00661 {
00662         __u8 ctrl;
00663 
00664         IRDA_DEBUG(2, __FUNCTION__ "\n");
00665 #if 0   
00666         /* Disable Rx */
00667         register_bank(iobase, 0);
00668         outb(0x00, iobase+IRCC_LCR_B);
00669 #endif
00670         register_bank(iobase, 1);
00671         outb(inb(iobase+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, 
00672              iobase+IRCC_SCE_CFGB);
00673 
00674         self->io.direction = IO_XMIT;
00675 
00676         /* Set BOF additional count for generating the min turn time */
00677         register_bank(iobase, 4);
00678         outb(bofs & 0xff, iobase+IRCC_BOF_COUNT_LO);
00679         ctrl = inb(iobase+IRCC_CONTROL) & 0xf0;
00680         outb(ctrl | ((bofs >> 8) & 0x0f), iobase+IRCC_BOF_COUNT_HI);
00681 
00682         /* Set max Tx frame size */
00683         outb(self->tx_buff.len >> 8, iobase+IRCC_TX_SIZE_HI);
00684         outb(self->tx_buff.len & 0xff, iobase+IRCC_TX_SIZE_LO);
00685 
00686         /* Setup DMA controller (must be done after enabling chip DMA) */
00687         setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, 
00688                   DMA_TX_MODE);
00689 
00690         outb(UART_MCR_OUT2, self->io.sir_base + UART_MCR);
00691         /* Enable burst mode chip Tx DMA */
00692         register_bank(iobase, 1);
00693         outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE |
00694              IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB);
00695 
00696         /* Enable interrupt */
00697         outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER);
00698         register_bank(iobase, 0);
00699         outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase+IRCC_IER);
00700 
00701         /* Enable transmit */
00702         outb(IRCC_LCR_B_SCE_TRANSMIT|IRCC_LCR_B_SIP_ENABLE, iobase+IRCC_LCR_B);
00703 }
00704 
00705 /*
00706  * Function ircc_dma_xmit_complete (self)
00707  *
00708  *    The transfer of a frame in finished. This function will only be called 
00709  *    by the interrupt handler
00710  *
00711  */
00712 static void ircc_dma_xmit_complete(struct ircc_cb *self, int iobase)
00713 {
00714         IRDA_DEBUG(2, __FUNCTION__ "\n");
00715 #if 0
00716         /* Disable Tx */
00717         register_bank(iobase, 0);
00718         outb(0x00, iobase+IRCC_LCR_B);
00719 #endif
00720         register_bank(self->io.fir_base, 1);
00721         outb(inb(self->io.fir_base+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE,
00722              self->io.fir_base+IRCC_SCE_CFGB);
00723 
00724         /* Check for underrrun! */
00725         register_bank(iobase, 0);
00726         if (inb(iobase+IRCC_LSR) & IRCC_LSR_UNDERRUN) {
00727                 self->irport->stats.tx_errors++;
00728                 self->irport->stats.tx_fifo_errors++;
00729 
00730                 /* Reset error condition */
00731                 register_bank(iobase, 0);
00732                 outb(IRCC_MASTER_ERROR_RESET, iobase+IRCC_MASTER);
00733                 outb(0x00, iobase+IRCC_MASTER);
00734         } else {
00735                 self->irport->stats.tx_packets++;
00736                 self->irport->stats.tx_bytes +=  self->tx_buff.len;
00737         }
00738 
00739         /* Check if it's time to change the speed */
00740         if (self->new_speed) {
00741                 ircc_change_speed(self, self->new_speed);               
00742                 self->new_speed = 0;
00743         }
00744 
00745         /* Unlock tx_buff and request another frame */
00746         self->netdev->tbusy = 0; /* Unlock */
00747         
00748         /* Tell the network layer, that we can accept more frames */
00749         mark_bh(NET_BH);
00750 }
00751 
00752 /*
00753  * Function ircc_dma_receive (self)
00754  *
00755  *    Get ready for receiving a frame. The device will initiate a DMA
00756  *    if it starts to receive a frame.
00757  *
00758  */
00759 static int ircc_dma_receive(struct ircc_cb *self, int iobase) 
00760 {       
00761         /* Turn off chip DMA */
00762         //register_bank(iobase, 1);
00763         //outb(inb(iobase+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, 
00764         //     iobase+IRCC_SCE_CFGB);
00765 
00766         setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, 
00767                   DMA_RX_MODE);
00768         /* Set max Rx frame size */
00769         register_bank(iobase, 4);
00770         outb((2050 >> 8) & 0x0f, iobase+IRCC_RX_SIZE_HI);
00771         outb(2050 & 0xff, iobase+IRCC_RX_SIZE_LO);
00772 
00773         self->io.direction = IO_RECV;
00774         self->rx_buff.data = self->rx_buff.head;
00775 
00776         /* Setup DMA controller */
00777         
00778         /* Enable receiver */
00779         register_bank(iobase, 0);
00780         outb(IRCC_LCR_B_SCE_RECEIVE | IRCC_LCR_B_SIP_ENABLE, 
00781              iobase+IRCC_LCR_B);
00782         
00783         /* Enable burst mode chip Rx DMA */
00784         register_bank(iobase, 1);
00785         outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE | 
00786              IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB);
00787 
00788         return 0;
00789 }
00790 
00791 /*
00792  * Function ircc_dma_receive_complete (self)
00793  *
00794  *    Finished with receiving frames
00795  *
00796  *    
00797  */
00798 static void ircc_dma_receive_complete(struct ircc_cb *self, int iobase)
00799 {
00800         unsigned long flags;
00801         struct sk_buff *skb;
00802         int len, msgcnt;
00803 
00804         IRDA_DEBUG(2, __FUNCTION__ "\n");
00805 #if 0
00806         /* Disable Rx */
00807         register_bank(iobase, 0);
00808         outb(0x00, iobase+IRCC_LCR_B);
00809 #endif
00810         register_bank(iobase, 0);
00811         msgcnt = inb(iobase+IRCC_LCR_B) & 0x08;
00812 
00813         IRDA_DEBUG(2, __FUNCTION__ ": dma count = %d\n",
00814                    get_dma_residue(self->io.dma));
00815 
00816         len = self->rx_buff.truesize - get_dma_residue(self->io.dma);
00817         
00818         /* Remove CRC */
00819         if (self->io.speed < 4000000)
00820                 len -= 2;
00821         else
00822                 len -= 4;
00823 
00824         if ((len < 2) && (len > 2050)) {
00825                 WARNING(__FUNCTION__ "(), bogus len=%d\n", len);
00826                 return;
00827         }
00828         IRDA_DEBUG(2, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len);
00829 
00830         skb = dev_alloc_skb(len+1);
00831         if (!skb)  {
00832                 WARNING(__FUNCTION__ "(), memory squeeze, dropping frame.\n");
00833                 return;
00834         }                       
00835         /* Make sure IP header gets aligned */
00836         skb_reserve(skb, 1); 
00837 
00838         memcpy(skb_put(skb, len), self->rx_buff.data, len);
00839         self->irport->stats.rx_packets++;
00840         self->irport->stats.rx_bytes += len;
00841 
00842         skb->dev = self->netdev;
00843         skb->mac.raw  = skb->data;
00844         skb->protocol = htons(ETH_P_IRDA);
00845         netif_rx(skb);
00846 }
00847 
00848 /*
00849  * Function ircc_interrupt (irq, dev_id, regs)
00850  *
00851  *    An interrupt from the chip has arrived. Time to do some work
00852  *
00853  */
00854 static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
00855 {
00856         struct device *dev = (struct device *) dev_id;
00857         struct irport_cb *irport;
00858         struct ircc_cb *self;
00859         int iobase, iir;
00860 
00861         if (dev == NULL) {
00862                 printk(KERN_WARNING "%s: irq %d for unknown device.\n", 
00863                        driver_name, irq);
00864                 return;
00865         }
00866         irport = (struct irport_cb *) dev->priv;
00867         ASSERT(irport != NULL, return;);
00868         self = (struct ircc_cb *) irport->priv;
00869         ASSERT(self != NULL, return;);
00870 
00871         /* Check if we should use the SIR interrupt handler */
00872         if (self->io.speed < 576000) {
00873                 irport_interrupt(irq, dev_id, regs);
00874                 return;
00875         }
00876         iobase = self->io.fir_base;
00877 
00878         spin_lock(&self->lock); 
00879         dev->interrupt = 1;
00880 
00881         register_bank(iobase, 0);
00882         iir = inb(iobase+IRCC_IIR);
00883 
00884         /* Disable interrupts */
00885         outb(0, iobase+IRCC_IER);
00886 
00887         IRDA_DEBUG(2, __FUNCTION__ "(), iir = 0x%02x\n", iir);
00888 
00889         if (iir & IRCC_IIR_EOM) {
00890                 if (self->io.direction == IO_RECV)
00891                         ircc_dma_receive_complete(self, iobase);
00892                 else
00893                         ircc_dma_xmit_complete(self, iobase);
00894                 
00895                 ircc_dma_receive(self, iobase);
00896         }
00897 
00898         /* Enable interrupts again */
00899         register_bank(iobase, 0);
00900         outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, iobase+IRCC_IER);
00901 
00902         dev->interrupt = 0;
00903         spin_unlock(&self->lock);
00904 }
00905 
00906 /*
00907  * Function ircc_is_receiving (self)
00908  *
00909  *    Return TRUE is we are currently receiving a frame
00910  *
00911  */
00912 static int ircc_is_receiving(struct ircc_cb *self)
00913 {
00914         int status = FALSE;
00915         /* int iobase; */
00916 
00917         IRDA_DEBUG(0, __FUNCTION__ "\n");
00918 
00919         ASSERT(self != NULL, return FALSE;);
00920 
00921         IRDA_DEBUG(0, __FUNCTION__ ": dma count = %d\n",
00922                    get_dma_residue(self->io.dma));
00923 
00924         status = (self->rx_buff.state != OUTSIDE_FRAME);
00925         
00926         return status;
00927 }
00928 
00929 /*
00930  * Function ircc_net_open (dev)
00931  *
00932  *    Start the device
00933  *
00934  */
00935 static int ircc_net_open(struct device *dev)
00936 {
00937         struct irport_cb *irport;
00938         struct ircc_cb *self;
00939         int iobase;
00940 
00941         IRDA_DEBUG(0, __FUNCTION__ "\n");
00942         
00943         ASSERT(dev != NULL, return -1;);
00944         irport = (struct irport_cb *) dev->priv;
00945         self = (struct ircc_cb *) irport->priv;
00946 
00947         ASSERT(self != NULL, return 0;);
00948         
00949         iobase = self->io.fir_base;
00950 
00951         irport_net_open(dev); /* irport allocates the irq */
00952 
00953         /*
00954          * Always allocate the DMA channel after the IRQ,
00955          * and clean up on failure.
00956          */
00957         if (request_dma(self->io.dma, dev->name)) {
00958                 irport_net_close(dev);
00959 
00960                 return -EAGAIN;
00961         }
00962         
00963         MOD_INC_USE_COUNT;
00964 
00965         return 0;
00966 }
00967 
00968 /*
00969  * Function ircc_net_close (dev)
00970  *
00971  *    Stop the device
00972  *
00973  */
00974 static int ircc_net_close(struct device *dev)
00975 {
00976         struct irport_cb *irport;
00977         struct ircc_cb *self;
00978         int iobase;
00979 
00980         IRDA_DEBUG(0, __FUNCTION__ "\n");
00981         
00982         ASSERT(dev != NULL, return -1;);
00983         irport = (struct irport_cb *) dev->priv;
00984         self = (struct ircc_cb *) irport->priv;
00985         
00986         ASSERT(self != NULL, return 0;);
00987         
00988         iobase = self->io.fir_base;
00989 
00990         irport_net_close(dev);
00991 
00992         disable_dma(self->io.dma);
00993 
00994         free_dma(self->io.dma);
00995 
00996         MOD_DEC_USE_COUNT;
00997 
00998         return 0;
00999 }
01000 
01001 #ifdef CONFIG_APM
01002 static void ircc_suspend(struct ircc_cb *self)
01003 {
01004         int i = 10;
01005 
01006         MESSAGE("%s, Suspending\n", driver_name);
01007 
01008         if (self->io.suspended)
01009                 return;
01010 
01011         ircc_net_close(self->netdev);
01012 
01013         self->io.suspended = 1;
01014 }
01015 
01016 static void ircc_wakeup(struct ircc_cb *self)
01017 {
01018         struct device *dev = self->netdev;
01019         unsigned long flags;
01020 
01021         if (!self->io.suspended)
01022                 return;
01023 
01024         save_flags(flags);
01025         cli();
01026 
01027         ircc_net_open(self->netdev);
01028         
01029         restore_flags(flags);
01030         MESSAGE("%s, Waking up\n", driver_name);
01031 }
01032 
01033 static int ircc_apmproc(apm_event_t event)
01034 {
01035         static int down = 0;          /* Filter out double events */
01036         int i;
01037 
01038         switch (event) {
01039         case APM_SYS_SUSPEND:
01040         case APM_USER_SUSPEND:
01041                 if (!down) {                    
01042                         for (i=0; i<4; i++) {
01043                                 if (dev_self[i])
01044                                         ircc_suspend(dev_self[i]);
01045                         }
01046                 }
01047                 down = 1;
01048                 break;
01049         case APM_NORMAL_RESUME:
01050         case APM_CRITICAL_RESUME:
01051                 if (down) {
01052                         for (i=0; i<4; i++) {
01053                                 if (dev_self[i])
01054                                         ircc_wakeup(dev_self[i]);
01055                         }
01056                 }
01057                 down = 0;
01058                 break;
01059         }
01060         return 0;
01061 }
01062 #endif /* CONFIG_APM */
01063 
01064 #ifdef MODULE
01065 MODULE_AUTHOR("Thomas Davis <tadavis@jps.net>");
01066 MODULE_DESCRIPTION("SMC IrCC controller driver");
01067 MODULE_PARM(ircc_dma, "1i");
01068 MODULE_PARM(ircc_irq, "1i");
01069 
01070 int init_module(void)
01071 {
01072         return ircc_init();
01073 }
01074 
01075 void cleanup_module(void)
01076 {
01077         ircc_cleanup();
01078 }
01079 
01080 #endif /* MODULE */