1 /*********************************************************************
5 * Description: Implementation of the Tekram IrMate IR-210B dongle
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Wed Oct 21 20:02:35 1998
9 * Modified at: Mon Jan 18 11:30:38 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
23 ********************************************************************/
25 #include <linux/module.h>
26 #include <linux/delay.h>
27 #include <linux/tty.h>
28 #include <linux/sched.h>
29 #include <linux/init.h>
31 #include <asm/ioctls.h>
32 #include <asm/segment.h>
33 #include <asm/uaccess.h>
35 #include <net/irda/irda.h>
36 #include <net/irda/irmod.h>
37 #include <net/irda/irda_device.h>
38 #include <net/irda/irtty.h>
39 #include <net/irda/dongle.h>
41 static void tekram_reset( struct irda_device
*dev
, int unused
);
42 static void tekram_open( struct irda_device
*dev
, int type
);
43 static void tekram_close( struct irda_device
*dev
);
44 static void tekram_change_speed( struct irda_device
*dev
, int baud
);
45 static void tekram_init_qos( struct irda_device
*idev
, struct qos_info
*qos
);
47 static struct dongle dongle
= {
56 __initfunc(void tekram_init(void))
58 irtty_register_dongle( &dongle
);
61 void tekram_cleanup(void)
63 irtty_unregister_dongle( &dongle
);
66 static void tekram_open( struct irda_device
*dev
, int type
)
68 strcat( dev
->name
, " <-> tekram");
73 static void tekram_close( struct irda_device
*dev
)
79 * Function tekram_change_speed (tty, baud)
81 * Set the speed for the Tekram IRMate 210 type dongle. Warning, this
82 * function must be called with a process context!
86 * 2. set RTS, and wait at least 7 us
87 * 3. send Control Byte to the IR-210 through TXD to set new baud rate
88 * wait until the stop bit of Control Byte is sent (for 9600 baud rate,
89 * it takes about 100 msec)
90 * 5. clear RTS (return to NORMAL Operation)
91 * 6. wait at least 50 us, new setting (baud rate, etc) takes effect here
94 static void tekram_change_speed( struct irda_device
*dev
, int baud
)
96 struct irtty_cb
*self
;
97 struct tty_struct
*tty
;
98 struct termios old_termios
;
105 DEBUG( 4, __FUNCTION__
"()\n");
107 ASSERT( dev
!= NULL
, return;);
108 ASSERT( dev
->magic
== IRDA_DEVICE_MAGIC
, return;);
110 self
= (struct irtty_cb
*) dev
->priv
;
112 ASSERT( self
!= NULL
, return;);
113 ASSERT( self
->magic
== IRTTY_MAGIC
, return;);
120 old_termios
= *(tty
->termios
);
121 cflag
= tty
->termios
->c_cflag
;
149 /* Set DTR, Clear RTS */
150 DEBUG( 0, __FUNCTION__
"(), Setting DTR, Clearing RTS\n");
151 arg
= TIOCM_DTR
| TIOCM_OUT2
;
156 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
157 (unsigned long) &arg
)) {
158 DEBUG( 0, "error setting Tekram speed!\n");
162 /* Wait at least 7us */
165 DEBUG( 0, __FUNCTION__
"(), Writing control byte\n");
166 /* Write control byte */
167 if ( tty
->driver
.write
)
168 actual
= tty
->driver
.write( self
->tty
, 0, &byte
, 1);
170 /* Wait at least 100 ms */
171 current
->state
= TASK_INTERRUPTIBLE
;
172 schedule_timeout( 10);
174 /* Set DTR, Set RTS */
175 DEBUG( 0, __FUNCTION__
"(), Setting DTR, Setting RTS\n");
176 arg
= TIOCM_DTR
| TIOCM_RTS
| TIOCM_OUT2
;
181 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
182 (unsigned long) &arg
)) {
183 DEBUG( 0, "error setting Tekram speed!\n");
187 DEBUG( 0, __FUNCTION__
"(), Setting new speed on serial port\n");
188 /* Now change the speed of the serial port */
189 tty
->termios
->c_cflag
= cflag
;
190 tty
->driver
.set_termios( tty
, &old_termios
);
194 * Function tekram_reset (driver)
196 * This function resets the tekram dongle. Warning, this function
197 * must be called with a process context!!
200 * 0. set RTS and DTR, and wait 50 ms
201 * ( power off the IR-210 )
203 * 2. set DTR, and wait at least 1 ms
204 * 3. clear DTR to SPACE state, wait at least 50 us for further
207 void tekram_reset( struct irda_device
*dev
, int unused
)
209 struct irtty_cb
*self
;
210 struct tty_struct
*tty
;
214 DEBUG( 4, __FUNCTION__
"()\n");
216 ASSERT( dev
!= NULL
, return;);
217 ASSERT( dev
->magic
== IRDA_DEVICE_MAGIC
, return;);
219 self
= (struct irtty_cb
*) dev
->priv
;
221 ASSERT( self
!= NULL
, return;);
222 ASSERT( self
->magic
== IRTTY_MAGIC
, return;);
228 DEBUG( 0, __FUNCTION__
"(), Power off dongle\n");
229 arg
= TIOCM_RTS
| TIOCM_DTR
| TIOCM_OUT2
;
234 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
235 (unsigned long) &arg
))
237 DEBUG(0, "error setting ESI speed!\n");
242 current
->state
= TASK_INTERRUPTIBLE
;
245 DEBUG( 0, __FUNCTION__
"(), Set DTR, clear RTS\n");
246 /* Set DTR, clear RTS */
247 arg
= TIOCM_DTR
| TIOCM_OUT2
;
252 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
,
253 (unsigned long) &arg
)) {
254 DEBUG( 0, "Error setting Tekram speed!\n");
258 /* Should sleep 1 ms, but 10-20 should not do any harm */
259 current
->state
= TASK_INTERRUPTIBLE
;
262 DEBUG( 0, __FUNCTION__
"(), STATE3\n");
263 /* Clear DTR, clear RTS */
269 if ( tty
->driver
.ioctl( tty
, NULL
, TIOCMSET
, (unsigned long) &arg
)) {
270 DEBUG( 0, "error setting Tekram speed!\n");
278 * Function tekram_init_qos (qos)
280 * Initialize QoS capabilities
283 static void tekram_init_qos( struct irda_device
*idev
, struct qos_info
*qos
)
285 qos
->baud_rate
.bits
&= IR_9600
|IR_19200
|IR_38400
|IR_57600
|IR_115200
;
286 qos
->min_turn_time
.bits
&= 0xfe; /* All except 0 ms */
292 * Function init_module (void)
294 * Initialize Tekram module
297 int init_module(void)
304 * Function cleanup_module (void)
306 * Cleanup Tekram module
309 void cleanup_module(void)