Pull thermal into release branch
[linux-2.6] / drivers / net / irda / ma600-sir.c
1 /*********************************************************************
2  *                
3  * Filename:      ma600.c
4  * Version:       0.1
5  * Description:   Implementation of the MA600 dongle
6  * Status:        Experimental.
7  * Author:        Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95
8  * Created at:    Sat Jun 10 20:02:35 2000
9  * Modified at:   Sat Aug 16 09:34:13 2003
10  * Modified by:   Martin Diehl <mad@mdiehl.de> (modified for new sir_dev)
11  *
12  * Note: very thanks to Mr. Maru Wang <maru@mobileaction.com.tw> for providing 
13  *       information on the MA600 dongle
14  * 
15  *     Copyright (c) 2000 Leung, All Rights Reserved.
16  *      
17  *     This program is free software; you can redistribute it and/or 
18  *     modify it under the terms of the GNU General Public License as 
19  *     published by the Free Software Foundation; either version 2 of 
20  *     the License, or (at your option) any later version.
21  *  
22  *     This program is distributed in the hope that it will be useful,
23  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
24  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  *     GNU General Public License for more details.
26  * 
27  *     You should have received a copy of the GNU General Public License 
28  *     along with this program; if not, write to the Free Software 
29  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
30  *     MA 02111-1307 USA
31  *     
32  ********************************************************************/
33
34 #include <linux/module.h>
35 #include <linux/delay.h>
36 #include <linux/init.h>
37
38 #include <net/irda/irda.h>
39
40 #include "sir-dev.h"
41
42 static int ma600_open(struct sir_dev *);
43 static int ma600_close(struct sir_dev *);
44 static int ma600_change_speed(struct sir_dev *, unsigned);
45 static int ma600_reset(struct sir_dev *);
46
47 /* control byte for MA600 */
48 #define MA600_9600      0x00
49 #define MA600_19200     0x01
50 #define MA600_38400     0x02
51 #define MA600_57600     0x03
52 #define MA600_115200    0x04
53 #define MA600_DEV_ID1   0x05
54 #define MA600_DEV_ID2   0x06
55 #define MA600_2400      0x08
56
57 static struct dongle_driver ma600 = {
58         .owner          = THIS_MODULE,
59         .driver_name    = "MA600",
60         .type           = IRDA_MA600_DONGLE,
61         .open           = ma600_open,
62         .close          = ma600_close,
63         .reset          = ma600_reset,
64         .set_speed      = ma600_change_speed,
65 };
66
67
68 static int __init ma600_sir_init(void)
69 {
70         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
71         return irda_register_dongle(&ma600);
72 }
73
74 static void __exit ma600_sir_cleanup(void)
75 {
76         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
77         irda_unregister_dongle(&ma600);
78 }
79
80 /*
81         Power on:
82                 (0) Clear RTS and DTR for 1 second
83                 (1) Set RTS and DTR for 1 second
84                 (2) 9600 bps now
85         Note: assume RTS, DTR are clear before
86 */
87 static int ma600_open(struct sir_dev *dev)
88 {
89         struct qos_info *qos = &dev->qos;
90
91         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
92
93         sirdev_set_dtr_rts(dev, TRUE, TRUE);
94
95         /* Explicitly set the speeds we can accept */
96         qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400
97                                 |IR_57600|IR_115200;
98         /* Hm, 0x01 means 10ms - for >= 1ms we would need 0x07 */
99         qos->min_turn_time.bits = 0x01;         /* Needs at least 1 ms */       
100         irda_qos_bits_to_value(qos);
101
102         /* irda thread waits 50 msec for power settling */
103
104         return 0;
105 }
106
107 static int ma600_close(struct sir_dev *dev)
108 {
109         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
110
111         /* Power off dongle */
112         sirdev_set_dtr_rts(dev, FALSE, FALSE);
113
114         return 0;
115 }
116
117 static __u8 get_control_byte(__u32 speed)
118 {
119         __u8 byte;
120
121         switch (speed) {
122         default:
123         case 115200:
124                 byte = MA600_115200;
125                 break;
126         case 57600:
127                 byte = MA600_57600;
128                 break;
129         case 38400:
130                 byte = MA600_38400;
131                 break;
132         case 19200:
133                 byte = MA600_19200;
134                 break;
135         case 9600:
136                 byte = MA600_9600;
137                 break;
138         case 2400:
139                 byte = MA600_2400;
140                 break;
141         }
142
143         return byte;
144 }
145
146 /*
147  * Function ma600_change_speed (dev, speed)
148  *
149  *    Set the speed for the MA600 type dongle.
150  *
151  *    The dongle has already been reset to a known state (dongle default)
152  *    We cycle through speeds by pulsing RTS low and then high.
153  */
154
155 /*
156  * Function ma600_change_speed (dev, speed)
157  *
158  *    Set the speed for the MA600 type dongle.
159  *
160  *    Algorithm
161  *    1. Reset (already done by irda thread state machine)
162  *    2. clear RTS, set DTR and wait for 1ms
163  *    3. send Control Byte to the MA600 through TXD to set new baud rate
164  *       wait until the stop bit of Control Byte is sent (for 9600 baud rate, 
165  *       it takes about 10 msec)
166  *    4. set RTS, set DTR (return to NORMAL Operation)
167  *    5. wait at least 10 ms, new setting (baud rate, etc) takes effect here 
168  *       after
169  */
170
171 /* total delays are only about 20ms - let's just sleep for now to
172  * avoid the state machine complexity before we get things working
173  */
174
175 static int ma600_change_speed(struct sir_dev *dev, unsigned speed)
176 {
177         u8      byte;
178         
179         IRDA_DEBUG(2, "%s(), speed=%d (was %d)\n", __FUNCTION__,
180                 speed, dev->speed);
181
182         /* dongle already reset, dongle and port at default speed (9600) */
183
184         /* Set RTS low for 1 ms */
185         sirdev_set_dtr_rts(dev, TRUE, FALSE);
186         mdelay(1);
187
188         /* Write control byte */
189         byte = get_control_byte(speed);
190         sirdev_raw_write(dev, &byte, sizeof(byte));
191
192         /* Wait at least 10ms: fake wait_until_sent - 10 bits at 9600 baud*/
193         msleep(15);                                     /* old ma600 uses 15ms */
194
195 #if 1
196         /* read-back of the control byte. ma600 is the first dongle driver
197          * which uses this so there might be some unidentified issues.
198          * Disable this in case of problems with readback.
199          */
200
201         sirdev_raw_read(dev, &byte, sizeof(byte));
202         if (byte != get_control_byte(speed))  {
203                 IRDA_WARNING("%s(): bad control byte read-back %02x != %02x\n",
204                              __FUNCTION__, (unsigned) byte,
205                              (unsigned) get_control_byte(speed));
206                 return -1;
207         }
208         else
209                 IRDA_DEBUG(2, "%s() control byte write read OK\n", __FUNCTION__);
210 #endif
211
212         /* Set DTR, Set RTS */
213         sirdev_set_dtr_rts(dev, TRUE, TRUE);
214
215         /* Wait at least 10ms */
216         msleep(10);
217
218         /* dongle is now switched to the new speed */
219         dev->speed = speed;
220
221         return 0;
222 }
223
224 /*
225  * Function ma600_reset (dev)
226  *
227  *      This function resets the ma600 dongle.
228  *
229  *      Algorithm:
230  *        0. DTR=0, RTS=1 and wait 10 ms
231  *        1. DTR=1, RTS=1 and wait 10 ms
232  *        2. 9600 bps now
233  */
234
235 /* total delays are only about 20ms - let's just sleep for now to
236  * avoid the state machine complexity before we get things working
237  */
238
239 int ma600_reset(struct sir_dev *dev)
240 {
241         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
242
243         /* Reset the dongle : set DTR low for 10 ms */
244         sirdev_set_dtr_rts(dev, FALSE, TRUE);
245         msleep(10);
246
247         /* Go back to normal mode */
248         sirdev_set_dtr_rts(dev, TRUE, TRUE);
249         msleep(10);
250
251         dev->speed = 9600;      /* That's the dongle-default */
252
253         return 0;
254 }
255
256 MODULE_AUTHOR("Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95");
257 MODULE_DESCRIPTION("MA600 dongle driver version 0.1");
258 MODULE_LICENSE("GPL");
259 MODULE_ALIAS("irda-dongle-11"); /* IRDA_MA600_DONGLE */
260                 
261 module_init(ma600_sir_init);
262 module_exit(ma600_sir_cleanup);
263