1 /*********************************************************************
5 * Description: Implementation for the ACTiSYS IR-220L and IR-220L+
7 * Status: Experimental.
8 * Author: Dag Brattli <dagb@cs.uit.no>
9 * Created at: Wed Oct 21 20:02:35 1998
10 * Modified at: Mon Jan 18 11:30:25 1999
11 * Modified by: Dag Brattli <dagb@cs.uit.no>
13 * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * Neither Dag Brattli nor University of Tromsø admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
24 ********************************************************************/
26 #include <linux/module.h>
27 #include <linux/delay.h>
28 #include <linux/tty.h>
29 #include <linux/sched.h>
30 #include <linux/init.h>
32 #include <asm/ioctls.h>
33 #include <asm/segment.h>
34 #include <asm/uaccess.h>
36 #include <net/irda/irda.h>
37 #include <net/irda/irmod.h>
38 #include <net/irda/irda_device.h>
39 #include <net/irda/irtty.h>
40 #include <net/irda/dongle.h>
42 static void actisys_reset( struct irda_device
*dev
, int unused
);
43 static void actisys_open( struct irda_device
*idev
, int type
);
44 static void actisys_close( struct irda_device
*dev
);
45 static void actisys_change_speed( struct irda_device
*dev
, int baudrate
);
46 static void actisys_reset( struct irda_device
*dev
, int unused
);
47 static void actisys_init_qos( struct irda_device
*idev
, struct qos_info
*qos
);
49 /* These are the baudrates supported */
50 static int baud_rates
[] = { 9600, 19200, 57600, 115200, 38400};
52 static struct dongle dongle
= {
61 __initfunc(void actisys_init(void))
63 irtty_register_dongle(&dongle
);
66 void actisys_cleanup(void)
68 irtty_unregister_dongle(&dongle
);
71 static void actisys_open( struct irda_device
*idev
, int type
)
73 strcat( idev
->name
, " <-> actisys");
75 idev
->io
.dongle_id
= type
;
80 static void actisys_close( struct irda_device
*dev
)
86 * Function actisys_change_speed (tty, baud)
88 * Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles.
89 * To cycle through the available baud rates, pulse RTS low for a few ms.
90 * To be compatible with the new IR-220L+, we have to reset the dongle
91 * first since its not possible cycle around anymore and still be
92 * compatible with both dongles :-(
94 static void actisys_change_speed( struct irda_device
*idev
, int baudrate
)
96 struct irtty_cb
*self
;
97 struct tty_struct
*tty
;
99 struct termios old_termios
;
101 int current_baudrate
;
105 DEBUG( 0, __FUNCTION__
"()\n");
107 ASSERT( idev
!= NULL
, return;);
108 ASSERT( idev
->magic
== IRDA_DEVICE_MAGIC
, return;);
110 self
= (struct irtty_cb
*) idev
->priv
;
112 ASSERT( self
!= NULL
, return;);
113 ASSERT( self
->magic
== IRTTY_MAGIC
, return;);
115 current_baudrate
= idev
->qos
.baud_rate
.value
;
117 /* Find the correct baudrate index for the currently used baudrate */
118 while ( current_baudrate
!= baud_rates
[index
])
121 DEBUG( 0, __FUNCTION__
"(), index=%d\n", index
);
128 /* Cycle through avaiable baudrates until we reach the correct one */
129 while ( current_baudrate
!= baudrate
) {
130 DEBUG( 0, __FUNCTION__
"(), current baudrate = %d\n",
132 DEBUG( 0, __FUNCTION__
"(), Clearing RTS\n");
134 /* Set DTR, clear RTS */
135 arg
= TIOCM_DTR
|TIOCM_OUT2
;
140 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
141 (unsigned long) &arg
)) {
142 DEBUG( 0, __FUNCTION__
143 "Error clearing RTS!\n");
147 /* Wait at a few ms */
148 current
->state
= TASK_INTERRUPTIBLE
;
151 /* Set DTR, Set RTS */
152 arg
= TIOCM_DTR
| TIOCM_RTS
|TIOCM_OUT2
;
157 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
158 (unsigned long) &arg
)) {
159 DEBUG( 0, __FUNCTION__
"Error setting RTS!\n");
163 /* Wait at a few ms again */
164 current
->state
= TASK_INTERRUPTIBLE
;
165 schedule_timeout( 2);
167 /* Go to next baudrate */
168 if ( idev
->io
.dongle_id
== ACTISYS_DONGLE
)
169 index
= (index
+1) % 4; /* IR-220L */
171 index
= (index
+1) % 5; /* IR-220L+ */
173 current_baudrate
= baud_rates
[index
];
175 DEBUG( 0, __FUNCTION__
"(), current baudrate = %d\n",
178 /* Now change the speed of the serial port */
179 old_termios
= *(tty
->termios
);
180 cflag
= tty
->termios
->c_cflag
;
203 tty
->termios
->c_cflag
= cflag
;
205 DEBUG( 0, __FUNCTION__
"(), Setting the speed of the serial port\n");
206 tty
->driver
.set_termios( tty
, &old_termios
);
210 * Function actisys_reset (dev)
212 * Reset the Actisys type dongle. Warning, this function must only be
213 * called with a process context!
215 * 1. Clear DTR for a few ms.
218 static void actisys_reset( struct irda_device
*idev
, int unused
)
220 struct irtty_cb
*self
;
221 struct tty_struct
*tty
;
225 DEBUG( 4, __FUNCTION__
"()\n");
227 ASSERT( idev
!= NULL
, return;);
228 ASSERT( idev
->magic
== IRDA_DEVICE_MAGIC
, return;);
230 self
= (struct irtty_cb
*) idev
->priv
;
232 ASSERT( self
!= NULL
, return;);
233 ASSERT( self
->magic
== IRTTY_MAGIC
, return;);
239 DEBUG( 0, __FUNCTION__
"(), Clearing DTR\n");
240 arg
= TIOCM_RTS
| TIOCM_OUT2
;
245 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
246 (unsigned long) &arg
))
248 DEBUG( 0, __FUNCTION__
"(), ioctl error!\n");
253 current
->state
= TASK_INTERRUPTIBLE
;
256 DEBUG( 0, __FUNCTION__
"(), Setting DTR\n");
257 arg
= TIOCM_RTS
| TIOCM_DTR
| TIOCM_OUT2
;
262 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
263 (unsigned long) &arg
))
265 DEBUG( 0, __FUNCTION__
"(), ioctl error!\n");
269 idev
->qos
.baud_rate
.value
= 9600;
273 * Function actisys_init_qos (qos)
275 * Initialize QoS capabilities
278 static void actisys_init_qos( struct irda_device
*idev
, struct qos_info
*qos
)
280 qos
->baud_rate
.bits
&= IR_9600
|IR_19200
|IR_38400
|IR_57600
|IR_115200
;
282 /* Remove support for 38400 if this is not a 220L+ dongle */
283 if ( idev
->io
.dongle_id
== ACTISYS_DONGLE
)
284 qos
->baud_rate
.bits
&= ~IR_38400
;
286 qos
->min_turn_time
.bits
&= 0xfe; /* All except 0 ms */
292 * Function init_module (void)
294 * Initialize Actisys module
297 int init_module(void)
304 * Function cleanup_module (void)
306 * Cleanup Actisys module
309 void cleanup_module(void)