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: Sat Jun 26 16:57:57 1999
11 * Modified by: Dag Brattli <dagb@cs.uit.no>
13 * Copyright (c) 1998-1999 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 <net/irda/irda.h>
33 #include <net/irda/irmod.h>
34 #include <net/irda/irda_device.h>
35 #include <net/irda/dongle.h>
37 static void actisys_reset(struct irda_device
*dev
);
38 static void actisys_open(struct irda_device
*idev
, int type
);
39 static void actisys_close(struct irda_device
*dev
);
40 static void actisys_change_speed( struct irda_device
*dev
, __u32 speed
);
41 static void actisys_init_qos(struct irda_device
*idev
, struct qos_info
*qos
);
43 /* These are the baudrates supported */
44 static __u32 baud_rates
[] = { 9600, 19200, 57600, 115200, 38400};
46 static struct dongle dongle
= {
55 static struct dongle dongle_plus
= {
64 int __init
actisys_init(void)
68 ret
= irda_device_register_dongle(&dongle
);
71 ret
= irda_device_register_dongle(&dongle_plus
);
73 irda_device_unregister_dongle(&dongle
);
79 void actisys_cleanup(void)
81 irda_device_unregister_dongle(&dongle
);
82 irda_device_unregister_dongle(&dongle_plus
);
85 static void actisys_open(struct irda_device
*idev
, int type
)
87 strcat(idev
->description
, " <-> actisys");
89 idev
->io
.dongle_id
= type
;
90 idev
->flags
|= IFF_DONGLE
;
95 static void actisys_close(struct irda_device
*idev
)
97 /* Power off dongle */
98 irda_device_set_dtr_rts(idev
, FALSE
, FALSE
);
104 * Function actisys_change_speed (tty, baud)
106 * Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles.
107 * To cycle through the available baud rates, pulse RTS low for a few
110 static void actisys_change_speed(struct irda_device
*idev
, __u32 speed
)
112 __u32 current_baudrate
;
115 DEBUG(4, __FUNCTION__
"()\n");
117 ASSERT(idev
!= NULL
, return;);
118 ASSERT(idev
->magic
== IRDA_DEVICE_MAGIC
, return;);
120 current_baudrate
= idev
->qos
.baud_rate
.value
;
122 /* Find the correct baudrate index for the currently used baudrate */
123 while (current_baudrate
!= baud_rates
[index
])
126 DEBUG( 4, __FUNCTION__
"(), index=%d\n", index
);
128 /* Cycle through avaiable baudrates until we reach the correct one */
129 while (current_baudrate
!= speed
) {
130 DEBUG(4, __FUNCTION__
"(), current baudrate = %d\n",
133 /* Set DTR, clear RTS */
134 irda_device_set_dtr_rts(idev
, TRUE
, FALSE
);
136 /* Wait at a few ms */
137 current
->state
= TASK_INTERRUPTIBLE
;
138 schedule_timeout(MSECS_TO_JIFFIES(20));
140 /* Set DTR, Set RTS */
141 irda_device_set_dtr_rts(idev
, TRUE
, TRUE
);
143 /* Wait at a few ms again */
144 current
->state
= TASK_INTERRUPTIBLE
;
145 schedule_timeout(MSECS_TO_JIFFIES(20));
147 /* Go to next baudrate */
148 if (idev
->io
.dongle_id
== ACTISYS_DONGLE
)
149 index
= (index
+1) % 4; /* IR-220L */
151 index
= (index
+1) % 5; /* IR-220L+ */
153 current_baudrate
= baud_rates
[index
];
155 DEBUG(4, __FUNCTION__
"(), current baudrate = %d\n", baud_rates
[index
]);
159 * Function actisys_reset (dev)
161 * Reset the Actisys type dongle. Warning, this function must only be
162 * called with a process context!
164 * 1. Clear DTR for a few ms.
167 static void actisys_reset(struct irda_device
*idev
)
169 ASSERT(idev
!= NULL
, return;);
170 ASSERT(idev
->magic
== IRDA_DEVICE_MAGIC
, return;);
173 irda_device_set_dtr_rts(idev
, FALSE
, TRUE
);
176 current
->state
= TASK_INTERRUPTIBLE
;
177 schedule_timeout(MSECS_TO_JIFFIES(20));
179 /* Go back to normal mode */
180 irda_device_set_dtr_rts(idev
, TRUE
, TRUE
);
182 idev
->qos
.baud_rate
.value
= 9600;
186 * Function actisys_init_qos (qos)
188 * Initialize QoS capabilities
191 static void actisys_init_qos(struct irda_device
*idev
, struct qos_info
*qos
)
193 qos
->baud_rate
.bits
&= IR_9600
|IR_19200
|IR_38400
|IR_57600
|IR_115200
;
195 /* Remove support for 38400 if this is not a 220L+ dongle */
196 if (idev
->io
.dongle_id
== ACTISYS_DONGLE
)
197 qos
->baud_rate
.bits
&= ~IR_38400
;
199 qos
->min_turn_time
.bits
&= 0x40; /* Needs 0.01 ms */
204 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
205 MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver");
208 * Function init_module (void)
210 * Initialize Actisys module
213 int init_module(void)
215 return actisys_init();
219 * Function cleanup_module (void)
221 * Cleanup Actisys module
224 void cleanup_module(void)