summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/nvmem.9 3.html
blob: 291f9867bfb61ee2d9676027e8e6468b83221067 (plain)
1
2
3
4
5
6
7
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<table class="head">
  <tr>
    <td class="head-ltitle">nvmem(9)</td>
    <td class="head-vol">Kernel Developer's Manual</td>
    <td class="head-rtitle">nvmem(9)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">nvmem</code>,
    <code class="Nm">nvmem_get_cell_len</code>,
    <code class="Nm">nvmem_read_cell_by_name</code>,
    <code class="Nm">nvmem_read_cell_by_idx</code>,
    <code class="Nm">nvmem_write_cell_by_name</code>,
    <code class="Nm">nvmem_write_cell_by_idx</code></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="Cd">options FDT</code>
  <br/>
  <code class="Cd">device nvmem</code>
  <br/>
  <code class="In">#include
    &lt;<a class="In">sys/extres/nvmem/nvmem.h</a>&gt;</code></p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">nvmem_get_cell_len</code>(<var class="Fa" style="white-space: nowrap;">phandle_t
    node</var>, <var class="Fa" style="white-space: nowrap;">const char
    *name</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">nvmem_read_cell_by_name</code>(<var class="Fa" style="white-space: nowrap;">phandle_t
    node</var>, <var class="Fa" style="white-space: nowrap;">const char
    *name</var>, <var class="Fa" style="white-space: nowrap;">void *cell</var>,
    <var class="Fa" style="white-space: nowrap;">size_t buflen</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">nvmem_read_cell_by_idx</code>(<var class="Fa" style="white-space: nowrap;">phandle_t
    node</var>, <var class="Fa" style="white-space: nowrap;">int idx</var>,
    <var class="Fa" style="white-space: nowrap;">void *cell</var>,
    <var class="Fa" style="white-space: nowrap;">size_t buflen</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">nvmem_write_cell_by_name</code>(<var class="Fa" style="white-space: nowrap;">phandle_t
    node</var>, <var class="Fa" style="white-space: nowrap;">const char
    *name</var>, <var class="Fa" style="white-space: nowrap;">void *cell</var>,
    <var class="Fa" style="white-space: nowrap;">size_t buflen</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">nvmem_write_cell_by_idx</code>(<var class="Fa" style="white-space: nowrap;">phandle_t
    node</var>, <var class="Fa" style="white-space: nowrap;">int idx</var>,
    <var class="Fa" style="white-space: nowrap;">void *cell</var>,
    <var class="Fa" style="white-space: nowrap;">size_t buflen</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">On some embedded boards, the manufacturer stored some data on a
    NVMEM (Non-Volatile Memory), this is generally stored in some eeprom or
    fuses.</p>
<p class="Pp">The <code class="Nm">nvmem</code> API consist of helpers functions
    for consumer and device methods for providers.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="FUNCTIONS"><a class="permalink" href="#FUNCTIONS">FUNCTIONS</a></h1>
<dl class="Bl-tag">
  <dt id="nvmem_get_cell_len"><a class="permalink" href="#nvmem_get_cell_len"><code class="Fn">nvmem_get_cell_len</code></a>(<var class="Fa">phandle_t
    node</var>, <var class="Fa">const char *name</var>)</dt>
  <dd>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</dd>
  <dt id="nvmem_read_cell_by_name"><a class="permalink" href="#nvmem_read_cell_by_name"><code class="Fn">nvmem_read_cell_by_name</code></a>(<var class="Fa">phandle_t
    node</var>, <var class="Fa">const char *name</var>, <var class="Fa">void
    *cell</var>, <var class="Fa">size_t buflen</var>)</dt>
  <dd>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.</dd>
  <dt id="nvmem_read_cell_by_idx"><a class="permalink" href="#nvmem_read_cell_by_idx"><code class="Fn">nvmem_read_cell_by_idx</code></a>(<var class="Fa">phandle_t
    node</var>, <var class="Fa">int idx</var>, <var class="Fa">void *cell</var>,
    <var class="Fa">size_t buflen</var>)</dt>
  <dd>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.</dd>
  <dt id="nvmem_write_cell_by_name"><a class="permalink" href="#nvmem_write_cell_by_name"><code class="Fn">nvmem_write_cell_by_name</code></a>(<var class="Fa">phandle_t
    node</var>, <var class="Fa">const char *name</var>, <var class="Fa">void
    *cell</var>, <var class="Fa">size_t buflen</var>)</dt>
  <dd>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.</dd>
  <dt id="nvmem_write_cell_by_idx"><a class="permalink" href="#nvmem_write_cell_by_idx"><code class="Fn">nvmem_write_cell_by_idx</code></a>(<var class="Fa">phandle_t
    node</var>, <var class="Fa">int idx</var>, <var class="Fa">void *cell</var>,
    <var class="Fa">size_t buflen</var>)</dt>
  <dd>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.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="DEVICE_METHODS"><a class="permalink" href="#DEVICE_METHODS">DEVICE
  METHODS</a></h1>
<dl class="Bl-tag">
  <dt id="nvmem_read"><a class="permalink" href="#nvmem_read"><code class="Fn">nvmem_read</code></a>(<var class="Fa">device_t
    dev</var>, <var class="Fa">uint32_t offset</var>, <var class="Fa">uint32_t
    size</var>, <var class="Fa">uint8_t *buffer</var>)</dt>
  <dd>Provider device method to read a cell content.</dd>
  <dt id="nvmem_write"><a class="permalink" href="#nvmem_write"><code class="Fn">nvmem_write</code></a>(<var class="Fa">device_t
    dev</var>, <var class="Fa">uint32_t offset</var>, <var class="Fa">uint32_t
    size</var>, <var class="Fa">uint8_t *buffer</var>)</dt>
  <dd>Provider device method to write a cell content.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
<p class="Pp">Consider this DTS</p>
<div class="Bd Pp Li">
<pre>/* Provider */
eeprom: eeprom@20000 {
	board_id: id@0 {
		reg = &lt;0x0 0x4&gt;;
	};
};
/* Consumer */
device@30000 {
	...

	nvmem-cells = &lt;&amp;board_id&gt;
	nvmem-cell-names = &quot;boardid&quot;;
};</pre>
</div>
<p class="Pp">The device driver for eeprom@20000 needs to expose itself as a
    provider</p>
<div class="Bd Pp Li">
<pre>#include &quot;nvmem_if.h&quot;

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
};</pre>
</div>
<p class="Pp">The consumer device driver for device@30000 can now read the nvmem
    data</p>
<div class="Bd Pp Li">
<pre>int
bar_attach(device_t dev)
{
	phandle_t node;
	uint32_t boardid;

	...
	node = ofw_bus_get_node(dev);
	nvmem_read_cell_by_name(node, &quot;boardid&quot;, (void *)&amp;boardid, sizeof(boardid));
	...
}</pre>
</div>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">The nvmem related function first appear in
    <span class="Ux">FreeBSD 12.0</span>. The nvmem interface and manual page
    was written by <span class="An">Emmanuel Vadot</span>
    &lt;<a class="Mt" href="mailto:manu@FreeBSD.org">manu@FreeBSD.org</a>&gt;.</p>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">July 24, 2018</td>
    <td class="foot-os">FreeBSD 15.0</td>
  </tr>
</table>