LCOV - code coverage report
Current view: top level - zephyr - nvmem.h Coverage Total Hit
Test: new.info Lines: 100.0 % 18 18
Test Date: 2025-10-20 12:20:01

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2025 Basalte bv
       3              :  * SPDX-License-Identifier: Apache-2.0
       4              :  */
       5              : 
       6              : /**
       7              :  * @file
       8              :  * @brief Main header file for NVMEM API.
       9              :  * @ingroup nvmem_interface
      10              :  */
      11              : 
      12              : #ifndef ZEPHYR_INCLUDE_NVMEM_H_
      13              : #define ZEPHYR_INCLUDE_NVMEM_H_
      14              : 
      15              : /**
      16              :  * @brief Interfaces for NVMEM cells.
      17              :  * @defgroup nvmem_interface NVMEM
      18              :  * @since 4.3
      19              :  * @version 0.1.0
      20              :  * @ingroup io_interfaces
      21              :  * @{
      22              :  */
      23              : 
      24              : #include <sys/types.h>
      25              : #include <zephyr/device.h>
      26              : #include <zephyr/devicetree.h>
      27              : #include <zephyr/devicetree/nvmem.h>
      28              : 
      29              : #ifdef __cplusplus
      30              : extern "C" {
      31              : #endif
      32              : 
      33              : /**
      34              :  * @brief Non-Volatile Memory cell representation.
      35              :  */
      36            1 : struct nvmem_cell {
      37              :         /** NVMEM parent controller device instance. */
      38            1 :         const struct device *dev;
      39              :         /** Offset of the NVMEM cell relative to the parent controller's base address */
      40            1 :         off_t offset;
      41              :         /** Size of the NVMEM cell */
      42            1 :         size_t size;
      43              :         /** Indicator if the NVMEM cell is read-write or read-only */
      44            1 :         bool read_only;
      45              : };
      46              : 
      47              : /**
      48              :  * @brief Static initializer for a struct nvmem_cell.
      49              :  *
      50              :  * This returns a static initializer for a struct nvmem_cell given a devicetree
      51              :  * node identifier.
      52              :  *
      53              :  * @note This is a helper macro for other NVMEM_CELL_GET macros to initialize the
      54              :  *       nvmem_cell struct.
      55              :  *
      56              :  * Example devicetree fragment:
      57              :  *
      58              :  * @code{.dts}
      59              :  *      mac_eeprom: mac_eeprom@2 {
      60              :  *              nvmem-layout {
      61              :  *                      compatible = "fixed-layout";
      62              :  *                      #address-cells = <1>;
      63              :  *                      #size-cells = <1>;
      64              :  *
      65              :  *                      mac_address: mac_address@fa {
      66              :  *                              reg = <0xfa 0x06>;
      67              :  *                              #nvmem-cell-cells = <0>;
      68              :  *                      };
      69              :  *              };
      70              :  *      };
      71              :  * @endcode
      72              :  *
      73              :  * Example usage:
      74              :  *
      75              :  * @code{.c}
      76              :  *      const struct nvmem_cell cell = NVMEM_CELL_INIT(DT_NODELABEL(mac_address));
      77              :  *
      78              :  *      // Initializes 'cell' to:
      79              :  *      // {
      80              :  *      //      .dev = DEVICE_DT_GET(DT_NODELABEL(mac_eeprom)),
      81              :  *      //      .offset = 0xfa,
      82              :  *      //      .size = 6,
      83              :  *      //      .read_only = false,
      84              :  *      // }
      85              :  * @endcode
      86              :  *
      87              :  * @param node_id Devicetree node identifier.
      88              :  *
      89              :  * @return Static initializer for a struct nvmem_cell
      90              :  */
      91            1 : #define NVMEM_CELL_INIT(node_id)                                                                   \
      92              :         {                                                                                          \
      93              :                 .dev = DEVICE_DT_GET(DT_MTD_FROM_NVMEM_CELL(node_id)),                             \
      94              :                 .offset = DT_REG_ADDR(node_id),                                                    \
      95              :                 .size = DT_REG_SIZE(node_id),                                                      \
      96              :                 .read_only = DT_PROP(node_id, read_only),                                          \
      97              :         }
      98              : 
      99              : /**
     100              :  * @brief Static initializer for a struct nvmem_cell.
     101              :  *
     102              :  * This returns a static initializer for a struct nvmem_cell given a devicetree
     103              :  * node identifier and a name.
     104              :  *
     105              :  * Example devicetree fragment:
     106              :  *
     107              :  * @code{.dts}
     108              :  *      mac_eeprom: mac_eeprom@2 {
     109              :  *              nvmem-layout {
     110              :  *                      compatible = "fixed-layout";
     111              :  *                      #address-cells = <1>;
     112              :  *                      #size-cells = <1>;
     113              :  *
     114              :  *                      mac_address: mac_address@fa {
     115              :  *                              reg = <0xfa 0x06>;
     116              :  *                              #nvmem-cell-cells = <0>;
     117              :  *                      };
     118              :  *              };
     119              :  *      };
     120              :  *
     121              :  *      eth: ethernet {
     122              :  *              nvmem-cells = <&mac_address>;
     123              :  *              nvmem-cell-names = "mac-address";
     124              :  *      };
     125              :  * @endcode
     126              :  *
     127              :  * Example usage:
     128              :  *
     129              :  * @code{.c}
     130              :  *      const struct nvmem_cell cell =
     131              :  *              NVMEM_CELL_GET_BY_NAME(DT_NODELABEL(eth), mac_address);
     132              :  *
     133              :  *      // Initializes 'cell' to:
     134              :  *      // {
     135              :  *      //      .dev = DEVICE_DT_GET(DT_NODELABEL(mac_eeprom)),
     136              :  *      //      .offset = 0xfa,
     137              :  *      //      .size = 6,
     138              :  *      //      .read_only = false,
     139              :  *      // }
     140              :  * @endcode
     141              :  *
     142              :  * @param node_id Devicetree node identifier.
     143              :  * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by
     144              :  *             the node's nvmem-cell-names property.
     145              :  *
     146              :  * @return Static initializer for a struct nvmem_cell for the property.
     147              :  *
     148              :  * @see NVMEM_CELL_INST_GET_BY_NAME
     149              :  */
     150            1 : #define NVMEM_CELL_GET_BY_NAME(node_id, name) NVMEM_CELL_INIT(DT_NVMEM_CELL_BY_NAME(node_id, name))
     151              : 
     152              : /**
     153              :  * @brief Static initializer for a struct nvmem_cell from a DT_DRV_COMPAT
     154              :  *        instance.
     155              :  *
     156              :  * @param inst DT_DRV_COMPAT instance number
     157              :  * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by
     158              :  *             the node's nvmem-cell-names property.
     159              :  *
     160              :  * @return Static initializer for a struct nvmem_cell for the property.
     161              :  *
     162              :  * @see NVMEM_CELL_GET_BY_NAME
     163              :  */
     164            1 : #define NVMEM_CELL_INST_GET_BY_NAME(inst, name) NVMEM_CELL_GET_BY_NAME(DT_DRV_INST(inst), name)
     165              : 
     166              : /**
     167              :  * @brief Like NVMEM_CELL_GET_BY_NAME(), with a fallback to a default value.
     168              :  *
     169              :  * If the devicetree node identifier 'node_id' refers to a node with a property
     170              :  * 'nvmem-cells', this expands to <tt>NVMEM_CELL_GET_BY_NAME(node_id, name)</tt>. The
     171              :  * @p default_value parameter is not expanded in this case. Otherwise, this
     172              :  * expands to @p default_value.
     173              :  *
     174              :  * @param node_id Devicetree node identifier.
     175              :  * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by
     176              :  *             the node's nvmem-cell-names property.
     177              :  * @param default_value Fallback value to expand to.
     178              :  *
     179              :  * @return Static initializer for a struct nvmem_cell for the property,
     180              :  *         or @p default_value if the node or property do not exist.
     181              :  *
     182              :  * @see NVMEM_CELL_INST_GET_BY_NAME_OR
     183              :  */
     184            1 : #define NVMEM_CELL_GET_BY_NAME_OR(node_id, name, default_value)                                    \
     185              :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, nvmem_cells),                                        \
     186              :                     (NVMEM_CELL_GET_BY_NAME(node_id, name)),                                       \
     187              :                     (default_value))
     188              : 
     189              : /**
     190              :  * @brief Like NVMEM_CELL_INST_GET_BY_NAME(), with a fallback to a default
     191              :  *        value.
     192              :  *
     193              :  * @param inst DT_DRV_COMPAT instance number
     194              :  * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by
     195              :  *             the node's nvmem-cell-names property.
     196              :  * @param default_value Fallback value to expand to.
     197              :  *
     198              :  * @return Static initializer for a struct nvmem_cell for the property,
     199              :  *         or @p default_value if the node or property do not exist.
     200              :  *
     201              :  * @see NVMEM_CELL_GET_BY_NAME_OR
     202              :  */
     203            1 : #define NVMEM_CELL_INST_GET_BY_NAME_OR(inst, name, default_value)                                  \
     204              :         NVMEM_CELL_GET_BY_NAME_OR(DT_DRV_INST(inst), name, default_value)
     205              : 
     206              : /**
     207              :  * @brief Static initializer for a struct nvmem_cell.
     208              :  *
     209              :  * This returns a static initializer for a struct nvmem_cell given a devicetree
     210              :  * node identifier and an index.
     211              :  *
     212              :  * Example devicetree fragment:
     213              :  *
     214              :  * @code{.dts}
     215              :  *      mac_eeprom: mac_eeprom@2 {
     216              :  *              nvmem-layout {
     217              :  *                      compatible = "fixed-layout";
     218              :  *                      #address-cells = <1>;
     219              :  *                      #size-cells = <1>;
     220              :  *
     221              :  *                      mac_address: mac_address@fa {
     222              :  *                              reg = <0xfa 0x06>;
     223              :  *                              #nvmem-cell-cells = <0>;
     224              :  *                      };
     225              :  *              };
     226              :  *      };
     227              :  *
     228              :  *      eth: ethernet {
     229              :  *              nvmem-cells = <&mac_address>;
     230              :  *              nvmem-cell-names = "mac-address";
     231              :  *      };
     232              :  * @endcode
     233              :  *
     234              :  * Example usage:
     235              :  *
     236              :  * @code{.c}
     237              :  *      const struct nvmem_cell cell =
     238              :  *              NVMEM_CELL_GET_BY_IDX(DT_NODELABEL(eth), 0);
     239              :  *
     240              :  *      // Initializes 'cell' to:
     241              :  *      // {
     242              :  *      //      .dev = DEVICE_DT_GET(DT_NODELABEL(mac_eeprom)),
     243              :  *      //      .offset = 0xfa,
     244              :  *      //      .size = 6,
     245              :  *      //      .read_only = false,
     246              :  *      // }
     247              :  * @endcode
     248              :  *
     249              :  * @param node_id Devicetree node identifier.
     250              :  * @param idx Logical index into 'nvmem-cells' property.
     251              :  *
     252              :  * @return Static initializer for a struct nvmem_cell for the property.
     253              :  *
     254              :  * @see NVMEM_CELL_INST_GET_BY_IDX
     255              :  */
     256            1 : #define NVMEM_CELL_GET_BY_IDX(node_id, idx) NVMEM_CELL_INIT(DT_NVMEM_CELL_BY_IDX(node_id, idx))
     257              : 
     258              : /**
     259              :  * @brief Static initializer for a struct nvmem_cell from a DT_DRV_COMPAT
     260              :  *        instance.
     261              :  *
     262              :  * @param inst DT_DRV_COMPAT instance number
     263              :  * @param idx Logical index into 'nvmem-cells' property.
     264              :  *
     265              :  * @return Static initializer for a struct nvmem_cell for the property.
     266              :  *
     267              :  * @see NVMEM_CELL_GET_BY_IDX
     268              :  */
     269            1 : #define NVMEM_CELL_INST_GET_BY_IDX(inst, idx) NVMEM_CELL_GET_BY_IDX(DT_DRV_INST(inst), idx)
     270              : 
     271              : /**
     272              :  * @brief Like NVMEM_CELL_GET_BY_IDX(), with a fallback to a default value.
     273              :  *
     274              :  * If the devicetree node identifier 'node_id' refers to a node with a property
     275              :  * 'nvmem-cells', this expands to <tt>NVMEM_CELL_GET_BY_IDX(node_id, idx)</tt>. The
     276              :  * @p default_value parameter is not expanded in this case. Otherwise, this
     277              :  * expands to @p default_value.
     278              :  *
     279              :  * @param node_id Devicetree node identifier.
     280              :  * @param idx Logical index into 'nvmem-cells' property.
     281              :  * @param default_value Fallback value to expand to.
     282              :  *
     283              :  * @return Static initializer for a struct nvmem_cell for the property,
     284              :  *         or @p default_value if the node or property do not exist.
     285              :  *
     286              :  * @see NVMEM_CELL_INST_GET_BY_IDX_OR
     287              :  */
     288            1 : #define NVMEM_CELL_GET_BY_IDX_OR(node_id, idx, default_value)                                      \
     289              :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, nvmem_cells),                                        \
     290              :                     (NVMEM_CELL_GET_BY_IDX(node_id, idx)),                                         \
     291              :                     (default_value))
     292              : 
     293              : /**
     294              :  * @brief Like NVMEM_CELL_INST_GET_BY_IDX(), with a fallback to a default
     295              :  *        value.
     296              :  *
     297              :  * @param inst DT_DRV_COMPAT instance number
     298              :  * @param idx Logical index into 'nvmem-cells' property.
     299              :  * @param default_value Fallback value to expand to.
     300              :  *
     301              :  * @return Static initializer for a struct nvmem_cell for the property,
     302              :  *         or @p default_value if the node or property do not exist.
     303              :  *
     304              :  * @see NVMEM_CELL_GET_BY_IDX_OR
     305              :  */
     306            1 : #define NVMEM_CELL_INST_GET_BY_IDX_OR(inst, idx, default_value)                                    \
     307              :         NVMEM_CELL_GET_BY_IDX_OR(DT_DRV_INST(inst), idx, default_value)
     308              : 
     309              : /**
     310              :  * @brief Read data from an NVMEM cell.
     311              :  *
     312              :  * @param cell The NVMEM cell.
     313              :  * @param data Buffer to store read data.
     314              :  * @param off The offset to start reading from.
     315              :  * @param len Number of bytes to read.
     316              :  *
     317              :  * @kconfig_dep{CONFIG_NVMEM}
     318              :  *
     319              :  * @return 0 on success, negative errno code on failure.
     320              :  */
     321            1 : int nvmem_cell_read(const struct nvmem_cell *cell, void *data, off_t off, size_t len);
     322              : 
     323              : /**
     324              :  * @brief Write data to an NVMEM cell.
     325              :  *
     326              :  * @param cell The NVMEM cell.
     327              :  * @param data Buffer with data to write.
     328              :  * @param off The offset to start writing to.
     329              :  * @param len Number of bytes to write.
     330              :  *
     331              :  * @kconfig_dep{CONFIG_NVMEM}
     332              :  *
     333              :  * @return 0 on success, negative errno code on failure.
     334              :  */
     335            1 : int nvmem_cell_write(const struct nvmem_cell *cell, const void *data, off_t off, size_t len);
     336              : 
     337              : /**
     338              :  * @brief Validate that the NVMEM cell is ready.
     339              :  *
     340              :  * @param cell The NVMEM cell.
     341              :  *
     342              :  * @return true if the NVMEM cell is ready for use and false otherwise.
     343              :  */
     344            1 : static inline bool nvmem_cell_is_ready(const struct nvmem_cell *cell)
     345              : {
     346              :         return cell != NULL && device_is_ready(cell->dev);
     347              : }
     348              : 
     349              : #ifdef __cplusplus
     350              : }
     351              : #endif
     352              : 
     353              : /**
     354              :  * @}
     355              :  */
     356              : 
     357              : #endif /* ZEPHYR_INCLUDE_NVMEM_H_ */
        

Generated by: LCOV version 2.0-1