Example #1
0
/*
 * 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;
}
Example #5
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;
}
Example #7
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;
}
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;

}
Example #9
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;
}
Example #10
0
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;
}