diff options
Diffstat (limited to 'drivers/w1/masters/ds2490.c')
-rw-r--r-- | drivers/w1/masters/ds2490.c | 155 |
1 files changed, 118 insertions, 37 deletions
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index 4f7e1d770f81..7404ad3062b7 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * dscore.c | 2 | * ds2490.c USB to one wire bridge |
3 | * | 3 | * |
4 | * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> | 4 | * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> |
5 | * | 5 | * |
@@ -28,6 +28,10 @@ | |||
28 | #include "../w1_int.h" | 28 | #include "../w1_int.h" |
29 | #include "../w1.h" | 29 | #include "../w1.h" |
30 | 30 | ||
31 | /* USB Standard */ | ||
32 | /* USB Control request vendor type */ | ||
33 | #define VENDOR 0x40 | ||
34 | |||
31 | /* COMMAND TYPE CODES */ | 35 | /* COMMAND TYPE CODES */ |
32 | #define CONTROL_CMD 0x00 | 36 | #define CONTROL_CMD 0x00 |
33 | #define COMM_CMD 0x01 | 37 | #define COMM_CMD 0x01 |
@@ -107,6 +111,8 @@ | |||
107 | #define ST_HALT 0x10 /* DS2490 is currently halted */ | 111 | #define ST_HALT 0x10 /* DS2490 is currently halted */ |
108 | #define ST_IDLE 0x20 /* DS2490 is currently idle */ | 112 | #define ST_IDLE 0x20 /* DS2490 is currently idle */ |
109 | #define ST_EPOF 0x80 | 113 | #define ST_EPOF 0x80 |
114 | /* Status transfer size, 16 bytes status, 16 byte result flags */ | ||
115 | #define ST_SIZE 0x20 | ||
110 | 116 | ||
111 | /* Result Register flags */ | 117 | /* Result Register flags */ |
112 | #define RR_DETECT 0xA5 /* New device detected */ | 118 | #define RR_DETECT 0xA5 /* New device detected */ |
@@ -198,7 +204,7 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) | |||
198 | int err; | 204 | int err; |
199 | 205 | ||
200 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | 206 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), |
201 | CONTROL_CMD, 0x40, value, index, NULL, 0, 1000); | 207 | CONTROL_CMD, VENDOR, value, index, NULL, 0, 1000); |
202 | if (err < 0) { | 208 | if (err < 0) { |
203 | printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", | 209 | printk(KERN_ERR "Failed to send command control message %x.%x: err=%d.\n", |
204 | value, index, err); | 210 | value, index, err); |
@@ -213,7 +219,7 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) | |||
213 | int err; | 219 | int err; |
214 | 220 | ||
215 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | 221 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), |
216 | MODE_CMD, 0x40, value, index, NULL, 0, 1000); | 222 | MODE_CMD, VENDOR, value, index, NULL, 0, 1000); |
217 | if (err < 0) { | 223 | if (err < 0) { |
218 | printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", | 224 | printk(KERN_ERR "Failed to send mode control message %x.%x: err=%d.\n", |
219 | value, index, err); | 225 | value, index, err); |
@@ -228,7 +234,7 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index) | |||
228 | int err; | 234 | int err; |
229 | 235 | ||
230 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), | 236 | err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]), |
231 | COMM_CMD, 0x40, value, index, NULL, 0, 1000); | 237 | COMM_CMD, VENDOR, value, index, NULL, 0, 1000); |
232 | if (err < 0) { | 238 | if (err < 0) { |
233 | printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", | 239 | printk(KERN_ERR "Failed to send control message %x.%x: err=%d.\n", |
234 | value, index, err); | 240 | value, index, err); |
@@ -246,7 +252,8 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st, | |||
246 | memset(st, 0, sizeof(*st)); | 252 | memset(st, 0, sizeof(*st)); |
247 | 253 | ||
248 | count = 0; | 254 | count = 0; |
249 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_STATUS]), buf, size, &count, 100); | 255 | err = usb_interrupt_msg(dev->udev, usb_rcvintpipe(dev->udev, |
256 | dev->ep[EP_STATUS]), buf, size, &count, 100); | ||
250 | if (err < 0) { | 257 | if (err < 0) { |
251 | printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); | 258 | printk(KERN_ERR "Failed to read 1-wire data from 0x%x: err=%d.\n", dev->ep[EP_STATUS], err); |
252 | return err; | 259 | return err; |
@@ -353,7 +360,7 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) | |||
353 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), | 360 | err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]), |
354 | buf, size, &count, 1000); | 361 | buf, size, &count, 1000); |
355 | if (err < 0) { | 362 | if (err < 0) { |
356 | u8 buf[0x20]; | 363 | u8 buf[ST_SIZE]; |
357 | int count; | 364 | int count; |
358 | 365 | ||
359 | printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); | 366 | printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]); |
@@ -398,7 +405,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit) | |||
398 | { | 405 | { |
399 | struct ds_status st; | 406 | struct ds_status st; |
400 | int count = 0, err = 0; | 407 | int count = 0, err = 0; |
401 | u8 buf[0x20]; | 408 | u8 buf[ST_SIZE]; |
402 | 409 | ||
403 | do { | 410 | do { |
404 | err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); | 411 | err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0); |
@@ -450,10 +457,11 @@ int ds_detect(struct ds_device *dev, struct ds_status *st) | |||
450 | 457 | ||
451 | static int ds_wait_status(struct ds_device *dev, struct ds_status *st) | 458 | static int ds_wait_status(struct ds_device *dev, struct ds_status *st) |
452 | { | 459 | { |
453 | u8 buf[0x20]; | 460 | u8 buf[ST_SIZE]; |
454 | int err, count = 0; | 461 | int err, count = 0; |
455 | 462 | ||
456 | do { | 463 | do { |
464 | st->status = 0; | ||
457 | err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); | 465 | err = ds_recv_status_nodump(dev, st, buf, sizeof(buf)); |
458 | #if 0 | 466 | #if 0 |
459 | if (err >= 0) { | 467 | if (err >= 0) { |
@@ -464,7 +472,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st) | |||
464 | printk("\n"); | 472 | printk("\n"); |
465 | } | 473 | } |
466 | #endif | 474 | #endif |
467 | } while (!(buf[0x08] & ST_IDLE) && !(err < 0) && ++count < 100); | 475 | } while (!(st->status & ST_IDLE) && !(err < 0) && ++count < 100); |
468 | 476 | ||
469 | if (err >= 16 && st->status & ST_EPOF) { | 477 | if (err >= 16 && st->status & ST_EPOF) { |
470 | printk(KERN_INFO "Resetting device after ST_EPOF.\n"); | 478 | printk(KERN_INFO "Resetting device after ST_EPOF.\n"); |
@@ -690,37 +698,106 @@ static int ds_write_block(struct ds_device *dev, u8 *buf, int len) | |||
690 | return !(err == len); | 698 | return !(err == len); |
691 | } | 699 | } |
692 | 700 | ||
693 | #if 0 | 701 | static void ds9490r_search(void *data, struct w1_master *master, |
694 | 702 | u8 search_type, w1_slave_found_callback callback) | |
695 | static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) | ||
696 | { | 703 | { |
704 | /* When starting with an existing id, the first id returned will | ||
705 | * be that device (if it is still on the bus most likely). | ||
706 | * | ||
707 | * If the number of devices found is less than or equal to the | ||
708 | * search_limit, that number of IDs will be returned. If there are | ||
709 | * more, search_limit IDs will be returned followed by a non-zero | ||
710 | * discrepency value. | ||
711 | */ | ||
712 | struct ds_device *dev = data; | ||
697 | int err; | 713 | int err; |
698 | u16 value, index; | 714 | u16 value, index; |
699 | struct ds_status st; | 715 | struct ds_status st; |
716 | u8 st_buf[ST_SIZE]; | ||
717 | int search_limit; | ||
718 | int found = 0; | ||
719 | int i; | ||
700 | 720 | ||
701 | memset(buf, 0, sizeof(buf)); | 721 | /* DS18b20 spec, 13.16 ms per device, 75 per second, sleep for |
722 | * discovering 8 devices (1 bulk transfer and 1/2 FIFO size) at a time. | ||
723 | */ | ||
724 | const unsigned long jtime = msecs_to_jiffies(1000*8/75); | ||
725 | /* FIFO 128 bytes, bulk packet size 64, read a multiple of the | ||
726 | * packet size. | ||
727 | */ | ||
728 | u64 buf[2*64/8]; | ||
702 | 729 | ||
703 | err = ds_send_data(ds_dev, (unsigned char *)&init, 8); | 730 | mutex_lock(&master->bus_mutex); |
704 | if (err) | ||
705 | return err; | ||
706 | 731 | ||
707 | ds_wait_status(ds_dev, &st); | 732 | /* address to start searching at */ |
733 | if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0) | ||
734 | goto search_out; | ||
735 | master->search_id = 0; | ||
708 | 736 | ||
709 | value = COMM_SEARCH_ACCESS | COMM_IM | COMM_SM | COMM_F | COMM_RTS; | 737 | value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F | |
710 | index = (conditional_search ? 0xEC : 0xF0) | (id_number << 8); | 738 | COMM_RTS; |
711 | err = ds_send_control(ds_dev, value, index); | 739 | search_limit = master->max_slave_count; |
712 | if (err) | 740 | if (search_limit > 255) |
713 | return err; | 741 | search_limit = 0; |
742 | index = search_type | (search_limit << 8); | ||
743 | if (ds_send_control(dev, value, index) < 0) | ||
744 | goto search_out; | ||
714 | 745 | ||
715 | ds_wait_status(ds_dev, &st); | 746 | do { |
747 | schedule_timeout(jtime); | ||
716 | 748 | ||
717 | err = ds_recv_data(ds_dev, (unsigned char *)buf, 8*id_number); | 749 | if (ds_recv_status_nodump(dev, &st, st_buf, sizeof(st_buf)) < |
718 | if (err < 0) | 750 | sizeof(st)) { |
719 | return err; | 751 | break; |
752 | } | ||
720 | 753 | ||
721 | return err/8; | 754 | if (st.data_in_buffer_status) { |
755 | /* Bulk in can receive partial ids, but when it does | ||
756 | * they fail crc and will be discarded anyway. | ||
757 | * That has only been seen when status in buffer | ||
758 | * is 0 and bulk is read anyway, so don't read | ||
759 | * bulk without first checking if status says there | ||
760 | * is data to read. | ||
761 | */ | ||
762 | err = ds_recv_data(dev, (u8 *)buf, sizeof(buf)); | ||
763 | if (err < 0) | ||
764 | break; | ||
765 | for (i = 0; i < err/8; ++i) { | ||
766 | ++found; | ||
767 | if (found <= search_limit) | ||
768 | callback(master, buf[i]); | ||
769 | /* can't know if there will be a discrepancy | ||
770 | * value after until the next id */ | ||
771 | if (found == search_limit) | ||
772 | master->search_id = buf[i]; | ||
773 | } | ||
774 | } | ||
775 | |||
776 | if (test_bit(W1_ABORT_SEARCH, &master->flags)) | ||
777 | break; | ||
778 | } while (!(st.status & (ST_IDLE | ST_HALT))); | ||
779 | |||
780 | /* only continue the search if some weren't found */ | ||
781 | if (found <= search_limit) { | ||
782 | master->search_id = 0; | ||
783 | } else if (!test_bit(W1_WARN_MAX_COUNT, &master->flags)) { | ||
784 | /* Only max_slave_count will be scanned in a search, | ||
785 | * but it will start where it left off next search | ||
786 | * until all ids are identified and then it will start | ||
787 | * over. A continued search will report the previous | ||
788 | * last id as the first id (provided it is still on the | ||
789 | * bus). | ||
790 | */ | ||
791 | dev_info(&dev->udev->dev, "%s: max_slave_count %d reached, " | ||
792 | "will continue next search.\n", __func__, | ||
793 | master->max_slave_count); | ||
794 | set_bit(W1_WARN_MAX_COUNT, &master->flags); | ||
795 | } | ||
796 | search_out: | ||
797 | mutex_unlock(&master->bus_mutex); | ||
722 | } | 798 | } |
723 | 799 | ||
800 | #if 0 | ||
724 | static int ds_match_access(struct ds_device *dev, u64 init) | 801 | static int ds_match_access(struct ds_device *dev, u64 init) |
725 | { | 802 | { |
726 | int err; | 803 | int err; |
@@ -894,6 +971,7 @@ static int ds_w1_init(struct ds_device *dev) | |||
894 | dev->master.write_block = &ds9490r_write_block; | 971 | dev->master.write_block = &ds9490r_write_block; |
895 | dev->master.reset_bus = &ds9490r_reset; | 972 | dev->master.reset_bus = &ds9490r_reset; |
896 | dev->master.set_pullup = &ds9490r_set_pullup; | 973 | dev->master.set_pullup = &ds9490r_set_pullup; |
974 | dev->master.search = &ds9490r_search; | ||
897 | 975 | ||
898 | return w1_add_master_device(&dev->master); | 976 | return w1_add_master_device(&dev->master); |
899 | } | 977 | } |
@@ -910,15 +988,13 @@ static int ds_probe(struct usb_interface *intf, | |||
910 | struct usb_endpoint_descriptor *endpoint; | 988 | struct usb_endpoint_descriptor *endpoint; |
911 | struct usb_host_interface *iface_desc; | 989 | struct usb_host_interface *iface_desc; |
912 | struct ds_device *dev; | 990 | struct ds_device *dev; |
913 | int i, err; | 991 | int i, err, alt; |
914 | 992 | ||
915 | dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); | 993 | dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL); |
916 | if (!dev) { | 994 | if (!dev) { |
917 | printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); | 995 | printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); |
918 | return -ENOMEM; | 996 | return -ENOMEM; |
919 | } | 997 | } |
920 | dev->spu_sleep = 0; | ||
921 | dev->spu_bit = 0; | ||
922 | dev->udev = usb_get_dev(udev); | 998 | dev->udev = usb_get_dev(udev); |
923 | if (!dev->udev) { | 999 | if (!dev->udev) { |
924 | err = -ENOMEM; | 1000 | err = -ENOMEM; |
@@ -928,20 +1004,25 @@ static int ds_probe(struct usb_interface *intf, | |||
928 | 1004 | ||
929 | usb_set_intfdata(intf, dev); | 1005 | usb_set_intfdata(intf, dev); |
930 | 1006 | ||
931 | err = usb_set_interface(dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); | 1007 | err = usb_reset_configuration(dev->udev); |
932 | if (err) { | 1008 | if (err) { |
933 | printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", | 1009 | dev_err(&dev->udev->dev, |
934 | intf->altsetting[0].desc.bInterfaceNumber, err); | 1010 | "Failed to reset configuration: err=%d.\n", err); |
935 | goto err_out_clear; | 1011 | goto err_out_clear; |
936 | } | 1012 | } |
937 | 1013 | ||
938 | err = usb_reset_configuration(dev->udev); | 1014 | /* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */ |
1015 | alt = 3; | ||
1016 | err = usb_set_interface(dev->udev, | ||
1017 | intf->altsetting[alt].desc.bInterfaceNumber, alt); | ||
939 | if (err) { | 1018 | if (err) { |
940 | printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); | 1019 | dev_err(&dev->udev->dev, "Failed to set alternative setting %d " |
1020 | "for %d interface: err=%d.\n", alt, | ||
1021 | intf->altsetting[alt].desc.bInterfaceNumber, err); | ||
941 | goto err_out_clear; | 1022 | goto err_out_clear; |
942 | } | 1023 | } |
943 | 1024 | ||
944 | iface_desc = &intf->altsetting[0]; | 1025 | iface_desc = &intf->altsetting[alt]; |
945 | if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { | 1026 | if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { |
946 | printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); | 1027 | printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); |
947 | err = -EINVAL; | 1028 | err = -EINVAL; |