in slaves/w1_ds28e04.c [160:220]
static int 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;
unsigned int 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;
wrbuf[0] = W1_F1C_WRITE_SCRATCH;
wrbuf[1] = addr & 0xff;
wrbuf[2] = addr >> 8;
w1_write_block(sl->master, wrbuf, 3);
w1_write_block(sl->master, data, len);
/* 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);
return 0;
}