Blame view

Documentation/driver-api/nvmem.rst 6.28 KB
baa293e95   Mauro Carvalho Chehab   docs: driver-api:...
1
  .. SPDX-License-Identifier: GPL-2.0
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
2
3
4
5
6
7
  
  ===============
  NVMEM Subsystem
  ===============
  
   Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
354ebb541   Srinivas Kandagatla   Documentation: nv...
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  
  This document explains the NVMEM Framework along with the APIs provided,
  and how to use it.
  
  1. Introduction
  ===============
  *NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to
  retrieve configuration of SOC or Device specific data from non volatile
  memories like eeprom, efuses and so on.
  
  Before this framework existed, NVMEM drivers like eeprom were stored in
  drivers/misc, where they all had to duplicate pretty much the same code to
  register a sysfs file, allow in-kernel users to access the content of the
  devices they were driving, etc.
  
  This was also a problem as far as other in-kernel users were involved, since
  the solutions used were pretty much different from one driver to another, there
  was a rather big abstraction leak.
  
  This framework aims at solve these problems. It also introduces DT
  representation for consumer devices to go get the data they require (MAC
  Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs. This
  framework is based on regmap, so that most of the abstraction available in
  regmap can be reused, across multiple types of buses.
  
  NVMEM Providers
  +++++++++++++++
  
  NVMEM provider refers to an entity that implements methods to initialize, read
  and write the non-volatile memory.
  
  2. Registering/Unregistering the NVMEM provider
  ===============================================
  
  A NVMEM provider can register with NVMEM core by supplying relevant
  nvmem configuration to nvmem_register(), on success core would return a valid
  nvmem_device pointer.
  
  nvmem_unregister(nvmem) is used to unregister a previously registered provider.
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
47
  For example, a simple qfprom case::
354ebb541   Srinivas Kandagatla   Documentation: nv...
48

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
49
    static struct nvmem_config econfig = {
354ebb541   Srinivas Kandagatla   Documentation: nv...
50
51
  	.name = "qfprom",
  	.owner = THIS_MODULE,
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
52
    };
354ebb541   Srinivas Kandagatla   Documentation: nv...
53

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
54
55
    static int qfprom_probe(struct platform_device *pdev)
    {
354ebb541   Srinivas Kandagatla   Documentation: nv...
56
57
58
59
  	...
  	econfig.dev = &pdev->dev;
  	nvmem = nvmem_register(&econfig);
  	...
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
60
    }
354ebb541   Srinivas Kandagatla   Documentation: nv...
61
62
63
  
  It is mandatory that the NVMEM provider has a regmap associated with its
  struct device. Failure to do would return error code from nvmem_register().
4903d19c2   Bartosz Golaszewski   Documentation: nv...
64
  Users of board files can define and register nvmem cells using the
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
65
  nvmem_cell_table struct::
4903d19c2   Bartosz Golaszewski   Documentation: nv...
66

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
67
    static struct nvmem_cell_info foo_nvmem_cells[] = {
4903d19c2   Bartosz Golaszewski   Documentation: nv...
68
69
70
71
72
  	{
  		.name		= "macaddr",
  		.offset		= 0x7f00,
  		.bytes		= ETH_ALEN,
  	}
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
73
    };
4903d19c2   Bartosz Golaszewski   Documentation: nv...
74

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
75
    static struct nvmem_cell_table foo_nvmem_cell_table = {
4903d19c2   Bartosz Golaszewski   Documentation: nv...
76
77
78
  	.nvmem_name		= "i2c-eeprom",
  	.cells			= foo_nvmem_cells,
  	.ncells			= ARRAY_SIZE(foo_nvmem_cells),
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
79
    };
4903d19c2   Bartosz Golaszewski   Documentation: nv...
80

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
81
    nvmem_add_cell_table(&foo_nvmem_cell_table);
4903d19c2   Bartosz Golaszewski   Documentation: nv...
82
83
  
  Additionally it is possible to create nvmem cell lookup entries and register
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
84
  them with the nvmem framework from machine code as shown in the example below::
4903d19c2   Bartosz Golaszewski   Documentation: nv...
85

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
86
    static struct nvmem_cell_lookup foo_nvmem_lookup = {
4903d19c2   Bartosz Golaszewski   Documentation: nv...
87
88
89
90
  	.nvmem_name		= "i2c-eeprom",
  	.cell_name		= "macaddr",
  	.dev_id			= "foo_mac.0",
  	.con_id			= "mac-address",
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
91
    };
4903d19c2   Bartosz Golaszewski   Documentation: nv...
92

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
93
    nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
4903d19c2   Bartosz Golaszewski   Documentation: nv...
94

354ebb541   Srinivas Kandagatla   Documentation: nv...
95
96
97
98
99
100
101
102
103
104
  NVMEM Consumers
  +++++++++++++++
  
  NVMEM consumers are the entities which make use of the NVMEM provider to
  read from and to NVMEM.
  
  3. NVMEM cell based consumer APIs
  =================================
  
  NVMEM cells are the data entries/fields in the NVMEM.
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
105
  The NVMEM framework provides 3 APIs to read/write NVMEM cells::
354ebb541   Srinivas Kandagatla   Documentation: nv...
106

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
107
108
    struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
    struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
354ebb541   Srinivas Kandagatla   Documentation: nv...
109

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
110
111
    void nvmem_cell_put(struct nvmem_cell *cell);
    void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
354ebb541   Srinivas Kandagatla   Documentation: nv...
112

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
113
114
    void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
    int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);
