Commit f0fbffae authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

adding erase functions for w1 eeprom

parent f5a4a27c
......@@ -43,6 +43,11 @@ static int sdb_w1_write(struct sdbfs *fs, int offset, void *buf, int count)
return w1_write_eeprom_bus(fs->drvdata, offset, buf, count);
}
static int sdb_w1_erase(struct sdbfs *fs, int offset, int count)
{
return w1_erase_eeprom_bus(fs->drvdata, offset, count);
}
/*
* I2C code.
* The functions in ./eeprom.c (legacy) are replicated here with the sdb
......@@ -191,6 +196,7 @@ void eeprom_init(int chosen_i2cif, int chosen_i2c_addr)
wrc_sdb.drvdata = &wrpc_w1_bus;
wrc_sdb.read = sdb_w1_read;
wrc_sdb.write = sdb_w1_write;
wrc_sdb.erase = sdb_w1_erase;
goto found_exit;
}
......
......@@ -49,6 +49,44 @@ static int w1_write_page(struct w1_dev *dev, int offset, const uint8_t *buffer,
return blen;
}
static int w1_erase_page(struct w1_dev *dev, int offset, int blen)
{
int i, j, es;
/* First, write scratchpad */
w1_match_rom(dev);
w1_write_byte(dev->bus, W1_CMDR_W_SPAD);
w1_write_byte(dev->bus, LSB_ADDR(offset));
w1_write_byte(dev->bus, MSB_ADDR(offset));
for(i = 0; i < blen; i++)
w1_write_byte(dev->bus, 0xFF);
/* Then, read it back, and remember the return E/S */
w1_match_rom(dev);
w1_write_byte(dev->bus, W1_CMDR_R_SPAD);
if (w1_read_byte(dev->bus) != LSB_ADDR(offset))
return -1;
if (w1_read_byte(dev->bus) != MSB_ADDR(offset))
return -2;
es = w1_read_byte(dev->bus);
for(i = 0; i < blen; i++) {
j = w1_read_byte(dev->bus);
if (j != 0xFF)
return -3;
}
/* Finally, "copy scratchpad" to actually write */
w1_match_rom(dev);
w1_write_byte(dev->bus, W1_CMDR_C_SPAD);
w1_write_byte(dev->bus, LSB_ADDR(offset));
w1_write_byte(dev->bus, MSB_ADDR(offset));
w1_write_byte(dev->bus, es);
usleep(10000); /* 10ms, in theory */
/* Don't read back, as nothing useful is there (I get 0xf9, why?) */
return blen;
}
int w1_write_eeprom(struct w1_dev *dev, int offset, const uint8_t *buffer,
int blen)
{
......@@ -106,6 +144,43 @@ int w1_read_eeprom(struct w1_dev *dev, int offset, uint8_t *buffer, int blen)
return blen;
}
int w1_erase_eeprom(struct w1_dev *dev, int offset, int blen)
{
int i, page, endpage;
int ret = 0;
/* Split the write into several page-local writes */
page = offset / 32;
endpage = (offset + blen - 1) / 32;
/* Traling part of first page */
if (offset % 32) {
if (endpage != page)
i = 32 - (offset % 32);
else
i = blen;
ret += w1_erase_page(dev, offset, i);
if (ret < 0)
return ret;
offset += i;
blen -= i;
}
/* Whole pages and leading part of last page */
while (blen > 0 ) {
i = blen;
if (blen > 32)
i = 32;
i = w1_erase_page(dev, offset, i);
if (i < 0)
return i;
ret += i;
offset += 32;
blen -= 32;
}
return ret;
}
int w1_read_eeprom_bus(struct w1_bus *bus,
int offset, uint8_t *buffer, int blen)
......@@ -136,3 +211,16 @@ int w1_write_eeprom_bus(struct w1_bus *bus,
/* not found */
return -1;
}
int w1_erase_eeprom_bus(struct w1_bus *bus, int offset, int blen)
{
int i, class;
for (i = 0; i < W1_MAX_DEVICES; i++) {
class = w1_class(bus->devs + i);
if (class == 0x43)
return w1_erase_eeprom(bus->devs + i, offset, blen);
}
/* not found */
return -1;
}
......@@ -72,6 +72,7 @@ extern int w1_read_eeprom(struct w1_dev *dev,
int offset, uint8_t *buffer, int blen);
extern int w1_write_eeprom(struct w1_dev *dev,
int offset, const uint8_t *buffer, int blen);
extern int w1_erase_eeprom(struct w1_dev *dev, int offset, int blen);
/* These are generic, using the first suitable device in the bus */
extern int32_t w1_read_temp_bus(struct w1_bus *bus, unsigned long flags);
......@@ -79,6 +80,7 @@ extern int w1_read_eeprom_bus(struct w1_bus *bus,
int offset, uint8_t *buffer, int blen);
extern int w1_write_eeprom_bus(struct w1_bus *bus,
int offset, const uint8_t *buffer, int blen);
extern int w1_erase_eeprom_bus(struct w1_bus *bus, int offset, int blen);
extern struct w1_ops wrpc_w1_ops;
extern struct w1_bus wrpc_w1_bus;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment