Commit 5739ab6b authored by Alessandro Rubini's avatar Alessandro Rubini

kernel/spec-i2c: read in burst mode

Now we read the whole eeprom area with a single command. Reading
time is thus 1/3 of what it was, and initialization time goes
down from 2 seconds to 0.6 seconds.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 580113ae
......@@ -141,32 +141,36 @@ int mi2c_scan(struct fmc_device *fmc)
return found;
}
/* FIXME: this is very inefficient: read several bytes in a row instead */
int spec_eeprom_read(struct fmc_device *fmc, uint32_t offset,
void *buf, size_t size)
{
int i;
int ret = size;
uint8_t *buf8 = buf;
unsigned char c;
for(i = 0; i < size; i++) {
mi2c_start(fmc);
if(mi2c_put_byte(fmc, fmc->eeprom_addr << 1) < 0) {
mi2c_stop(fmc);
return -EIO;
}
if (offset > SPEC_I2C_EEPROM_SIZE)
return -EINVAL;
if (offset + size > SPEC_I2C_EEPROM_SIZE)
return -EINVAL;
mi2c_put_byte(fmc, (offset >> 8) & 0xff);
mi2c_put_byte(fmc, offset & 0xff);
offset++;
/* Read it all in a single loop: hardware allows it */
mi2c_start(fmc);
if(mi2c_put_byte(fmc, fmc->eeprom_addr << 1) < 0) {
mi2c_stop(fmc);
mi2c_start(fmc);
mi2c_put_byte(fmc, (fmc->eeprom_addr << 1) | 1);
mi2c_get_byte(fmc, &c, 0);
return -EIO;
}
mi2c_put_byte(fmc, (offset >> 8) & 0xff);
mi2c_put_byte(fmc, offset & 0xff);
mi2c_stop(fmc);
mi2c_start(fmc);
mi2c_put_byte(fmc, (fmc->eeprom_addr << 1) | 1);
while (size--) {
mi2c_get_byte(fmc, &c, size != 0);
*buf8++ = c;
mi2c_stop(fmc);
//printk("read 0x%08x, %4i to go\n", c, size);
}
return size;
mi2c_stop(fmc);
return ret;
}
int spec_eeprom_write(struct fmc_device *fmc, uint32_t offset,
......
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