/** * Writing to the activity file resets the activity latches. */ static ssize_t w1_f29_write_activity( struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); unsigned int retries = W1_F29_RETRIES; if (count != 1 || off != 0) return -EFAULT; mutex_lock(&sl->master->mutex); if (w1_reset_select_slave(sl)) goto error; while (retries--) { w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES); if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) { mutex_unlock(&sl->master->mutex); return 1; } if (w1_reset_resume_command(sl->master)) goto error; } error: mutex_unlock(&sl->master->mutex); return -EIO; }
static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) { u8 w1_buf[3]; if (w1_reset_resume_command(sl->master)) return false; w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE; w1_buf[2] = 0; w1_write_block(sl->master, w1_buf, 3); return (w1_read_8(sl->master) == expected); }
static ssize_t w1_f29_write_status_control( struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[4]; unsigned int retries = W1_F29_RETRIES; if (count != 1 || off != 0) return -EFAULT; mutex_lock(&sl->master->mutex); if (w1_reset_select_slave(sl)) goto error; while (retries--) { w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG; w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS; w1_buf[2] = 0; w1_buf[3] = *buf; w1_write_block(sl->master, w1_buf, 4); if (w1_reset_resume_command(sl->master)) goto error; w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS; w1_buf[2] = 0; w1_write_block(sl->master, w1_buf, 3); if (w1_read_8(sl->master) == *buf) { /* success! */ mutex_unlock(&sl->master->mutex); return 1; } } error: mutex_unlock(&sl->master->mutex); return -EIO; }
static ssize_t output_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[3]; unsigned int retries = W1_F29_RETRIES; ssize_t bytes_written = -EIO; if (count != 1 || off != 0) return -EFAULT; dev_dbg(&sl->dev, "locking mutex for write_output"); mutex_lock(&sl->master->bus_mutex); dev_dbg(&sl->dev, "mutex locked"); if (w1_reset_select_slave(sl)) goto out; do { w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE; w1_buf[1] = *buf; w1_buf[2] = ~(*buf); w1_write_block(sl->master, w1_buf, 3); if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE && optional_read_back_valid(sl, *buf)) { bytes_written = 1; goto out; } if (w1_reset_resume_command(sl->master)) goto out; /* unrecoverable error */ /* try again, the slave is ready for a command */ } while (--retries); out: mutex_unlock(&sl->master->bus_mutex); dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n", (bytes_written > 0) ? "succeeded" : "error", retries); return bytes_written; }
static ssize_t w1_f29_write_output( struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { struct w1_slave *sl = kobj_to_w1_slave(kobj); u8 w1_buf[3]; u8 readBack; unsigned int retries = W1_F29_RETRIES; if (count != 1 || off != 0) return -EFAULT; dev_dbg(&sl->dev, "locking mutex for write_output"); mutex_lock(&sl->master->mutex); dev_dbg(&sl->dev, "mutex locked"); if (w1_reset_select_slave(sl)) goto error; while (retries--) { w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE; w1_buf[1] = *buf; w1_buf[2] = ~(*buf); w1_write_block(sl->master, w1_buf, 3); readBack = w1_read_8(sl->master); /* here the master could read another byte which would be the PIO reg (the actual pin logic state) since in this driver we don't know which pins are in and outs, there's no value to read the state and compare. with (*buf) so end this command abruptly: */ if (w1_reset_resume_command(sl->master)) goto error; if (readBack != 0xAA) { /* try again, the slave is ready for a command */ continue; } /* go read back the output latches */ /* (the direct effect of the write above) */ w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS; w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE; w1_buf[2] = 0; w1_write_block(sl->master, w1_buf, 3); /* read the result of the READ_PIO_REGS command */ if (w1_read_8(sl->master) == *buf) { /* success! */ mutex_unlock(&sl->master->mutex); dev_dbg(&sl->dev, "mutex unlocked, retries:%d", retries); return 1; } } error: mutex_unlock(&sl->master->mutex); dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries); return -EIO; }