OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [irda/] [mcp2120.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*********************************************************************
2
 *
3
 *
4
 * Filename:      mcp2120.c
5
 * Version:       1.0
6
 * Description:   Implementation for the MCP2120 (Microchip)
7
 * Status:        Experimental.
8
 * Author:        Felix Tang (tangf@eyetap.org)
9
 * Created at:    Sun Mar 31 19:32:12 EST 2002
10
 * Based on code by:   Dag Brattli <dagb@cs.uit.no>
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/tty.h>
24
#include <linux/init.h>
25
 
26
#include <net/irda/irda.h>
27
#include <net/irda/irda_device.h>
28
 
29
static int  mcp2120_reset(struct irda_task *task);
30
static void mcp2120_open(dongle_t *self, struct qos_info *qos);
31
static void mcp2120_close(dongle_t *self);
32
static int  mcp2120_change_speed(struct irda_task *task);
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_reg dongle = {
43
        .type = IRDA_MCP2120_DONGLE,
44
        .open = mcp2120_open,
45
        .close = mcp2120_close,
46
        .reset = mcp2120_reset,
47
        .change_speed = mcp2120_change_speed,
48
        .owner = THIS_MODULE,
49
};
50
 
51
static int __init mcp2120_init(void)
52
{
53
        return irda_device_register_dongle(&dongle);
54
}
55
 
56
static void __exit mcp2120_cleanup(void)
57
{
58
        irda_device_unregister_dongle(&dongle);
59
}
60
 
61
static void mcp2120_open(dongle_t *self, struct qos_info *qos)
62
{
63
        qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
64
        qos->min_turn_time.bits = 0x01;
65
}
66
 
67
static void mcp2120_close(dongle_t *self)
68
{
69
        /* Power off dongle */
70
        /* reset and inhibit mcp2120 */
71
        self->set_dtr_rts(self->dev, TRUE, TRUE);
72
        //self->set_dtr_rts(self->dev, FALSE, FALSE);
73
}
74
 
75
/*
76
 * Function mcp2120_change_speed (dev, speed)
77
 *
78
 *    Set the speed for the MCP2120.
79
 *
80
 */
81
static int mcp2120_change_speed(struct irda_task *task)
82
{
83
        dongle_t *self = (dongle_t *) task->instance;
84
        __u32 speed = (__u32) task->param;
85
        __u8 control[2];
86
        int ret = 0;
87
 
88
        self->speed_task = task;
89
 
90
        switch (task->state) {
91
        case IRDA_TASK_INIT:
92
                /* Need to reset the dongle and go to 9600 bps before
93
                   programming */
94
                //printk("Dmcp2120_change_speed irda_task_init\n");
95
                if (irda_task_execute(self, mcp2120_reset, NULL, task,
96
                                      (void *) speed))
97
                {
98
                        /* Dongle need more time to reset */
99
                        irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
100
 
101
                        /* Give reset 1 sec to finish */
102
                        ret = msecs_to_jiffies(1000);
103
                }
104
                break;
105
        case IRDA_TASK_CHILD_WAIT:
106
                IRDA_WARNING("%s(), resetting dongle timed out!\n",
107
                             __FUNCTION__);
108
                ret = -1;
109
                break;
110
        case IRDA_TASK_CHILD_DONE:
111
                /* Set DTR to enter command mode */
112
                self->set_dtr_rts(self->dev, TRUE, FALSE);
113
                udelay(500);
114
 
115
                switch (speed) {
116
                case 9600:
117
                default:
118
                        control[0] = MCP2120_9600;
119
                        //printk("mcp2120 9600\n");
120
                        break;
121
                case 19200:
122
                        control[0] = MCP2120_19200;
123
                        //printk("mcp2120 19200\n");
124
                        break;
125
                case 34800:
126
                        control[0] = MCP2120_38400;
127
                        //printk("mcp2120 38400\n");
128
                        break;
129
                case 57600:
130
                        control[0] = MCP2120_57600;
131
                        //printk("mcp2120 57600\n");
132
                        break;
133
                case 115200:
134
                        control[0] = MCP2120_115200;
135
                        //printk("mcp2120 115200\n");
136
                        break;
137
                }
138
                control[1] = MCP2120_COMMIT;
139
 
140
                /* Write control bytes */
141
                self->write(self->dev, control, 2);
142
 
143
                irda_task_next_state(task, IRDA_TASK_WAIT);
144
                ret = msecs_to_jiffies(100);
145
                //printk("mcp2120_change_speed irda_child_done\n");
146
                break;
147
        case IRDA_TASK_WAIT:
148
                /* Go back to normal mode */
149
                self->set_dtr_rts(self->dev, FALSE, FALSE);
150
                irda_task_next_state(task, IRDA_TASK_DONE);
151
                self->speed_task = NULL;
152
                //printk("mcp2120_change_speed irda_task_wait\n");
153
                break;
154
        default:
155
                IRDA_ERROR("%s(), unknown state %d\n",
156
                           __FUNCTION__, task->state);
157
                irda_task_next_state(task, IRDA_TASK_DONE);
158
                self->speed_task = NULL;
159
                ret = -1;
160
                break;
161
        }
162
        return ret;
163
}
164
 
165
/*
166
 * Function mcp2120_reset (driver)
167
 *
168
 *      This function resets the mcp2120 dongle.
169
 *
170
 *      Info: -set RTS to reset mcp2120
171
 *            -set DTR to set mcp2120 software command mode
172
 *            -mcp2120 defaults to 9600 baud after reset
173
 *
174
 *      Algorithm:
175
 *      0. Set RTS to reset mcp2120.
176
 *      1. Clear RTS and wait for device reset timer of 30 ms (max).
177
 *
178
 */
179
 
180
 
181
static int mcp2120_reset(struct irda_task *task)
182
{
183
        dongle_t *self = (dongle_t *) task->instance;
184
        int ret = 0;
185
 
186
        self->reset_task = task;
187
 
188
        switch (task->state) {
189
        case IRDA_TASK_INIT:
190
                //printk("mcp2120_reset irda_task_init\n");
191
                /* Reset dongle by setting RTS*/
192
                self->set_dtr_rts(self->dev, TRUE, TRUE);
193
                irda_task_next_state(task, IRDA_TASK_WAIT1);
194
                ret = msecs_to_jiffies(50);
195
                break;
196
        case IRDA_TASK_WAIT1:
197
                //printk("mcp2120_reset irda_task_wait1\n");
198
                /* clear RTS and wait for at least 30 ms. */
199
                self->set_dtr_rts(self->dev, FALSE, FALSE);
200
                irda_task_next_state(task, IRDA_TASK_WAIT2);
201
                ret = msecs_to_jiffies(50);
202
                break;
203
        case IRDA_TASK_WAIT2:
204
                //printk("mcp2120_reset irda_task_wait2\n");
205
                /* Go back to normal mode */
206
                self->set_dtr_rts(self->dev, FALSE, FALSE);
207
                irda_task_next_state(task, IRDA_TASK_DONE);
208
                self->reset_task = NULL;
209
                break;
210
        default:
211
                IRDA_ERROR("%s(), unknown state %d\n",
212
                           __FUNCTION__, task->state);
213
                irda_task_next_state(task, IRDA_TASK_DONE);
214
                self->reset_task = NULL;
215
                ret = -1;
216
                break;
217
        }
218
        return ret;
219
}
220
 
221
MODULE_AUTHOR("Felix Tang <tangf@eyetap.org>");
222
MODULE_DESCRIPTION("Microchip MCP2120");
223
MODULE_LICENSE("GPL");
224
MODULE_ALIAS("irda-dongle-9"); /* IRDA_MCP2120_DONGLE */
225
 
226
/*
227
 * Function init_module (void)
228
 *
229
 *    Initialize MCP2120 module
230
 *
231
 */
232
module_init(mcp2120_init);
233
 
234
/*
235
 * Function cleanup_module (void)
236
 *
237
 *    Cleanup MCP2120 module
238
 *
239
 */
240
module_exit(mcp2120_cleanup);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.