blob: 287e868196400f5dfa44d556dd202909406f64fa [file] [log] [blame]
Mauro Carvalho Chehabbaa293e2019-06-27 15:39:22 -03001.. SPDX-License-Identifier: GPL-2.0
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -03002
3===============
4NVMEM Subsystem
5===============
6
7 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +01008
9This document explains the NVMEM Framework along with the APIs provided,
10and how to use it.
11
121. Introduction
13===============
14*NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to
15retrieve configuration of SOC or Device specific data from non volatile
16memories like eeprom, efuses and so on.
17
18Before this framework existed, NVMEM drivers like eeprom were stored in
19drivers/misc, where they all had to duplicate pretty much the same code to
20register a sysfs file, allow in-kernel users to access the content of the
21devices they were driving, etc.
22
23This was also a problem as far as other in-kernel users were involved, since
24the solutions used were pretty much different from one driver to another, there
25was a rather big abstraction leak.
26
27This framework aims at solve these problems. It also introduces DT
28representation for consumer devices to go get the data they require (MAC
29Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs. This
30framework is based on regmap, so that most of the abstraction available in
31regmap can be reused, across multiple types of buses.
32
33NVMEM Providers
34+++++++++++++++
35
36NVMEM provider refers to an entity that implements methods to initialize, read
37and write the non-volatile memory.
38
392. Registering/Unregistering the NVMEM provider
40===============================================
41
42A NVMEM provider can register with NVMEM core by supplying relevant
43nvmem configuration to nvmem_register(), on success core would return a valid
44nvmem_device pointer.
45
46nvmem_unregister(nvmem) is used to unregister a previously registered provider.
47
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030048For example, a simple qfprom case::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010049
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030050 static struct nvmem_config econfig = {
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010051 .name = "qfprom",
52 .owner = THIS_MODULE,
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030053 };
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010054
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030055 static int qfprom_probe(struct platform_device *pdev)
56 {
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010057 ...
58 econfig.dev = &pdev->dev;
59 nvmem = nvmem_register(&econfig);
60 ...
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030061 }
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010062
63It is mandatory that the NVMEM provider has a regmap associated with its
64struct device. Failure to do would return error code from nvmem_register().
65
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070066Users of board files can define and register nvmem cells using the
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030067nvmem_cell_table struct::
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070068
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030069 static struct nvmem_cell_info foo_nvmem_cells[] = {
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070070 {
71 .name = "macaddr",
72 .offset = 0x7f00,
73 .bytes = ETH_ALEN,
74 }
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030075 };
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070076
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030077 static struct nvmem_cell_table foo_nvmem_cell_table = {
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070078 .nvmem_name = "i2c-eeprom",
79 .cells = foo_nvmem_cells,
80 .ncells = ARRAY_SIZE(foo_nvmem_cells),
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030081 };
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070082
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030083 nvmem_add_cell_table(&foo_nvmem_cell_table);
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070084
85Additionally it is possible to create nvmem cell lookup entries and register
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030086them with the nvmem framework from machine code as shown in the example below::
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070087
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030088 static struct nvmem_cell_lookup foo_nvmem_lookup = {
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070089 .nvmem_name = "i2c-eeprom",
90 .cell_name = "macaddr",
91 .dev_id = "foo_mac.0",
92 .con_id = "mac-address",
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030093 };
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070094
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030095 nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070096
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010097NVMEM Consumers
98+++++++++++++++
99
100NVMEM consumers are the entities which make use of the NVMEM provider to
101read from and to NVMEM.
102
1033. NVMEM cell based consumer APIs
104=================================
105
106NVMEM cells are the data entries/fields in the NVMEM.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300107The NVMEM framework provides 3 APIs to read/write NVMEM cells::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100108
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300109 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
110 struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100111
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300112 void nvmem_cell_put(struct nvmem_cell *cell);
113 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100114
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300115 void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
116 int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100117
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300118`*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100119and nvmem_cell_read/write() can then read or write to the cell.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300120Once the usage of the cell is finished the consumer should call
121`*nvmem_cell_put()` to free all the allocation memory for the cell.
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100122
1234. Direct NVMEM device based consumer APIs
124==========================================
125
126In some instances it is necessary to directly read/write the NVMEM.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300127To facilitate such consumers NVMEM framework provides below apis::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100128
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300129 struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
130 struct nvmem_device *devm_nvmem_device_get(struct device *dev,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100131 const char *name);
Thomas Bogendoerfer8c2a2b82019-10-03 11:52:29 +0200132 struct nvmem_device *nvmem_device_find(void *data,
133 int (*match)(struct device *dev, const void *data));
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300134 void nvmem_device_put(struct nvmem_device *nvmem);
135 int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100136 size_t bytes, void *buf);
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300137 int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100138 size_t bytes, void *buf);
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300139 int nvmem_device_cell_read(struct nvmem_device *nvmem,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100140 struct nvmem_cell_info *info, void *buf);
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300141 int nvmem_device_cell_write(struct nvmem_device *nvmem,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100142 struct nvmem_cell_info *info, void *buf);
143
144Before the consumers can read/write NVMEM directly, it should get hold
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300145of nvmem_controller from one of the `*nvmem_device_get()` api.
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100146
147The difference between these apis and cell based apis is that these apis always
148take nvmem_device as parameter.
149
1505. Releasing a reference to the NVMEM
151=====================================
152
Narenbe629b42017-08-16 15:45:57 -0700153When a consumer no longer needs the NVMEM, it has to release the reference
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100154to the NVMEM it has obtained using the APIs mentioned in the above section.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300155The NVMEM framework provides 2 APIs to release a reference to the NVMEM::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100156
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300157 void nvmem_cell_put(struct nvmem_cell *cell);
158 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
159 void nvmem_device_put(struct nvmem_device *nvmem);
160 void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100161
162Both these APIs are used to release a reference to the NVMEM and
163devm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated
164with this NVMEM.
165
166Userspace
167+++++++++
168
1696. Userspace binary interface
170==============================
171
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300172Userspace can read/write the raw NVMEM file located at::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100173
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300174 /sys/bus/nvmem/devices/*/nvmem
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100175
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300176ex::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100177
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300178 hexdump /sys/bus/nvmem/devices/qfprom0/nvmem
179
180 0000000 0000 0000 0000 0000 0000 0000 0000 0000
181 *
182 00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
183 0000000 0000 0000 0000 0000 0000 0000 0000 0000
184 ...
185 *
186 0001000
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100187
1887. DeviceTree Binding
189=====================
190
191See Documentation/devicetree/bindings/nvmem/nvmem.txt