From 7e4cd730d806fc176addaa70a9cec977dab98bdf Mon Sep 17 00:00:00 2001 From: David Fries Date: Wed, 15 Oct 2008 22:05:10 -0700 Subject: [PATCH] --- yaml --- r: 114943 b: refs/heads/master c: ade6d810b585d749db24d734947a30a29470cccd h: refs/heads/master i: 114941: 0a9322336bcb7e6a190eb16d29f05f8fa931f995 114939: b72cb6ceefa5232332b1011349b05628be087472 114935: 502d7f5c38569ca66ace7a8490dfa2ae68518179 114927: f40a52dc130b3e6080bc81cabb6bc53a9d9bfec3 114911: b46d36d2080a2be3eed58e1d4033a3ce80c092bb 114879: 17bbd3f4274f1c8cfc1e3900fdd57fc9e62e0d2e 114815: b3dad57aaa4edd385c907c50a38bf650b42bbb68 114687: b5e6a135573c779a59c8ee52a2b1c8f9dfd54520 v: v3 --- [refs] | 2 +- trunk/drivers/w1/masters/ds2490.c | 64 ++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/[refs] b/[refs] index 690ae12ec975..d14c73fa9901 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3823ee44cfa8b0e6edbc0c21b81b49b95a27ca0d +refs/heads/master: ade6d810b585d749db24d734947a30a29470cccd diff --git a/trunk/drivers/w1/masters/ds2490.c b/trunk/drivers/w1/masters/ds2490.c index 4faf4f9ec068..59ad6e95af8f 100644 --- a/trunk/drivers/w1/masters/ds2490.c +++ b/trunk/drivers/w1/masters/ds2490.c @@ -141,6 +141,10 @@ struct ds_device * 0: pullup not active, else duration in milliseconds */ int spu_sleep; + /* spu_bit contains COMM_SPU or 0 depending on if the strong pullup + * should be active or not for writes. + */ + u16 spu_bit; struct w1_bus_master master; }; @@ -311,6 +315,25 @@ static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count) } } +static void ds_reset_device(struct ds_device *dev) +{ + ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); + /* Always allow strong pullup which allow individual writes to use + * the strong pullup. + */ + if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE)) + printk(KERN_ERR "ds_reset_device: " + "Error allowing strong pullup\n"); + /* Chip strong pullup time was cleared. */ + if (dev->spu_sleep) { + /* lower 4 bits are 0, see ds_set_pullup */ + u8 del = dev->spu_sleep>>4; + if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del)) + printk(KERN_ERR "ds_reset_device: " + "Error setting duration\n"); + } +} + static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) { int count, err; @@ -444,7 +467,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st) if (err >= 16 && st->status & ST_EPOF) { printk(KERN_INFO "Resetting device after ST_EPOF.\n"); - ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); + ds_reset_device(dev); /* Always dump the device status. */ count = 101; } @@ -509,24 +532,26 @@ static int ds_set_speed(struct ds_device *dev, int speed) static int ds_set_pullup(struct ds_device *dev, int delay) { - int err; + int err = 0; u8 del = 1 + (u8)(delay >> 4); + /* Just storing delay would not get the trunication and roundup. */ + int ms = del<<4; + + /* Enable spu_bit if a delay is set. */ + dev->spu_bit = delay ? COMM_SPU : 0; + /* If delay is zero, it has already been disabled, if the time is + * the same as the hardware was last programmed to, there is also + * nothing more to do. Compare with the recalculated value ms + * rather than del or delay which can have a different value. + */ + if (delay == 0 || ms == dev->spu_sleep) + return err; - dev->spu_sleep = 0; - err = ds_send_control_mode(dev, MOD_PULSE_EN, delay ? PULSE_SPUE : 0); + err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); if (err) return err; - if (delay) { - err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); - if (err) - return err; - - /* Just storing delay would not get the trunication and - * roundup. - */ - dev->spu_sleep = del<<4; - } + dev->spu_sleep = ms; return err; } @@ -577,11 +602,11 @@ static int ds_write_byte(struct ds_device *dev, u8 byte) struct ds_status st; u8 rbyte; - err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); + err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte); if (err) return err; - if (dev->spu_sleep) + if (dev->spu_bit) msleep(dev->spu_sleep); err = ds_wait_status(dev, &st); @@ -648,11 +673,11 @@ static int ds_write_block(struct ds_device *dev, u8 *buf, int len) if (err < 0) return err; - err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); + err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | dev->spu_bit, len); if (err) return err; - if (dev->spu_sleep) + if (dev->spu_bit) msleep(dev->spu_sleep); ds_wait_status(dev, &st); @@ -849,7 +874,7 @@ static int ds_w1_init(struct ds_device *dev) * the input buffer. This will cause the next read to fail * see the note in ds_recv_data. */ - ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); + ds_reset_device(dev); dev->master.data = dev; dev->master.touch_bit = &ds9490r_touch_bit; @@ -892,6 +917,7 @@ static int ds_probe(struct usb_interface *intf, return -ENOMEM; } dev->spu_sleep = 0; + dev->spu_bit = 0; dev->udev = usb_get_dev(udev); if (!dev->udev) { err = -ENOMEM;