diff --git a/boards/atmel/sam/sam_e70_xplained/Kconfig.defconfig b/boards/atmel/sam/sam_e70_xplained/Kconfig.defconfig index 59f0676d06b57..a32341ba2f0e8 100644 --- a/boards/atmel/sam/sam_e70_xplained/Kconfig.defconfig +++ b/boards/atmel/sam/sam_e70_xplained/Kconfig.defconfig @@ -3,21 +3,10 @@ # Copyright (c) 2016 Piotr Mienkowski # SPDX-License-Identifier: Apache-2.0 -if ETH_SAM_GMAC - # Read MAC address from AT24MAC402 EEPROM - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS - default 0x9A - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE - default 1 - -config ETH_SAM_GMAC_MAC_I2C_EEPROM +config ETH_SAM_GMAC_MAC_EEPROM default y - select I2C - -endif # ETH_SAM_GMAC + depends on ETH_SAM_GMAC if NETWORKING diff --git a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained-common.dtsi b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained-common.dtsi index d6190e050f979..0677228f0abc1 100644 --- a/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained-common.dtsi +++ b/boards/atmel/sam/sam_e70_xplained/sam_e70_xplained-common.dtsi @@ -79,8 +79,18 @@ pinctrl-names = "default"; eeprom: eeprom@5f { - compatible = "atmel,24mac402"; + compatible = "atmel,at24", "atmel,24mac402"; reg = <0x5f>; + size = <256>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + + #address-cells = <1>; + #size-cells = <1>; + mac_address: mac_address@9a { + reg = <0x9a 0x06>; + }; }; }; @@ -126,7 +136,8 @@ zephyr_udc0: &usbhs { pinctrl-0 = <&gmac_rmii>; pinctrl-names = "default"; - mac-eeprom = <&eeprom>; + nvmem-cells = <&mac_address>; + nvmem-cell-names = "mac-address"; phy-handle = <&phy>; }; diff --git a/boards/atmel/sam/sam_v71_xult/Kconfig.defconfig b/boards/atmel/sam/sam_v71_xult/Kconfig.defconfig index 5c860149dc8b9..9268a4a874e36 100644 --- a/boards/atmel/sam/sam_v71_xult/Kconfig.defconfig +++ b/boards/atmel/sam/sam_v71_xult/Kconfig.defconfig @@ -4,21 +4,11 @@ # Copyright (c) 2016 Piotr Mienkowski # SPDX-License-Identifier: Apache-2.0 -if ETH_SAM_GMAC # Read MAC address from AT24MAC402 EEPROM - -config ETH_SAM_GMAC_MAC_I2C_EEPROM +config ETH_SAM_GMAC_MAC_EEPROM default y - select I2C - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS - default 0x9A - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE - default 1 - -endif # ETH_SAM_GMAC + depends on ETH_SAM_GMAC if NETWORKING diff --git a/boards/atmel/sam/sam_v71_xult/sam_v71_xult-common.dtsi b/boards/atmel/sam/sam_v71_xult/sam_v71_xult-common.dtsi index f6981455b5122..df7fca719d088 100644 --- a/boards/atmel/sam/sam_v71_xult/sam_v71_xult-common.dtsi +++ b/boards/atmel/sam/sam_v71_xult/sam_v71_xult-common.dtsi @@ -179,8 +179,18 @@ pinctrl-names = "default"; eeprom: eeprom@5f { - compatible = "atmel,24mac402"; + compatible = "atmel,at24", "atmel,24mac402"; reg = <0x5f>; + size = <256>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + + #address-cells = <1>; + #size-cells = <1>; + mac_address: mac_address@9a { + reg = <0x9a 0x06>; + }; }; }; @@ -235,7 +245,8 @@ zephyr_udc0: &usbhs { pinctrl-0 = <&gmac_rmii>; pinctrl-names = "default"; - mac-eeprom = <&eeprom>; + nvmem-cells = <&mac_address>; + nvmem-cell-names = "mac-address"; phy-handle = <&phy>; }; diff --git a/boards/atmel/sam0/same54_xpro/Kconfig.defconfig b/boards/atmel/sam0/same54_xpro/Kconfig.defconfig index 17f73bc5ce43f..61d39a79f7641 100644 --- a/boards/atmel/sam0/same54_xpro/Kconfig.defconfig +++ b/boards/atmel/sam0/same54_xpro/Kconfig.defconfig @@ -4,21 +4,10 @@ # Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 -if ETH_SAM_GMAC - # Read MAC address from AT24MAC402 EEPROM - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS - default 0x9A - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE - default 1 - -config ETH_SAM_GMAC_MAC_I2C_EEPROM +config ETH_SAM_GMAC_MAC_EEPROM default y - select I2C - -endif # ETH_SAM_GMAC + depends on ETH_SAM_GMAC if NETWORKING diff --git a/boards/atmel/sam0/same54_xpro/same54_xpro.dts b/boards/atmel/sam0/same54_xpro/same54_xpro.dts index f8d957727cd4d..97c362d6c6a8a 100644 --- a/boards/atmel/sam0/same54_xpro/same54_xpro.dts +++ b/boards/atmel/sam0/same54_xpro/same54_xpro.dts @@ -104,8 +104,18 @@ pinctrl-names = "default"; eeprom: eeprom@5e { - compatible = "atmel,24mac402"; + compatible = "atmel,at24", "atmel,24mac402"; reg = <0x5e>; + size = <256>; + pagesize = <16>; + address-width = <8>; + timeout = <5>; + + #address-cells = <1>; + #size-cells = <1>; + mac_address: mac_address@9a { + reg = <0x9a 0x06>; + }; }; }; @@ -126,7 +136,8 @@ zephyr_udc0: &usb0 { pinctrl-0 = <&gmac_rmii>; pinctrl-names = "default"; - mac-eeprom = <&eeprom>; + nvmem-cells = <&mac_address>; + nvmem-cell-names = "mac-address"; phy-handle = <&phy>; }; diff --git a/drivers/ethernet/Kconfig.sam_gmac b/drivers/ethernet/Kconfig.sam_gmac index 7037c313a00fb..ffc3e12cdd118 100644 --- a/drivers/ethernet/Kconfig.sam_gmac +++ b/drivers/ethernet/Kconfig.sam_gmac @@ -73,29 +73,11 @@ config ETH_SAM_GMAC_BUF_RX_COUNT fit at least two Ethernet frames: one being received by the GMAC module and the other being processed by the higher layer networking stack. -config ETH_SAM_GMAC_MAC_I2C_EEPROM - bool "Read from an I2C EEPROM" +config ETH_SAM_GMAC_MAC_EEPROM + bool "MAC eeprom" + select EEPROM help - Read MAC address from an I2C EEPROM. - -if ETH_SAM_GMAC_MAC_I2C_EEPROM - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS - hex "I2C EEPROM internal address" - range 0 0xffffffff - help - Internal address of the EEPROM chip where the MAC address is stored. - Chips with 1 to 4 byte internal address size are supported. Address - size has to be configured in a separate Kconfig option. - -config ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE - int "I2C EEPROM internal address size" - default 1 - range 1 4 - help - Size (in bytes) of the internal EEPROM address. - -endif # ETH_SAM_GMAC_MAC_I2C_EEPROM + Enable reading MAC address from external flash memory. config PTP_CLOCK_SAM_GMAC bool "SAM GMAC PTP clock driver support" diff --git a/drivers/ethernet/eth_sam_gmac.c b/drivers/ethernet/eth_sam_gmac.c index c7d90bb6e30be..4f10b68948534 100644 --- a/drivers/ethernet/eth_sam_gmac.c +++ b/drivers/ethernet/eth_sam_gmac.c @@ -43,7 +43,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include +#include +#include #include #include #include @@ -1729,24 +1730,21 @@ static int eth_initialize(const struct device *dev) return retval; } -#if DT_INST_NODE_HAS_PROP(0, mac_eeprom) -static void get_mac_addr_from_i2c_eeprom(uint8_t mac_addr[6]) +#if DT_INST_NODE_HAS_PROP(0, nvmem_cells) && defined(CONFIG_ETH_SAM_GMAC_MAC_EEPROM) +static void get_mac_addr_from_eeprom(uint8_t mac_addr[6]) { - uint32_t iaddr = CONFIG_ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS; int ret; - const struct i2c_dt_spec i2c = I2C_DT_SPEC_GET(DT_INST_PHANDLE(0, mac_eeprom)); + const struct device *eeprom_dev = DT_NVMEM_DEV_BY_IDX(DT_DRV_INST(0), 0); + uint32_t addr = DT_NVMEM_ADDR_BY_IDX(DT_DRV_INST(0), 0); - if (!device_is_ready(i2c.bus)) { - LOG_ERR("Bus device is not ready"); + if (!device_is_ready(eeprom_dev)) { + LOG_ERR("EEPROM device not ready."); return; } - ret = i2c_write_read_dt(&i2c, - &iaddr, CONFIG_ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE, - mac_addr, 6); - - if (ret != 0) { - LOG_ERR("I2C: failed to read MAC addr"); + ret = eeprom_read(eeprom_dev, addr, mac_addr, 6); + if (ret < 0) { + LOG_ERR("Error reading MAC address from EEPROM [%d]", ret); return; } } @@ -1754,8 +1752,8 @@ static void get_mac_addr_from_i2c_eeprom(uint8_t mac_addr[6]) static void generate_mac(uint8_t mac_addr[6]) { -#if DT_INST_NODE_HAS_PROP(0, mac_eeprom) - get_mac_addr_from_i2c_eeprom(mac_addr); +#if DT_INST_NODE_HAS_PROP(0, nvmem_cells) && defined(CONFIG_ETH_SAM_GMAC_MAC_EEPROM) + get_mac_addr_from_eeprom(mac_addr); #elif DT_INST_PROP(0, zephyr_random_mac_address) gen_random_mac(mac_addr, ATMEL_OUI_B0, ATMEL_OUI_B1, ATMEL_OUI_B2); #endif diff --git a/drivers/ethernet/eth_xmc4xxx.c b/drivers/ethernet/eth_xmc4xxx.c index f2197099e27c7..52187d948ced8 100644 --- a/drivers/ethernet/eth_xmc4xxx.c +++ b/drivers/ethernet/eth_xmc4xxx.c @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include #include @@ -799,6 +801,31 @@ static inline int eth_xmc4xxx_init_timestamp_control_reg(ETH_GLOBAL_TypeDef *reg return 0; } +static int eth_xmc4xxx_get_mac_address_eeprom(const struct device *dev) +{ +#if DT_INST_NODE_HAS_PROP(0, nvmem_cells) + struct eth_xmc4xxx_data *dev_data = dev->data; + const struct device *eeprom_dev = DT_NVMEM_DEV_BY_IDX(DT_DRV_INST(0), 0); + uint16_t addr = DT_NVMEM_ADDR_BY_IDX(DT_DRV_INST(0), 0); + + int ret; + + if (!device_is_ready(eeprom_dev)) { + LOG_ERR("EEPROM device not ready."); + return -ENODEV; + } + + ret = eeprom_read(eeprom_dev, addr, dev_data->mac_addr, sizeof(dev_data->mac_addr)); + if (ret < 0) { + LOG_ERR("Error reading MAC address from EEPROM [%d]", ret); + } + + return ret; +#else + return -ENODEV; +#endif +} + static int eth_xmc4xxx_init(const struct device *dev) { struct eth_xmc4xxx_data *dev_data = dev->data; @@ -867,7 +894,10 @@ static int eth_xmc4xxx_init(const struct device *dev) eth_xmc4xxx_mask_unused_interrupts(dev_cfg->regs); #if !DT_INST_NODE_HAS_PROP(0, local_mac_address) - gen_random_mac(dev_data->mac_addr, INFINEON_OUI_B0, INFINEON_OUI_B1, INFINEON_OUI_B2); + if (eth_xmc4xxx_get_mac_address_eeprom(dev) < 0) { + gen_random_mac(dev_data->mac_addr, INFINEON_OUI_B0, INFINEON_OUI_B1, + INFINEON_OUI_B2); + } #endif eth_xmc4xxx_set_mac_address(dev_cfg->regs, dev_data->mac_addr); diff --git a/dts/bindings/ethernet/atmel,gmac-common.yaml b/dts/bindings/ethernet/atmel,gmac-common.yaml index 0975647e1875c..fb03d2570a440 100644 --- a/dts/bindings/ethernet/atmel,gmac-common.yaml +++ b/dts/bindings/ethernet/atmel,gmac-common.yaml @@ -5,6 +5,7 @@ include: - name: ethernet-controller.yaml - name: pinctrl-device.yaml + - name: nvmem-consumer.yaml properties: reg: diff --git a/dts/bindings/ethernet/infineon,xmc4xxx-ethernet.yaml b/dts/bindings/ethernet/infineon,xmc4xxx-ethernet.yaml index c526fe89055e3..f3af3aab5ed1e 100644 --- a/dts/bindings/ethernet/infineon,xmc4xxx-ethernet.yaml +++ b/dts/bindings/ethernet/infineon,xmc4xxx-ethernet.yaml @@ -8,6 +8,7 @@ compatible: "infineon,xmc4xxx-ethernet" include: - name: ethernet-controller.yaml - name: pinctrl-device.yaml + - name: nvmem-consumer.yaml properties: interrupts: diff --git a/dts/bindings/mtd/nvmem-consumer.yaml b/dts/bindings/mtd/nvmem-consumer.yaml new file mode 100644 index 0000000000000..a2fcb40ae72ed --- /dev/null +++ b/dts/bindings/mtd/nvmem-consumer.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024, Andriy Gelman +# SPDX-License-Identifier: Apache-2.0 + +include: base.yaml + +properties: + nvmem-cell-names: + type: string-array + description: + Names for each nvmem-cells specified. + + nvmem-cells: + type: phandles + description: + List of phandle to the nvmem data cells. diff --git a/include/zephyr/devicetree/nvmem.h b/include/zephyr/devicetree/nvmem.h new file mode 100644 index 0000000000000..41a74cba44f94 --- /dev/null +++ b/include/zephyr/devicetree/nvmem.h @@ -0,0 +1,97 @@ +/** + * @file + * @brief NVMEM Devicetree macro public API header file. + */ + +/* + * Copyright (c) 2024, Andriy Gelman + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef INCLUDE_ZEPHYR_DEVICETREE_NVMEM_H_ +#define INCLUDE_ZEPHYR_DEVICETREE_NVMEM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup devicetree-nvmem Devicetree NVMEM API + * @ingroup devicetree + * @{ + */ + +/** + * @brief Get the pointer to the nvmem device from the nvmem-cells property + * + * Example devicetree fragment: + * + * mac_eeprom: mac_eeprom@2 { + * #address-cells = <1>; + * #size-cells = <1>; + * mac_address: mac_address@fa { + * reg = <0xfa 0x06>; + * }; + * }; + * + * eth: ethernet { + * nvmem-cells = <&mac_address>; + * nvmem-cell-names = "mac-address"; + * }; + * + * Example usage: + * + * DT_NVMEM_DEV_BY_IDX(DT_NODELABEL(eth), 0) // DEVICE_DT_GET(DT_NODELABEL(mac_eeprom)) + * + * @param node_id node identifier for a node with nvmem-cells property + * @param idx index into the nvmem-cells proprty + * @return the pointer to the nvmem device at index idx + */ + +#define DT_NVMEM_DEV_BY_IDX(node_id, idx) \ + DEVICE_DT_GET(DT_PARENT(DT_PHANDLE_BY_IDX(node_id, nvmem_cells, idx))) + +/** + * @brief Get the target address referenced by the nvmem-cells property + * + * Example devicetree fragment: + * + * mac_eeprom: mac_eeprom@2 { + * status = "okay"; + * + * #address-cells = <1>; + * #size-cells = <1>; + * + * mac_address: mac_address@fa { + * reg = <0xfa 0x06>; + * }; + * }; + * + * eth: ethernet@ { + * ... + * nvmem-cells = <&mac_address>; + * nvmem-cell-names = "mac-address"; + * ... + * }; + * + * Example usage: + * + * DT_NVMEM_ADDR_BY_IDX(DT_NODELABEL(eth), 0) // 0xfa + * + * @param node_id node identifier for a node with nvmem-cells property + * @param idx index into the nvmem-cells property + * @return the address of the nvmem device where the information is stored + */ + +#define DT_NVMEM_ADDR_BY_IDX(node_id, idx) DT_REG_ADDR(DT_PHANDLE_BY_IDX(node_id, nvmem_cells, idx)) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_ZEPHYR_DEVICETREE_NVMEM_H_ */ diff --git a/samples/net/gptp/boards/sam_e70_xplained_same70q21.conf b/samples/net/gptp/boards/sam_e70_xplained_same70q21.conf index d4118583c5072..3cbf10cba5f30 100644 --- a/samples/net/gptp/boards/sam_e70_xplained_same70q21.conf +++ b/samples/net/gptp/boards/sam_e70_xplained_same70q21.conf @@ -1,4 +1,2 @@ # GMAC driver settings CONFIG_PTP_CLOCK_SAM_GMAC=y - -CONFIG_ETH_SAM_GMAC_MAC_I2C_EEPROM=y