Import 2.3.4pre3
[davej-history.git] / drivers / net / irda / irport.c
blob7c8864f5d79ef04cfb9d2525445b5e4545ca6bb3
1 /*********************************************************************
2 *
3 * Filename: irport.c
4 * Version: 0.9
5 * Description: Serial driver for IrDA.
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 3 13:49:59 1997
9 * Modified at: Sat May 23 23:15:20 1998
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Sources: serial.c by Linus Torvalds
13 * Copyright (c) 1997,1998 Dag Brattli <dagb@cs.uit.no>
14 * All Rights Reserved.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
25 * NOTICE:
27 * This driver is ment to be a small half duplex serial driver to be
28 * used for IR-chipsets that has a UART (16550) compatibility mode. If
29 * your chipset is is UART only, you should probably use IrTTY instead
30 * since the Linux serial driver is probably more robust and optimized.
32 * The functions in this file may be used by FIR drivers, but this
33 * driver knows nothing about FIR drivers so don't ever insert such
34 * code into this file. Instead you should code your FIR driver in a
35 * separate file, and then call the functions in this file if
36 * necessary. This is becase it is difficult to use the Linux serial
37 * driver with a FIR driver becase they must share interrupts etc. Most
38 * FIR chipsets can function in advanced SIR mode, and you should
39 * probably use that mode instead of the UART compatibility mode (and
40 * then just forget about this file)
42 ********************************************************************/
44 #include <linux/module.h>
46 #include <linux/kernel.h>
47 #include <linux/types.h>
48 #include <linux/ioport.h>
49 #include <linux/malloc.h>
50 #include <linux/string.h>
51 #include <asm/system.h>
52 #include <asm/bitops.h>
53 #include <asm/io.h>
54 #include <linux/errno.h>
55 #include <linux/init.h>
57 #include <linux/skbuff.h>
58 #include <linux/serial_reg.h>
60 #include <net/irda/irda.h>
61 #include <net/irda/irmod.h>
62 #include <net/irda/wrapper.h>
63 #include <net/irda/irport.h>
65 #define IO_EXTENT 8
67 /*
68 * Currently you'll need to set these values using insmod like this:
69 * insmod irport io=0x3e8 irq=11
71 static unsigned int io[] = { ~0, ~0, ~0, ~0 };
72 static unsigned int irq[] = { 0, 0, 0, 0 };
74 static unsigned int qos_mtt_bits = 0x03;
76 static struct irda_device *dev_self[] = { NULL, NULL, NULL, NULL};
77 static char *driver_name = "irport";
79 static int irport_open(int i, unsigned int iobase, unsigned int irq);
80 static int irport_close(struct irda_device *idev);
82 static void irport_write_wakeup(struct irda_device *idev);
83 static int irport_write(int iobase, int fifo_size, __u8 *buf, int len);
84 static void irport_receive(struct irda_device *idev);
86 static int irport_net_init(struct device *dev);
87 static int irport_net_open(struct device *dev);
88 static int irport_net_close(struct device *dev);
89 static void irport_wait_until_sent(struct irda_device *idev);
90 static int irport_is_receiving(struct irda_device *idev);
91 static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts);
92 static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len);
94 __initfunc(int irport_init(void))
96 int i;
98 for (i=0; (io[i] < 2000) && (i < 4); i++) {
99 int ioaddr = io[i];
100 if (check_region(ioaddr, IO_EXTENT))
101 continue;
102 if (irport_open(i, io[i], irq[i]) == 0)
103 return 0;
106 * Maybe something failed, but we can still be usable for FIR drivers
108 return 0;
112 * Function irport_cleanup ()
114 * Close all configured ports
117 #ifdef MODULE
118 static void irport_cleanup(void)
120 int i;
122 DEBUG( 4, __FUNCTION__ "()\n");
124 for (i=0; i < 4; i++) {
125 if (dev_self[i])
126 irport_close(dev_self[i]);
129 #endif /* MODULE */
131 static int irport_open(int i, unsigned int iobase, unsigned int irq)
133 struct irda_device *idev;
134 int ret;
136 DEBUG( 0, __FUNCTION__ "()\n");
138 /* if (irport_probe(iobase, irq) == -1) */
139 /* return -1; */
142 * Allocate new instance of the driver
144 idev = kmalloc(sizeof(struct irda_device), GFP_KERNEL);
145 if (idev == NULL) {
146 printk( KERN_ERR "IrDA: Can't allocate memory for "
147 "IrDA control block!\n");
148 return -ENOMEM;
150 memset(idev, 0, sizeof(struct irda_device));
152 /* Need to store self somewhere */
153 dev_self[i] = idev;
155 /* Initialize IO */
156 idev->io.iobase2 = iobase;
157 idev->io.irq2 = irq;
158 idev->io.io_ext = IO_EXTENT;
159 idev->io.fifo_size = 16;
161 /* Lock the port that we need */
162 ret = check_region(idev->io.iobase2, idev->io.io_ext);
163 if (ret < 0) {
164 DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
165 idev->io.iobase2);
166 /* w83977af_cleanup( self->idev); */
167 return -ENODEV;
169 request_region(idev->io.iobase2, idev->io.io_ext, idev->name);
171 /* Initialize QoS for this device */
172 irda_init_max_qos_capabilies(&idev->qos);
174 idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
175 IR_115200;
177 idev->qos.min_turn_time.bits = qos_mtt_bits;
178 irda_qos_bits_to_value(&idev->qos);
180 idev->flags = IFF_SIR|IFF_PIO;
182 /* Specify which buffer allocation policy we need */
183 idev->rx_buff.flags = GFP_KERNEL;
184 idev->tx_buff.flags = GFP_KERNEL;
186 idev->rx_buff.truesize = 4000;
187 idev->tx_buff.truesize = 4000;
189 /* Initialize callbacks */
190 idev->change_speed = irport_change_speed;
191 idev->wait_until_sent = irport_wait_until_sent;
192 idev->is_receiving = irport_is_receiving;
193 idev->set_dtr_rts = irport_set_dtr_rts;
194 idev->raw_write = irport_raw_write;
196 /* Override the network functions we need to use */
197 idev->netdev.init = irport_net_init;
198 idev->netdev.hard_start_xmit = irport_hard_xmit;
199 idev->netdev.open = irport_net_open;
200 idev->netdev.stop = irport_net_close;
202 /* Open the IrDA device */
203 irda_device_open(idev, driver_name, NULL);
205 return 0;
208 static int irport_close(struct irda_device *idev)
210 DEBUG(0, __FUNCTION__ "()\n");
212 ASSERT(idev != NULL, return -1;);
213 ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
215 /* Release the PORT that this driver is using */
216 DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n",
217 idev->io.iobase2);
218 release_region(idev->io.iobase2, idev->io.io_ext);
220 irda_device_close(idev);
222 kfree(idev);
224 return 0;
227 void irport_start(int iobase)
229 /* Initialize UART */
230 outb(UART_LCR_WLEN8, iobase+UART_LCR); /* Reset DLAB */
231 outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
233 /* Turn on interrups */
234 outb((UART_IER_RLSI | UART_IER_RDI), iobase+UART_IER);
238 void irport_stop(int iobase)
240 /* Reset UART */
241 outb(0, iobase+UART_MCR);
243 /* Turn off interrupts */
244 outb(0, iobase+UART_IER);
248 * Function irport_probe (void)
250 * Start IO port
253 int irport_probe(int iobase)
255 DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
258 return 0;
262 * Function irport_change_speed (idev, speed)
264 * Set speed of port to specified baudrate
267 void irport_change_speed(struct irda_device *idev, int speed)
269 int iobase;
270 int fcr; /* FIFO control reg */
271 int lcr; /* Line control reg */
272 int divisor;
274 DEBUG( 0, __FUNCTION__ "(), Setting speed to: %d\n", speed);
276 ASSERT(idev != NULL, return;);
277 ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
279 iobase = idev->io.iobase2;
281 /* Update accounting for new speed */
282 idev->io.baudrate = speed;
284 /* Turn off interrupts */
285 outb(0, iobase+UART_IER);
287 divisor = SPEED_MAX/speed;
289 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
291 /* IrDA ports use 8N1 */
292 lcr = UART_LCR_WLEN8;
294 outb(UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */
295 outb(divisor & 0xff, iobase+UART_DLL); /* Set speed */
296 outb(divisor >> 8, iobase+UART_DLM);
297 outb(lcr, iobase+UART_LCR); /* Set 8N1 */
298 outb(fcr, iobase+UART_FCR); /* Enable FIFO's */
300 /* Turn on receive interrups */
301 outb(UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER);
305 * Function irport_write_wakeup (tty)
307 * Called by the driver when there's room for more data. If we have
308 * more packets to send, we send them here.
311 static void irport_write_wakeup(struct irda_device *idev)
313 int actual = 0;
314 int iobase;
316 ASSERT(idev != NULL, return;);
317 ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
319 /* Finished with frame? */
320 if (idev->tx_buff.len > 0) {
321 /* Write data left in transmit buffer */
322 actual = irport_write(idev->io.iobase2, idev->io.fifo_size,
323 idev->tx_buff.data, idev->tx_buff.len);
324 idev->tx_buff.data += actual;
325 idev->tx_buff.len -= actual;
326 } else {
327 iobase = idev->io.iobase2;
329 * Now serial buffer is almost free & we can start
330 * transmission of another packet
332 idev->netdev.tbusy = 0; /* Unlock */
333 idev->stats.tx_packets++;
335 /* Schedule network layer, so we can get some more frames */
336 mark_bh(NET_BH);
338 outb(UART_FCR_ENABLE_FIFO |
339 UART_FCR_TRIGGER_14 |
340 UART_FCR_CLEAR_RCVR, iobase+UART_FCR); /* Enable FIFO's */
342 /* Turn on receive interrupts */
343 outb(UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER);
348 * Function irport_write (driver)
353 static int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
355 int actual = 0;
357 /* Tx FIFO should be empty! */
358 if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
359 DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
360 return -1;
363 /* Fill FIFO with current frame */
364 while (( fifo_size-- > 0) && (actual < len)) {
365 /* Transmit next byte */
366 outb( buf[actual], iobase+UART_TX);
368 actual++;
371 DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n",
372 fifo_size, actual, len);
374 return actual;
378 * Function irport_xmit (void)
380 * Transmits the current frame until FIFO is full, then
381 * waits until the next transmitt interrupt, and continues until the
382 * frame is transmited.
384 int irport_hard_xmit(struct sk_buff *skb, struct device *dev)
386 struct irda_device *idev;
387 int actual = 0;
388 int iobase;
390 DEBUG(5, __FUNCTION__ "(), dev=%p\n", dev);
392 ASSERT(dev != NULL, return 0;);
394 idev = (struct irda_device *) dev->priv;
396 ASSERT(idev != NULL, return 0;);
397 ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;);
399 iobase = idev->io.iobase2;
401 /* Lock transmit buffer */
402 if (irda_lock((void *) &dev->tbusy) == FALSE)
403 return -EBUSY;
405 /* Init tx buffer */
406 idev->tx_buff.data = idev->tx_buff.head;
408 /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
409 idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data,
410 idev->tx_buff.truesize);
412 idev->tx_buff.data += actual;
413 idev->tx_buff.len -= actual;
415 /* Turn on transmit finished interrupt. Will fire immediately! */
416 outb(UART_IER_THRI, iobase+UART_IER);
418 dev_kfree_skb(skb);
420 return 0;
424 * Function irport_receive (void)
426 * Receive one frame from the infrared port
429 static void irport_receive(struct irda_device *idev)
431 int iobase;
432 int boguscount = 0;
434 if (!idev)
435 return;
437 DEBUG(4, __FUNCTION__ "()\n");
439 iobase = idev->io.iobase2;
442 * Receive all characters in Rx FIFO, unwrap and unstuff them.
443 * async_unwrap_char will deliver all found frames
445 do {
446 async_unwrap_char(idev, inb(iobase+UART_RX));
448 /* Make sure we don't stay here to long */
449 if (boguscount++ > 32) {
450 DEBUG(0,__FUNCTION__ "(), breaking!\n");
451 break;
453 } while (inb(iobase+UART_LSR) & UART_LSR_DR);
457 * Function irport_interrupt (irq, dev_id, regs)
459 * Interrupt handler
461 void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
463 struct irda_device *idev = (struct irda_device *) dev_id;
464 int iobase;
465 int iir, lsr;
466 int boguscount = 0;
468 if (!idev) {
469 printk(KERN_WARNING __FUNCTION__
470 "() irq %d for unknown device.\n", irq);
471 return;
474 idev->netdev.interrupt = 1;
476 iobase = idev->io.iobase2;
478 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
479 while (iir) {
480 /* Clear interrupt */
481 lsr = inb(iobase+UART_LSR);
483 if ((iir & UART_IIR_THRI) && (lsr & UART_LSR_THRE)) {
484 /* Transmitter ready for data */
485 irport_write_wakeup(idev);
486 } else if ((iir & UART_IIR_RDI) && (lsr & UART_LSR_DR)) {
487 /* Receive interrupt */
488 irport_receive(idev);
491 /* Make sure we don't stay here to long */
492 if (boguscount++ > 32)
493 break;
495 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
497 idev->netdev.interrupt = 0;
500 static int irport_net_init(struct device *dev)
502 /* Set up to be a normal IrDA network device driver */
503 irda_device_setup(dev);
505 /* Insert overrides below this line! */
507 return 0;
511 * Function irport_net_open (dev)
516 static int irport_net_open(struct device *dev)
518 struct irda_device *idev;
519 int iobase;
521 ASSERT(dev != NULL, return -1;);
522 idev = (struct irda_device *) dev->priv;
524 iobase = idev->io.iobase2;
526 if (request_irq(idev->io.irq2, irport_interrupt, 0, idev->name,
527 (void *) idev)) {
528 return -EAGAIN;
531 /* Ready to play! */
532 dev->tbusy = 0;
533 dev->interrupt = 0;
534 dev->start = 1;
536 MOD_INC_USE_COUNT;
538 irport_start(iobase);
540 return 0;
544 * Function irport_net_close (idev)
549 static int irport_net_close(struct device *dev)
551 struct irda_device *idev;
552 int iobase;
554 ASSERT(dev != NULL, return -1;);
555 idev = (struct irda_device *) dev->priv;
557 DEBUG(4, __FUNCTION__ "()\n");
559 iobase = idev->io.iobase2;
561 irport_stop(iobase);
563 /* Stop device */
564 dev->tbusy = 1;
565 dev->start = 0;
567 free_irq(idev->io.irq2, idev);
569 MOD_DEC_USE_COUNT;
571 return 0;
574 static void irport_wait_until_sent(struct irda_device *idev)
576 current->state = TASK_INTERRUPTIBLE;
577 schedule_timeout(60*HZ/1000);
580 static int irport_is_receiving(struct irda_device *idev)
582 return (idev->rx_buff.state != OUTSIDE_FRAME);
586 * Function irtty_set_dtr_rts (tty, dtr, rts)
588 * This function can be used by dongles etc. to set or reset the status
589 * of the dtr and rts lines
591 static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts)
593 int iobase;
595 ASSERT(idev != NULL, return;);
596 ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
598 iobase = idev->io.iobase2;
600 if (dtr)
601 dtr = UART_MCR_DTR;
602 if (rts)
603 rts = UART_MCR_RTS;
605 outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
608 static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len)
610 int iobase;
611 int actual = 0;
613 ASSERT(idev != NULL, return -1;);
614 ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
616 iobase = idev->io.iobase2;
618 /* Tx FIFO should be empty! */
619 if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
620 DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
621 return -1;
624 /* Fill FIFO with current frame */
625 while (actual < len) {
626 /* Transmit next byte */
627 outb(buf[actual], iobase+UART_TX);
628 actual++;
631 return actual;
634 #ifdef MODULE
636 MODULE_PARM(io, "1-4i");
637 MODULE_PARM(irq, "1-4i");
640 * Function cleanup_module (void)
645 void cleanup_module(void)
647 irport_cleanup();
651 * Function init_module (void)
655 int init_module(void)
657 return irport_init();
660 #endif /* MODULE */