[PATCH 4/4] i2c: cgbc: Add virtual storage devices on the virtual I2C bus
"Thomas Richard (congatec GmbH)" <[email protected]> Tue, 04 Aug 2026 16:55:54 +0200
| Newsgroups | org.kernel.vger.linux-i2c,dev.linux.lists.mfd,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260804-cgbc-i2c-storage-devices-support-v1-4-fed38510671c@bootlin.com> |
Add support for virtual storage devices exposed by the Board Controller on its virtual I2C bus. There are two device types: EEPROM for persistent storage and RAM for non-persistent storage: - Secure Data EEPROM (64 bytes, RO): static and dynamic board info - BIOS EEPROM (32 bytes, RW): reserved for BIOS applications - BC EEPROM (32 bytes, RO): Board Controller operational params - User EEPROM (32 bytes, RW): user applications - BIOS RAM (32 bytes, RW): reserved for BIOS applications - BC RAM (8 bytes, RO): Board Controller operational params - User RAM (16 bytes, RW): user applications Use the at24 driver with the 24c01 entry (the most generic one) for all virtual storage devices, customizing parameters via software_node properties (size, pagesize, read-only flag, label). Signed-off-by: Thomas Richard (congatec GmbH) <[email protected]> --- drivers/i2c/busses/i2c-cgbc.c | 151 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-cgbc.c b/drivers/i2c/busses/i2c-cgbc.c index c3f1c83b105a..418de90e11bb 100644 --- a/drivers/i2c/busses/i2c-cgbc.c +++ b/drivers/i2c/busses/i2c-cgbc.c @@ -372,6 +372,149 @@ static const struct i2c_adapter cgbc_i2c_adapter[] = { }, }; +static const struct property_entry cgbc_secure_data_eeprom_props[] = { + PROPERTY_ENTRY_U32("size", 64), + PROPERTY_ENTRY_U32("pagesize", 1), + PROPERTY_ENTRY_BOOL("read-only"), + PROPERTY_ENTRY_STRING("label", "cgbc-secure-data-eeprom"), + { } +}; + +static const struct software_node cgbc_secure_data_eeprom_node = { + .properties = cgbc_secure_data_eeprom_props, +}; + +static const struct property_entry cgbc_bc_eeprom_props[] = { + PROPERTY_ENTRY_U32("size", 32), + PROPERTY_ENTRY_U32("pagesize", 1), + PROPERTY_ENTRY_BOOL("read-only"), + PROPERTY_ENTRY_STRING("label", "cgbc-bc-eeprom"), + { } +}; + +static const struct software_node cgbc_bc_eeprom_node = { + .properties = cgbc_bc_eeprom_props, +}; + +static const struct property_entry cgbc_user_eeprom_props[] = { + PROPERTY_ENTRY_U32("size", 32), + PROPERTY_ENTRY_U32("pagesize", 1), + PROPERTY_ENTRY_STRING("label", "cgbc-user-eeprom"), + { } +}; + +static const struct software_node cgbc_user_eeprom_node = { + .properties = cgbc_user_eeprom_props, +}; + +static const struct property_entry cgbc_bios_eeprom_props[] = { + PROPERTY_ENTRY_U32("size", 32), + PROPERTY_ENTRY_U32("pagesize", 1), + PROPERTY_ENTRY_STRING("label", "cgbc-bios-eprom"), + { } +}; + +static const struct software_node cgbc_bios_eeprom_node = { + .properties = cgbc_bios_eeprom_props, +}; + +static const struct property_entry cgbc_bc_ram_props[] = { + PROPERTY_ENTRY_U32("size", 8), + PROPERTY_ENTRY_U32("pagesize", 1), + PROPERTY_ENTRY_BOOL("read-only"), + PROPERTY_ENTRY_STRING("label", "cgbc-bc-ram"), + { } +}; + +static const struct software_node cgbc_bc_ram_node = { + .properties = cgbc_bc_ram_props, +}; + +static const struct property_entry cgbc_user_ram_props[] = { + PROPERTY_ENTRY_U32("size", 16), + PROPERTY_ENTRY_U32("pagesize", 1), + PROPERTY_ENTRY_STRING("label", "cgbc-user-ram"), + { } +}; + +static const struct software_node cgbc_user_ram_node = { + .properties = cgbc_user_ram_props, +}; + +static const struct property_entry cgbc_bios_ram_props[] = { + PROPERTY_ENTRY_U32("size", 32), + PROPERTY_ENTRY_U32("pagesize", 1), + PROPERTY_ENTRY_STRING("label", "cgbc-bios-ram"), + { } +}; + +static const struct software_node cgbc_bios_ram_node = { + .properties = cgbc_bios_ram_props, +}; + +static const struct i2c_board_info cgbc_i2c_board_info[] = { + { + .type = "24c01", + .addr = 0x40, + .dev_name = "cgbc-secure-data-eeprom", + .swnode = &cgbc_secure_data_eeprom_node, + }, + { + .type = "24c01", + .addr = 0x48, + .dev_name = "cgbc-bc-eeprom", + .swnode = &cgbc_bc_eeprom_node, + }, + { + .type = "24c01", + .addr = 0x50, + .dev_name = "cgbc-user-eeprom", + .swnode = &cgbc_user_eeprom_node, + }, + { + .type = "24c01", + .addr = 0x58, + .dev_name = "cgbc-bios-eeprom", + .swnode = &cgbc_bios_eeprom_node, + }, + { + .type = "24c01", + .addr = 0x60, + .dev_name = "cgbc-bc-ram", + .swnode = &cgbc_bc_ram_node, + }, + { + .type = "24c01", + .addr = 0x68, + .dev_name = "cgbc-user-ram", + .swnode = &cgbc_user_ram_node, + }, + { + .type = "24c01", + .addr = 0x70, + .dev_name = "cgbc-bios-ram", + .swnode = &cgbc_bios_ram_node, + } +}; + +static void cgbc_i2c_instantiate_devices(struct i2c_adapter *adap) +{ + struct i2c_algo_cgbc_data *algo_data = adap->algo_data; + struct i2c_client *client; + int i; + + /* We only instantiate devices on Virtual bus */ + if (algo_data->bus_id != CGBC_I2C_VIRTUAL_BUS_ID) + return; + + for (i = 0; i < ARRAY_SIZE(cgbc_i2c_board_info); i++) { + client = i2c_new_client_device(adap, &cgbc_i2c_board_info[i]); + if (IS_ERR(client)) + dev_err(&adap->dev, "Failed to register %s\n", + cgbc_i2c_board_info[i].dev_name); + } +} + static int cgbc_i2c_probe(struct platform_device *pdev) { struct cgbc_device_data *cgbc = dev_get_drvdata(pdev->dev.parent); @@ -393,7 +536,13 @@ static int cgbc_i2c_probe(struct platform_device *pdev) if (ret) return ret; - return i2c_add_numbered_adapter(&i2c->adap); + ret = i2c_add_numbered_adapter(&i2c->adap); + if (ret) + return ret; + + cgbc_i2c_instantiate_devices(&i2c->adap); + + return ret; } static void cgbc_i2c_remove(struct platform_device *pdev) -- 2.53.0