/* Allow the strong pullup to be disabled, but default to enabled. * If it was disabled a parasite powered device might not get the required * current to copy the data from the scratchpad to EEPROM. If it is enabled * parasite powered devices have a better chance of getting the current * required.
*/ staticint w1_strong_pullup = 1;
module_param_named(strong_pullup, w1_strong_pullup, int, 0);
/* * Check the file size bounds and adjusts count as needed. * This would not be needed if the file size didn't reset to 0 after a write.
*/ staticinline size_t w1_f1C_fix_count(loff_t off, size_t count, size_t size)
{ if (off > size) return 0;
if ((off + count) > size) return size - off;
return count;
}
staticint w1_f1C_refresh_block(struct w1_slave *sl, struct w1_f1C_data *data, int block)
{
u8 wrbuf[3]; int off = block * W1_PAGE_SIZE;
if (data->validcrc & (1 << block)) return 0;
if (w1_reset_select_slave(sl)) {
data->validcrc = 0; return -EIO;
}
wrbuf[0] = W1_F1C_READ_EEPROM;
wrbuf[1] = off & 0xff;
wrbuf[2] = off >> 8;
w1_write_block(sl->master, wrbuf, 3);
w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);
/* cache the block if the CRC is valid */ if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
data->validcrc |= (1 << block);
return 0;
}
staticint w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data)
{
u8 wrbuf[3];
/* read directly from the EEPROM */ if (w1_reset_select_slave(sl)) return -EIO;
/** * w1_f1C_write() - Writes to the scratchpad and reads it back for verification. * @sl: The slave structure * @addr: Address for the write * @len: length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK)) * @data: The data to write * * Then copies the scratchpad to EEPROM. * The data must be on one page. * The master must be locked. * * Return: 0=Success, -1=failure
*/ staticint w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data)
{
u8 wrbuf[4];
u8 rdbuf[W1_PAGE_SIZE + 3];
u8 es = (addr + len - 1) & 0x1f; unsignedint tm = 10; int i; struct w1_f1C_data *f1C = sl->family_data;
/* Write the data to the scratchpad */ if (w1_reset_select_slave(sl)) return -1;
/* Read the scratchpad and verify */ if (w1_reset_select_slave(sl)) return -1;
w1_write_8(sl->master, W1_F1C_READ_SCRATCH);
w1_read_block(sl->master, 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)) return -1;
/* Copy the scratchpad to EEPROM */ if (w1_reset_select_slave(sl)) return -1;
wrbuf[0] = W1_F1C_COPY_SCRATCH;
wrbuf[3] = es;
for (i = 0; i < sizeof(wrbuf); ++i) { /* * issue 10ms strong pullup (or delay) on the last byte * for writing the data from the scratchpad to EEPROM
*/ if (w1_strong_pullup && i == sizeof(wrbuf)-1)
w1_next_pullup(sl->master, tm);
w1_write_8(sl->master, wrbuf[i]);
}
if (!w1_strong_pullup)
msleep(tm);
if (w1_enable_crccheck) { /* invalidate cached data */
f1C->validcrc &= ~(1 << (addr >> W1_PAGE_BITS));
}
/* Reset the bus to wake up the EEPROM (this may not be needed) */
w1_reset_bus(sl->master);
if (w1_enable_crccheck) { /* can only write full blocks in cached mode */ if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n",
(int)off, count); return -EINVAL;
}
/* make sure the block CRCs are valid */ for (idx = 0; idx < count; idx += W1_PAGE_SIZE) { if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE)
!= CRC16_VALID) {
dev_err(&sl->dev, "bad CRC at offset %d\n",
(int)off); return -EINVAL;
}
}
}
mutex_lock(&sl->master->mutex);
/* Can only write data to one page at a time */
idx = 0; while (idx < count) {
addr = off + idx;
len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK); if (len > (count - idx))
len = count - idx;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.