drivers/w1/slaves/w1_ds2805.c

Source file repositories/reference/linux-study-clean/drivers/w1/slaves/w1_ds2805.c

File Facts

System
Linux kernel
Corpus path
drivers/w1/slaves/w1_ds2805.c
Extension
.c
Size
7002 bytes
Lines
299
Domain
Driver Families
Bucket
drivers/w1
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (w1_f0d_readblock(sl, off, block_read, buf) < 0) {
			count = -EIO;
			break;
		}

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

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

	return count;
}

/*
 * Writes to the scratchpad and reads it back for verification.
 * Then copies the scratchpad to EEPROM.
 * The data must be aligned at W1_F0D_SCRATCH_SIZE bytes and
 * must be W1_F0D_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_F0D_PAGE_SIZE - (addr & W1_F0D_PAGE_MASK))
 * @param data	The data to write
 * @return	0=Success -1=failure
 */
static int w1_f0d_write(struct w1_slave *sl, int addr, int len, const u8 *data)
{
	int tries = W1_F0D_READ_RETRIES;
	u8 wrbuf[3];
	u8 rdbuf[W1_F0D_SCRATCH_SIZE];
	u8 cs;

	if ((addr & 1) || (len != 2)) {
		dev_err(&sl->dev, "%s: bad addr/len -  addr=%#x len=%d\n",
		    __func__, addr, len);
		return -1;
	}

retry:

	/* Write the data to the scratchpad */
	if (w1_reset_select_slave(sl))
		return -1;

	wrbuf[0] = W1_F0D_WRITE_EEPROM;
	wrbuf[1] = addr & 0xff;
	wrbuf[2] = 0xff; /* ?? from Example */

	w1_write_block(sl->master, wrbuf, sizeof(wrbuf));
	w1_write_block(sl->master, data, len);

	w1_read_block(sl->master, rdbuf, sizeof(rdbuf));
	/* Compare what was read against the data written */
	if ((rdbuf[0] != data[0]) || (rdbuf[1] != data[1])) {

		if (--tries)
			goto retry;

		dev_err(&sl->dev,
			"could not write to eeprom, scratchpad compare failed %d times\n",
			W1_F0D_READ_RETRIES);
		pr_info("%s: rdbuf = %#x %#x data = %#x %#x\n",
		    __func__, rdbuf[0], rdbuf[1], data[0], data[1]);

		return -1;
	}

	/* Trigger write out to EEPROM */
	w1_write_8(sl->master, W1_F0D_RELEASE);

	/* Sleep for tprog ms to wait for the write to complete */
	msleep(W1_F0D_TPROG_MS);

	/* Check CS (Command Status) == 0xAA ? */
	cs = w1_read_8(sl->master);
	if (cs != W1_F0D_CS_OK) {
		dev_err(&sl->dev, "save to eeprom failed = CS=%#x\n", cs);
		return -1;
	}

	return 0;
}

static ssize_t w1_f0d_write_bin(struct file *filp, struct kobject *kobj,
				const struct bin_attribute *bin_attr,
				char *buf, loff_t off, size_t count)
{

Annotation

Implementation Notes