diff options
Diffstat (limited to 'drivers/w1/masters/ds2490.c')
-rw-r--r-- | drivers/w1/masters/ds2490.c | 947 |
1 files changed, 947 insertions, 0 deletions
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c new file mode 100644 index 000000000000..637677833da5 --- /dev/null +++ b/drivers/w1/masters/ds2490.c | |||
@@ -0,0 +1,947 @@ | |||
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 "../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 | ||
91 | #define COMM_NTP 0x0400 | ||
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 | |||
101 | /* | ||
102 | * Duration of the strong pull-up pulse in milliseconds. | ||
103 | */ | ||
104 | #define PULLUP_PULSE_DURATION 750 | ||
105 | |||
106 | /* Status flags */ | ||
107 | #define ST_SPUA 0x01 /* Strong Pull-up is active */ | ||
108 | #define ST_PRGA 0x02 /* 12V programming pulse is being generated */ | ||
109 | #define ST_12VP 0x04 /* external 12V programming voltage is present */ | ||
110 | #define ST_PMOD 0x08 /* DS2490 powered from USB and external sources */ | ||
111 | #define ST_HALT 0x10 /* DS2490 is currently halted */ | ||
112 | #define ST_IDLE 0x20 /* DS2490 is currently idle */ | ||
113 | #define ST_EPOF 0x80 | ||
114 | |||
115 | #define SPEED_NORMAL 0x00 | ||
116 | #define SPEED_FLEXIBLE 0x01 | ||
117 | #define SPEED_OVERDRIVE 0x02 | ||
118 | |||
119 | #define NUM_EP 4 | ||
120 | #define EP_CONTROL 0 | ||
121 | #define EP_STATUS 1 | ||
122 | #define EP_DATA_OUT 2 | ||
123 | #define EP_DATA_IN 3 | ||
124 | |||
125 | struct ds_device | ||
126 | { | ||
127 | struct list_head ds_entry; | ||
128 | |||
129 | struct usb_device *udev; | ||
130 | struct usb_interface *intf; | ||
131 | |||
132 | int ep[NUM_EP]; | ||
133 | |||
134 | struct w1_bus_master master; | ||
135 | }; | ||
136 | |||
137 | struct ds_status | ||
138 | { | ||
139 | u8 enable; | ||
140 | u8 speed; | ||
141 | u8 pullup_dur; | ||
142 | u8 ppuls_dur; | ||
143 | u8 pulldown_slew; | ||
144 | u8 write1_time; | ||
145 | u8 write0_time; | ||
146 | u8 reserved0; | ||
147 | u8 status; | ||
148 | u8 command0; | ||
149 | u8 command1; | ||
150 | u8 command_buffer_status; | ||
151 | u8 data_out_buffer_status; | ||
152 | u8 data_in_buffer_status; | ||
153 | u8 reserved1; | ||
154 | u8 reserved2; | ||
155 | |||
156 | }; | ||
157 | |||
158 | static struct usb_device_id ds_id_table [] = { | ||
159 | { USB_DEVICE(0x04fa, 0x2490) }, | ||
160 | { }, | ||
161 | }; | ||
162 | MODULE_DEVICE_TABLE(usb, ds_id_table); | ||
163 | |||
164 | static int ds_probe(struct usb_interface *, const struct usb_device_id *); | ||
165 | static void ds_disconnect(struct usb_interface *); | ||
166 | |||
167 | static inline void ds_dump_status(unsigned char *, unsigned char *, int); | ||
168 | static int ds_send_control(struct ds_device *, u16, u16); | ||
169 | static int ds_send_control_cmd(struct ds_device *, u16, u16); | ||
170 | |||
171 | static LIST_HEAD(ds_devices); | ||
172 | static DECLARE_MUTEX(ds_mutex); | ||
173 | |||
174 | static struct usb_driver ds_driver = { | ||
175 | .name = "DS9490R", | ||
176 | .probe = ds_probe, | ||
177 | .disconnect = ds_disconnect, | ||
178 | .id_table = ds_id_table, | ||
179 | }; | ||
180 | |||
181 | static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) | ||
182 | { | ||
183 | int err; | ||
184 | |||
185 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | ||
186 | CONTROL_CMD, 0x40, value, index, NULL, 0, 1000); | ||
187 | if (err < 0) { | ||
188 | printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", | ||
189 | value, index, err); | ||
190 | return err; | ||
191 | } | ||
192 | |||
193 | return err; | ||
194 | } | ||
195 | #if 0 | ||
196 | static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) | ||
197 | { | ||
198 | int err; | ||
199 | |||
200 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | ||
201 | MODE_CMD, 0x40, value, index, NULL, 0, 1000); | ||
202 | if (err < 0) { | ||
203 | printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", | ||
204 | value, index, err); | ||
205 | return err; | ||
206 | } | ||
207 | |||
208 | return err; | ||
209 | } | ||
210 | #endif | ||
211 | static int ds_send_control(struct ds_device *dev, u16 value, u16 index) | ||
212 | { | ||
213 | int err; | ||
214 | |||
215 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | ||
216 | COMM_CMD, 0x40, value, index, NULL, 0, 1000); | ||
217 | if (err < 0) { | ||
218 | printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", | ||
219 | value, index, err); | ||
220 | return err; | ||
221 | } | ||
222 | |||
223 | return err; | ||
224 | } | ||
225 | |||
226 | static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off) | ||
227 | { | ||
228 | printk("%45s: %8x\n", str, buf[off]); | ||
229 | } | ||
230 | |||
231 | static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, | ||
232 | unsigned char *buf, int size) | ||
233 | { | ||
234 | int count, err; | ||
235 | |||
236 | memset(st, 0, sizeof(st)); | ||
237 | |||
238 | count = 0; | ||
239 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); | ||
240 | if (err < 0) { | ||
241 | printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); | ||
242 | return err; | ||
243 | } | ||
244 | |||
245 | if (count >= sizeof(*st)) | ||
246 | memcpy(st, buf, sizeof(*st)); | ||
247 | |||
248 | return count; | ||
249 | } | ||
250 | |||
251 | static int ds_recv_status(struct ds_device *dev, struct ds_status *st) | ||
252 | { | ||
253 | unsigned char buf[64]; | ||
254 | int count, err = 0, i; | ||
255 | |||
256 | memcpy(st, buf, sizeof(*st)); | ||
257 | |||
258 | count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | ||
259 | if (count < 0) | ||
260 | return err; | ||
261 | |||
262 | printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); | ||
263 | for (i=0; i<count; ++i) | ||
264 | printk("%02x ", buf[i]); | ||
265 | printk("\n"); | ||
266 | |||
267 | if (count >= 16) { | ||
268 | ds_dump_status(buf, "enable flag", 0); | ||
269 | ds_dump_status(buf, "1-wire speed", 1); | ||
270 | ds_dump_status(buf, "strong pullup duration", 2); | ||
271 | ds_dump_status(buf, "programming pulse duration", 3); | ||
272 | ds_dump_status(buf, "pulldown slew rate control", 4); | ||
273 | ds_dump_status(buf, "write-1 low time", 5); | ||
274 | ds_dump_status(buf, "data sample offset/write-0 recovery time", 6); | ||
275 | ds_dump_status(buf, "reserved (test register)", 7); | ||
276 | ds_dump_status(buf, "device status flags", 8); | ||
277 | ds_dump_status(buf, "communication command byte 1", 9); | ||
278 | ds_dump_status(buf, "communication command byte 2", 10); | ||
279 | ds_dump_status(buf, "communication command buffer status", 11); | ||
280 | ds_dump_status(buf, "1-wire data output buffer status", 12); | ||
281 | ds_dump_status(buf, "1-wire data input buffer status", 13); | ||
282 | ds_dump_status(buf, "reserved", 14); | ||
283 | ds_dump_status(buf, "reserved", 15); | ||
284 | } | ||
285 | |||
286 | memcpy(st, buf, sizeof(*st)); | ||
287 | |||
288 | if (st->status & ST_EPOF) { | ||
289 | printk(KERN_INFO "Resetting device after ST_EPOF.\n"); | ||
290 | err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); | ||
291 | if (err) | ||
292 | return err; | ||
293 | count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | ||
294 | if (count < 0) | ||
295 | return err; | ||
296 | } | ||
297 | #if 0 | ||
298 | if (st->status & ST_IDLE) { | ||
299 | printk(KERN_INFO "Resetting pulse after ST_IDLE.\n"); | ||
300 | err = ds_start_pulse(dev, PULLUP_PULSE_DURATION); | ||
301 | if (err) | ||
302 | return err; | ||
303 | } | ||
304 | #endif | ||
305 | |||
306 | return err; | ||
307 | } | ||
308 | |||
309 | static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) | ||
310 | { | ||
311 | int count, err; | ||
312 | struct ds_status st; | ||
313 | |||
314 | count = 0; | ||
315 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), | ||
316 | buf, size, &count, 1000); | ||
317 | if (err < 0) { | ||
318 | printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); | ||
319 | usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); | ||
320 | ds_recv_status(dev, &st); | ||
321 | return err; | ||
322 | } | ||
323 | |||
324 | #if 0 | ||
325 | { | ||
326 | int i; | ||
327 | |||
328 | printk("%s: count=%d: ", __func__, count); | ||
329 | for (i=0; i<count; ++i) | ||
330 | printk("%02x ", buf[i]); | ||
331 | printk("\n"); | ||
332 | } | ||
333 | #endif | ||
334 | return count; | ||
335 | } | ||
336 | |||
337 | static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len) | ||
338 | { | ||
339 | int count, err; | ||
340 | |||
341 | count = 0; | ||
342 | err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000); | ||
343 | if (err < 0) { | ||
344 | printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err); | ||
345 | return err; | ||
346 | } | ||
347 | |||
348 | return err; | ||
349 | } | ||
350 | |||
351 | #if 0 | ||
352 | |||
353 | int ds_stop_pulse(struct ds_device *dev, int limit) | ||
354 | { | ||
355 | struct ds_status st; | ||
356 | int count = 0, err = 0; | ||
357 | u8 buf[0x20]; | ||
358 | |||
359 | do { | ||
360 | err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); | ||
361 | if (err) | ||
362 | break; | ||
363 | err = ds_send_control(dev, CTL_RESUME_EXE, 0); | ||
364 | if (err) | ||
365 | break; | ||
366 | err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf)); | ||
367 | if (err) | ||
368 | break; | ||
369 | |||
370 | if ((st.status & ST_SPUA) == 0) { | ||
371 | err = ds_send_control_mode(dev, MOD_PULSE_EN, 0); | ||
372 | if (err) | ||
373 | break; | ||
374 | } | ||
375 | } while(++count < limit); | ||
376 | |||
377 | return err; | ||
378 | } | ||
379 | |||
380 | int ds_detect(struct ds_device *dev, struct ds_status *st) | ||
381 | { | ||
382 | int err; | ||
383 | |||
384 | err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); | ||
385 | if (err) | ||
386 | return err; | ||
387 | |||
388 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0); | ||
389 | if (err) | ||
390 | return err; | ||
391 | |||
392 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40); | ||
393 | if (err) | ||
394 | return err; | ||
395 | |||
396 | err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG); | ||
397 | if (err) | ||
398 | return err; | ||
399 | |||
400 | err = ds_recv_status(dev, st); | ||
401 | |||
402 | return err; | ||
403 | } | ||
404 | |||
405 | #endif /* 0 */ | ||
406 | |||
407 | static int ds_wait_status(struct ds_device *dev, struct ds_status *st) | ||
408 | { | ||
409 | u8 buf[0x20]; | ||
410 | int err, count = 0; | ||
411 | |||
412 | do { | ||
413 | err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | ||
414 | #if 0 | ||
415 | if (err >= 0) { | ||
416 | int i; | ||
417 | printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err); | ||
418 | for (i=0; i<err; ++i) | ||
419 | printk("%02x ", buf[i]); | ||
420 | printk("\n"); | ||
421 | } | ||
422 | #endif | ||
423 | } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100); | ||
424 | |||
425 | |||
426 | if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) { | ||
427 | ds_recv_status(dev, st); | ||
428 | return -1; | ||
429 | } else | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static int ds_reset(struct ds_device *dev, struct ds_status *st) | ||
434 | { | ||
435 | int err; | ||
436 | |||
437 | //err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE); | ||
438 | err = ds_send_control(dev, 0x43, SPEED_NORMAL); | ||
439 | if (err) | ||
440 | return err; | ||
441 | |||
442 | ds_wait_status(dev, st); | ||
443 | #if 0 | ||
444 | if (st->command_buffer_status) { | ||
445 | printk(KERN_INFO "Short circuit.\n"); | ||
446 | return -EIO; | ||
447 | } | ||
448 | #endif | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | #if 0 | ||
454 | static int ds_set_speed(struct ds_device *dev, int speed) | ||
455 | { | ||
456 | int err; | ||
457 | |||
458 | if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE) | ||
459 | return -EINVAL; | ||
460 | |||
461 | if (speed != SPEED_OVERDRIVE) | ||
462 | speed = SPEED_FLEXIBLE; | ||
463 | |||
464 | speed &= 0xff; | ||
465 | |||
466 | err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed); | ||
467 | if (err) | ||
468 | return err; | ||
469 | |||
470 | return err; | ||
471 | } | ||
472 | #endif /* 0 */ | ||
473 | |||
474 | static int ds_start_pulse(struct ds_device *dev, int delay) | ||
475 | { | ||
476 | int err; | ||
477 | u8 del = 1 + (u8)(delay >> 4); | ||
478 | struct ds_status st; | ||
479 | |||
480 | #if 0 | ||
481 | err = ds_stop_pulse(dev, 10); | ||
482 | if (err) | ||
483 | return err; | ||
484 | |||
485 | err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); | ||
486 | if (err) | ||
487 | return err; | ||
488 | #endif | ||
489 | err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); | ||
490 | if (err) | ||
491 | return err; | ||
492 | |||
493 | err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0); | ||
494 | if (err) | ||
495 | return err; | ||
496 | |||
497 | mdelay(delay); | ||
498 | |||
499 | ds_wait_status(dev, &st); | ||
500 | |||
501 | return err; | ||
502 | } | ||
503 | |||
504 | static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) | ||
505 | { | ||
506 | int err, count; | ||
507 | struct ds_status st; | ||
508 | u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0); | ||
509 | u16 cmd; | ||
510 | |||
511 | err = ds_send_control(dev, value, 0); | ||
512 | if (err) | ||
513 | return err; | ||
514 | |||
515 | count = 0; | ||
516 | do { | ||
517 | err = ds_wait_status(dev, &st); | ||
518 | if (err) | ||
519 | return err; | ||
520 | |||
521 | cmd = st.command0 | (st.command1 << 8); | ||
522 | } while (cmd != value && ++count < 10); | ||
523 | |||
524 | if (err < 0 || count >= 10) { | ||
525 | printk(KERN_ERR "Failed to obtain status.\n"); | ||
526 | return -EINVAL; | ||
527 | } | ||
528 | |||
529 | err = ds_recv_data(dev, tbit, sizeof(*tbit)); | ||
530 | if (err < 0) | ||
531 | return err; | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int ds_write_bit(struct ds_device *dev, u8 bit) | ||
537 | { | ||
538 | int err; | ||
539 | struct ds_status st; | ||
540 | |||
541 | err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0); | ||
542 | if (err) | ||
543 | return err; | ||
544 | |||
545 | ds_wait_status(dev, &st); | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int ds_write_byte(struct ds_device *dev, u8 byte) | ||
551 | { | ||
552 | int err; | ||
553 | struct ds_status st; | ||
554 | u8 rbyte; | ||
555 | |||
556 | err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); | ||
557 | if (err) | ||
558 | return err; | ||
559 | |||
560 | err = ds_wait_status(dev, &st); | ||
561 | if (err) | ||
562 | return err; | ||
563 | |||
564 | err = ds_recv_data(dev, &rbyte, sizeof(rbyte)); | ||
565 | if (err < 0) | ||
566 | return err; | ||
567 | |||
568 | ds_start_pulse(dev, PULLUP_PULSE_DURATION); | ||
569 | |||
570 | return !(byte == rbyte); | ||
571 | } | ||
572 | |||
573 | static int ds_read_byte(struct ds_device *dev, u8 *byte) | ||
574 | { | ||
575 | int err; | ||
576 | struct ds_status st; | ||
577 | |||
578 | err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM , 0xff); | ||
579 | if (err) | ||
580 | return err; | ||
581 | |||
582 | ds_wait_status(dev, &st); | ||
583 | |||
584 | err = ds_recv_data(dev, byte, sizeof(*byte)); | ||
585 | if (err < 0) | ||
586 | return err; | ||
587 | |||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static int ds_read_block(struct ds_device *dev, u8 *buf, int len) | ||
592 | { | ||
593 | struct ds_status st; | ||
594 | int err; | ||
595 | |||
596 | if (len > 64*1024) | ||
597 | return -E2BIG; | ||
598 | |||
599 | memset(buf, 0xFF, len); | ||
600 | |||
601 | err = ds_send_data(dev, buf, len); | ||
602 | if (err < 0) | ||
603 | return err; | ||
604 | |||
605 | err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); | ||
606 | if (err) | ||
607 | return err; | ||
608 | |||
609 | ds_wait_status(dev, &st); | ||
610 | |||
611 | memset(buf, 0x00, len); | ||
612 | err = ds_recv_data(dev, buf, len); | ||
613 | |||
614 | return err; | ||
615 | } | ||
616 | |||
617 | static int ds_write_block(struct ds_device *dev, u8 *buf, int len) | ||
618 | { | ||
619 | int err; | ||
620 | struct ds_status st; | ||
621 | |||
622 | err = ds_send_data(dev, buf, len); | ||
623 | if (err < 0) | ||
624 | return err; | ||
625 | |||
626 | ds_wait_status(dev, &st); | ||
627 | |||
628 | err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); | ||
629 | if (err) | ||
630 | return err; | ||
631 | |||
632 | ds_wait_status(dev, &st); | ||
633 | |||
634 | err = ds_recv_data(dev, buf, len); | ||
635 | if (err < 0) | ||
636 | return err; | ||
637 | |||
638 | ds_start_pulse(dev, PULLUP_PULSE_DURATION); | ||
639 | |||
640 | return !(err == len); | ||
641 | } | ||
642 | |||
643 | #if 0 | ||
644 | |||
645 | static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) | ||
646 | { | ||
647 | int err; | ||
648 | u16 value, index; | ||
649 | struct ds_status st; | ||
650 | |||
651 | memset(buf, 0, sizeof(buf)); | ||
652 | |||
653 | err = ds_send_data(ds_dev, (unsigned char *)&init, 8); | ||
654 | if (err) | ||
655 | return err; | ||
656 | |||
657 | ds_wait_status(ds_dev, &st); | ||
658 | |||
659 | value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; | ||
660 | index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); | ||
661 | err = ds_send_control(ds_dev, value, index); | ||
662 | if (err) | ||
663 | return err; | ||
664 | |||
665 | ds_wait_status(ds_dev, &st); | ||
666 | |||
667 | err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); | ||
668 | if (err < 0) | ||
669 | return err; | ||
670 | |||
671 | return err/8; | ||
672 | } | ||
673 | |||
674 | static int ds_match_access(struct ds_device *dev, u64 init) | ||
675 | { | ||
676 | int err; | ||
677 | struct ds_status st; | ||
678 | |||
679 | err = ds_send_data(dev, (unsigned char *)&init, sizeof(init)); | ||
680 | if (err) | ||
681 | return err; | ||
682 | |||
683 | ds_wait_status(dev, &st); | ||
684 | |||
685 | err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055); | ||
686 | if (err) | ||
687 | return err; | ||
688 | |||
689 | ds_wait_status(dev, &st); | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | static int ds_set_path(struct ds_device *dev, u64 init) | ||
695 | { | ||
696 | int err; | ||
697 | struct ds_status st; | ||
698 | u8 buf[9]; | ||
699 | |||
700 | memcpy(buf, &init, 8); | ||
701 | buf[8] = BRANCH_MAIN; | ||
702 | |||
703 | err = ds_send_data(dev, buf, sizeof(buf)); | ||
704 | if (err) | ||
705 | return err; | ||
706 | |||
707 | ds_wait_status(dev, &st); | ||
708 | |||
709 | err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0); | ||
710 | if (err) | ||
711 | return err; | ||
712 | |||
713 | ds_wait_status(dev, &st); | ||
714 | |||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | #endif /* 0 */ | ||
719 | |||
720 | static u8 ds9490r_touch_bit(void *data, u8 bit) | ||
721 | { | ||
722 | u8 ret; | ||
723 | struct ds_device *dev = data; | ||
724 | |||
725 | if (ds_touch_bit(dev, bit, &ret)) | ||
726 | return 0; | ||
727 | |||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | static void ds9490r_write_bit(void *data, u8 bit) | ||
732 | { | ||
733 | struct ds_device *dev = data; | ||
734 | |||
735 | ds_write_bit(dev, bit); | ||
736 | } | ||
737 | |||
738 | static void ds9490r_write_byte(void *data, u8 byte) | ||
739 | { | ||
740 | struct ds_device *dev = data; | ||
741 | |||
742 | ds_write_byte(dev, byte); | ||
743 | } | ||
744 | |||
745 | static u8 ds9490r_read_bit(void *data) | ||
746 | { | ||
747 | struct ds_device *dev = data; | ||
748 | int err; | ||
749 | u8 bit = 0; | ||
750 | |||
751 | err = ds_touch_bit(dev, 1, &bit); | ||
752 | if (err) | ||
753 | return 0; | ||
754 | |||
755 | return bit & 1; | ||
756 | } | ||
757 | |||
758 | static u8 ds9490r_read_byte(void *data) | ||
759 | { | ||
760 | struct ds_device *dev = data; | ||
761 | int err; | ||
762 | u8 byte = 0; | ||
763 | |||
764 | err = ds_read_byte(dev, &byte); | ||
765 | if (err) | ||
766 | return 0; | ||
767 | |||
768 | return byte; | ||
769 | } | ||
770 | |||
771 | static void ds9490r_write_block(void *data, const u8 *buf, int len) | ||
772 | { | ||
773 | struct ds_device *dev = data; | ||
774 | |||
775 | ds_write_block(dev, (u8 *)buf, len); | ||
776 | } | ||
777 | |||
778 | static u8 ds9490r_read_block(void *data, u8 *buf, int len) | ||
779 | { | ||
780 | struct ds_device *dev = data; | ||
781 | int err; | ||
782 | |||
783 | err = ds_read_block(dev, buf, len); | ||
784 | if (err < 0) | ||
785 | return 0; | ||
786 | |||
787 | return len; | ||
788 | } | ||
789 | |||
790 | static u8 ds9490r_reset(void *data) | ||
791 | { | ||
792 | struct ds_device *dev = data; | ||
793 | struct ds_status st; | ||
794 | int err; | ||
795 | |||
796 | memset(&st, 0, sizeof(st)); | ||
797 | |||
798 | err = ds_reset(dev, &st); | ||
799 | if (err) | ||
800 | return 1; | ||
801 | |||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | static int ds_w1_init(struct ds_device *dev) | ||
806 | { | ||
807 | memset(&dev->master, 0, sizeof(struct w1_bus_master)); | ||
808 | |||
809 | dev->master.data = dev; | ||
810 | dev->master.touch_bit = &ds9490r_touch_bit; | ||
811 | dev->master.read_bit = &ds9490r_read_bit; | ||
812 | dev->master.write_bit = &ds9490r_write_bit; | ||
813 | dev->master.read_byte = &ds9490r_read_byte; | ||
814 | dev->master.write_byte = &ds9490r_write_byte; | ||
815 | dev->master.read_block = &ds9490r_read_block; | ||
816 | dev->master.write_block = &ds9490r_write_block; | ||
817 | dev->master.reset_bus = &ds9490r_reset; | ||
818 | |||
819 | return w1_add_master_device(&dev->master); | ||
820 | } | ||
821 | |||
822 | static void ds_w1_fini(struct ds_device *dev) | ||
823 | { | ||
824 | w1_remove_master_device(&dev->master); | ||
825 | } | ||
826 | |||
827 | static int ds_probe(struct usb_interface *intf, | ||
828 | const struct usb_device_id *udev_id) | ||
829 | { | ||
830 | struct usb_device *udev = interface_to_usbdev(intf); | ||
831 | struct usb_endpoint_descriptor *endpoint; | ||
832 | struct usb_host_interface *iface_desc; | ||
833 | struct ds_device *dev; | ||
834 | int i, err; | ||
835 | |||
836 | dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); | ||
837 | if (!dev) { | ||
838 | printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); | ||
839 | return -ENOMEM; | ||
840 | } | ||
841 | dev->udev = usb_get_dev(udev); | ||
842 | if (!dev->udev) { | ||
843 | err = -ENOMEM; | ||
844 | goto err_out_free; | ||
845 | } | ||
846 | memset(dev->ep, 0, sizeof(dev->ep)); | ||
847 | |||
848 | usb_set_intfdata(intf, dev); | ||
849 | |||
850 | err = usb_set_interface(dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); | ||
851 | if (err) { | ||
852 | printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", | ||
853 | intf->altsetting[0].desc.bInterfaceNumber, err); | ||
854 | goto err_out_clear; | ||
855 | } | ||
856 | |||
857 | err = usb_reset_configuration(dev->udev); | ||
858 | if (err) { | ||
859 | printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); | ||
860 | goto err_out_clear; | ||
861 | } | ||
862 | |||
863 | iface_desc = &intf->altsetting[0]; | ||
864 | if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { | ||
865 | printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); | ||
866 | err = -EINVAL; | ||
867 | goto err_out_clear; | ||
868 | } | ||
869 | |||
870 | /* | ||
871 | * This loop doesn'd show control 0 endpoint, | ||
872 | * so we will fill only 1-3 endpoints entry. | ||
873 | */ | ||
874 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
875 | endpoint = &iface_desc->endpoint[i].desc; | ||
876 | |||
877 | dev->ep[i+1] = endpoint->bEndpointAddress; | ||
878 | #if 0 | ||
879 | printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", | ||
880 | i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), | ||
881 | (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", | ||
882 | endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
883 | #endif | ||
884 | } | ||
885 | |||
886 | err = ds_w1_init(dev); | ||
887 | if (err) | ||
888 | goto err_out_clear; | ||
889 | |||
890 | down(&ds_mutex); | ||
891 | list_add_tail(&dev->ds_entry, &ds_devices); | ||
892 | up(&ds_mutex); | ||
893 | |||
894 | return 0; | ||
895 | |||
896 | err_out_clear: | ||
897 | usb_set_intfdata(intf, NULL); | ||
898 | usb_put_dev(dev->udev); | ||
899 | err_out_free: | ||
900 | kfree(dev); | ||
901 | return err; | ||
902 | } | ||
903 | |||
904 | static void ds_disconnect(struct usb_interface *intf) | ||
905 | { | ||
906 | struct ds_device *dev; | ||
907 | |||
908 | dev = usb_get_intfdata(intf); | ||
909 | if (!dev) | ||
910 | return; | ||
911 | |||
912 | down(&ds_mutex); | ||
913 | list_del(&dev->ds_entry); | ||
914 | up(&ds_mutex); | ||
915 | |||
916 | ds_w1_fini(dev); | ||
917 | |||
918 | usb_set_intfdata(intf, NULL); | ||
919 | |||
920 | usb_put_dev(dev->udev); | ||
921 | kfree(dev); | ||
922 | } | ||
923 | |||
924 | static int ds_init(void) | ||
925 | { | ||
926 | int err; | ||
927 | |||
928 | err = usb_register(&ds_driver); | ||
929 | if (err) { | ||
930 | printk(KERN_INFO "Failed to register DS9490R USB device: err=%d.\n", err); | ||
931 | return err; | ||
932 | } | ||
933 | |||
934 | return 0; | ||
935 | } | ||
936 | |||
937 | static void ds_fini(void) | ||
938 | { | ||
939 | usb_deregister(&ds_driver); | ||
940 | } | ||
941 | |||
942 | module_init(ds_init); | ||
943 | module_exit(ds_fini); | ||
944 | |||
945 | MODULE_LICENSE("GPL"); | ||
946 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | ||
947 | MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)"); | ||