2.2.0-final
[davej-history.git] / drivers / net / irda / tekram.c
blobbdada4afab5e7603aed4846dd8167d1e38847a6b
1 /*********************************************************************
2 *
3 * Filename: tekram.c
4 * Version: 0.4
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 = {
48 TEKRAM_DONGLE,
49 tekram_open,
50 tekram_close,
51 tekram_reset,
52 tekram_change_speed,
53 tekram_init_qos,
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");
70 MOD_INC_USE_COUNT;
73 static void tekram_close( struct irda_device *dev)
75 MOD_DEC_USE_COUNT;
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!
84 * Algorithm
85 * 1. clear DTR
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
92 * after
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;
99 int arg = 0;
100 int cflag;
101 __u8 byte;
102 int actual;
103 mm_segment_t fs;
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;);
115 if ( !self->tty)
116 return;
118 tty = self->tty;
120 old_termios = *(tty->termios);
121 cflag = tty->termios->c_cflag;
123 cflag &= ~CBAUD;
125 switch (baud) {
126 case 9600:
127 default:
128 cflag |= B9600;
129 byte = 4;
130 break;
131 case 19200:
132 cflag |= B19200;
133 byte = 3;
134 break;
135 case 34800:
136 cflag |= B38400;
137 byte = 2;
138 break;
139 case 57600:
140 cflag |= B57600;
141 byte = 1;
142 break;
143 case 115200:
144 cflag |= B115200;
145 byte = 0;
146 break;
149 /* Set DTR, Clear RTS */
150 DEBUG( 0, __FUNCTION__ "(), Setting DTR, Clearing RTS\n");
151 arg = TIOCM_DTR | TIOCM_OUT2;
153 fs = get_fs();
154 set_fs( get_ds());
156 if ( tty->driver.ioctl( tty, NULL, TIOCMSET,
157 (unsigned long) &arg)) {
158 DEBUG( 0, "error setting Tekram speed!\n");
160 set_fs(fs);
162 /* Wait at least 7us */
163 udelay( 7);
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;
178 fs = get_fs();
179 set_fs( get_ds());
181 if ( tty->driver.ioctl( tty, NULL, TIOCMSET,
182 (unsigned long) &arg)) {
183 DEBUG( 0, "error setting Tekram speed!\n");
185 set_fs(fs);
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!!
199 * Algorithm:
200 * 0. set RTS and DTR, and wait 50 ms
201 * ( power off the IR-210 )
202 * 1. clear RTS
203 * 2. set DTR, and wait at least 1 ms
204 * 3. clear DTR to SPACE state, wait at least 50 us for further
205 * operation
207 void tekram_reset( struct irda_device *dev, int unused)
209 struct irtty_cb *self;
210 struct tty_struct *tty;
211 int arg = 0;
212 mm_segment_t fs;
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;);
224 tty = self->tty;
225 if ( !tty)
226 return;
228 DEBUG( 0, __FUNCTION__ "(), Power off dongle\n");
229 arg = TIOCM_RTS | TIOCM_DTR | TIOCM_OUT2;
231 fs = get_fs();
232 set_fs( get_ds());
234 if ( tty->driver.ioctl( tty, NULL, TIOCMSET,
235 (unsigned long) &arg))
237 DEBUG(0, "error setting ESI speed!\n");
239 set_fs(fs);
241 /* Sleep 50 ms */
242 current->state = TASK_INTERRUPTIBLE;
243 schedule_timeout(5);
245 DEBUG( 0, __FUNCTION__ "(), Set DTR, clear RTS\n");
246 /* Set DTR, clear RTS */
247 arg = TIOCM_DTR | TIOCM_OUT2;
249 fs = get_fs();
250 set_fs( get_ds());
252 if ( tty->driver.ioctl( tty, NULL, TIOCMSET,
253 (unsigned long) &arg)) {
254 DEBUG( 0, "Error setting Tekram speed!\n");
256 set_fs(fs);
258 /* Should sleep 1 ms, but 10-20 should not do any harm */
259 current->state = TASK_INTERRUPTIBLE;
260 schedule_timeout(2);
262 DEBUG( 0, __FUNCTION__ "(), STATE3\n");
263 /* Clear DTR, clear RTS */
264 arg = TIOCM_OUT2;
266 fs = get_fs();
267 set_fs( get_ds());
269 if ( tty->driver.ioctl( tty, NULL, TIOCMSET, (unsigned long) &arg)) {
270 DEBUG( 0, "error setting Tekram speed!\n");
272 set_fs(fs);
274 /* Finished! */
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 */
289 #ifdef MODULE
292 * Function init_module (void)
294 * Initialize Tekram module
297 int init_module(void)
299 tekram_init();
300 return(0);
304 * Function cleanup_module (void)
306 * Cleanup Tekram module
309 void cleanup_module(void)
311 tekram_cleanup();
314 #endif