Ejemplo n.º 1
0
/**
 * 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;
}
Ejemplo n.º 2
0
static ssize_t w1_f2d_read_bin(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);
	int todo = count;

	count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
	if (count == 0)
		return 0;

	mutex_lock(&sl->master->mutex);

	/* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */
	while (todo > 0) {
		int block_read;

		if (todo >= W1_F2D_READ_MAXLEN)
			block_read = W1_F2D_READ_MAXLEN;
		else
			block_read = todo;

		if (w1_f2d_readblock(sl, off, block_read, buf) < 0)
			count = -EIO;

		todo -= W1_F2D_READ_MAXLEN;
		buf += W1_F2D_READ_MAXLEN;
		off += W1_F2D_READ_MAXLEN;
	}

	mutex_unlock(&sl->master->mutex);

	return count;
}
Ejemplo n.º 3
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
Ejemplo n.º 4
0
static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
				   struct bin_attribute *bin_attr, char *buf,
				   loff_t off, size_t count)
{
	if (count != 1 || off != 0)
		return -EFAULT;
	return _read_reg(kobj_to_w1_slave(kobj),
		W1_F29_REG_CONTROL_AND_STATUS, buf);
}
Ejemplo n.º 5
0
static ssize_t w1_f29_read_cond_search_polarity(
	struct file *filp, struct kobject *kobj,
	struct bin_attribute *bin_attr,
	char *buf, loff_t off, size_t count)
{
	if (count != 1 || off != 0)
		return -EFAULT;
	return _read_reg(kobj_to_w1_slave(kobj),
		W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
}
Ejemplo n.º 6
0
static ssize_t w1_f29_write_status_control(
	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);
	u8 w1_buf[4];
	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_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
		w1_buf[2] = 0;
		w1_buf[3] = *buf;

		w1_write_block(sl->master, w1_buf, 4);
		if (w1_reset_resume_command(sl->master))
			goto error;

		w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
		w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
		w1_buf[2] = 0;

		w1_write_block(sl->master, w1_buf, 3);
		if (w1_read_8(sl->master) == *buf) {
			/* success! */
			mutex_unlock(&sl->master->mutex);
			return 1;
		}
	}
error:
	mutex_unlock(&sl->master->mutex);

	return -EIO;
}
Ejemplo n.º 7
0
static ssize_t output_write(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);
	u8 w1_buf[3];
	unsigned int retries = W1_F29_RETRIES;
	ssize_t bytes_written = -EIO;

	if (count != 1 || off != 0)
		return -EFAULT;

	dev_dbg(&sl->dev, "locking mutex for write_output");
	mutex_lock(&sl->master->bus_mutex);
	dev_dbg(&sl->dev, "mutex locked");

	if (w1_reset_select_slave(sl))
		goto out;

	do {
		w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
		w1_buf[1] = *buf;
		w1_buf[2] = ~(*buf);

		w1_write_block(sl->master, w1_buf, 3);

		if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE &&
		    optional_read_back_valid(sl, *buf)) {
			bytes_written = 1;
			goto out;
		}

		if (w1_reset_resume_command(sl->master))
			goto out; /* unrecoverable error */
		/* try again, the slave is ready for a command */
	} while (--retries);

out:
	mutex_unlock(&sl->master->bus_mutex);

	dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n",
		(bytes_written > 0) ? "succeeded" : "error", retries);

	return bytes_written;
}
Ejemplo n.º 8
0
static ssize_t w1_f2d_write_bin(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);
	int addr, len;
	int copy;

	count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
	if (count == 0)
		return 0;

	mutex_lock(&sl->master->bus_mutex);

	/* Can only write data in blocks of the size of the scratchpad */
	addr = off;
	len = count;
	while (len > 0) {

		/* if len too short or addr not aligned */
		if (len < W1_F2D_SCRATCH_SIZE || addr & W1_F2D_SCRATCH_MASK) {
			char tmp[W1_F2D_SCRATCH_SIZE];

			/* read the block and update the parts to be written */
			if (w1_f2d_readblock(sl, addr & ~W1_F2D_SCRATCH_MASK,
					W1_F2D_SCRATCH_SIZE, tmp)) {
				count = -EIO;
				goto out_up;
			}

			/* copy at most to the boundary of the PAGE or len */
			copy = W1_F2D_SCRATCH_SIZE -
				(addr & W1_F2D_SCRATCH_MASK);

			if (copy > len)
				copy = len;

			memcpy(&tmp[addr & W1_F2D_SCRATCH_MASK], buf, copy);
			if (w1_f2d_write(sl, addr & ~W1_F2D_SCRATCH_MASK,
					W1_F2D_SCRATCH_SIZE, tmp) < 0) {
				count = -EIO;
				goto out_up;
			}
		} else {

			copy = W1_F2D_SCRATCH_SIZE;
			if (w1_f2d_write(sl, addr, copy, buf) < 0) {
				count = -EIO;
				goto out_up;
			}
		}
		buf += copy;
		addr += copy;
		len -= copy;
	}

