Reference

nvmem(9)

NAME

nvmem, nvmem_get_cell_len, nvmem_read_cell_by_name, nvmem_read_cell_by_idx, nvmem_write_cell_by_name, nvmem_write_cell_by_idx

SYNOPSIS

options FDT device nvmem

#include <sys/extres/nvmem/nvmem.h>

int

nvmem_get_cell_len(phandle_t node, const char *name);

int

nvmem_read_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen);

int

nvmem_read_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen);

int

nvmem_write_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen);

int

nvmem_write_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen);

DESCRIPTION

On some embedded boards, the manufacturer stored some data on a NVMEM (Non-Volatile Memory), this is generally stored in some eeprom or fuses.

The nvmem API consist of helpers functions for consumer and device methods for providers.

FUNCTIONS

nvmem_get_cell_len(phandle_t node, const char *name)

Get the size of the cell base on the reg property on the node. Return the size or ENOENT if the cell name wasn't found

nvmem_read_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen)

Get the cell content based on the name. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

nvmem_read_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen)

Get the cell content based on the id. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

nvmem_write_cell_by_name(phandle_t node, const char *name, void *cell, size_t buflen)

Write the cell content based on the name. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

nvmem_write_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen)

Write the cell content based on the id. Return 0 on success or ENOENT if the cell doesn't exists, ENXIO if no provider device was found, EINVAL if the size isn't correct.

DEVICE METHODS

nvmem_read(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)

Provider device method to read a cell content.

nvmem_write(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)

Provider device method to write a cell content.

EXAMPLES

Consider this DTS

/* Provider */
eeprom: eeprom@20000 {
	board_id: id@0 {
		reg = <0x0 0x4>;
	};
};
/* Consumer */
device@30000 {
	...
	nvmem-cells = <&board_id>
	nvmem-cell-names = "boardid";
};

The device driver for eeprom@20000 needs to expose itself as a provider

#include "nvmem_if.h"
int
foo_nvmem_read(device_t dev, uint32_t offset, uint32_t size, uint8_t *buffer)
{
	/* Read the data */
}
int
foo_attach(device_t dev)
{
	phandle_t node;
	node = ofw_bus_get_node(dev);
	...
	/* Registering the device so the consumers can find us */
	OF_device_register_xref(OF_xref_from_node(node), dev);
	...
}
static device_method_t foo_methods[] = {
	...
	/* nvmem interface */
	DEVMETHOD(nvmem_read, foo_nvmem_read),
	/* Terminate method list */
	DEVMETHOD_END
};

The consumer device driver for device@30000 can now read the nvmem data

int
bar_attach(device_t dev)
{
	phandle_t node;
	uint32_t boardid;
	...
	node = ofw_bus_get_node(dev);
	nvmem_read_cell_by_name(node, "boardid", (void *)&boardid, sizeof(boardid));
	...
}

HISTORY

The nvmem related function first appear in FreeBSD 12.0. The nvmem interface and manual page was written by Emmanuel Vadot ⟨[email protected]⟩.

History