aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/masters/ds2490.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1/masters/ds2490.c')
-rw-r--r--drivers/w1/masters/ds2490.c134
1 files changed, 84 insertions, 50 deletions
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
index c4ff70b2c7c4..065042db69f7 100644
--- a/drivers/w1/masters/ds2490.c
+++ b/drivers/w1/masters/ds2490.c
@@ -107,6 +107,17 @@
107#define ST_IDLE 0x20 /* DS2490 is currently idle */ 107#define ST_IDLE 0x20 /* DS2490 is currently idle */
108#define ST_EPOF 0x80 108#define ST_EPOF 0x80
109 109
110/* Result Register flags */
111#define RR_DETECT 0xA5 /* New device detected */
112#define RR_NRS 0x01 /* Reset no presence or ... */
113#define RR_SH 0x02 /* short on reset or set path */
114#define RR_APP 0x04 /* alarming presence on reset */
115#define RR_VPP 0x08 /* 12V expected not seen */
116#define RR_CMP 0x10 /* compare error */
117#define RR_CRC 0x20 /* CRC error detected */
118#define RR_RDP 0x40 /* redirected page */
119#define RR_EOS 0x80 /* end of search error */
120
110#define SPEED_NORMAL 0x00 121#define SPEED_NORMAL 0x00
111#define SPEED_FLEXIBLE 0x01 122#define SPEED_FLEXIBLE 0x01
112#define SPEED_OVERDRIVE 0x02 123#define SPEED_OVERDRIVE 0x02
@@ -164,7 +175,6 @@ MODULE_DEVICE_TABLE(usb, ds_id_table);
164static int ds_probe(struct usb_interface *, const struct usb_device_id *); 175static int ds_probe(struct usb_interface *, const struct usb_device_id *);
165static void ds_disconnect(struct usb_interface *); 176static void ds_disconnect(struct usb_interface *);
166 177
167static inline void ds_dump_status(unsigned char *, unsigned char *, int);
168static int ds_send_control(struct ds_device *, u16, u16); 178static int ds_send_control(struct ds_device *, u16, u16);
169static int ds_send_control_cmd(struct ds_device *, u16, u16); 179static int ds_send_control_cmd(struct ds_device *, u16, u16);
170 180
@@ -223,11 +233,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
223 return err; 233 return err;
224} 234}
225 235
226static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off)
227{
228 printk("%45s: %8x\n", str, buf[off]);
229}
230
231static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, 236static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
232 unsigned char *buf, int size) 237 unsigned char *buf, int size)
233{ 238{
@@ -248,54 +253,62 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
248 return count; 253 return count;
249} 254}
250 255
251static int ds_recv_status(struct ds_device *dev, struct ds_status *st) 256static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
252{ 257{
253 unsigned char buf[64]; 258 printk(KERN_INFO "%45s: %8x\n", str, buf[off]);
254 int count, err = 0, i; 259}
255
256 memcpy(st, buf, sizeof(*st));
257 260
258 count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); 261static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
259 if (count < 0) 262{
260 return err; 263 int i;
261 264
262 printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count); 265 printk(KERN_INFO "0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
263 for (i=0; i<count; ++i) 266 for (i=0; i<count; ++i)
264 printk("%02x ", buf[i]); 267 printk("%02x ", buf[i]);
265 printk("\n"); 268 printk(KERN_INFO "\n");
266 269
267 if (count >= 16) { 270 if (count >= 16) {
268 ds_dump_status(buf, "enable flag", 0); 271 ds_print_msg(buf, "enable flag", 0);
269 ds_dump_status(buf, "1-wire speed", 1); 272 ds_print_msg(buf, "1-wire speed", 1);
270 ds_dump_status(buf, "strong pullup duration", 2); 273 ds_print_msg(buf, "strong pullup duration", 2);
271 ds_dump_status(buf, "programming pulse duration", 3); 274 ds_print_msg(buf, "programming pulse duration", 3);
272 ds_dump_status(buf, "pulldown slew rate control", 4); 275 ds_print_msg(buf, "pulldown slew rate control", 4);
273 ds_dump_status(buf, "write-1 low time", 5); 276 ds_print_msg(buf, "write-1 low time", 5);
274 ds_dump_status(buf, "data sample offset/write-0 recovery time", 6); 277 ds_print_msg(buf, "data sample offset/write-0 recovery time",
275 ds_dump_status(buf, "reserved (test register)", 7); 278 6);
276 ds_dump_status(buf, "device status flags", 8); 279 ds_print_msg(buf, "reserved (test register)", 7);
277 ds_dump_status(buf, "communication command byte 1", 9); 280 ds_print_msg(buf, "device status flags", 8);
278 ds_dump_status(buf, "communication command byte 2", 10); 281 ds_print_msg(buf, "communication command byte 1", 9);
279 ds_dump_status(buf, "communication command buffer status", 11); 282 ds_print_msg(buf, "communication command byte 2", 10);
280 ds_dump_status(buf, "1-wire data output buffer status", 12); 283 ds_print_msg(buf, "communication command buffer status", 11);
281 ds_dump_status(buf, "1-wire data input buffer status", 13); 284 ds_print_msg(buf, "1-wire data output buffer status", 12);
282 ds_dump_status(buf, "reserved", 14); 285 ds_print_msg(buf, "1-wire data input buffer status", 13);
283 ds_dump_status(buf, "reserved", 15); 286 ds_print_msg(buf, "reserved", 14);
287 ds_print_msg(buf, "reserved", 15);
284 } 288 }
285 289 for (i = 16; i < count; ++i) {
286 memcpy(st, buf, sizeof(*st)); 290 if (buf[i] == RR_DETECT) {
287 291 ds_print_msg(buf, "new device detect", i);
288 if (st->status & ST_EPOF) { 292 continue;
289 printk(KERN_INFO "Resetting device after ST_EPOF.\n"); 293 }
290 err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); 294 ds_print_msg(buf, "Result Register Value: ", i);
291 if (err) 295 if (buf[i] & RR_NRS)
292 return err; 296 printk(KERN_INFO "NRS: Reset no presence or ...\n");
293 count = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); 297 if (buf[i] & RR_SH)
294 if (count < 0) 298 printk(KERN_INFO "SH: short on reset or set path\n");
295 return err; 299 if (buf[i] & RR_APP)
300 printk(KERN_INFO "APP: alarming presence on reset\n");
301 if (buf[i] & RR_VPP)
302 printk(KERN_INFO "VPP: 12V expected not seen\n");
303 if (buf[i] & RR_CMP)
304 printk(KERN_INFO "CMP: compare error\n");
305 if (buf[i] & RR_CRC)
306 printk(KERN_INFO "CRC: CRC error detected\n");
307 if (buf[i] & RR_RDP)
308 printk(KERN_INFO "RDP: redirected page\n");
309 if (buf[i] & RR_EOS)
310 printk(KERN_INFO "EOS: end of search error\n");
296 } 311 }
297
298 return err;
299} 312}
300 313
301static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) 314static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
@@ -307,9 +320,14 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
307 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), 320 err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
308 buf, size, &count, 1000); 321 buf, size, &count, 1000);
309 if (err < 0) { 322 if (err < 0) {
323 u8 buf[0x20];
324 int count;
325
310 printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); 326 printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
311 usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN])); 327 usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
312 ds_recv_status(dev, &st); 328
329 count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
330 ds_dump_status(dev, buf, count);
313 return err; 331 return err;
314 } 332 }
315 333
@@ -390,7 +408,7 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
390 if (err) 408 if (err)
391 return err; 409 return err;
392 410
393 err = ds_recv_status(dev, st); 411 err = ds_dump_status(dev, st);
394 412
395 return err; 413 return err;
396} 414}
@@ -415,11 +433,27 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
415#endif 433#endif
416 } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100); 434 } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100);
417 435
436 if (err >= 16 && st->status & ST_EPOF) {
437 printk(KERN_INFO "Resetting device after ST_EPOF.\n");
438 ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
439 /* Always dump the device status. */
440 count = 101;
441 }
442
443 /* Dump the status for errors or if there is extended return data.
444 * The extended status includes new device detection (maybe someone
445 * can do something with it).
446 */
447 if (err > 16 || count >= 100 || err < 0)
448 ds_dump_status(dev, buf, err);
418 449
419 if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) { 450 /* Extended data isn't an error. Well, a short is, but the dump
420 ds_recv_status(dev, st); 451 * would have already told the user that and we can't do anything
452 * about it in software anyway.
453 */
454 if (count >= 100 || err < 0)
421 return -1; 455 return -1;
422 } else 456 else
423 return 0; 457 return 0;
424} 458}
425 459