diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/w1/dscore.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/w1/dscore.c')
-rw-r--r-- | drivers/w1/dscore.c | 789 |
1 files changed, 789 insertions, 0 deletions
diff --git a/drivers/w1/dscore.c b/drivers/w1/dscore.c new file mode 100644 index 000000000000..eee6644d33d6 --- /dev/null +++ b/drivers/w1/dscore.c | |||
@@ -0,0 +1,789 @@ | |||
1 | /* | ||
2 | * dscore.c | ||
3 | * | ||
4 | * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> | ||
5 | * | ||
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 | |||
27 | #include "dscore.h" | ||
28 | |||
29 | static struct usb_device_id ds_id_table [] = { | ||
30 | { USB_DEVICE(0x04fa, 0x2490) }, | ||
31 | { }, | ||
32 | }; | ||
33 | MODULE_DEVICE_TABLE(usb, ds_id_table); | ||
34 | |||
35 | int ds_probe(struct usb_interface *, const struct usb_device_id *); | ||
36 | void ds_disconnect(struct usb_interface *); | ||
37 | |||
38 | int ds_touch_bit(struct ds_device *, u8, u8 *); | ||
39 | int ds_read_byte(struct ds_device *, u8 *); | ||
40 | int ds_read_bit(struct ds_device *, u8 *); | ||
41 | int ds_write_byte(struct ds_device *, u8); | ||
42 | int ds_write_bit(struct ds_device *, u8); | ||
43 | int ds_start_pulse(struct ds_device *, int); | ||
44 | int ds_set_speed(struct ds_device *, int); | ||
45 | int ds_reset(struct ds_device *, struct ds_status *); | ||
46 | int ds_detect(struct ds_device *, struct ds_status *); | ||
47 | int ds_stop_pulse(struct ds_device *, int); | ||
48 | struct ds_device * ds_get_device(void); | ||
49 | void ds_put_device(struct ds_device *); | ||
50 | |||
51 | static inline void ds_dump_status(unsigned char *, unsigned char *, int); | ||
52 | static int ds_send_control(struct ds_device *, u16, u16); | ||
53 | static int ds_send_control_mode(struct ds_device *, u16, u16); | ||
54 | static int ds_send_control_cmd(struct ds_device *, u16, u16); | ||
55 | |||
56 | |||
57 | static struct usb_driver ds_driver = { | ||
58 | .owner = THIS_MODULE, | ||
59 | .name = "DS9490R", | ||
60 | .probe = ds_probe, | ||
61 | .disconnect = ds_disconnect, | ||
62 | .id_table = ds_id_table, | ||
63 | }; | ||
64 | |||
65 | static struct ds_device *ds_dev; | ||
66 | |||
67 | struct ds_device * ds_get_device(void) | ||
68 | { | ||
69 | if (ds_dev) | ||
70 | atomic_inc(&ds_dev->refcnt); | ||
71 | return ds_dev; | ||
72 | } | ||
73 | |||
74 | void ds_put_device(struct ds_device *dev) | ||
75 | { | ||
76 | atomic_dec(&dev->refcnt); | ||
77 | } | ||
78 | |||
79 | static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) | ||
80 | { | ||
81 | int err; | ||
82 | |||
83 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | ||
84 | CONTROL_CMD, 0x40, value, index, NULL, 0, 1000); | ||
85 | if (err < 0) { | ||
86 | printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", | ||
87 | value, index, err); | ||
88 | return err; | ||
89 | } | ||
90 | |||
91 | return err; | ||
92 | } | ||
93 | |||
94 | static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) | ||
95 | { | ||
96 | int err; | ||
97 | |||
98 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | ||
99 | MODE_CMD, 0x40, value, index, NULL, 0, 1000); | ||
100 | if (err < 0) { | ||
101 | printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", | ||
102 | value, index, err); | ||
103 | return err; | ||
104 | } | ||
105 | |||
106 | return err; | ||
107 | } | ||
108 | |||
109 | static int ds_send_control(struct ds_device *dev, u16 value, u16 index) | ||
110 | { | ||
111 | int err; | ||
112 | |||
113 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | ||
114 | COMM_CMD, 0x40, value, index, NULL, 0, 1000); | ||
115 | if (err < 0) { | ||
116 | printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", | ||
117 | value, index, err); | ||
118 | return err; | ||
119 | } | ||
120 | |||
121 | return err; | ||
122 | } | ||
123 | |||
124 | static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off) | ||
125 | { | ||
126 | printk("%45s: %8x\n", str, buf[off]); | ||
127 | } | ||
128 | |||
129 | int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, unsigned char *buf, int size) | ||
130 | { | ||
131 | int count, err; | ||
132 | |||
133 | memset(st, 0, sizeof(st)); | ||
134 | |||
135 | count = 0; | ||
136 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); | ||
137 | if (err < 0) { | ||
138 | printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); | ||
139 | return err; | ||
140 | } | ||
141 | |||
142 | if (count >= sizeof(*st)) | ||
143 | memcpy(st, buf, sizeof(*st)); | ||
144 | |||
145 | return count; | ||
146 | } | ||
147 | |||
148 | static int ds_recv_status(struct ds_device *dev, struct ds_status *st) | ||
149 | { | ||
150 | unsigned char buf[64]; | ||
151 | int count, err = 0, i; | ||
152 | |||
153 | memcpy(st, buf, sizeof(*st)); | ||
154 | |||
155 | count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | ||
156 | if (count < 0) | ||
157 | return err; | ||
158 | |||
159 | printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); | ||
160 | for (i=0; i<count; ++i) | ||
161 | printk("%02x ", buf[i]); | ||
162 | printk("\n"); | ||
163 | |||
164 | if (count >= 16) { | ||
165 | ds_dump_status(buf, "enable flag", 0); | ||
166 | ds_dump_status(buf, "1-wire speed", 1); | ||
167 | ds_dump_status(buf, "strong pullup duration", 2); | ||
168 | ds_dump_status(buf, "programming pulse duration", 3); | ||
169 | ds_dump_status(buf, "pulldown slew rate control", 4); | ||
170 | ds_dump_status(buf, "write-1 low time", 5); | ||
171 | ds_dump_status(buf, "data sample offset/write-0 recovery time", 6); | ||
172 | ds_dump_status(buf, "reserved (test register)", 7); | ||
173 | ds_dump_status(buf, "device status flags", 8); | ||
174 | ds_dump_status(buf, "communication command byte 1", 9); | ||
175 | ds_dump_status(buf, "communication command byte 2", 10); | ||
176 | ds_dump_status(buf, "communication command buffer status", 11); | ||
177 | ds_dump_status(buf, "1-wire data output buffer status", 12); | ||
178 | ds_dump_status(buf, "1-wire data input buffer status", 13); | ||
179 | ds_dump_status(buf, "reserved", 14); | ||
180 | ds_dump_status(buf, "reserved", 15); | ||
181 | } | ||
182 | |||
183 | memcpy(st, buf, sizeof(*st)); | ||
184 | |||
185 | if (st->status & ST_EPOF) { | ||
186 | printk(KERN_INFO "Resetting device after ST_EPOF.\n"); | ||
187 | err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); | ||
188 | if (err) | ||
189 | return err; | ||
190 | count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | ||
191 | if (count < 0) | ||
192 | return err; | ||
193 | } | ||
194 | #if 0 | ||
195 | if (st->status & ST_IDLE) { | ||
196 | printk(KERN_INFO "Resetting pulse after ST_IDLE.\n"); | ||
197 | err = ds_start_pulse(dev, PULLUP_PULSE_DURATION); | ||
198 | if (err) | ||
199 | return err; | ||
200 | } | ||
201 | #endif | ||
202 | |||
203 | return err; | ||
204 | } | ||
205 | |||
206 | static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) | ||
207 | { | ||
208 | int count, err; | ||
209 | struct ds_status st; | ||
210 | |||
211 | count = 0; | ||
212 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), | ||
213 | buf, size, &count, 1000); | ||
214 | if (err < 0) { | ||
215 | printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); | ||
216 | usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); | ||
217 | ds_recv_status(dev, &st); | ||
218 | return err; | ||
219 | } | ||
220 | |||
221 | #if 0 | ||
222 | { | ||
223 | int i; | ||
224 | |||
225 | printk("%s: count=%d: ", __func__, count); | ||
226 | for (i=0; i<count; ++i) | ||
227 | printk("%02x ", buf[i]); | ||
228 | printk("\n"); | ||
229 | } | ||
230 | #endif | ||
231 | return count; | ||
232 | } | ||
233 | |||
234 | static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len) | ||
235 | { | ||
236 | int count, err; | ||
237 | |||
238 | count = 0; | ||
239 | err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000); | ||
240 | if (err < 0) { | ||
241 | printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err); | ||
242 | return err; | ||
243 | } | ||
244 | |||
245 | return err; | ||
246 | } | ||
247 | |||
248 | int ds_stop_pulse(struct ds_device *dev, int limit) | ||
249 | { | ||
250 | struct ds_status st; | ||
251 | int count = 0, err = 0; | ||
252 | u8 buf[0x20]; | ||
253 | |||
254 | do { | ||
255 | err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); | ||
256 | if (err) | ||
257 | break; | ||
258 | err = ds_send_control(dev, CTL_RESUME_EXE, 0); | ||
259 | if (err) | ||
260 | break; | ||
261 | err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); | ||
262 | if (err) | ||
263 | break; | ||
264 | |||
265 | if ((st.status & ST_SPUA) == 0) { | ||
266 | err = ds_send_control_mode(dev, MOD_PULSE_EN, 0); | ||
267 | if (err) | ||
268 | break; | ||
269 | } | ||
270 | } while(++count < limit); | ||
271 | |||
272 | return err; | ||
273 | } | ||
274 | |||
275 | int ds_detect(struct ds_device *dev, struct ds_status *st) | ||
276 | { | ||
277 | int err; | ||
278 | |||
279 | err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); | ||
280 | if (err) | ||
281 | return err; | ||
282 | |||
283 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0); | ||
284 | if (err) | ||
285 | return err; | ||
286 | |||
287 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40); | ||
288 | if (err) | ||
289 | return err; | ||
290 | |||
291 | err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG); | ||
292 | if (err) | ||
293 | return err; | ||
294 | |||
295 | err = ds_recv_status(dev, st); | ||
296 | |||
297 | return err; | ||
298 | } | ||
299 | |||
300 | int ds_wait_status(struct ds_device *dev, struct ds_status *st) | ||
301 | { | ||
302 | u8 buf[0x20]; | ||
303 | int err, count = 0; | ||
304 | |||
305 | do { | ||
306 | err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | ||
307 | #if 0 | ||
308 | if (err >= 0) { | ||
309 | int i; | ||
310 | printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); | ||
311 | for (i=0; i<err; ++i) | ||
312 | printk("%02x ", buf[i]); | ||
313 | printk("\n"); | ||
314 | } | ||
315 | #endif | ||
316 | } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100); | ||
317 | |||
318 | |||
319 | if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) { | ||
320 | ds_recv_status(dev, st); | ||
321 | return -1; | ||
322 | } | ||
323 | else { | ||
324 | return 0; | ||
325 | } | ||
326 | } | ||
327 | |||
328 | int ds_reset(struct ds_device *dev, struct ds_status *st) | ||
329 | { | ||
330 | int err; | ||
331 | |||
332 | //err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE); | ||
333 | err = ds_send_control(dev, 0x43, SPEED_NORMAL); | ||
334 | if (err) | ||
335 | return err; | ||
336 | |||
337 | ds_wait_status(dev, st); | ||
338 | #if 0 | ||
339 | if (st->command_buffer_status) { | ||
340 | printk(KERN_INFO "Short circuit.\n"); | ||
341 | return -EIO; | ||
342 | } | ||
343 | #endif | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | int ds_set_speed(struct ds_device *dev, int speed) | ||
349 | { | ||
350 | int err; | ||
351 | |||
352 | if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE) | ||
353 | return -EINVAL; | ||
354 | |||
355 | if (speed != SPEED_OVERDRIVE) | ||
356 | speed = SPEED_FLEXIBLE; | ||
357 | |||
358 | speed &= 0xff; | ||
359 | |||
360 | err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed); | ||
361 | if (err) | ||
362 | return err; | ||
363 | |||
364 | return err; | ||
365 | } | ||
366 | |||
367 | int ds_start_pulse(struct ds_device *dev, int delay) | ||
368 | { | ||
369 | int err; | ||
370 | u8 del = 1 + (u8)(delay >> 4); | ||
371 | struct ds_status st; | ||
372 | |||
373 | #if 0 | ||
374 | err = ds_stop_pulse(dev, 10); | ||
375 | if (err) | ||
376 | return err; | ||
377 | |||
378 | err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); | ||
379 | if (err) | ||
380 | return err; | ||
381 | #endif | ||
382 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); | ||
383 | if (err) | ||
384 | return err; | ||
385 | |||
386 | err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0); | ||
387 | if (err) | ||
388 | return err; | ||
389 | |||
390 | mdelay(delay); | ||
391 | |||
392 | ds_wait_status(dev, &st); | ||
393 | |||
394 | return err; | ||
395 | } | ||
396 | |||
397 | int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) | ||
398 | { | ||
399 | int err, count; | ||
400 | struct ds_status st; | ||
401 | u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0); | ||
402 | u16 cmd; | ||
403 | |||
404 | err = ds_send_control(dev, value, 0); | ||
405 | if (err) | ||
406 | return err; | ||
407 | |||
408 | count = 0; | ||
409 | do { | ||
410 | err = ds_wait_status(dev, &st); | ||
411 | if (err) | ||
412 | return err; | ||
413 | |||
414 | cmd = st.command0 | (st.command1 << 8); | ||
415 | } while (cmd != value && ++count < 10); | ||
416 | |||
417 | if (err < 0 || count >= 10) { | ||
418 | printk(KERN_ERR "Failed to obtain status.\n"); | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | |||
422 | err = ds_recv_data(dev, tbit, sizeof(*tbit)); | ||
423 | if (err < 0) | ||
424 | return err; | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | int ds_write_bit(struct ds_device *dev, u8 bit) | ||
430 | { | ||
431 | int err; | ||
432 | struct ds_status st; | ||
433 | |||
434 | err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0); | ||
435 | if (err) | ||
436 | return err; | ||
437 | |||
438 | ds_wait_status(dev, &st); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | int ds_write_byte(struct ds_device *dev, u8 byte) | ||
444 | { | ||
445 | int err; | ||
446 | struct ds_status st; | ||
447 | u8 rbyte; | ||
448 | |||
449 | err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); | ||
450 | if (err) | ||
451 | return err; | ||
452 | |||
453 | err = ds_wait_status(dev, &st); | ||
454 | if (err) | ||
455 | return err; | ||
456 | |||
457 | err = ds_recv_data(dev, &rbyte, sizeof(rbyte)); | ||
458 | if (err < 0) | ||
459 | return err; | ||
460 | |||
461 | ds_start_pulse(dev, PULLUP_PULSE_DURATION); | ||
462 | |||
463 | return !(byte == rbyte); | ||
464 | } | ||
465 | |||
466 | int ds_read_bit(struct ds_device *dev, u8 *bit) | ||
467 | { | ||
468 | int err; | ||
469 | |||
470 | err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); | ||
471 | if (err) | ||
472 | return err; | ||
473 | |||
474 | err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D, 0); | ||
475 | if (err) | ||
476 | return err; | ||
477 | |||
478 | err = ds_recv_data(dev, bit, sizeof(*bit)); | ||
479 | if (err < 0) | ||
480 | return err; | ||
481 | |||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | int ds_read_byte(struct ds_device *dev, u8 *byte) | ||
486 | { | ||
487 | int err; | ||
488 | struct ds_status st; | ||
489 | |||
490 | err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM , 0xff); | ||
491 | if (err) | ||
492 | return err; | ||
493 | |||
494 | ds_wait_status(dev, &st); | ||
495 | |||
496 | err = ds_recv_data(dev, byte, sizeof(*byte)); | ||
497 | if (err < 0) | ||
498 | return err; | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | int ds_read_block(struct ds_device *dev, u8 *buf, int len) | ||
504 | { | ||
505 | struct ds_status st; | ||
506 | int err; | ||
507 | |||
508 | if (len > 64*1024) | ||
509 | return -E2BIG; | ||
510 | |||
511 | memset(buf, 0xFF, len); | ||
512 | |||
513 | err = ds_send_data(dev, buf, len); | ||
514 | if (err < 0) | ||
515 | return err; | ||
516 | |||
517 | err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); | ||
518 | if (err) | ||
519 | return err; | ||
520 | |||
521 | ds_wait_status(dev, &st); | ||
522 | |||
523 | memset(buf, 0x00, len); | ||
524 | err = ds_recv_data(dev, buf, len); | ||
525 | |||
526 | return err; | ||
527 | } | ||
528 | |||
529 | int ds_write_block(struct ds_device *dev, u8 *buf, int len) | ||
530 | { | ||
531 | int err; | ||
532 | struct ds_status st; | ||
533 | |||
534 | err = ds_send_data(dev, buf, len); | ||
535 | if (err < 0) | ||
536 | return err; | ||
537 | |||
538 | ds_wait_status(dev, &st); | ||
539 | |||
540 | err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); | ||
541 | if (err) | ||
542 | return err; | ||
543 | |||
544 | ds_wait_status(dev, &st); | ||
545 | |||
546 | err = ds_recv_data(dev, buf, len); | ||
547 | if (err < 0) | ||
548 | return err; | ||
549 | |||
550 | ds_start_pulse(dev, PULLUP_PULSE_DURATION); | ||
551 | |||
552 | return !(err == len); | ||
553 | } | ||
554 | |||
555 | int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) | ||
556 | { | ||
557 | int err; | ||
558 | u16 value, index; | ||
559 | struct ds_status st; | ||
560 | |||
561 | memset(buf, 0, sizeof(buf)); | ||
562 | |||
563 | err = ds_send_data(ds_dev, (unsigned char *)&init, 8); | ||
564 | if (err) | ||
565 | return err; | ||
566 | |||
567 | ds_wait_status(ds_dev, &st); | ||
568 | |||
569 | value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; | ||
570 | index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); | ||
571 | err = ds_send_control(ds_dev, value, index); | ||
572 | if (err) | ||
573 | return err; | ||
574 | |||
575 | ds_wait_status(ds_dev, &st); | ||
576 | |||
577 | err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); | ||
578 | if (err < 0) | ||
579 | return err; | ||
580 | |||
581 | return err/8; | ||
582 | } | ||
583 | |||
584 | int ds_match_access(struct ds_device *dev, u64 init) | ||
585 | { | ||
586 | int err; | ||
587 | struct ds_status st; | ||
588 | |||
589 | err = ds_send_data(dev, (unsigned char *)&init, sizeof(init)); | ||
590 | if (err) | ||
591 | return err; | ||
592 | |||
593 | ds_wait_status(dev, &st); | ||
594 | |||
595 | err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055); | ||
596 | if (err) | ||
597 | return err; | ||
598 | |||
599 | ds_wait_status(dev, &st); | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | int ds_set_path(struct ds_device *dev, u64 init) | ||
605 | { | ||
606 | int err; | ||
607 | struct ds_status st; | ||
608 | u8 buf[9]; | ||
609 | |||
610 | memcpy(buf, &init, 8); | ||
611 | buf[8] = BRANCH_MAIN; | ||
612 | |||
613 | err = ds_send_data(dev, buf, sizeof(buf)); | ||
614 | if (err) | ||
615 | return err; | ||
616 | |||
617 | ds_wait_status(dev, &st); | ||
618 | |||
619 | err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0); | ||
620 | if (err) | ||
621 | return err; | ||
622 | |||
623 | ds_wait_status(dev, &st); | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | int ds_probe(struct usb_interface *intf, const struct usb_device_id *udev_id) | ||
629 | { | ||
630 | struct usb_device *udev = interface_to_usbdev(intf); | ||
631 | struct usb_endpoint_descriptor *endpoint; | ||
632 | struct usb_host_interface *iface_desc; | ||
633 | int i, err; | ||
634 | |||
635 | ds_dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); | ||
636 | if (!ds_dev) { | ||
637 | printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); | ||
638 | return -ENOMEM; | ||
639 | } | ||
640 | |||
641 | ds_dev->udev = usb_get_dev(udev); | ||
642 | usb_set_intfdata(intf, ds_dev); | ||
643 | |||
644 | err = usb_set_interface(ds_dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); | ||
645 | if (err) { | ||
646 | printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", | ||
647 | intf->altsetting[0].desc.bInterfaceNumber, err); | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | err = usb_reset_configuration(ds_dev->udev); | ||
652 | if (err) { | ||
653 | printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); | ||
654 | return err; | ||
655 | } | ||
656 | |||
657 | iface_desc = &intf->altsetting[0]; | ||
658 | if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { | ||
659 | printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); | ||
660 | return -ENODEV; | ||
661 | } | ||
662 | |||
663 | atomic_set(&ds_dev->refcnt, 0); | ||
664 | memset(ds_dev->ep, 0, sizeof(ds_dev->ep)); | ||
665 | |||
666 | /* | ||
667 | * This loop doesn'd show control 0 endpoint, | ||
668 | * so we will fill only 1-3 endpoints entry. | ||
669 | */ | ||
670 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
671 | endpoint = &iface_desc->endpoint[i].desc; | ||
672 | |||
673 | ds_dev->ep[i+1] = endpoint->bEndpointAddress; | ||
674 | |||
675 | printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", | ||
676 | i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), | ||
677 | (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", | ||
678 | endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
679 | } | ||
680 | |||
681 | #if 0 | ||
682 | { | ||
683 | int err, i; | ||
684 | u64 buf[3]; | ||
685 | u64 init=0xb30000002078ee81ull; | ||
686 | struct ds_status st; | ||
687 | |||
688 | ds_reset(ds_dev, &st); | ||
689 | err = ds_search(ds_dev, init, buf, 3, 0); | ||
690 | if (err < 0) | ||
691 | return err; | ||
692 | for (i=0; i<err; ++i) | ||
693 | printk("%d: %llx\n", i, buf[i]); | ||
694 | |||
695 | printk("Resetting...\n"); | ||
696 | ds_reset(ds_dev, &st); | ||
697 | printk("Setting path for %llx.\n", init); | ||
698 | err = ds_set_path(ds_dev, init); | ||
699 | if (err) | ||
700 | return err; | ||
701 | printk("Calling MATCH_ACCESS.\n"); | ||
702 | err = ds_match_access(ds_dev, init); | ||
703 | if (err) | ||
704 | return err; | ||
705 | |||
706 | printk("Searching the bus...\n"); | ||
707 | err = ds_search(ds_dev, init, buf, 3, 0); | ||
708 | |||
709 | printk("ds_search() returned %d\n", err); | ||
710 | |||
711 | if (err < 0) | ||
712 | return err; | ||
713 | for (i=0; i<err; ++i) | ||
714 | printk("%d: %llx\n", i, buf[i]); | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | #endif | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | void ds_disconnect(struct usb_interface *intf) | ||
724 | { | ||
725 | struct ds_device *dev; | ||
726 | |||
727 | dev = usb_get_intfdata(intf); | ||
728 | usb_set_intfdata(intf, NULL); | ||
729 | |||
730 | while (atomic_read(&dev->refcnt)) { | ||
731 | printk(KERN_INFO "Waiting for DS to become free: refcnt=%d.\n", | ||
732 | atomic_read(&dev->refcnt)); | ||
733 | |||
734 | if (msleep_interruptible(1000)) | ||
735 | flush_signals(current); | ||
736 | } | ||
737 | |||
738 | usb_put_dev(dev->udev); | ||
739 | kfree(dev); | ||
740 | ds_dev = NULL; | ||
741 | } | ||
742 | |||
743 | int ds_init(void) | ||
744 | { | ||
745 | int err; | ||
746 | |||
747 | err = usb_register(&ds_driver); | ||
748 | if (err) { | ||
749 | printk(KERN_INFO "Failed to register DS9490R USB device: err=%d.\n", err); | ||
750 | return err; | ||
751 | } | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | void ds_fini(void) | ||
757 | { | ||
758 | usb_deregister(&ds_driver); | ||
759 | } | ||
760 | |||
761 | module_init(ds_init); | ||
762 | module_exit(ds_fini); | ||
763 | |||
764 | MODULE_LICENSE("GPL"); | ||
765 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | ||
766 | |||
767 | EXPORT_SYMBOL(ds_touch_bit); | ||
768 | EXPORT_SYMBOL(ds_read_byte); | ||
769 | EXPORT_SYMBOL(ds_read_bit); | ||
770 | EXPORT_SYMBOL(ds_read_block); | ||
771 | EXPORT_SYMBOL(ds_write_byte); | ||
772 | EXPORT_SYMBOL(ds_write_bit); | ||
773 | EXPORT_SYMBOL(ds_write_block); | ||
774 | EXPORT_SYMBOL(ds_reset); | ||
775 | EXPORT_SYMBOL(ds_get_device); | ||
776 | EXPORT_SYMBOL(ds_put_device); | ||
777 | |||
778 | /* | ||
779 | * This functions can be used for EEPROM programming, | ||
780 | * when driver will be included into mainline this will | ||
781 | * require uncommenting. | ||
782 | */ | ||
783 | #if 0 | ||
784 | EXPORT_SYMBOL(ds_start_pulse); | ||
785 | EXPORT_SYMBOL(ds_set_speed); | ||
786 | EXPORT_SYMBOL(ds_detect); | ||
787 | EXPORT_SYMBOL(ds_stop_pulse); | ||
788 | EXPORT_SYMBOL(ds_search); | ||
789 | #endif | ||