/* * Read a block from W1 ROM two times and compares the results. * If they are equal they are returned, otherwise the read * is repeated W1_F2D_READ_RETRIES times. * * count must not exceed W1_F2D_READ_MAXLEN. */ int ds2431_readblock(struct w1_device *dev, int off, int count, char *buf) { struct w1_bus *bus = dev->bus; u8 wrbuf[3]; u8 cmp[W1_F2D_READ_MAXLEN]; int tries = W1_F2D_READ_RETRIES; do { wrbuf[0] = W1_F2D_READ_EEPROM; wrbuf[1] = off & 0xff; wrbuf[2] = off >> 8; if (w1_reset_select_slave(dev)) return -1; w1_write_block(bus, wrbuf, 3); w1_read_block(bus, buf, count); if (w1_reset_select_slave(dev)) return -1; w1_write_block(bus, wrbuf, 3); w1_read_block(bus, cmp, count); if (!memcmp(cmp, buf, count)) return 0; } while (--tries); dev_err(&dev->dev, "proof reading failed %d times\n", W1_F2D_READ_RETRIES); return -1; }
/* * Read a block from W1 ROM two times and compares the results. * If they are equal they are returned, otherwise the read * is repeated W1_F2D_READ_RETRIES times. * * count must not exceed W1_F2D_READ_MAXLEN. */ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf) { u8 wrbuf[3]; u8 cmp[W1_F2D_READ_MAXLEN]; int tries = W1_F2D_READ_RETRIES; do { wrbuf[0] = W1_F2D_READ_EEPROM; wrbuf[1] = off & 0xff; wrbuf[2] = off >> 8; if (w1_reset_select_slave(sl)) return -1; w1_write_block(sl->master, wrbuf, 3); w1_read_block(sl->master, buf, count); if (w1_reset_select_slave(sl)) return -1; w1_write_block(sl->master, wrbuf, 3); w1_read_block(sl->master, cmp, count); if (!memcmp(cmp, buf, count)) return 0; } while (--tries); dev_err(&sl->dev, "proof reading failed %d times\n", W1_F2D_READ_RETRIES); return -1; }
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; }
static int w1_bq2022_add_slave(struct w1_slave *sl) { char cmd[4]; int retries = 5; bq2022_battery_info battery_info; if (!sl) { pr_err("%s: No w1 device\n", __func__); return -1; } retry: /* Initialization, master's mutex should be hold */ if (!(retries--)) { pr_err("%s: fatal error\n", __func__); return -1; } if (w1_reset_bus(sl->master)) { pr_warn("%s: reset bus failed, just retry!\n", __func__); goto retry; } /* rom comm byte + read comm byte + addr 2 bytes */ cmd[0] = BQ2022_COMMAND_SKIP_SERIALIZATION_ROM; cmd[1] = BQ2022_COMMAND_READ_MEMORY_FIELD_CRC; cmd[2] = 0x0; cmd[3] = 0x0; /* send command */ w1_write_block(sl->master, cmd, 4); /* crc verified for read comm byte and addr 2 bytes*/ if (w1_read_8(sl->master) != w1_calc_crc8(&cmd[1], 3)) { pr_err("%s: com crc err\n", __func__); goto retry; } /* read the whole memory, 1024-bit */ w1_read_block(sl->master, (char*) &battery_info, sizeof(battery_info)); /* crc verified for data */ if (w1_read_8(sl->master) != w1_calc_crc8((char*) &battery_info, sizeof(battery_info))) { pr_err("%s: w1_bq2022 data crc err\n", __func__); goto retry; } if (battery_info.magic != BQ2022_BATTERY_INFO_MAGIC) { pr_err("%s: invalid battery info magic\n", __func__); return -1; } pr_hexdump(&battery_info, sizeof(battery_info)); w1_bq2022_battery_info_id = battery_info.data1 | battery_info.data2 << 8; w1_bq2022_print_battery(); return 0; }
static ssize_t w1_f12_read_state( struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { u8 w1_buf[6]={W1_F12_FUNC_READ_STATUS, 7, 0, 0, 0, 0}; struct w1_slave *sl = kobj_to_w1_slave(kobj); u16 crc=0; int i; ssize_t rtnval=1; if (off != 0) return 0; if (!buf) return -EINVAL; mutex_lock(&sl->master->bus_mutex); if (w1_reset_select_slave(sl)) { mutex_unlock(&sl->master->bus_mutex); return -EIO; } w1_write_block(sl->master, w1_buf, 3); w1_read_block(sl->master, w1_buf+3, 3); for (i=0; i<6; i++) crc=crc16_byte(crc, w1_buf[i]); if (crc==0xb001) /* good read? */ *buf=((w1_buf[3]>>5)&3)|0x30; else
static enum w1_ds2502_state w1_ds2502_rx_data(struct w1_slave *sl, unsigned char retry_cnt) { enum w1_ds2502_state next_state = STATE_DETECT; unsigned int data_crc; unsigned int computed_crc; struct w1_ds2502_data *data = sl->family_data; CDBG("%s: Enter\n", __func__); /* start address was sent in STATE_SEND_COMMAND state */ w1_read_block(sl->master, &data->rawdata[0], DS2502_EEPROM_SIZE); /* check CRC16 in data */ data_crc = (data->rawdata[DS2502_EEPROM_SIZE-2] << 8) | (data->rawdata[DS2502_EEPROM_SIZE-1]); computed_crc = crc16(CRC16_INIT, &data->rawdata[0], DS2502_EEPROM_SIZE-2); CDBG("%s: data_crc:0x%x computed_crc:0x%x\n", __func__, data_crc, computed_crc); if (computed_crc == data_crc) { data->crcvalid = 1; next_state = STATE_READ_DONE; } if (data->crcvalid == 0 && retry_cnt == MAX_RETRIES-1) { /* tried a few times, but CRC is invalid */ pr_err("%s: CRC invalid, report data read (%d)", __func__, retry_cnt); next_state = STATE_READ_DONE; } return next_state; }
/* * 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; }
static int w1_bq2022_read(void) { struct w1_slave *sl = bq2022_slave; char cmd[4]; u8 crc, calc_crc; int retries = 5; if (!sl) { pr_err("No w1 device\n"); return -1; } retry: /* Initialization, master's mutex should be hold */ if (!(retries--)) { pr_err("w1_bq2022_read fatal error\n"); return -1; } if (w1_reset_bus(sl->master)) { pr_warn("reset bus failed, just retry!\n"); goto retry; } /* rom comm byte + read comm byte + addr 2 bytes */ cmd[0] = HDQ_CMD_SKIP_ROM; cmd[1] = HDQ_CMD_READ_FIELD; cmd[2] = 0x0; cmd[3] = 0x0; /* send command */ w1_write_block(sl->master, cmd, 4); /* crc verified for read comm byte and addr 2 bytes*/ crc = w1_read_8(sl->master); calc_crc = w1_calc_crc8(&cmd[1], 3); if (calc_crc != crc) { pr_err("com crc err\n"); goto retry; } /* read the whole memory, 1024-bit */ w1_read_block(sl->master, batt_crypt_info, 128); /* crc verified for data */ crc = w1_read_8(sl->master); calc_crc = w1_calc_crc8(batt_crypt_info, 128); if (calc_crc != crc) { pr_err("w1_bq2022 data crc err\n"); goto retry; } 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; }
static ssize_t w1_counter_read(struct device *device, struct device_attribute *attr, char *out_buf) { struct w1_slave *sl = dev_to_w1_slave(device); struct w1_master *dev = sl->master; u8 rbuf[COUNTER_COUNT * READ_BYTE_COUNT]; u8 wrbuf[3]; int rom_addr; int read_byte_count; int result; ssize_t c; int ii; int p; int crc; c = PAGE_SIZE; rom_addr = (12 << 5) + 31; wrbuf[0] = 0xA5; wrbuf[1] = rom_addr & 0xFF; wrbuf[2] = rom_addr >> 8; mutex_lock(&dev->mutex); if (!w1_reset_select_slave(sl)) { w1_write_block(dev, wrbuf, 3); read_byte_count = 0; for (p = 0; p < 4; p++) { /* * 1 byte for first bytes in ram page read * 4 bytes for counter * 4 bytes for zero bits * 2 bytes for crc * 31 remaining bytes from the ram page */ read_byte_count += w1_read_block(dev, rbuf + (p * READ_BYTE_COUNT), READ_BYTE_COUNT); for (ii = 0; ii < READ_BYTE_COUNT; ++ii) c -= snprintf(out_buf + PAGE_SIZE - c, c, "%02x ", rbuf[(p * READ_BYTE_COUNT) + ii]); if (read_byte_count != (p + 1) * READ_BYTE_COUNT) { dev_warn(device, "w1_counter_read() returned %u bytes " "instead of %d bytes wanted.\n", read_byte_count, READ_BYTE_COUNT); c -= snprintf(out_buf + PAGE_SIZE - c, c, "crc=NO\n"); } else { if (p == 0) { crc = crc16(CRC16_INIT, wrbuf, 3); crc = crc16(crc, rbuf, 11); } else { /* * DS2423 calculates crc from all bytes * read after the previous crc bytes. */ crc = crc16(CRC16_INIT, (rbuf + 11) + ((p - 1) * READ_BYTE_COUNT), READ_BYTE_COUNT); } if (crc == CRC16_VALID) { result = 0; for (ii = 4; ii > 0; ii--) { result <<= 8; result |= rbuf[(p * READ_BYTE_COUNT) + ii]; } c -= snprintf(out_buf + PAGE_SIZE - c, c, "crc=YES c=%d\n", result); } else { c -= snprintf(out_buf + PAGE_SIZE - c, c, "crc=NO\n"); } } } } else { c -= snprintf(out_buf + PAGE_SIZE - c, c, "Connection error"); } mutex_unlock(&dev->mutex); return PAGE_SIZE - c; }