xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/nvmem.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun===============
4*4882a593SmuzhiyunNVMEM Subsystem
5*4882a593Smuzhiyun===============
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunThis document explains the NVMEM Framework along with the APIs provided,
10*4882a593Smuzhiyunand how to use it.
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun1. Introduction
13*4882a593Smuzhiyun===============
14*4882a593Smuzhiyun*NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to
15*4882a593Smuzhiyunretrieve configuration of SOC or Device specific data from non volatile
16*4882a593Smuzhiyunmemories like eeprom, efuses and so on.
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunBefore this framework existed, NVMEM drivers like eeprom were stored in
19*4882a593Smuzhiyundrivers/misc, where they all had to duplicate pretty much the same code to
20*4882a593Smuzhiyunregister a sysfs file, allow in-kernel users to access the content of the
21*4882a593Smuzhiyundevices they were driving, etc.
22*4882a593Smuzhiyun
23*4882a593SmuzhiyunThis was also a problem as far as other in-kernel users were involved, since
24*4882a593Smuzhiyunthe solutions used were pretty much different from one driver to another, there
25*4882a593Smuzhiyunwas a rather big abstraction leak.
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunThis framework aims at solve these problems. It also introduces DT
28*4882a593Smuzhiyunrepresentation for consumer devices to go get the data they require (MAC
29*4882a593SmuzhiyunAddresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs. This
30*4882a593Smuzhiyunframework is based on regmap, so that most of the abstraction available in
31*4882a593Smuzhiyunregmap can be reused, across multiple types of buses.
32*4882a593Smuzhiyun
33*4882a593SmuzhiyunNVMEM Providers
34*4882a593Smuzhiyun+++++++++++++++
35*4882a593Smuzhiyun
36*4882a593SmuzhiyunNVMEM provider refers to an entity that implements methods to initialize, read
37*4882a593Smuzhiyunand write the non-volatile memory.
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun2. Registering/Unregistering the NVMEM provider
40*4882a593Smuzhiyun===============================================
41*4882a593Smuzhiyun
42*4882a593SmuzhiyunA NVMEM provider can register with NVMEM core by supplying relevant
43*4882a593Smuzhiyunnvmem configuration to nvmem_register(), on success core would return a valid
44*4882a593Smuzhiyunnvmem_device pointer.
45*4882a593Smuzhiyun
46*4882a593Smuzhiyunnvmem_unregister(nvmem) is used to unregister a previously registered provider.
47*4882a593Smuzhiyun
48*4882a593SmuzhiyunFor example, a simple qfprom case::
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun  static struct nvmem_config econfig = {
51*4882a593Smuzhiyun	.name = "qfprom",
52*4882a593Smuzhiyun	.owner = THIS_MODULE,
53*4882a593Smuzhiyun  };
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun  static int qfprom_probe(struct platform_device *pdev)
56*4882a593Smuzhiyun  {
57*4882a593Smuzhiyun	...
58*4882a593Smuzhiyun	econfig.dev = &pdev->dev;
59*4882a593Smuzhiyun	nvmem = nvmem_register(&econfig);
60*4882a593Smuzhiyun	...
61*4882a593Smuzhiyun  }
62*4882a593Smuzhiyun
63*4882a593SmuzhiyunIt is mandatory that the NVMEM provider has a regmap associated with its
64*4882a593Smuzhiyunstruct device. Failure to do would return error code from nvmem_register().
65*4882a593Smuzhiyun
66*4882a593SmuzhiyunUsers of board files can define and register nvmem cells using the
67*4882a593Smuzhiyunnvmem_cell_table struct::
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun  static struct nvmem_cell_info foo_nvmem_cells[] = {
70*4882a593Smuzhiyun	{
71*4882a593Smuzhiyun		.name		= "macaddr",
72*4882a593Smuzhiyun		.offset		= 0x7f00,
73*4882a593Smuzhiyun		.bytes		= ETH_ALEN,
74*4882a593Smuzhiyun	}
75*4882a593Smuzhiyun  };
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun  static struct nvmem_cell_table foo_nvmem_cell_table = {
78*4882a593Smuzhiyun	.nvmem_name		= "i2c-eeprom",
79*4882a593Smuzhiyun	.cells			= foo_nvmem_cells,
80*4882a593Smuzhiyun	.ncells			= ARRAY_SIZE(foo_nvmem_cells),
81*4882a593Smuzhiyun  };
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun  nvmem_add_cell_table(&foo_nvmem_cell_table);
84*4882a593Smuzhiyun
85*4882a593SmuzhiyunAdditionally it is possible to create nvmem cell lookup entries and register
86*4882a593Smuzhiyunthem with the nvmem framework from machine code as shown in the example below::
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun  static struct nvmem_cell_lookup foo_nvmem_lookup = {
89*4882a593Smuzhiyun	.nvmem_name		= "i2c-eeprom",
90*4882a593Smuzhiyun	.cell_name		= "macaddr",
91*4882a593Smuzhiyun	.dev_id			= "foo_mac.0",
92*4882a593Smuzhiyun	.con_id			= "mac-address",
93*4882a593Smuzhiyun  };
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun  nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
96*4882a593Smuzhiyun
97*4882a593SmuzhiyunNVMEM Consumers
98*4882a593Smuzhiyun+++++++++++++++
99*4882a593Smuzhiyun
100*4882a593SmuzhiyunNVMEM consumers are the entities which make use of the NVMEM provider to
101*4882a593Smuzhiyunread from and to NVMEM.
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun3. NVMEM cell based consumer APIs
104*4882a593Smuzhiyun=================================
105*4882a593Smuzhiyun
106*4882a593SmuzhiyunNVMEM cells are the data entries/fields in the NVMEM.
107*4882a593SmuzhiyunThe NVMEM framework provides 3 APIs to read/write NVMEM cells::
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun  struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
110*4882a593Smuzhiyun  struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun  void nvmem_cell_put(struct nvmem_cell *cell);
113*4882a593Smuzhiyun  void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun  void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
116*4882a593Smuzhiyun  int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun`*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,
119*4882a593Smuzhiyunand nvmem_cell_read/write() can then read or write to the cell.
120*4882a593SmuzhiyunOnce the usage of the cell is finished the consumer should call
121*4882a593Smuzhiyun`*nvmem_cell_put()` to free all the allocation memory for the cell.
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun4. Direct NVMEM device based consumer APIs
124*4882a593Smuzhiyun==========================================
125*4882a593Smuzhiyun
126*4882a593SmuzhiyunIn some instances it is necessary to directly read/write the NVMEM.
127*4882a593SmuzhiyunTo facilitate such consumers NVMEM framework provides below apis::
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun  struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
130*4882a593Smuzhiyun  struct nvmem_device *devm_nvmem_device_get(struct device *dev,
131*4882a593Smuzhiyun					   const char *name);
132*4882a593Smuzhiyun  struct nvmem_device *nvmem_device_find(void *data,
133*4882a593Smuzhiyun			int (*match)(struct device *dev, const void *data));
134*4882a593Smuzhiyun  void nvmem_device_put(struct nvmem_device *nvmem);
135*4882a593Smuzhiyun  int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
136*4882a593Smuzhiyun		      size_t bytes, void *buf);
137*4882a593Smuzhiyun  int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
138*4882a593Smuzhiyun		       size_t bytes, void *buf);
139*4882a593Smuzhiyun  int nvmem_device_cell_read(struct nvmem_device *nvmem,
140*4882a593Smuzhiyun			   struct nvmem_cell_info *info, void *buf);
141*4882a593Smuzhiyun  int nvmem_device_cell_write(struct nvmem_device *nvmem,
142*4882a593Smuzhiyun			    struct nvmem_cell_info *info, void *buf);
143*4882a593Smuzhiyun
144*4882a593SmuzhiyunBefore the consumers can read/write NVMEM directly, it should get hold
145*4882a593Smuzhiyunof nvmem_controller from one of the `*nvmem_device_get()` api.
146*4882a593Smuzhiyun
147*4882a593SmuzhiyunThe difference between these apis and cell based apis is that these apis always
148*4882a593Smuzhiyuntake nvmem_device as parameter.
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun5. Releasing a reference to the NVMEM
151*4882a593Smuzhiyun=====================================
152*4882a593Smuzhiyun
153*4882a593SmuzhiyunWhen a consumer no longer needs the NVMEM, it has to release the reference
154*4882a593Smuzhiyunto the NVMEM it has obtained using the APIs mentioned in the above section.
155*4882a593SmuzhiyunThe NVMEM framework provides 2 APIs to release a reference to the NVMEM::
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun  void nvmem_cell_put(struct nvmem_cell *cell);
158*4882a593Smuzhiyun  void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
159*4882a593Smuzhiyun  void nvmem_device_put(struct nvmem_device *nvmem);
160*4882a593Smuzhiyun  void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
161*4882a593Smuzhiyun
162*4882a593SmuzhiyunBoth these APIs are used to release a reference to the NVMEM and
163*4882a593Smuzhiyundevm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated
164*4882a593Smuzhiyunwith this NVMEM.
165*4882a593Smuzhiyun
166*4882a593SmuzhiyunUserspace
167*4882a593Smuzhiyun+++++++++
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun6. Userspace binary interface
170*4882a593Smuzhiyun==============================
171*4882a593Smuzhiyun
172*4882a593SmuzhiyunUserspace can read/write the raw NVMEM file located at::
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun	/sys/bus/nvmem/devices/*/nvmem
175*4882a593Smuzhiyun
176*4882a593Smuzhiyunex::
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun  hexdump /sys/bus/nvmem/devices/qfprom0/nvmem
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun  0000000 0000 0000 0000 0000 0000 0000 0000 0000
181*4882a593Smuzhiyun  *
182*4882a593Smuzhiyun  00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
183*4882a593Smuzhiyun  0000000 0000 0000 0000 0000 0000 0000 0000 0000
184*4882a593Smuzhiyun  ...
185*4882a593Smuzhiyun  *
186*4882a593Smuzhiyun  0001000
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun7. DeviceTree Binding
189*4882a593Smuzhiyun=====================
190*4882a593Smuzhiyun
191*4882a593SmuzhiyunSee Documentation/devicetree/bindings/nvmem/nvmem.txt
192