1 /*********************************************************************
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.
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>
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>
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))
98 for (i
=0; (io
[i
] < 2000) && (i
< 4); i
++) {
100 if (check_region(ioaddr
, IO_EXTENT
))
102 if (irport_open(i
, io
[i
], irq
[i
]) == 0)
106 * Maybe something failed, but we can still be usable for FIR drivers
112 * Function irport_cleanup ()
114 * Close all configured ports
118 static void irport_cleanup(void)
122 DEBUG( 4, __FUNCTION__
"()\n");
124 for (i
=0; i
< 4; i
++) {
126 irport_close(dev_self
[i
]);
131 static int irport_open(int i
, unsigned int iobase
, unsigned int irq
)
133 struct irda_device
*idev
;
136 DEBUG( 0, __FUNCTION__
"()\n");
138 /* if (irport_probe(iobase, irq) == -1) */
142 * Allocate new instance of the driver
144 idev
= kmalloc(sizeof(struct irda_device
), GFP_KERNEL
);
146 printk( KERN_ERR
"IrDA: Can't allocate memory for "
147 "IrDA control block!\n");
150 memset(idev
, 0, sizeof(struct irda_device
));
152 /* Need to store self somewhere */
156 idev
->io
.iobase2
= iobase
;
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
);
164 DEBUG( 0, __FUNCTION__
"(), can't get iobase of 0x%03x\n",
166 /* w83977af_cleanup( self->idev); */
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
|
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
);
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",
218 release_region(idev
->io
.iobase2
, idev
->io
.io_ext
);
220 irda_device_close(idev
);
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
)
241 outb(0, iobase
+UART_MCR
);
243 /* Turn off interrupts */
244 outb(0, iobase
+UART_IER
);
248 * Function irport_probe (void)
253 int irport_probe(int iobase
)
255 DEBUG(4, __FUNCTION__
"(), iobase=%#x\n", iobase
);
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
)
270 int fcr
; /* FIFO control reg */
271 int lcr
; /* Line control reg */
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
)
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
;
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 */
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
)
357 /* Tx FIFO should be empty! */
358 if (!(inb(iobase
+UART_LSR
) & UART_LSR_THRE
)) {
359 DEBUG( 0, __FUNCTION__
"(), failed, fifo not empty!\n");
363 /* Fill FIFO with current frame */
364 while (( fifo_size
-- > 0) && (actual
< len
)) {
365 /* Transmit next byte */
366 outb( buf
[actual
], iobase
+UART_TX
);
371 DEBUG(4, __FUNCTION__
"(), fifo_size %d ; %d sent of %d\n",
372 fifo_size
, actual
, len
);
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
;
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
)
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
);
424 * Function irport_receive (void)
426 * Receive one frame from the infrared port
429 static void irport_receive(struct irda_device
*idev
)
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
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");
453 } while (inb(iobase
+UART_LSR
) & UART_LSR_DR
);
457 * Function irport_interrupt (irq, dev_id, regs)
461 void irport_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
463 struct irda_device
*idev
= (struct irda_device
*) dev_id
;
469 printk(KERN_WARNING __FUNCTION__
470 "() irq %d for unknown device.\n", irq
);
474 idev
->netdev
.interrupt
= 1;
476 iobase
= idev
->io
.iobase2
;
478 iir
= inb(iobase
+ UART_IIR
) & UART_IIR_ID
;
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)
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! */
511 * Function irport_net_open (dev)
516 static int irport_net_open(struct device
*dev
)
518 struct irda_device
*idev
;
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
,
538 irport_start(iobase
);
544 * Function irport_net_close (idev)
549 static int irport_net_close(struct device
*dev
)
551 struct irda_device
*idev
;
554 ASSERT(dev
!= NULL
, return -1;);
555 idev
= (struct irda_device
*) dev
->priv
;
557 DEBUG(4, __FUNCTION__
"()\n");
559 iobase
= idev
->io
.iobase2
;
567 free_irq(idev
->io
.irq2
, idev
);
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
)
595 ASSERT(idev
!= NULL
, return;);
596 ASSERT(idev
->magic
== IRDA_DEVICE_MAGIC
, return;);
598 iobase
= idev
->io
.iobase2
;
605 outb(dtr
|rts
|UART_MCR_OUT2
, iobase
+UART_MCR
);
608 static int irport_raw_write(struct irda_device
*idev
, __u8
*buf
, int len
)
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");
624 /* Fill FIFO with current frame */
625 while (actual
< len
) {
626 /* Transmit next byte */
627 outb(buf
[actual
], iobase
+UART_TX
);
636 MODULE_PARM(io
, "1-4i");
637 MODULE_PARM(irq
, "1-4i");
640 * Function cleanup_module (void)
645 void cleanup_module(void)
651 * Function init_module (void)
655 int init_module(void)
657 return irport_init();