out_up:
	mutex_unlock(&sl->master->bus_mutex);

	return count;
}
Ejemplo n.º 9
0
static ssize_t w1_f29_write_output(
	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);
	u8 w1_buf[3];
	u8 readBack;
	unsigned int retries = W1_F29_RETRIES;

	if (count != 1 || off != 0)
		return -EFAULT;

	dev_dbg(&sl->dev, "locking mutex for write_output");
	mutex_lock(&sl->master->mutex);
	dev_dbg(&sl->dev, "mutex locked");

	if (w1_reset_select_slave(sl))
		goto error;

	while (retries--) {
		w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
		w1_buf[1] = *buf;
		w1_buf[2] = ~(*buf);
		w1_write_block(sl->master, w1_buf, 3);

		readBack = w1_read_8(sl->master);
		/* here the master could read another byte which
		   would be the PIO reg (the actual pin logic state)
		   since in this driver we don't know which pins are
		   in and outs, there's no value to read the state and
		   compare. with (*buf) so end this command abruptly: */
		if (w1_reset_resume_command(sl->master))
			goto error;

		if (readBack != 0xAA) {
			/* try again, the slave is ready for a command */
			continue;
		}

		/* go read back the output latches */
		/* (the direct effect of the write above) */
		w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
		w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE;
		w1_buf[2] = 0;
		w1_write_block(sl->master, w1_buf, 3);
		/* read the result of the READ_PIO_REGS command */
		if (w1_read_8(sl->master) == *buf) {
			/* success! */
			mutex_unlock(&sl->master->mutex);
			dev_dbg(&sl->dev,
				"mutex unlocked, retries:%d", retries);
			return 1;
		}
	}
error:
	mutex_unlock(&sl->master->mutex);
	dev_dbg(&sl->dev, "mutex unlocked in error, retries:%d", retries);

	return -EIO;
}
Ejemplo n.º 10
0
static ssize_t w1_ds2502_read_eeprom(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);
	struct w1_gpio_platform_data *w1_gpio_pdata =
			sl->master->bus_master->data;
	struct w1_ds2502_data *data = sl->family_data;
	unsigned int num_bytes_copied = 0;
	int error;

	CDBG("%s: Enter count=%zu\n", __func__, count);

	if (count < DS2502_FILE_OUTPUT_SIZE) {
		pr_err("%s: input buffer too small %zu", __func__, count);
		return num_bytes_copied;
	}

	if (data->status == STATUS_DATA_NOT_READ) {

		/* turn on regulator */
		if (w1_gpio_pdata->w1_gpio_vdd != NULL) {
			error = regulator_enable(w1_gpio_pdata->w1_gpio_vdd);
			if (error) {
				pr_err("%s: Error %d enabling w1-vdd regulator\n",
					__func__, error);
			} else {
				w1_gpio_pdata->regulator_en = 1;
				CDBG("%s: en: w1-vdd regulator is %s\n", __func__,
					regulator_is_enabled(w1_gpio_pdata->w1_gpio_vdd) ?
					"on" : "off");
			}
		}

		/* read data for first time */
		mutex_lock(&sl->master->mutex);

		w1_ds2502_first_eeprom_read(sl);

		mutex_unlock(&sl->master->mutex);

		/* turn off regulator */
		if (w1_gpio_pdata->regulator_en) {
			error = regulator_disable(w1_gpio_pdata->w1_gpio_vdd);
			if (error) {
				pr_err("%s: Error %d disabling w1-vdd regulator\n",
					__func__, error);
			} else {
				w1_gpio_pdata->regulator_en = 0;
				CDBG("%s: dis: w1-vdd regulator is %s\n", __func__,
					regulator_is_enabled(w1_gpio_pdata->w1_gpio_vdd) ?
					"on" : "off");
			}
		}
	} else {
		/* already read, so skip reading */
		CDBG("%s: already read data once\n", __func__);
	}

	if (data->status == STATUS_DATA_POPULATED) {
#ifdef W1_DS2502_DRIVER_DEBUG
		w1_ds2502_dump_data(data);
#endif
		memcpy(buf, &data->rawdata[0], DS2502_EEPROM_SIZE);
		memcpy(buf+DS2502_EEPROM_SIZE, &data->crcvalid, 1);
		num_bytes_copied = DS2502_FILE_OUTPUT_SIZE;
	}

	return (num_bytes_copied == 0) ? 0 : count;
}