354ebb541   Srinivas Kandagatla   Documentation: nv...
115

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
116
  `*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,
354ebb541   Srinivas Kandagatla   Documentation: nv...
117
  and nvmem_cell_read/write() can then read or write to the cell.
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
118
119
  Once the usage of the cell is finished the consumer should call
  `*nvmem_cell_put()` to free all the allocation memory for the cell.
354ebb541   Srinivas Kandagatla   Documentation: nv...
120
121
122
123
124
  
  4. Direct NVMEM device based consumer APIs
  ==========================================
  
  In some instances it is necessary to directly read/write the NVMEM.
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
125
  To facilitate such consumers NVMEM framework provides below apis::
354ebb541   Srinivas Kandagatla   Documentation: nv...
126

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
127
128
    struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
    struct nvmem_device *devm_nvmem_device_get(struct device *dev,
354ebb541   Srinivas Kandagatla   Documentation: nv...
129
  					   const char *name);
8c2a2b8c2   Thomas Bogendoerfer   nvmem: core: add ...
130
131
    struct nvmem_device *nvmem_device_find(void *data,
  			int (*match)(struct device *dev, const void *data));
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
132
133
    void nvmem_device_put(struct nvmem_device *nvmem);
    int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
354ebb541   Srinivas Kandagatla   Documentation: nv...
134
  		      size_t bytes, void *buf);
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
135
    int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
354ebb541   Srinivas Kandagatla   Documentation: nv...
136
  		       size_t bytes, void *buf);
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
137
    int nvmem_device_cell_read(struct nvmem_device *nvmem,
354ebb541   Srinivas Kandagatla   Documentation: nv...
138
  			   struct nvmem_cell_info *info, void *buf);
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
139
    int nvmem_device_cell_write(struct nvmem_device *nvmem,
354ebb541   Srinivas Kandagatla   Documentation: nv...
140
141
142
  			    struct nvmem_cell_info *info, void *buf);
  
  Before the consumers can read/write NVMEM directly, it should get hold
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
143
  of nvmem_controller from one of the `*nvmem_device_get()` api.
354ebb541   Srinivas Kandagatla   Documentation: nv...
144
145
146
147
148
149
  
  The difference between these apis and cell based apis is that these apis always
  take nvmem_device as parameter.
  
  5. Releasing a reference to the NVMEM
  =====================================
be629b441   Naren   NVMEM documentati...
150
  When a consumer no longer needs the NVMEM, it has to release the reference
354ebb541   Srinivas Kandagatla   Documentation: nv...
151
  to the NVMEM it has obtained using the APIs mentioned in the above section.
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
152
  The NVMEM framework provides 2 APIs to release a reference to the NVMEM::
354ebb541   Srinivas Kandagatla   Documentation: nv...
153

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
154
155
156
157
    void nvmem_cell_put(struct nvmem_cell *cell);
    void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
    void nvmem_device_put(struct nvmem_device *nvmem);
    void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
354ebb541   Srinivas Kandagatla   Documentation: nv...
158
159
160
161
162
163
164
165
166
167
  
  Both these APIs are used to release a reference to the NVMEM and
  devm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated
  with this NVMEM.
  
  Userspace
  +++++++++
  
  6. Userspace binary interface
  ==============================
a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
168
169
170
  Userspace can read/write the raw NVMEM file located at::
  
  	/sys/bus/nvmem/devices/*/nvmem
354ebb541   Srinivas Kandagatla   Documentation: nv...
171

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
172
  ex::
354ebb541   Srinivas Kandagatla   Documentation: nv...
173

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
174
    hexdump /sys/bus/nvmem/devices/qfprom0/nvmem
354ebb541   Srinivas Kandagatla   Documentation: nv...
175

a278295cc   Mauro Carvalho Chehab   docs: nvmem: conv...
176
177
178
179
180
181
182
    0000000 0000 0000 0000 0000 0000 0000 0000 0000
    *
    00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
    0000000 0000 0000 0000 0000 0000 0000 0000 0000
    ...
    *
    0001000
354ebb541   Srinivas Kandagatla   Documentation: nv...
183
184
185
186
187
  
  7. DeviceTree Binding
  =====================
  
  See Documentation/devicetree/bindings/nvmem/nvmem.txt