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 
ma600_sir_init(void)68 static int __init ma600_sir_init(void)
69 {
70 	IRDA_DEBUG(2, "%s()\n", __func__);
71 	return irda_register_dongle(&ma600);
72 }
73 
ma600_sir_cleanup(void)74 static void __exit ma600_sir_cleanup(void)
75 {
76 	IRDA_DEBUG(2, "%s()\n", __func__);
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 */
ma600_open(struct sir_dev * dev)87 static int ma600_open(struct sir_dev *dev)
88 {
89 	struct qos_info *qos = &dev->qos;
90 
91 	IRDA_DEBUG(2, "%s()\n", __func__);
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 
ma600_close(struct sir_dev * dev)107 static int ma600_close(struct sir_dev *dev)
108 {
109 	IRDA_DEBUG(2, "%s()\n", __func__);
110 
111 	/* Power off dongle */
112 	sirdev_set_dtr_rts(dev, FALSE, FALSE);
113 
114 	return 0;
115 }
116 
get_control_byte(__u32 speed)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 
ma600_change_speed(struct sir_dev * dev,unsigned speed)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", __func__,
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 			     __func__, (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", __func__);
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 
ma600_reset(struct sir_dev * dev)239 static int ma600_reset(struct sir_dev *dev)
240 {
241 	IRDA_DEBUG(2, "%s()\n", __func__);
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 
264