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
mcp2120-sir.c
Go to the documentation of this file.
1
/*********************************************************************
2
*
3
*
4
* Filename: mcp2120.c
5
* Version: 1.0
6
* Description: Implementation for the MCP2120 (Microchip)
7
* Status: Experimental.
8
* Author: Felix Tang (
[email protected]
)
9
* Created at: Sun Mar 31 19:32:12 EST 2002
10
* Based on code by: Dag Brattli <
[email protected]
>
11
*
12
* Copyright (c) 2002 Felix Tang, All Rights Reserved.
13
*
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.
18
*
19
********************************************************************/
20
21
#include <linux/module.h>
22
#include <
linux/delay.h
>
23
#include <
linux/init.h
>
24
25
#include <
net/irda/irda.h
>
26
27
#include "
sir-dev.h
"
28
29
static
int
mcp2120_reset(
struct
sir_dev
*
dev
);
30
static
int
mcp2120_open(
struct
sir_dev
*
dev
);
31
static
int
mcp2120_close(
struct
sir_dev
*
dev
);
32
static
int
mcp2120_change_speed(
struct
sir_dev
*
dev
,
unsigned
speed);
33
34
#define MCP2120_9600 0x87
35
#define MCP2120_19200 0x8B
36
#define MCP2120_38400 0x85
37
#define MCP2120_57600 0x83
38
#define MCP2120_115200 0x81
39
40
#define MCP2120_COMMIT 0x11
41
42
static
struct
dongle_driver
mcp2120 = {
43
.owner =
THIS_MODULE
,
44
.driver_name =
"Microchip MCP2120"
,
45
.type =
IRDA_MCP2120_DONGLE
,
46
.open = mcp2120_open,
47
.close = mcp2120_close,
48
.reset = mcp2120_reset,
49
.set_speed = mcp2120_change_speed,
50
};
51
52
static
int
__init
mcp2120_sir_init(
void
)
53
{
54
return
irda_register_dongle
(&mcp2120);
55
}
56
57
static
void
__exit
mcp2120_sir_cleanup(
void
)
58
{
59
irda_unregister_dongle
(&mcp2120);
60
}
61
62
static
int
mcp2120_open(
struct
sir_dev
*
dev
)
63
{
64
struct
qos_info
*qos = &dev->
qos
;
65
66
IRDA_DEBUG
(2,
"%s()\n"
, __func__);
67
68
/* seems no explicit power-on required here and reset switching it on anyway */
69
70
qos->
baud_rate
.
bits
&=
IR_9600
|
IR_19200
|
IR_38400
|
IR_57600
|
IR_115200
;
71
qos->
min_turn_time
.
bits
= 0x01;
72
irda_qos_bits_to_value
(qos);
73
74
return
0;
75
}
76
77
static
int
mcp2120_close(
struct
sir_dev
*
dev
)
78
{
79
IRDA_DEBUG
(2,
"%s()\n"
, __func__);
80
81
/* Power off dongle */
82
/* reset and inhibit mcp2120 */
83
sirdev_set_dtr_rts
(dev,
TRUE
,
TRUE
);
84
// sirdev_set_dtr_rts(dev, FALSE, FALSE);
85
86
return
0;
87
}
88
89
/*
90
* Function mcp2120_change_speed (dev, speed)
91
*
92
* Set the speed for the MCP2120.
93
*
94
*/
95
96
#define MCP2120_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED+1)
97
98
static
int
mcp2120_change_speed(
struct
sir_dev
*
dev
,
unsigned
speed)
99
{
100
unsigned
state
= dev->
fsm
.substate;
101
unsigned
delay
= 0;
102
u8
control
[2];
103
static
int
ret
= 0;
104
105
IRDA_DEBUG
(2,
"%s()\n"
, __func__);
106
107
switch
(state) {
108
case
SIRDEV_STATE_DONGLE_SPEED
:
109
/* Set DTR to enter command mode */
110
sirdev_set_dtr_rts
(dev,
TRUE
,
FALSE
);
111
udelay
(500);
112
113
ret = 0;
114
switch
(speed) {
115
default
:
116
speed = 9600;
117
ret = -
EINVAL
;
118
/* fall through */
119
case
9600:
120
control[0] =
MCP2120_9600
;
121
//printk("mcp2120 9600\n");
122
break
;
123
case
19200:
124
control[0] =
MCP2120_19200
;
125
//printk("mcp2120 19200\n");
126
break
;
127
case
34800:
128
control[0] =
MCP2120_38400
;
129
//printk("mcp2120 38400\n");
130
break
;
131
case
57600:
132
control[0] =
MCP2120_57600
;
133
//printk("mcp2120 57600\n");
134
break
;
135
case
115200:
136
control[0] =
MCP2120_115200
;
137
//printk("mcp2120 115200\n");
138
break
;
139
}
140
control[1] =
MCP2120_COMMIT
;
141
142
/* Write control bytes */
143
sirdev_raw_write
(dev, control, 2);
144
dev->
speed
= speed;
145
146
state =
MCP2120_STATE_WAIT_SPEED
;
147
delay = 100;
148
//printk("mcp2120_change_speed: dongle_speed\n");
149
break
;
150
151
case
MCP2120_STATE_WAIT_SPEED
:
152
/* Go back to normal mode */
153
sirdev_set_dtr_rts
(dev,
FALSE
,
FALSE
);
154
//printk("mcp2120_change_speed: mcp_wait\n");
155
break
;
156
157
default
:
158
IRDA_ERROR
(
"%s(), undefine state %d\n"
, __func__, state);
159
ret = -
EINVAL
;
160
break
;
161
}
162
dev->
fsm
.substate =
state
;
163
return
(delay > 0) ? delay :
ret
;
164
}
165
166
/*
167
* Function mcp2120_reset (driver)
168
*
169
* This function resets the mcp2120 dongle.
170
*
171
* Info: -set RTS to reset mcp2120
172
* -set DTR to set mcp2120 software command mode
173
* -mcp2120 defaults to 9600 baud after reset
174
*
175
* Algorithm:
176
* 0. Set RTS to reset mcp2120.
177
* 1. Clear RTS and wait for device reset timer of 30 ms (max).
178
*
179
*/
180
181
#define MCP2120_STATE_WAIT1_RESET (SIRDEV_STATE_DONGLE_RESET+1)
182
#define MCP2120_STATE_WAIT2_RESET (SIRDEV_STATE_DONGLE_RESET+2)
183
184
static
int
mcp2120_reset(
struct
sir_dev
*
dev
)
185
{
186
unsigned
state
= dev->
fsm
.substate;
187
unsigned
delay
= 0;
188
int
ret
= 0;
189
190
IRDA_DEBUG
(2,
"%s()\n"
, __func__);
191
192
switch
(state) {
193
case
SIRDEV_STATE_DONGLE_RESET
:
194
//printk("mcp2120_reset: dongle_reset\n");
195
/* Reset dongle by setting RTS*/
196
sirdev_set_dtr_rts
(dev,
TRUE
,
TRUE
);
197
state =
MCP2120_STATE_WAIT1_RESET
;
198
delay = 50;
199
break
;
200
201
case
MCP2120_STATE_WAIT1_RESET
:
202
//printk("mcp2120_reset: mcp2120_wait1\n");
203
/* clear RTS and wait for at least 30 ms. */
204
sirdev_set_dtr_rts
(dev,
FALSE
,
FALSE
);
205
state =
MCP2120_STATE_WAIT2_RESET
;
206
delay = 50;
207
break
;
208
209
case
MCP2120_STATE_WAIT2_RESET
:
210
//printk("mcp2120_reset mcp2120_wait2\n");
211
/* Go back to normal mode */
212
sirdev_set_dtr_rts
(dev,
FALSE
,
FALSE
);
213
break
;
214
215
default
:
216
IRDA_ERROR
(
"%s(), undefined state %d\n"
, __func__, state);
217
ret = -
EINVAL
;
218
break
;
219
}
220
dev->
fsm
.substate =
state
;
221
return
(delay > 0) ? delay :
ret
;
222
}
223
224
MODULE_AUTHOR
(
"Felix Tang <
[email protected]
>"
);
225
MODULE_DESCRIPTION
(
"Microchip MCP2120"
);
226
MODULE_LICENSE
(
"GPL"
);
227
MODULE_ALIAS
(
"irda-dongle-9"
);
/* IRDA_MCP2120_DONGLE */
228
229
module_init
(mcp2120_sir_init);
230
module_exit
(mcp2120_sir_cleanup);
Generated on Thu Jan 10 2013 14:06:46 for Linux Kernel by
1.8.2