On Tue, Apr 13, 2021 at 1:03 PM <Claudiu.Beznea@xxxxxxxxxxxxx> wrote: > > On 12.04.2021 21:29, Bartosz Golaszewski wrote: > > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe > > > > On Mon, Apr 12, 2021 at 9:42 AM <Claudiu.Beznea@xxxxxxxxxxxxx> wrote: > >> > >> On 07.04.2021 21:37, Bartosz Golaszewski wrote: > >>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe > >>> > >>> On Fri, Apr 2, 2021 at 3:24 PM Claudiu Beznea > >>> <claudiu.beznea@xxxxxxxxxxxxx> wrote: > >>>> > >>>> Some EEPROMs could be used only for MAC storage. In this case the > >>>> EEPROM areas where MACs resides could be modeled as NVMEM cells > >>>> (directly via DT bindings) such that the already available networking > >>>> infrastructure to read properly the MAC addresses (via > >>>> of_get_mac_address()). Add "atmel,24mac02e4", "atmel,24mac02e4" > >>>> compatible for the usage w/ 24AA025E{48, 64} type of EEPROMs and adapt > >>>> the driver to not do offset adjustments. > >>>> > >>>> Signed-off-by: Claudiu Beznea <claudiu.beznea@xxxxxxxxxxxxx> > >>>> --- > >>>> > >>>> Hi Bartosz, > >>>> > >>>> For the previously available compatibles the offset adjustment is done > >>>> (probably for compatibility w/ old DT bindings?). In my scenario 24AA025E48 > >>>> is used in setup with macb driver which is calling of_get_mac_address() > >>>> to get the proper NVMEM cell in EEPROM where the MAC resides and read > >>>> directly from there. We modeled the EEPROM and NVMEM cell in DT as > >>>> follows: > >>>> > >>>> &i2cnode { > >>>> // ... > >>>> eeprom0: eeprom0@52 { > >>>> compatible = "atmel,24mac02e4"; > > > > Can you point me to the datasheet for this model, google only directs > > me to this very email. > > This is the datasheet: > https://ww1.microchip.com/downloads/en/DeviceDoc/24AA02E48-24AA025E48-24AA02E64-24AA025E64-Data-Sheet-20002124H.pdf > > > > >>From the device tree it looks as if it was just a regular 24c02 EEPROM > > with MAC hard-coded at 250-255 bytes, is that right? > > Yes, the MAC is hard-coded at 250. But using "24c02" compatible will > involve the offset adjustment in the driver (let me know if I missed > something). > Something seems to be wrong. There's no offset adjustment for "24c02". Have you tried running i2cdump on the EEPROM's address? Do you see the MAC? Bartosz > Thank you, > Claudiu > > > > > Bartosz > > > >>>> #address-cells = <1>; > >>>> #size-cells = <0>; > >>>> reg = <0x52>; > >>>> pagesize = <16>; > >>>> size = <256>; > >>>> status = "okay"; > >>>> > >>>> eeprom0_eui48: eui48@fa { > >>>> reg = <0xfa 0x6>; > >>>> }; > >>>> }; > >>>> }; > >>>> > >>>> &gmac { > >>>> // ... > >>>> > >>>> nvmem-cells = <&eeprom0_eui48>; > >>>> nvmem-cell-names = "mac-address"; > >>>> > >>>> // ... > >>>> }; > >>>> > >>>> > >>>> Let me know if some other approach needs to be taken into account in > >>>> at24 driver for this to work. > >>>> > >>>> Thank you, > >>>> Claudiu Beznea > >>>> > >>> > >>> Hi Claudiu, > >>> > >>> First of all: any new compatibles need to go into the DT bindings document. > >> > >> Agree! I missed this. > >> > >>> > >>> > >>>> drivers/misc/eeprom/at24.c | 69 ++++++++++++++++++++++---------------- > >>>> 1 file changed, 40 insertions(+), 29 deletions(-) > >>>> > >>>> diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c > >>>> index 926408b41270..ae2fbcb5e83d 100644 > >>>> --- a/drivers/misc/eeprom/at24.c > >>>> +++ b/drivers/misc/eeprom/at24.c > >>>> @@ -123,17 +123,19 @@ MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)"); > >>>> struct at24_chip_data { > >>>> u32 byte_len; > >>>> u8 flags; > >>>> + u8 adjoff; > >>>> void (*read_post)(unsigned int off, char *buf, size_t count); > >>>> }; > >>>> > >>>> -#define AT24_CHIP_DATA(_name, _len, _flags) \ > >>>> +#define AT24_CHIP_DATA(_name, _len, _flags, _adjoff) \ > >>>> static const struct at24_chip_data _name = { \ > >>>> - .byte_len = _len, .flags = _flags, \ > >>>> + .byte_len = _len, .flags = _flags, .adjoff = _adjoff, \ > >>>> } > >>>> > >>>> -#define AT24_CHIP_DATA_CB(_name, _len, _flags, _read_post) \ > >>>> +#define AT24_CHIP_DATA_CB(_name, _len, _flags, _adjoff, _read_post) \ > >>>> static const struct at24_chip_data _name = { \ > >>>> .byte_len = _len, .flags = _flags, \ > >>>> + .adjoff = _adjoff, \ > >>>> .read_post = _read_post, \ > >>>> } > >>>> > >>>> @@ -158,48 +160,52 @@ static void at24_read_post_vaio(unsigned int off, char *buf, size_t count) > >>>> } > >>>> > >>>> /* needs 8 addresses as A0-A2 are ignored */ > >>>> -AT24_CHIP_DATA(at24_data_24c00, 128 / 8, AT24_FLAG_TAKE8ADDR); > >>>> +AT24_CHIP_DATA(at24_data_24c00, 128 / 8, AT24_FLAG_TAKE8ADDR, 0); > >>>> /* old variants can't be handled with this generic entry! */ > >>>> -AT24_CHIP_DATA(at24_data_24c01, 1024 / 8, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c01, 1024 / 8, 0, 0); > >>>> AT24_CHIP_DATA(at24_data_24cs01, 16, > >>>> - AT24_FLAG_SERIAL | AT24_FLAG_READONLY); > >>>> -AT24_CHIP_DATA(at24_data_24c02, 2048 / 8, 0); > >>>> + AT24_FLAG_SERIAL | AT24_FLAG_READONLY, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c02, 2048 / 8, 0, 0); > >>>> AT24_CHIP_DATA(at24_data_24cs02, 16, > >>>> - AT24_FLAG_SERIAL | AT24_FLAG_READONLY); > >>>> + AT24_FLAG_SERIAL | AT24_FLAG_READONLY, 0); > >>>> AT24_CHIP_DATA(at24_data_24mac402, 48 / 8, > >>>> - AT24_FLAG_MAC | AT24_FLAG_READONLY); > >>>> + AT24_FLAG_MAC | AT24_FLAG_READONLY, 1); > >>>> AT24_CHIP_DATA(at24_data_24mac602, 64 / 8, > >>>> - AT24_FLAG_MAC | AT24_FLAG_READONLY); > >>>> + AT24_FLAG_MAC | AT24_FLAG_READONLY, 1); > >>>> +AT24_CHIP_DATA(at24_data_24mac02e4, 48 / 8, > >>>> + AT24_FLAG_MAC | AT24_FLAG_READONLY, 0); > >>>> +AT24_CHIP_DATA(at24_data_24mac02e6, 64 / 8, > >>>> + AT24_FLAG_MAC | AT24_FLAG_READONLY, 0); > >>>> /* spd is a 24c02 in memory DIMMs */ > >>>> AT24_CHIP_DATA(at24_data_spd, 2048 / 8, > >>>> - AT24_FLAG_READONLY | AT24_FLAG_IRUGO); > >>>> + AT24_FLAG_READONLY | AT24_FLAG_IRUGO, 0); > >>>> /* 24c02_vaio is a 24c02 on some Sony laptops */ > >>>> AT24_CHIP_DATA_CB(at24_data_24c02_vaio, 2048 / 8, > >>>> - AT24_FLAG_READONLY | AT24_FLAG_IRUGO, > >>>> + AT24_FLAG_READONLY | AT24_FLAG_IRUGO, 0, > >>>> at24_read_post_vaio); > >>>> -AT24_CHIP_DATA(at24_data_24c04, 4096 / 8, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c04, 4096 / 8, 0, 0); > >>>> AT24_CHIP_DATA(at24_data_24cs04, 16, > >>>> - AT24_FLAG_SERIAL | AT24_FLAG_READONLY); > >>>> + AT24_FLAG_SERIAL | AT24_FLAG_READONLY, 0); > >>>> /* 24rf08 quirk is handled at i2c-core */ > >>>> -AT24_CHIP_DATA(at24_data_24c08, 8192 / 8, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c08, 8192 / 8, 0, 0); > >>>> AT24_CHIP_DATA(at24_data_24cs08, 16, > >>>> - AT24_FLAG_SERIAL | AT24_FLAG_READONLY); > >>>> -AT24_CHIP_DATA(at24_data_24c16, 16384 / 8, 0); > >>>> + AT24_FLAG_SERIAL | AT24_FLAG_READONLY, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c16, 16384 / 8, 0, 0); > >>>> AT24_CHIP_DATA(at24_data_24cs16, 16, > >>>> - AT24_FLAG_SERIAL | AT24_FLAG_READONLY); > >>>> -AT24_CHIP_DATA(at24_data_24c32, 32768 / 8, AT24_FLAG_ADDR16); > >>>> + AT24_FLAG_SERIAL | AT24_FLAG_READONLY, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c32, 32768 / 8, AT24_FLAG_ADDR16, 0); > >>>> AT24_CHIP_DATA(at24_data_24cs32, 16, > >>>> - AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY); > >>>> -AT24_CHIP_DATA(at24_data_24c64, 65536 / 8, AT24_FLAG_ADDR16); > >>>> + AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c64, 65536 / 8, AT24_FLAG_ADDR16, 0); > >>>> AT24_CHIP_DATA(at24_data_24cs64, 16, > >>>> - AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY); > >>>> -AT24_CHIP_DATA(at24_data_24c128, 131072 / 8, AT24_FLAG_ADDR16); > >>>> -AT24_CHIP_DATA(at24_data_24c256, 262144 / 8, AT24_FLAG_ADDR16); > >>>> -AT24_CHIP_DATA(at24_data_24c512, 524288 / 8, AT24_FLAG_ADDR16); > >>>> -AT24_CHIP_DATA(at24_data_24c1024, 1048576 / 8, AT24_FLAG_ADDR16); > >>>> -AT24_CHIP_DATA(at24_data_24c2048, 2097152 / 8, AT24_FLAG_ADDR16); > >>>> + AT24_FLAG_ADDR16 | AT24_FLAG_SERIAL | AT24_FLAG_READONLY, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c128, 131072 / 8, AT24_FLAG_ADDR16, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c256, 262144 / 8, AT24_FLAG_ADDR16, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c512, 524288 / 8, AT24_FLAG_ADDR16, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c1024, 1048576 / 8, AT24_FLAG_ADDR16, 0); > >>>> +AT24_CHIP_DATA(at24_data_24c2048, 2097152 / 8, AT24_FLAG_ADDR16, 0); > >>>> /* identical to 24c08 ? */ > >>>> -AT24_CHIP_DATA(at24_data_INT3499, 8192 / 8, 0); > >>>> +AT24_CHIP_DATA(at24_data_INT3499, 8192 / 8, 0, 0); > >>>> > >>>> static const struct i2c_device_id at24_ids[] = { > >>>> { "24c00", (kernel_ulong_t)&at24_data_24c00 }, > >>>> @@ -208,7 +214,9 @@ static const struct i2c_device_id at24_ids[] = { > >>>> { "24c02", (kernel_ulong_t)&at24_data_24c02 }, > >>>> { "24cs02", (kernel_ulong_t)&at24_data_24cs02 }, > >>>> { "24mac402", (kernel_ulong_t)&at24_data_24mac402 }, > >>>> + { "24mac02e4", (kernel_ulong_t)&at24_data_24mac02e4 }, > >>>> { "24mac602", (kernel_ulong_t)&at24_data_24mac602 }, > >>>> + { "24mac02e6", (kernel_ulong_t)&at24_data_24mac02e6 }, > >>>> { "spd", (kernel_ulong_t)&at24_data_spd }, > >>>> { "24c02-vaio", (kernel_ulong_t)&at24_data_24c02_vaio }, > >>>> { "24c04", (kernel_ulong_t)&at24_data_24c04 }, > >>>> @@ -238,7 +246,9 @@ static const struct of_device_id at24_of_match[] = { > >>>> { .compatible = "atmel,24c02", .data = &at24_data_24c02 }, > >>>> { .compatible = "atmel,24cs02", .data = &at24_data_24cs02 }, > >>>> { .compatible = "atmel,24mac402", .data = &at24_data_24mac402 }, > >>>> + { .compatible = "atmel,24mac02e4", .data = &at24_data_24mac02e4 }, > >>>> { .compatible = "atmel,24mac602", .data = &at24_data_24mac602 }, > >>>> + { .compatible = "atmel,24mac02e6", .data = &at24_data_24mac02e6 }, > >>>> { .compatible = "atmel,spd", .data = &at24_data_spd }, > >>>> { .compatible = "atmel,24c04", .data = &at24_data_24c04 }, > >>>> { .compatible = "atmel,24cs04", .data = &at24_data_24cs04 }, > >>>> @@ -690,7 +700,8 @@ static int at24_probe(struct i2c_client *client) > >>>> at24->flags = flags; > >>>> at24->read_post = cdata->read_post; > >>>> at24->num_addresses = num_addresses; > >>>> - at24->offset_adj = at24_get_offset_adj(flags, byte_len); > >>>> + at24->offset_adj = cdata->adjoff ? > >>>> + at24_get_offset_adj(flags, byte_len) : 0; > >>>> at24->client[0].client = client; > >>>> at24->client[0].regmap = regmap; > >>>> > >>>> -- > >>>> 2.25.1 > >>>> > >>> > >>> What is the problem you're trying to solve? > >> > >> I wanted to instantiate a NVMEM cell with proper offset and size via DT and > >> make whatever Ethernet driver aware of this NVMEM cell via DT bindings, as > >> bellow: > >> > >> &i2cnode { > >> // ... > >> eeprom0: eeprom0@52 { > >> compatible = "atmel,24mac02e4"; > >> #address-cells = <1>; > >> #size-cells = <0>; > >> reg = <0x52>; > >> pagesize = <16>; > >> size = <256>; > >> status = "okay"; > >> > >> eeprom0_eui48: eui48@fa { > >> reg = <0xfa 0x6>; > >> }; > >> }; > >> }; > >> > >> &gmac { > >> // ... > >> > >> nvmem-cells = <&eeprom0_eui48>; > >> nvmem-cell-names = "mac-address"; > >> > >> // ... > >> }; > >> > >> By adding this new compatible and changing the driver to not adjust the > >> NVMEM cell offset for it but make it use the one provided in DT I was > >> thinking this may scale for any future EEPROM storing MAC addresses at any > >> offsets (because these would be provided via DT and not adjusted by driver). > >> > >> I the current at24 driver I haven't managed to find a compatible in the > >> driver that mach the offset 0xfa (used to store MAC address on case of > >> 24AA025E48). > >> > >>> The MAC area is accessible > >>> on a different device address. The variants with serial and MAC areas > >>> are meant to be instantiated as devices separate from the main > >>> writeable area and you can then create an nvmem cell that will take up > >>> the whole MAC. > >>> > >>> Or does your model keep the MAC in the same block that's used for > >>> writing? In which case just using a regular compatible that matches > >>> the size and creating the nvmem cell at the right offset should be > >>> enough, right? > >> > >> Meaning describing the NVMEM cell in DT with an offset such that the driver > >> adjustment +/- that offset to lead to the offset described in EEPROM datasheet? > >> > >>> > >>> Am I missing something? > >> > >> > >> > >>> > >>> Bartosz > >>> > >> >