Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
net
irda
actisys-sir.c
Go to the documentation of this file.
1
/*********************************************************************
2
*
3
* Filename: actisys.c
4
* Version: 1.1
5
* Description: Implementation for the ACTiSYS IR-220L and IR-220L+
6
* dongles
7
* Status: Beta.
8
* Authors: Dag Brattli <
[email protected]
> (initially)
9
* Jean Tourrilhes <
[email protected]
> (new version)
10
* Martin Diehl <
[email protected]
> (new version for sir_dev)
11
* Created at: Wed Oct 21 20:02:35 1998
12
* Modified at: Sun Oct 27 22:02:13 2002
13
* Modified by: Martin Diehl <
[email protected]
>
14
*
15
* Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
16
* Copyright (c) 1999 Jean Tourrilhes
17
* Copyright (c) 2002 Martin Diehl
18
*
19
* This program is free software; you can redistribute it and/or
20
* modify it under the terms of the GNU General Public License as
21
* published by the Free Software Foundation; either version 2 of
22
* the License, or (at your option) any later version.
23
*
24
* Neither Dag Brattli nor University of Tromsø admit liability nor
25
* provide warranty for any of this software. This material is
26
* provided "AS-IS" and at no charge.
27
*
28
********************************************************************/
29
30
/*
31
* Changelog
32
*
33
* 0.8 -> 0.9999 - Jean
34
* o New initialisation procedure : much safer and correct
35
* o New procedure the change speed : much faster and simpler
36
* o Other cleanups & comments
37
* Thanks to Lichen Wang @ Actisys for his excellent help...
38
*
39
* 1.0 -> 1.1 - Martin Diehl
40
* modified for new sir infrastructure
41
*/
42
43
#include <linux/module.h>
44
#include <
linux/delay.h
>
45
#include <
linux/init.h
>
46
47
#include <
net/irda/irda.h
>
48
49
#include "
sir-dev.h
"
50
51
/*
52
* Define the timing of the pulses we send to the dongle (to reset it, and
53
* to toggle speeds). Basically, the limit here is the propagation speed of
54
* the signals through the serial port, the dongle being much faster. Any
55
* serial port support 115 kb/s, so we are sure that pulses 8.5 us wide can
56
* go through cleanly . If you are on the wild side, you can try to lower
57
* this value (Actisys recommended me 2 us, and 0 us work for me on a P233!)
58
*/
59
#define MIN_DELAY 10
/* 10 us to be on the conservative side */
60
61
static
int
actisys_open(
struct
sir_dev
*);
62
static
int
actisys_close(
struct
sir_dev
*);
63
static
int
actisys_change_speed(
struct
sir_dev
*,
unsigned
);
64
static
int
actisys_reset(
struct
sir_dev
*);
65
66
/* These are the baudrates supported, in the order available */
67
/* Note : the 220L doesn't support 38400, but we will fix that below */
68
static
unsigned
baud_rates[] = { 9600, 19200, 57600, 115200, 38400 };
69
70
#define MAX_SPEEDS ARRAY_SIZE(baud_rates)
71
72
static
struct
dongle_driver
act220l = {
73
.owner =
THIS_MODULE
,
74
.driver_name =
"Actisys ACT-220L"
,
75
.type =
IRDA_ACTISYS_DONGLE
,
76
.open = actisys_open,
77
.close = actisys_close,
78
.reset = actisys_reset,
79
.set_speed = actisys_change_speed,
80
};
81
82
static
struct
dongle_driver
act220l_plus = {
83
.owner =
THIS_MODULE
,
84
.driver_name =
"Actisys ACT-220L+"
,
85
.type =
IRDA_ACTISYS_PLUS_DONGLE
,
86
.open = actisys_open,
87
.close = actisys_close,
88
.reset = actisys_reset,
89
.set_speed = actisys_change_speed,
90
};
91
92
static
int
__init
actisys_sir_init(
void
)
93
{
94
int
ret
;
95
96
/* First, register an Actisys 220L dongle */
97
ret =
irda_register_dongle
(&act220l);
98
if
(ret < 0)
99
return
ret
;
100
101
/* Now, register an Actisys 220L+ dongle */
102
ret =
irda_register_dongle
(&act220l_plus);
103
if
(ret < 0) {
104
irda_unregister_dongle
(&act220l);
105
return
ret
;
106
}
107
return
0;
108
}
109
110
static
void
__exit
actisys_sir_cleanup(
void
)
111
{
112
/* We have to remove both dongles */
113
irda_unregister_dongle
(&act220l_plus);
114
irda_unregister_dongle
(&act220l);
115
}
116
117
static
int
actisys_open(
struct
sir_dev
*
dev
)
118
{
119
struct
qos_info
*qos = &dev->
qos
;
120
121
sirdev_set_dtr_rts
(dev,
TRUE
,
TRUE
);
122
123
/* Set the speeds we can accept */
124
qos->
baud_rate
.
bits
&=
IR_9600
|
IR_19200
|
IR_38400
|
IR_57600
|
IR_115200
;
125
126
/* Remove support for 38400 if this is not a 220L+ dongle */
127
if
(dev->
dongle_drv
->type ==
IRDA_ACTISYS_DONGLE
)
128
qos->
baud_rate
.
bits
&= ~
IR_38400
;
129
130
qos->
min_turn_time
.
bits
= 0x7f;
/* Needs 0.01 ms */
131
irda_qos_bits_to_value
(qos);
132
133
/* irda thread waits 50 msec for power settling */
134
135
return
0;
136
}
137
138
static
int
actisys_close(
struct
sir_dev
*dev)
139
{
140
/* Power off the dongle */
141
sirdev_set_dtr_rts
(dev,
FALSE
,
FALSE
);
142
143
return
0;
144
}
145
146
/*
147
* Function actisys_change_speed (task)
148
*
149
* Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles.
150
* To cycle through the available baud rates, pulse RTS low for a few us.
151
*
152
* First, we reset the dongle to always start from a known state.
153
* Then, we cycle through the speeds by pulsing RTS low and then up.
154
* The dongle allow us to pulse quite fast, se we can set speed in one go,
155
* which is must faster ( < 100 us) and less complex than what is found
156
* in some other dongle drivers...
157
* Note that even if the new speed is the same as the current speed,
158
* we reassert the speed. This make sure that things are all right,
159
* and it's fast anyway...
160
* By the way, this function will work for both type of dongles,
161
* because the additional speed is at the end of the sequence...
162
*/
163
static
int
actisys_change_speed(
struct
sir_dev
*dev,
unsigned
speed)
164
{
165
int
ret = 0;
166
int
i
= 0;
167
168
IRDA_DEBUG
(4,
"%s(), speed=%d (was %d)\n"
, __func__,
169
speed, dev->
speed
);
170
171
/* dongle was already resetted from irda_request state machine,
172
* we are in known state (dongle default)
173
*/
174
175
/*
176
* Now, we can set the speed requested. Send RTS pulses until we
177
* reach the target speed
178
*/
179
for
(i = 0; i <
MAX_SPEEDS
; i++) {
180
if
(speed == baud_rates[i]) {
181
dev->
speed
= speed;
182
break
;
183
}
184
/* Set RTS low for 10 us */
185
sirdev_set_dtr_rts
(dev,
TRUE
,
FALSE
);
186
udelay
(
MIN_DELAY
);
187
188
/* Set RTS high for 10 us */
189
sirdev_set_dtr_rts
(dev,
TRUE
,
TRUE
);
190
udelay
(
MIN_DELAY
);
191
}
192
193
/* Check if life is sweet... */
194
if
(i >= MAX_SPEEDS) {
195
actisys_reset(dev);
196
ret = -
EINVAL
;
/* This should not happen */
197
}
198
199
/* Basta lavoro, on se casse d'ici... */
200
return
ret
;
201
}
202
203
/*
204
* Function actisys_reset (task)
205
*
206
* Reset the Actisys type dongle. Warning, this function must only be
207
* called with a process context!
208
*
209
* We need to do two things in this function :
210
* o first make sure that the dongle is in a state where it can operate
211
* o second put the dongle in a know state
212
*
213
* The dongle is powered of the RTS and DTR lines. In the dongle, there
214
* is a big capacitor to accommodate the current spikes. This capacitor
215
* takes a least 50 ms to be charged. In theory, the Bios set those lines
216
* up, so by the time we arrive here we should be set. It doesn't hurt
217
* to be on the conservative side, so we will wait...
218
* <Martin : move above comment to irda_config_fsm>
219
* Then, we set the speed to 9600 b/s to get in a known state (see in
220
* change_speed for details). It is needed because the IrDA stack
221
* has tried to set the speed immediately after our first return,
222
* so before we can be sure the dongle is up and running.
223
*/
224
225
static
int
actisys_reset(
struct
sir_dev
*dev)
226
{
227
/* Reset the dongle : set DTR low for 10 us */
228
sirdev_set_dtr_rts
(dev,
FALSE
,
TRUE
);
229
udelay
(
MIN_DELAY
);
230
231
/* Go back to normal mode */
232
sirdev_set_dtr_rts
(dev,
TRUE
,
TRUE
);
233
234
dev->
speed
= 9600;
/* That's the default */
235
236
return
0;
237
}
238
239
MODULE_AUTHOR
(
"Dag Brattli <
[email protected]
> - Jean Tourrilhes <
[email protected]
>"
);
240
MODULE_DESCRIPTION
(
"ACTiSYS IR-220L and IR-220L+ dongle driver"
);
241
MODULE_LICENSE
(
"GPL"
);
242
MODULE_ALIAS
(
"irda-dongle-2"
);
/* IRDA_ACTISYS_DONGLE */
243
MODULE_ALIAS
(
"irda-dongle-3"
);
/* IRDA_ACTISYS_PLUS_DONGLE */
244
245
module_init
(actisys_sir_init);
246
module_exit
(actisys_sir_cleanup);
Generated on Thu Jan 10 2013 14:06:41 for Linux Kernel by
1.8.2