* 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;
};
}
}
+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;
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;
}
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;
}
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);
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);
* 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;
return -ENOMEM;
}
dev->spu_sleep = 0;
+ dev->spu_bit = 0;
dev->udev = usb_get_dev(udev);
if (!dev->udev) {
err = -ENOMEM;