static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, int io) { struct w1_slave *sl = container_of(dev, struct w1_slave, dev); if (!dev) return 0; mutex_lock(&sl->master->bus_mutex); if (addr > DS2760_DATA_SIZE || addr < 0) { count = 0; goto out; } if (addr + count > DS2760_DATA_SIZE) count = DS2760_DATA_SIZE - addr; if (!w1_reset_select_slave(sl)) { if (!io) { w1_write_8(sl->master, W1_DS2760_READ_DATA); w1_write_8(sl->master, addr); count = w1_read_block(sl->master, buf, count); } else { w1_write_8(sl->master, W1_DS2760_WRITE_DATA); w1_write_8(sl->master, addr); w1_write_block(sl->master, buf, count); /* XXX w1_write_block returns void, not n_written */ } } out: mutex_unlock(&sl->master->bus_mutex); return count; }
void w1_bq27000_write(struct device *dev, u8 buf, u8 reg) { struct w1_slave *sl = container_of(dev, struct w1_slave, dev); if (!dev) { pr_info("Could not obtain slave dev ptr\n"); return; } w1_write_8(sl->master, HDQ_CMD_WRITE | reg); w1_write_8(sl->master, buf); }
/** * 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 enum w1_ds2502_state w1_ds2502_send_command(struct w1_slave *sl) { enum w1_ds2502_state next_state = STATE_DETECT; unsigned char current_cmd; unsigned char bus_crc; unsigned char cmd_count; unsigned char computed_crc; CDBG("%s: Enter\n", __func__); for (cmd_count = 0; cmd_count < DS2503_NUM_READ_MEM_CMD; cmd_count++) { current_cmd = read_memory_cmd_addr[cmd_count]; w1_write_8(sl->master, current_cmd); } /* Time to read CRC (1byte) for MEMORY FUNCTION COMMAND. This will be * compared with the computed CRC by the master. */ bus_crc = w1_read_8(sl->master); computed_crc = w1_calc_crc8((unsigned char *)read_memory_cmd_addr, DS2503_NUM_READ_MEM_CMD); CDBG("%s: bus_crc:0x%x computed_crc:0x%x\n", __func__, bus_crc, computed_crc); if (bus_crc == computed_crc) next_state = STATE_RX_DATA; return next_state; }
static int w1_ds2405_select(struct w1_slave *sl, bool only_active) { struct w1_master *dev = sl->master; u64 dev_addr = le64_to_cpu(*(u64 *)&sl->reg_num); unsigned int bit_ctr; if (w1_reset_bus(dev) != 0) return 0; /* * We cannot use a normal Match ROM command * since doing so would toggle PIO state */ w1_write_8(dev, only_active ? W1_ALARM_SEARCH : W1_SEARCH); for (bit_ctr = 0; bit_ctr < 64; bit_ctr++) { int bit2send = !!(dev_addr & BIT(bit_ctr)); u8 ret; ret = w1_triplet(dev, bit2send); if ((ret & (BIT(0) | BIT(1))) == (BIT(0) | BIT(1))) /* no devices found */ return 0; if (!!(ret & BIT(2)) != bit2send) /* wrong direction taken - no such device */ return 0; } return 1; }
static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd) { struct w1_slave *sl = container_of(dev, struct w1_slave, dev); if (!dev) return -EINVAL; mutex_lock(&sl->master->bus_mutex); if (w1_reset_select_slave(sl) == 0) { w1_write_8(sl->master, cmd); w1_write_8(sl->master, addr); } mutex_unlock(&sl->master->bus_mutex); return 0; }
/** * Resets the bus and then selects the slave by sending either a skip rom * or a rom match. * The w1 master lock must be held. * * @param sl the slave to select * @return 0=success, anything else=error */ int w1_reset_overdrive_select_slave(struct w1_slave *sl) { if (w1_reset_bus(sl->master)) return -1; w1_write_8(sl->master, W1_OVSKIP_ROM); return 0; }
/* * Writes to the scratchpad and reads it back for verification. * Then copies the scratchpad to EEPROM. * The data must be aligned at W1_F2D_SCRATCH_SIZE bytes and * must be W1_F2D_SCRATCH_SIZE bytes long. * The master must be locked. * * @param sl The slave structure * @param addr Address for the write * @param len length must be <= (W1_F2D_PAGE_SIZE - (addr & W1_F2D_PAGE_MASK)) * @param data The data to write * @return 0=Success -1=failure */ static int ds2431_write(struct w1_device *dev, int addr, int len, const u8 *data) { struct w1_bus *bus = dev->bus; int tries = W1_F2D_READ_RETRIES; u8 wrbuf[4]; u8 rdbuf[W1_F2D_SCRATCH_SIZE + 3]; u8 es = (addr + len - 1) % W1_F2D_SCRATCH_SIZE; retry: /* Write the data to the scratchpad */ if (w1_reset_select_slave(dev)) return -1; wrbuf[0] = W1_F2D_WRITE_SCRATCH; wrbuf[1] = addr & 0xff; wrbuf[2] = addr >> 8; w1_write_block(bus, wrbuf, 3); w1_write_block(bus, data, len); /* Read the scratchpad and verify */ if (w1_reset_select_slave(dev)) return -1; w1_write_8(bus, W1_F2D_READ_SCRATCH); w1_read_block(bus, rdbuf, len + 3); /* Compare what was read against the data written */ if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) || (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) { if (--tries) goto retry; dev_err(&dev->dev, "could not write to eeprom, scratchpad compare failed %d times\n", W1_F2D_READ_RETRIES); return -1; } /* Copy the scratchpad to EEPROM */ if (w1_reset_select_slave(dev)) return -1; wrbuf[0] = W1_F2D_COPY_SCRATCH; wrbuf[3] = es; w1_write_block(bus, wrbuf, 4); /* Sleep for tprog ms to wait for the write to complete */ mdelay(W1_F2D_TPROG_MS); /* Reset the bus to wake up the EEPROM */ w1_reset_bus(bus); return 0; }
/** * w1_reset_resume_command() - resume instead of another match ROM * @dev: the master device * * When the workflow with a slave amongst many requires several * successive commands a reset between each, this function is similar * to doing a reset then a match ROM for the last matched ROM. The * advantage being that the matched ROM step is skipped in favor of the * resume command. The slave must support the command of course. * * If the bus has only one slave, traditionnaly the match ROM is skipped * and a "SKIP ROM" is done for efficiency. On multi-slave busses, this * doesn't work of course, but the resume command is the next best thing. * * The w1 master lock must be held. */ int w1_reset_resume_command(struct w1_master *dev) { if (w1_reset_bus(dev)) return -1; /* This will make only the last matched slave perform a skip ROM. */ w1_write_8(dev, W1_RESUME_CMD); return 0; }
int w1_reset_resume_command(struct w1_master *dev) { if (w1_reset_bus(dev)) return -1; /* */ w1_write_8(dev, W1_RESUME_CMD); return 0; }
void w1_write_block(struct w1_master *dev, u8 *buf, int len) { int i; if (dev->bus_master->write_block) dev->bus_master->write_block(dev->bus_master->data, buf, len); else for (i = 0; i < len; ++i) w1_write_8(dev, buf[i]); }
static enum w1_ds2502_state w1_ds2502_identify(struct w1_slave *sl) { enum w1_ds2502_state next_state = STATE_SEND_COMMAND; CDBG("%s: Enter\n", __func__); w1_write_8(sl->master, DS2502_SKIP_ROM_CMD); return next_state; }
int w1_bq27000_read(struct device *dev, u8 reg) { u8 val; struct w1_slave *sl = container_of(dev, struct w1_slave, dev); if (!dev) return 0; w1_write_8(sl->master, HDQ_CMD_READ | reg); val = w1_read_8(sl->master); return val; }
/** * w1_write_block() - Writes a series of bytes. * @dev: the master device * @buf: pointer to the data to write * @len: the number of bytes to write */ void w1_write_block(struct w1_master *dev, const u8 *buf, int len) { int i; if (dev->bus_master->write_block) { w1_pre_write(dev); dev->bus_master->write_block(dev->bus_master->data, buf, len); } else for (i = 0; i < len; ++i) w1_write_8(dev, buf[i]); /* calls w1_pre_write */ w1_post_write(dev); }
/** * Resets the bus and then selects the slave by sending either a skip rom * or a rom match. * The w1 master lock must be held. * * @param sl the slave to select * @return 0=success, anything else=error */ int w1_reset_select_slave(struct w1_slave *sl) { if (w1_reset_bus(sl->master)) return -1; if (sl->master->slave_count == 1) w1_write_8(sl->master, W1_SKIP_ROM); else { u8 match[9] = {W1_MATCH_ROM, }; memcpy(&match[1], (u8 *)&sl->reg_num, 8); w1_write_block(sl->master, match, 9); } return 0; }
static int w1_ds2781_do_io(struct device *dev, char *buf, int addr, size_t count, int io) { struct w1_slave *sl = container_of(dev, struct w1_slave, dev); if (addr > DS2781_DATA_SIZE || addr < 0) return 0; count = min_t(int, count, DS2781_DATA_SIZE - addr); if (w1_reset_select_slave(sl) == 0) { if (io) { w1_write_8(sl->master, W1_DS2781_WRITE_DATA); w1_write_8(sl->master, addr); w1_write_block(sl->master, buf, count); } else { w1_write_8(sl->master, W1_DS2781_READ_DATA); w1_write_8(sl->master, addr); count = w1_read_block(sl->master, buf, count); } } return count; }