Beispiel #1
0
static ssize_t output_store(struct device *device,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{
	struct w1_slave *sl = dev_to_w1_slave(device);
	struct w1_master *dev = sl->master;

	int ret, current_pio;
	unsigned int val;
	ssize_t f_retval;

	if (count < 1)
		return -EINVAL;

	if (sscanf(buf, " %u%n", &val, &ret) < 1)
		return -EINVAL;

	if (val != 0 && val != 1)
		return -EINVAL;

	f_retval = ret;

	ret = mutex_lock_interruptible(&dev->bus_mutex);
	if (ret)
		return ret;

	current_pio = w1_ds2405_read_pio(sl);
	if (current_pio < 0) {
		f_retval = current_pio;
		goto out_unlock;
	}

	if (current_pio == val)
		goto out_unlock;

	if (w1_reset_bus(dev) != 0) {
		f_retval = -ENODEV;
		goto out_unlock;
	}

	/*
	 * can't use w1_reset_select_slave() here since it uses Skip ROM if
	 * there is only one device on bus
	 */
	do {
		u64 dev_addr = le64_to_cpu(*(u64 *)&sl->reg_num);
		u8 cmd[9];

		cmd[0] = W1_MATCH_ROM;
		memcpy(&cmd[1], &dev_addr, sizeof(dev_addr));

		w1_write_block(dev, cmd, sizeof(cmd));
	} while (0);

out_unlock:
	w1_reset_bus(dev);
	mutex_unlock(&dev->bus_mutex);

	return f_retval;
}
Beispiel #2
0
static ssize_t output_show(struct device *device,
			   struct device_attribute *attr, char *buf)
{
	struct w1_slave *sl = dev_to_w1_slave(device);
	struct w1_master *dev = sl->master;

	int ret;
	ssize_t f_retval;

	ret = mutex_lock_interruptible(&dev->bus_mutex);
	if (ret)
		return ret;

	ret = w1_ds2405_read_pio(sl);
	if (ret < 0) {
		f_retval = ret;
		goto out_unlock;
	}

	*buf = ret ? '1' : '0';
	f_retval = 1;

out_unlock:
	w1_reset_bus(dev);
	mutex_unlock(&dev->bus_mutex);

	return f_retval;
}
Beispiel #3
0
static ssize_t state_show(struct device *device,
			  struct device_attribute *attr, char *buf)
{
	struct w1_slave *sl = dev_to_w1_slave(device);
	struct w1_master *dev = sl->master;

	int ret;
	ssize_t f_retval;
	u8 state;

	ret = mutex_lock_interruptible(&dev->bus_mutex);
	if (ret)
		return ret;

	if (!w1_ds2405_select(sl, false)) {
		f_retval = -ENODEV;
		goto out_unlock;
	}

	state = w1_read_8(dev);
	if (state != 0 &&
	    state != 0xff) {
		dev_err(device, "non-consistent state %x\n", state);
		f_retval = -EIO;
		goto out_unlock;
	}

	*buf = state ? '1' : '0';
	f_retval = 1;

out_unlock:
	w1_reset_bus(dev);
	mutex_unlock(&dev->bus_mutex);

	return f_retval;
}
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;
}