Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
8949d2aa | 2 | * dscore.c |
1da177e4 LT |
3 | * |
4 | * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> | |
8949d2aa | 5 | * |
1da177e4 LT |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | */ | |
21 | ||
22 | #include <linux/module.h> | |
23 | #include <linux/kernel.h> | |
24 | #include <linux/mod_devicetable.h> | |
25 | #include <linux/usb.h> | |
26 | ||
81f6075e EP |
27 | #include "../w1_int.h" |
28 | #include "../w1.h" | |
29 | ||
30 | /* COMMAND TYPE CODES */ | |
31 | #define CONTROL_CMD 0x00 | |
32 | #define COMM_CMD 0x01 | |
33 | #define MODE_CMD 0x02 | |
34 | ||
35 | /* CONTROL COMMAND CODES */ | |
36 | #define CTL_RESET_DEVICE 0x0000 | |
37 | #define CTL_START_EXE 0x0001 | |
38 | #define CTL_RESUME_EXE 0x0002 | |
39 | #define CTL_HALT_EXE_IDLE 0x0003 | |
40 | #define CTL_HALT_EXE_DONE 0x0004 | |
41 | #define CTL_FLUSH_COMM_CMDS 0x0007 | |
42 | #define CTL_FLUSH_RCV_BUFFER 0x0008 | |
43 | #define CTL_FLUSH_XMT_BUFFER 0x0009 | |
44 | #define CTL_GET_COMM_CMDS 0x000A | |
45 | ||
46 | /* MODE COMMAND CODES */ | |
47 | #define MOD_PULSE_EN 0x0000 | |
48 | #define MOD_SPEED_CHANGE_EN 0x0001 | |
49 | #define MOD_1WIRE_SPEED 0x0002 | |
50 | #define MOD_STRONG_PU_DURATION 0x0003 | |
51 | #define MOD_PULLDOWN_SLEWRATE 0x0004 | |
52 | #define MOD_PROG_PULSE_DURATION 0x0005 | |
53 | #define MOD_WRITE1_LOWTIME 0x0006 | |
54 | #define MOD_DSOW0_TREC 0x0007 | |
55 | ||
56 | /* COMMUNICATION COMMAND CODES */ | |
57 | #define COMM_ERROR_ESCAPE 0x0601 | |
58 | #define COMM_SET_DURATION 0x0012 | |
59 | #define COMM_BIT_IO 0x0020 | |
60 | #define COMM_PULSE 0x0030 | |
61 | #define COMM_1_WIRE_RESET 0x0042 | |
62 | #define COMM_BYTE_IO 0x0052 | |
63 | #define COMM_MATCH_ACCESS 0x0064 | |
64 | #define COMM_BLOCK_IO 0x0074 | |
65 | #define COMM_READ_STRAIGHT 0x0080 | |
66 | #define COMM_DO_RELEASE 0x6092 | |
67 | #define COMM_SET_PATH 0x00A2 | |
68 | #define COMM_WRITE_SRAM_PAGE 0x00B2 | |
69 | #define COMM_WRITE_EPROM 0x00C4 | |
70 | #define COMM_READ_CRC_PROT_PAGE 0x00D4 | |
71 | #define COMM_READ_REDIRECT_PAGE_CRC 0x21E4 | |
72 | #define COMM_SEARCH_ACCESS 0x00F4 | |
73 | ||
74 | /* Communication command bits */ | |
75 | #define COMM_TYPE 0x0008 | |
76 | #define COMM_SE 0x0008 | |
77 | #define COMM_D 0x0008 | |
78 | #define COMM_Z 0x0008 | |
79 | #define COMM_CH 0x0008 | |
80 | #define COMM_SM 0x0008 | |
81 | #define COMM_R 0x0008 | |
82 | #define COMM_IM 0x0001 | |
83 | ||
84 | #define COMM_PS 0x4000 | |
85 | #define COMM_PST 0x4000 | |
86 | #define COMM_CIB 0x4000 | |
87 | #define COMM_RTS 0x4000 | |
88 | #define COMM_DT 0x2000 | |
89 | #define COMM_SPU 0x1000 | |
90 | #define COMM_F 0x0800 | |
19e7184f | 91 | #define COMM_NTF 0x0400 |
81f6075e EP |
92 | #define COMM_ICP 0x0200 |
93 | #define COMM_RST 0x0100 | |
94 | ||
95 | #define PULSE_PROG 0x01 | |
96 | #define PULSE_SPUE 0x02 | |
97 | ||
98 | #define BRANCH_MAIN 0xCC | |
99 | #define BRANCH_AUX 0x33 | |
100 | ||
81f6075e EP |
101 | /* Status flags */ |
102 | #define ST_SPUA 0x01 /* Strong Pull-up is active */ | |
103 | #define ST_PRGA 0x02 /* 12V programming pulse is being generated */ | |
104 | #define ST_12VP 0x04 /* external 12V programming voltage is present */ | |
105 | #define ST_PMOD 0x08 /* DS2490 powered from USB and external sources */ | |
106 | #define ST_HALT 0x10 /* DS2490 is currently halted */ | |
107 | #define ST_IDLE 0x20 /* DS2490 is currently idle */ | |
108 | #define ST_EPOF 0x80 | |
109 | ||
4b9cf1bc DF |
110 | /* Result Register flags */ |
111 | #define RR_DETECT 0xA5 /* New device detected */ | |
112 | #define RR_NRS 0x01 /* Reset no presence or ... */ | |
113 | #define RR_SH 0x02 /* short on reset or set path */ | |
114 | #define RR_APP 0x04 /* alarming presence on reset */ | |
115 | #define RR_VPP 0x08 /* 12V expected not seen */ | |
116 | #define RR_CMP 0x10 /* compare error */ | |
117 | #define RR_CRC 0x20 /* CRC error detected */ | |
118 | #define RR_RDP 0x40 /* redirected page */ | |
119 | #define RR_EOS 0x80 /* end of search error */ | |
120 | ||
81f6075e EP |
121 | #define SPEED_NORMAL 0x00 |
122 | #define SPEED_FLEXIBLE 0x01 | |
123 | #define SPEED_OVERDRIVE 0x02 | |
124 | ||
125 | #define NUM_EP 4 | |
126 | #define EP_CONTROL 0 | |
127 | #define EP_STATUS 1 | |
128 | #define EP_DATA_OUT 2 | |
129 | #define EP_DATA_IN 3 | |
130 | ||
131 | struct ds_device | |
132 | { | |
133 | struct list_head ds_entry; | |
134 | ||
135 | struct usb_device *udev; | |
136 | struct usb_interface *intf; | |
137 | ||
138 | int ep[NUM_EP]; | |
139 | ||
1f4ec2d7 DF |
140 | /* Strong PullUp |
141 | * 0: pullup not active, else duration in milliseconds | |
142 | */ | |
143 | int spu_sleep; | |
144 | ||
81f6075e EP |
145 | struct w1_bus_master master; |
146 | }; | |
147 | ||
148 | struct ds_status | |
149 | { | |
150 | u8 enable; | |
151 | u8 speed; | |
152 | u8 pullup_dur; | |
153 | u8 ppuls_dur; | |
154 | u8 pulldown_slew; | |
155 | u8 write1_time; | |
156 | u8 write0_time; | |
157 | u8 reserved0; | |
158 | u8 status; | |
159 | u8 command0; | |
160 | u8 command1; | |
161 | u8 command_buffer_status; | |
162 | u8 data_out_buffer_status; | |
163 | u8 data_in_buffer_status; | |
164 | u8 reserved1; | |
165 | u8 reserved2; | |
166 | ||
167 | }; | |
1da177e4 LT |
168 | |
169 | static struct usb_device_id ds_id_table [] = { | |
170 | { USB_DEVICE(0x04fa, 0x2490) }, | |
171 | { }, | |
172 | }; | |
173 | MODULE_DEVICE_TABLE(usb, ds_id_table); | |
174 | ||
8949d2aa EP |
175 | static int ds_probe(struct usb_interface *, const struct usb_device_id *); |
176 | static void ds_disconnect(struct usb_interface *); | |
1da177e4 | 177 | |
1da177e4 | 178 | static int ds_send_control(struct ds_device *, u16, u16); |
1da177e4 LT |
179 | static int ds_send_control_cmd(struct ds_device *, u16, u16); |
180 | ||
81f6075e | 181 | static LIST_HEAD(ds_devices); |
abd52a13 | 182 | static DEFINE_MUTEX(ds_mutex); |
1da177e4 LT |
183 | |
184 | static struct usb_driver ds_driver = { | |
1da177e4 LT |
185 | .name = "DS9490R", |
186 | .probe = ds_probe, | |
187 | .disconnect = ds_disconnect, | |
188 | .id_table = ds_id_table, | |
189 | }; | |
190 | ||
1da177e4 LT |
191 | static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) |
192 | { | |
193 | int err; | |
8949d2aa EP |
194 | |
195 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | |
1da177e4 LT |
196 | CONTROL_CMD, 0x40, value, index, NULL, 0, 1000); |
197 | if (err < 0) { | |
8949d2aa | 198 | printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", |
1da177e4 LT |
199 | value, index, err); |
200 | return err; | |
201 | } | |
202 | ||
203 | return err; | |
204 | } | |
1f4ec2d7 | 205 | |
1da177e4 LT |
206 | static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) |
207 | { | |
208 | int err; | |
8949d2aa EP |
209 | |
210 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | |
1da177e4 LT |
211 | MODE_CMD, 0x40, value, index, NULL, 0, 1000); |
212 | if (err < 0) { | |
8949d2aa | 213 | printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", |
1da177e4 LT |
214 | value, index, err); |
215 | return err; | |
216 | } | |
217 | ||
218 | return err; | |
219 | } | |
1f4ec2d7 | 220 | |
1da177e4 LT |
221 | static int ds_send_control(struct ds_device *dev, u16 value, u16 index) |
222 | { | |
223 | int err; | |
8949d2aa EP |
224 | |
225 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | |
1da177e4 LT |
226 | COMM_CMD, 0x40, value, index, NULL, 0, 1000); |
227 | if (err < 0) { | |
8949d2aa | 228 | printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", |
1da177e4 LT |
229 | value, index, err); |
230 | return err; | |
231 | } | |
232 | ||
233 | return err; | |
234 | } | |
235 | ||
8949d2aa EP |
236 | static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, |
237 | unsigned char *buf, int size) | |
1da177e4 LT |
238 | { |
239 | int count, err; | |
8949d2aa | 240 | |
e9b5a495 | 241 | memset(st, 0, sizeof(*st)); |
8949d2aa | 242 | |
1da177e4 LT |
243 | count = 0; |
244 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); | |
245 | if (err < 0) { | |
246 | printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); | |
247 | return err; | |
248 | } | |
8949d2aa | 249 | |
1da177e4 LT |
250 | if (count >= sizeof(*st)) |
251 | memcpy(st, buf, sizeof(*st)); | |
252 | ||
253 | return count; | |
254 | } | |
255 | ||
4b9cf1bc | 256 | static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off) |
1da177e4 | 257 | { |
4b9cf1bc DF |
258 | printk(KERN_INFO "%45s: %8x\n", str, buf[off]); |
259 | } | |
8949d2aa | 260 | |
4b9cf1bc DF |
261 | static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count) |
262 | { | |
263 | int i; | |
8949d2aa | 264 | |
4b9cf1bc | 265 | printk(KERN_INFO "0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); |
1da177e4 LT |
266 | for (i=0; i<count; ++i) |
267 | printk("%02x ", buf[i]); | |
4b9cf1bc | 268 | printk(KERN_INFO "\n"); |
1da177e4 LT |
269 | |
270 | if (count >= 16) { | |
4b9cf1bc DF |
271 | ds_print_msg(buf, "enable flag", 0); |
272 | ds_print_msg(buf, "1-wire speed", 1); | |
273 | ds_print_msg(buf, "strong pullup duration", 2); | |
274 | ds_print_msg(buf, "programming pulse duration", 3); | |
275 | ds_print_msg(buf, "pulldown slew rate control", 4); | |
276 | ds_print_msg(buf, "write-1 low time", 5); | |
277 | ds_print_msg(buf, "data sample offset/write-0 recovery time", | |
278 | 6); | |
279 | ds_print_msg(buf, "reserved (test register)", 7); | |
280 | ds_print_msg(buf, "device status flags", 8); | |
281 | ds_print_msg(buf, "communication command byte 1", 9); | |
282 | ds_print_msg(buf, "communication command byte 2", 10); | |
283 | ds_print_msg(buf, "communication command buffer status", 11); | |
284 | ds_print_msg(buf, "1-wire data output buffer status", 12); | |
285 | ds_print_msg(buf, "1-wire data input buffer status", 13); | |
286 | ds_print_msg(buf, "reserved", 14); | |
287 | ds_print_msg(buf, "reserved", 15); | |
1da177e4 | 288 | } |
4b9cf1bc DF |
289 | for (i = 16; i < count; ++i) { |
290 | if (buf[i] == RR_DETECT) { | |
291 | ds_print_msg(buf, "new device detect", i); | |
292 | continue; | |
293 | } | |
294 | ds_print_msg(buf, "Result Register Value: ", i); | |
295 | if (buf[i] & RR_NRS) | |
296 | printk(KERN_INFO "NRS: Reset no presence or ...\n"); | |
297 | if (buf[i] & RR_SH) | |
298 | printk(KERN_INFO "SH: short on reset or set path\n"); | |
299 | if (buf[i] & RR_APP) | |
300 | printk(KERN_INFO "APP: alarming presence on reset\n"); | |
301 | if (buf[i] & RR_VPP) | |
302 | printk(KERN_INFO "VPP: 12V expected not seen\n"); | |
303 | if (buf[i] & RR_CMP) | |
304 | printk(KERN_INFO "CMP: compare error\n"); | |
305 | if (buf[i] & RR_CRC) | |
306 | printk(KERN_INFO "CRC: CRC error detected\n"); | |
307 | if (buf[i] & RR_RDP) | |
308 | printk(KERN_INFO "RDP: redirected page\n"); | |
309 | if (buf[i] & RR_EOS) | |
310 | printk(KERN_INFO "EOS: end of search error\n"); | |
1da177e4 | 311 | } |
1da177e4 LT |
312 | } |
313 | ||
314 | static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) | |
315 | { | |
316 | int count, err; | |
317 | struct ds_status st; | |
8949d2aa | 318 | |
e464af24 DF |
319 | /* Careful on size. If size is less than what is available in |
320 | * the input buffer, the device fails the bulk transfer and | |
321 | * clears the input buffer. It could read the maximum size of | |
322 | * the data buffer, but then do you return the first, last, or | |
323 | * some set of the middle size bytes? As long as the rest of | |
324 | * the code is correct there will be size bytes waiting. A | |
325 | * call to ds_wait_status will wait until the device is idle | |
326 | * and any data to be received would have been available. | |
327 | */ | |
1da177e4 | 328 | count = 0; |
8949d2aa | 329 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), |
1da177e4 LT |
330 | buf, size, &count, 1000); |
331 | if (err < 0) { | |
4b9cf1bc DF |
332 | u8 buf[0x20]; |
333 | int count; | |
334 | ||
1da177e4 LT |
335 | printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); |
336 | usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); | |
4b9cf1bc DF |
337 | |
338 | count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); | |
339 | ds_dump_status(dev, buf, count); | |
1da177e4 LT |
340 | return err; |
341 | } | |
342 | ||
343 | #if 0 | |
344 | { | |
345 | int i; | |
346 | ||
347 | printk("%s: count=%d: ", __func__, count); | |
348 | for (i=0; i<count; ++i) | |
349 | printk("%02x ", buf[i]); | |
350 | printk("\n"); | |
351 | } | |
352 | #endif | |
353 | return count; | |
354 | } | |
355 | ||
356 | static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len) | |
357 | { | |
358 | int count, err; | |
8949d2aa | 359 | |
1da177e4 LT |
360 | count = 0; |
361 | err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000); | |
362 | if (err < 0) { | |
95cfaebf DF |
363 | printk(KERN_ERR "Failed to write 1-wire data to ep0x%x: " |
364 | "err=%d.\n", dev->ep[EP_DATA_OUT], err); | |
1da177e4 LT |
365 | return err; |
366 | } | |
367 | ||
368 | return err; | |
369 | } | |
370 | ||
8949d2aa EP |
371 | #if 0 |
372 | ||
1da177e4 LT |
373 | int ds_stop_pulse(struct ds_device *dev, int limit) |
374 | { | |
375 | struct ds_status st; | |
376 | int count = 0, err = 0; | |
377 | u8 buf[0x20]; | |
8949d2aa | 378 | |
1da177e4 LT |
379 | do { |
380 | err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); | |
381 | if (err) | |
382 | break; | |
383 | err = ds_send_control(dev, CTL_RESUME_EXE, 0); | |
384 | if (err) | |
385 | break; | |
386 | err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); | |
387 | if (err) | |
388 | break; | |
389 | ||
390 | if ((st.status & ST_SPUA) == 0) { | |
391 | err = ds_send_control_mode(dev, MOD_PULSE_EN, 0); | |
392 | if (err) | |
393 | break; | |
394 | } | |
395 | } while(++count < limit); | |
396 | ||
397 | return err; | |
398 | } | |
399 | ||
400 | int ds_detect(struct ds_device *dev, struct ds_status *st) | |
401 | { | |
402 | int err; | |
8949d2aa | 403 | |
1da177e4 LT |
404 | err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); |
405 | if (err) | |
406 | return err; | |
407 | ||
408 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0); | |
409 | if (err) | |
410 | return err; | |
8949d2aa | 411 | |
1da177e4 LT |
412 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40); |
413 | if (err) | |
414 | return err; | |
8949d2aa | 415 | |
1da177e4 LT |
416 | err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG); |
417 | if (err) | |
418 | return err; | |
419 | ||
4b9cf1bc | 420 | err = ds_dump_status(dev, st); |
1da177e4 LT |
421 | |
422 | return err; | |
423 | } | |
424 | ||
8949d2aa EP |
425 | #endif /* 0 */ |
426 | ||
427 | static int ds_wait_status(struct ds_device *dev, struct ds_status *st) | |
1da177e4 LT |
428 | { |
429 | u8 buf[0x20]; | |
430 | int err, count = 0; | |
431 | ||
432 | do { | |
433 | err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | |
434 | #if 0 | |
8949d2aa | 435 | if (err >= 0) { |
1da177e4 LT |
436 | int i; |
437 | printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); | |
438 | for (i=0; i<err; ++i) | |
439 | printk("%02x ", buf[i]); | |
440 | printk("\n"); | |
441 | } | |
442 | #endif | |
19e7184f | 443 | } while (!(buf[0x08] & ST_IDLE) && !(err < 0) && ++count < 100); |
1da177e4 | 444 | |
4b9cf1bc DF |
445 | if (err >= 16 && st->status & ST_EPOF) { |
446 | printk(KERN_INFO "Resetting device after ST_EPOF.\n"); | |
447 | ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); | |
448 | /* Always dump the device status. */ | |
449 | count = 101; | |
450 | } | |
1da177e4 | 451 | |
4b9cf1bc DF |
452 | /* Dump the status for errors or if there is extended return data. |
453 | * The extended status includes new device detection (maybe someone | |
454 | * can do something with it). | |
455 | */ | |
456 | if (err > 16 || count >= 100 || err < 0) | |
457 | ds_dump_status(dev, buf, err); | |
458 | ||
459 | /* Extended data isn't an error. Well, a short is, but the dump | |
460 | * would have already told the user that and we can't do anything | |
461 | * about it in software anyway. | |
462 | */ | |
463 | if (count >= 100 || err < 0) | |
1da177e4 | 464 | return -1; |
4b9cf1bc | 465 | else |
1da177e4 | 466 | return 0; |
1da177e4 LT |
467 | } |
468 | ||
7a4b9706 | 469 | static int ds_reset(struct ds_device *dev) |
1da177e4 LT |
470 | { |
471 | int err; | |
472 | ||
19e7184f DF |
473 | /* Other potentionally interesting flags for reset. |
474 | * | |
475 | * COMM_NTF: Return result register feedback. This could be used to | |
476 | * detect some conditions such as short, alarming presence, or | |
477 | * detect if a new device was detected. | |
478 | * | |
479 | * COMM_SE which allows SPEED_NORMAL, SPEED_FLEXIBLE, SPEED_OVERDRIVE: | |
480 | * Select the data transfer rate. | |
481 | */ | |
482 | err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL); | |
1da177e4 LT |
483 | if (err) |
484 | return err; | |
485 | ||
1da177e4 LT |
486 | return 0; |
487 | } | |
488 | ||
8949d2aa | 489 | #if 0 |
81f6075e | 490 | static int ds_set_speed(struct ds_device *dev, int speed) |
1da177e4 LT |
491 | { |
492 | int err; | |
bd529cfb | 493 | |
1da177e4 LT |
494 | if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE) |
495 | return -EINVAL; | |
496 | ||
497 | if (speed != SPEED_OVERDRIVE) | |
498 | speed = SPEED_FLEXIBLE; | |
499 | ||
500 | speed &= 0xff; | |
8949d2aa | 501 | |
1da177e4 LT |
502 | err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed); |
503 | if (err) | |
504 | return err; | |
505 | ||
506 | return err; | |
507 | } | |
8949d2aa | 508 | #endif /* 0 */ |
1da177e4 | 509 | |
1f4ec2d7 | 510 | static int ds_set_pullup(struct ds_device *dev, int delay) |
1da177e4 LT |
511 | { |
512 | int err; | |
513 | u8 del = 1 + (u8)(delay >> 4); | |
1da177e4 | 514 | |
1f4ec2d7 DF |
515 | dev->spu_sleep = 0; |
516 | err = ds_send_control_mode(dev, MOD_PULSE_EN, delay ? PULSE_SPUE : 0); | |
1da177e4 LT |
517 | if (err) |
518 | return err; | |
519 | ||
1f4ec2d7 DF |
520 | if (delay) { |
521 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); | |
522 | if (err) | |
523 | return err; | |
1da177e4 | 524 | |
1f4ec2d7 DF |
525 | /* Just storing delay would not get the trunication and |
526 | * roundup. | |
527 | */ | |
528 | dev->spu_sleep = del<<4; | |
529 | } | |
8949d2aa | 530 | |
1da177e4 LT |
531 | return err; |
532 | } | |
533 | ||
81f6075e | 534 | static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) |
1da177e4 | 535 | { |
6e10f654 | 536 | int err; |
1da177e4 | 537 | struct ds_status st; |
8949d2aa | 538 | |
6e10f654 DF |
539 | err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit ? COMM_D : 0), |
540 | 0); | |
1da177e4 LT |
541 | if (err) |
542 | return err; | |
543 | ||
6e10f654 | 544 | ds_wait_status(dev, &st); |
1da177e4 LT |
545 | |
546 | err = ds_recv_data(dev, tbit, sizeof(*tbit)); | |
547 | if (err < 0) | |
548 | return err; | |
549 | ||
550 | return 0; | |
551 | } | |
552 | ||
a08e2d33 | 553 | #if 0 |
81f6075e | 554 | static int ds_write_bit(struct ds_device *dev, u8 bit) |
1da177e4 LT |
555 | { |
556 | int err; | |
557 | struct ds_status st; | |
8949d2aa | 558 | |
e1c86d22 DF |
559 | /* Set COMM_ICP to write without a readback. Note, this will |
560 | * produce one time slot, a down followed by an up with COMM_D | |
561 | * only determing the timing. | |
562 | */ | |
563 | err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_ICP | | |
564 | (bit ? COMM_D : 0), 0); | |
1da177e4 LT |
565 | if (err) |
566 | return err; | |
567 | ||
568 | ds_wait_status(dev, &st); | |
569 | ||
570 | return 0; | |
571 | } | |
a08e2d33 | 572 | #endif |
1da177e4 | 573 | |
81f6075e | 574 | static int ds_write_byte(struct ds_device *dev, u8 byte) |
1da177e4 LT |
575 | { |
576 | int err; | |
577 | struct ds_status st; | |
578 | u8 rbyte; | |
8949d2aa | 579 | |
1da177e4 LT |
580 | err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); |
581 | if (err) | |
582 | return err; | |
583 | ||
1f4ec2d7 DF |
584 | if (dev->spu_sleep) |
585 | msleep(dev->spu_sleep); | |
586 | ||
1da177e4 LT |
587 | err = ds_wait_status(dev, &st); |
588 | if (err) | |
589 | return err; | |
8949d2aa | 590 | |
1da177e4 LT |
591 | err = ds_recv_data(dev, &rbyte, sizeof(rbyte)); |
592 | if (err < 0) | |
593 | return err; | |
8949d2aa | 594 | |
1da177e4 LT |
595 | return !(byte == rbyte); |
596 | } | |
597 | ||
81f6075e | 598 | static int ds_read_byte(struct ds_device *dev, u8 *byte) |
1da177e4 LT |
599 | { |
600 | int err; | |
601 | struct ds_status st; | |
602 | ||
603 | err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM , 0xff); | |
604 | if (err) | |
605 | return err; | |
606 | ||
607 | ds_wait_status(dev, &st); | |
8949d2aa | 608 | |
1da177e4 LT |
609 | err = ds_recv_data(dev, byte, sizeof(*byte)); |
610 | if (err < 0) | |
611 | return err; | |
612 | ||
613 | return 0; | |
614 | } | |
615 | ||
81f6075e | 616 | static int ds_read_block(struct ds_device *dev, u8 *buf, int len) |
1da177e4 LT |
617 | { |
618 | struct ds_status st; | |
619 | int err; | |
620 | ||
621 | if (len > 64*1024) | |
622 | return -E2BIG; | |
623 | ||
624 | memset(buf, 0xFF, len); | |
8949d2aa | 625 | |
1da177e4 LT |
626 | err = ds_send_data(dev, buf, len); |
627 | if (err < 0) | |
628 | return err; | |
8949d2aa | 629 | |
1f4ec2d7 | 630 | err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM, len); |
1da177e4 LT |
631 | if (err) |
632 | return err; | |
633 | ||
634 | ds_wait_status(dev, &st); | |
8949d2aa | 635 | |
1da177e4 LT |
636 | memset(buf, 0x00, len); |
637 | err = ds_recv_data(dev, buf, len); | |
638 | ||
639 | return err; | |
640 | } | |
641 | ||
81f6075e | 642 | static int ds_write_block(struct ds_device *dev, u8 *buf, int len) |
1da177e4 LT |
643 | { |
644 | int err; | |
645 | struct ds_status st; | |
8949d2aa | 646 | |
1da177e4 LT |
647 | err = ds_send_data(dev, buf, len); |
648 | if (err < 0) | |
649 | return err; | |
8949d2aa | 650 | |
1da177e4 LT |
651 | ds_wait_status(dev, &st); |
652 | ||
653 | err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); | |
654 | if (err) | |
655 | return err; | |
656 | ||
1f4ec2d7 DF |
657 | if (dev->spu_sleep) |
658 | msleep(dev->spu_sleep); | |
659 | ||
1da177e4 LT |
660 | ds_wait_status(dev, &st); |
661 | ||
662 | err = ds_recv_data(dev, buf, len); | |
663 | if (err < 0) | |
664 | return err; | |
665 | ||
1da177e4 LT |
666 | return !(err == len); |
667 | } | |
668 | ||
8949d2aa EP |
669 | #if 0 |
670 | ||
81f6075e | 671 | static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) |
1da177e4 LT |
672 | { |
673 | int err; | |
674 | u16 value, index; | |
675 | struct ds_status st; | |
676 | ||
677 | memset(buf, 0, sizeof(buf)); | |
8949d2aa | 678 | |
1da177e4 LT |
679 | err = ds_send_data(ds_dev, (unsigned char *)&init, 8); |
680 | if (err) | |
681 | return err; | |
8949d2aa | 682 | |
1da177e4 LT |
683 | ds_wait_status(ds_dev, &st); |
684 | ||
685 | value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; | |
686 | index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); | |
687 | err = ds_send_control(ds_dev, value, index); | |
688 | if (err) | |
689 | return err; | |
690 | ||
691 | ds_wait_status(ds_dev, &st); | |
692 | ||
693 | err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); | |
694 | if (err < 0) | |
695 | return err; | |
696 | ||
697 | return err/8; | |
698 | } | |
699 | ||
81f6075e | 700 | static int ds_match_access(struct ds_device *dev, u64 init) |
1da177e4 LT |
701 | { |
702 | int err; | |
703 | struct ds_status st; | |
704 | ||
705 | err = ds_send_data(dev, (unsigned char *)&init, sizeof(init)); | |
706 | if (err) | |
707 | return err; | |
8949d2aa | 708 | |
1da177e4 LT |
709 | ds_wait_status(dev, &st); |
710 | ||
711 | err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055); | |
712 | if (err) | |
713 | return err; | |
714 | ||
715 | ds_wait_status(dev, &st); | |
716 | ||
717 | return 0; | |
718 | } | |
719 | ||
81f6075e | 720 | static int ds_set_path(struct ds_device *dev, u64 init) |
1da177e4 LT |
721 | { |
722 | int err; | |
723 | struct ds_status st; | |
724 | u8 buf[9]; | |
725 | ||
726 | memcpy(buf, &init, 8); | |
727 | buf[8] = BRANCH_MAIN; | |
8949d2aa | 728 | |
1da177e4 LT |
729 | err = ds_send_data(dev, buf, sizeof(buf)); |
730 | if (err) | |
731 | return err; | |
8949d2aa | 732 | |
1da177e4 LT |
733 | ds_wait_status(dev, &st); |
734 | ||
735 | err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0); | |
736 | if (err) | |
737 | return err; | |
738 | ||
739 | ds_wait_status(dev, &st); | |
740 | ||
741 | return 0; | |
742 | } | |
743 | ||
8949d2aa EP |
744 | #endif /* 0 */ |
745 | ||
81f6075e EP |
746 | static u8 ds9490r_touch_bit(void *data, u8 bit) |
747 | { | |
748 | u8 ret; | |
749 | struct ds_device *dev = data; | |
750 | ||
751 | if (ds_touch_bit(dev, bit, &ret)) | |
752 | return 0; | |
753 | ||
754 | return ret; | |
755 | } | |
756 | ||
a08e2d33 | 757 | #if 0 |
81f6075e EP |
758 | static void ds9490r_write_bit(void *data, u8 bit) |
759 | { | |
760 | struct ds_device *dev = data; | |
761 | ||
762 | ds_write_bit(dev, bit); | |
763 | } | |
764 | ||
81f6075e EP |
765 | static u8 ds9490r_read_bit(void *data) |
766 | { | |
767 | struct ds_device *dev = data; | |
768 | int err; | |
769 | u8 bit = 0; | |
770 | ||
771 | err = ds_touch_bit(dev, 1, &bit); | |
772 | if (err) | |
773 | return 0; | |
774 | ||
775 | return bit & 1; | |
776 | } | |
a08e2d33 DF |
777 | #endif |
778 | ||
779 | static void ds9490r_write_byte(void *data, u8 byte) | |
780 | { | |
781 | struct ds_device *dev = data; | |
782 | ||
783 | ds_write_byte(dev, byte); | |
784 | } | |
81f6075e EP |
785 | |
786 | static u8 ds9490r_read_byte(void *data) | |
787 | { | |
788 | struct ds_device *dev = data; | |
789 | int err; | |
790 | u8 byte = 0; | |
791 | ||
792 | err = ds_read_byte(dev, &byte); | |
793 | if (err) | |
794 | return 0; | |
795 | ||
796 | return byte; | |
797 | } | |
798 | ||
799 | static void ds9490r_write_block(void *data, const u8 *buf, int len) | |
800 | { | |
801 | struct ds_device *dev = data; | |
802 | ||
803 | ds_write_block(dev, (u8 *)buf, len); | |
804 | } | |
805 | ||
806 | static u8 ds9490r_read_block(void *data, u8 *buf, int len) | |
807 | { | |
808 | struct ds_device *dev = data; | |
809 | int err; | |
810 | ||
811 | err = ds_read_block(dev, buf, len); | |
812 | if (err < 0) | |
813 | return 0; | |
814 | ||
815 | return len; | |
816 | } | |
817 | ||
818 | static u8 ds9490r_reset(void *data) | |
819 | { | |
820 | struct ds_device *dev = data; | |
81f6075e EP |
821 | int err; |
822 | ||
7a4b9706 | 823 | err = ds_reset(dev); |
81f6075e EP |
824 | if (err) |
825 | return 1; | |
826 | ||
827 | return 0; | |
828 | } | |
829 | ||
1f4ec2d7 DF |
830 | static u8 ds9490r_set_pullup(void *data, int delay) |
831 | { | |
832 | struct ds_device *dev = data; | |
833 | ||
834 | if (ds_set_pullup(dev, delay)) | |
835 | return 1; | |
836 | ||
837 | return 0; | |
838 | } | |
839 | ||
81f6075e EP |
840 | static int ds_w1_init(struct ds_device *dev) |
841 | { | |
842 | memset(&dev->master, 0, sizeof(struct w1_bus_master)); | |
843 | ||
e464af24 DF |
844 | /* Reset the device as it can be in a bad state. |
845 | * This is necessary because a block write will wait for data | |
846 | * to be placed in the output buffer and block any later | |
847 | * commands which will keep accumulating and the device will | |
848 | * not be idle. Another case is removing the ds2490 module | |
849 | * while a bus search is in progress, somehow a few commands | |
850 | * get through, but the input transfers fail leaving data in | |
851 | * the input buffer. This will cause the next read to fail | |
852 | * see the note in ds_recv_data. | |
853 | */ | |
854 | ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); | |
855 | ||
81f6075e EP |
856 | dev->master.data = dev; |
857 | dev->master.touch_bit = &ds9490r_touch_bit; | |
a08e2d33 DF |
858 | /* read_bit and write_bit in w1_bus_master are expected to set and |
859 | * sample the line level. For write_bit that means it is expected to | |
860 | * set it to that value and leave it there. ds2490 only supports an | |
861 | * individual time slot at the lowest level. The requirement from | |
862 | * pulling the bus state down to reading the state is 15us, something | |
863 | * that isn't realistic on the USB bus anyway. | |
81f6075e EP |
864 | dev->master.read_bit = &ds9490r_read_bit; |
865 | dev->master.write_bit = &ds9490r_write_bit; | |
a08e2d33 | 866 | */ |
81f6075e EP |
867 | dev->master.read_byte = &ds9490r_read_byte; |
868 | dev->master.write_byte = &ds9490r_write_byte; | |
869 | dev->master.read_block = &ds9490r_read_block; | |
870 | dev->master.write_block = &ds9490r_write_block; | |
871 | dev->master.reset_bus = &ds9490r_reset; | |
1f4ec2d7 | 872 | dev->master.set_pullup = &ds9490r_set_pullup; |
81f6075e EP |
873 | |
874 | return w1_add_master_device(&dev->master); | |
875 | } | |
876 | ||
877 | static void ds_w1_fini(struct ds_device *dev) | |
878 | { | |
879 | w1_remove_master_device(&dev->master); | |
880 | } | |
881 | ||
8949d2aa EP |
882 | static int ds_probe(struct usb_interface *intf, |
883 | const struct usb_device_id *udev_id) | |
1da177e4 LT |
884 | { |
885 | struct usb_device *udev = interface_to_usbdev(intf); | |
886 | struct usb_endpoint_descriptor *endpoint; | |
887 | struct usb_host_interface *iface_desc; | |
81f6075e | 888 | struct ds_device *dev; |
1da177e4 LT |
889 | int i, err; |
890 | ||
81f6075e EP |
891 | dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); |
892 | if (!dev) { | |
1da177e4 LT |
893 | printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); |
894 | return -ENOMEM; | |
895 | } | |
1f4ec2d7 | 896 | dev->spu_sleep = 0; |
81f6075e EP |
897 | dev->udev = usb_get_dev(udev); |
898 | if (!dev->udev) { | |
899 | err = -ENOMEM; | |
900 | goto err_out_free; | |
901 | } | |
902 | memset(dev->ep, 0, sizeof(dev->ep)); | |
1da177e4 | 903 | |
81f6075e | 904 | usb_set_intfdata(intf, dev); |
1da177e4 | 905 | |
81f6075e | 906 | err = usb_set_interface(dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); |
1da177e4 LT |
907 | if (err) { |
908 | printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", | |
909 | intf->altsetting[0].desc.bInterfaceNumber, err); | |
81f6075e | 910 | goto err_out_clear; |
1da177e4 LT |
911 | } |
912 | ||
81f6075e | 913 | err = usb_reset_configuration(dev->udev); |
1da177e4 LT |
914 | if (err) { |
915 | printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); | |
81f6075e | 916 | goto err_out_clear; |
1da177e4 | 917 | } |
8949d2aa | 918 | |
1da177e4 LT |
919 | iface_desc = &intf->altsetting[0]; |
920 | if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { | |
921 | printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); | |
81f6075e EP |
922 | err = -EINVAL; |
923 | goto err_out_clear; | |
1da177e4 LT |
924 | } |
925 | ||
1da177e4 | 926 | /* |
8949d2aa | 927 | * This loop doesn'd show control 0 endpoint, |
1da177e4 LT |
928 | * so we will fill only 1-3 endpoints entry. |
929 | */ | |
930 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | |
931 | endpoint = &iface_desc->endpoint[i].desc; | |
932 | ||
81f6075e EP |
933 | dev->ep[i+1] = endpoint->bEndpointAddress; |
934 | #if 0 | |
1da177e4 LT |
935 | printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", |
936 | i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), | |
937 | (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", | |
938 | endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | |
81f6075e | 939 | #endif |
1da177e4 | 940 | } |
8949d2aa | 941 | |
81f6075e EP |
942 | err = ds_w1_init(dev); |
943 | if (err) | |
944 | goto err_out_clear; | |
8949d2aa | 945 | |
abd52a13 | 946 | mutex_lock(&ds_mutex); |
81f6075e | 947 | list_add_tail(&dev->ds_entry, &ds_devices); |
abd52a13 | 948 | mutex_unlock(&ds_mutex); |
1da177e4 LT |
949 | |
950 | return 0; | |
81f6075e EP |
951 | |
952 | err_out_clear: | |
953 | usb_set_intfdata(intf, NULL); | |
954 | usb_put_dev(dev->udev); | |
955 | err_out_free: | |
956 | kfree(dev); | |
957 | return err; | |
1da177e4 LT |
958 | } |
959 | ||
8949d2aa | 960 | static void ds_disconnect(struct usb_interface *intf) |
1da177e4 LT |
961 | { |
962 | struct ds_device *dev; | |
8949d2aa | 963 | |
1da177e4 | 964 | dev = usb_get_intfdata(intf); |
81f6075e EP |
965 | if (!dev) |
966 | return; | |
1da177e4 | 967 | |
abd52a13 | 968 | mutex_lock(&ds_mutex); |
81f6075e | 969 | list_del(&dev->ds_entry); |
abd52a13 | 970 | mutex_unlock(&ds_mutex); |
1da177e4 | 971 | |
81f6075e EP |
972 | ds_w1_fini(dev); |
973 | ||
974 | usb_set_intfdata(intf, NULL); | |
1da177e4 LT |
975 | |
976 | usb_put_dev(dev->udev); | |
977 | kfree(dev); | |
1da177e4 LT |
978 | } |
979 | ||
8949d2aa | 980 | static int ds_init(void) |
1da177e4 LT |
981 | { |
982 | int err; | |
983 | ||
984 | err = usb_register(&ds_driver); | |
985 | if (err) { | |
986 | printk(KERN_INFO "Failed to register DS9490R USB device: err=%d.\n", err); | |
987 | return err; | |
988 | } | |
989 | ||
990 | return 0; | |
991 | } | |
992 | ||
8949d2aa | 993 | static void ds_fini(void) |
1da177e4 LT |
994 | { |
995 | usb_deregister(&ds_driver); | |
996 | } | |
997 | ||
998 | module_init(ds_init); | |
999 | module_exit(ds_fini); | |
1000 | ||
1001 | MODULE_LICENSE("GPL"); | |
1002 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | |
81f6075e | 1003 | MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)"); |