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