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