From mboxrd@z Thu Jan 1 00:00:00 1970 From: Baruch Siach Date: Wed, 06 May 2020 19:47:51 +0300 Subject: [PATCH] misc: i2c_eeprom: implement different probe test eeprom offset In-Reply-To: <20200506160813.538933-1-eugen.hristev@microchip.com> References: <20200506160813.538933-1-eugen.hristev@microchip.com> Message-ID: <87ftcd6mdk.fsf@tarshish> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Eugen, On Wed, May 06 2020, Eugen Hristev wrote: > Because of this commit : > 5ae84860b0 ("misc: i2c_eeprom: verify that the chip is functional at probe()") > at probe time, each eeprom is tested for read at offset 0. > > The Atmel AT24MAC402 eeprom has different mapping. One i2c slave address is > used for the lower 0x80 bytes and another i2c slave address is used for the > upper 0x80 bytes. Because of this basically the i2c master sees 2 different > slaves. We need the upper bytes because we read the unique MAC address from > this EEPROM area. > > However this implies that our slave address will return error on reads > from address 0x0 to 0x80. > > To solve this, implemented a way to figure out from the compatible udevice_id > 'data' field which offset we should attempt to read. > Added the offset as one byte in the data field (byte number 3). > Created two macros that will convert offset to 'data' field and back. > > The probe function will now read this offset and use it, instead of blindly > checking offset 0. > > This will fix the regression noticed on these EEPROMs since the commit > abovementioned that introduces the probe failed issue. Judging from the Linux at24 driver that commit appears to break a number of other eeprom chips. I suggest to just revert it. baruch > > The offset field can for sure be updated later at a 2byte offset if needed > by anyone. > > Signed-off-by: Eugen Hristev > --- > drivers/misc/i2c_eeprom.c | 18 ++++++++++++++++-- > 1 file changed, 16 insertions(+), 2 deletions(-) > > diff --git a/drivers/misc/i2c_eeprom.c b/drivers/misc/i2c_eeprom.c > index 3755dbf74b..79805cc46e 100644 > --- a/drivers/misc/i2c_eeprom.c > +++ b/drivers/misc/i2c_eeprom.c > @@ -11,6 +11,13 @@ > #include > #include > > +/* These macros are used to encode/decode the starting EEPROM offset into the > + * udevice_id structure's data field 3rd byte. > + * Lower 2 bytes of the data field are used for pagewidth. > + */ > +#define I2C_EEPROM_OFFSET_TO_DATA(v) ((v) << 16) > +#define I2C_EEPROM_DATA_TO_OFFSET(v) ((v) >> 16) > + > int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size) > { > const struct i2c_eeprom_ops *ops = device_get_ops(dev); > @@ -85,11 +92,17 @@ static int i2c_eeprom_std_ofdata_to_platdata(struct udevice *dev) > > static int i2c_eeprom_std_probe(struct udevice *dev) > { > + u64 data = dev_get_driver_data(dev); > u8 test_byte; > int ret; > > /* Verify that the chip is functional */ > - ret = i2c_eeprom_read(dev, 0, &test_byte, 1); > + /* > + * Not all eeproms start from offset 0. Valid offset is encoded in > + * upper bits of the data (byte 3). > + */ > + ret = i2c_eeprom_read(dev, I2C_EEPROM_DATA_TO_OFFSET(data) & 0xFF, > + &test_byte, 1); > if (ret) > return -ENODEV; > > @@ -105,7 +118,8 @@ static const struct udevice_id i2c_eeprom_std_ids[] = { > { .compatible = "atmel,24c08", .data = 4 }, > { .compatible = "atmel,24c08a", .data = 4 }, > { .compatible = "atmel,24c16a", .data = 4 }, > - { .compatible = "atmel,24mac402", .data = 4 }, > + { .compatible = "atmel,24mac402", > + .data = (4 | I2C_EEPROM_OFFSET_TO_DATA(0x80))}, > { .compatible = "atmel,24c32", .data = 5 }, > { .compatible = "atmel,24c64", .data = 5 }, > { .compatible = "atmel,24c128", .data = 6 }, -- ~. .~ Tk Open Systems =}------------------------------------------------ooO--U--Ooo------------{= - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -