1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <lib/shared/ibinder/ibinder.h>
20 #include <lk/compiler.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 __BEGIN_CDECLS
25 
26 // an error originating from backend functionality
27 const int DT_ERROR_GENERIC = 1;
28 // an error resulting from passing bad arguments, e.g. null pointers
29 const int DT_ERROR_INVALID_ARGS = 2;
30 // a failure to allocate a structure on the heap
31 const int DT_ERROR_NO_MEMORY = 3;
32 // a failure to find any set of nodes
33 const int DT_ERROR_NODE_NOT_FOUND = 4;
34 // a failure to find any set of properties
35 const int DT_ERROR_PROP_NOT_FOUND = 5;
36 
37 struct device_tree_idevice_tree;
38 struct device_tree_inode;
39 struct device_tree_inode_iter;
40 struct device_tree_prop;
41 struct device_tree_iprop_iter;
42 
43 /**
44  * device_tree_get_service() - Connect to a device tree service
45  *
46  * @tree:    Pointer to the output device tree interface
47  *
48  * Return:   An error code reflecting success or failure
49  */
50 int device_tree_get_service(struct device_tree_idevice_tree** tree);
51 
52 /**
53  * device_tree_idevice_tree_get_compatible_nodes() - Get a node iterator for
54  *                                                 a given compatible string
55  *
56  * @self:          Pointer to the device tree interface
57  * @compat_str:    The compatible string to search for
58  * @iter:          Pointer to the output node iterator
59  *
60  * Return:         An error code reflecting success or failure
61  */
62 int device_tree_idevice_tree_get_compatible_nodes(
63         struct device_tree_idevice_tree* self,
64         const char* compat_str,
65         struct device_tree_inode_iter** iter);
66 /**
67  * device_tree_idevice_tree_get_compatible_nodes_from_list() - Get a node
68  * iterator for various compatible strings
69  *
70  * @self:               Pointer to the device tree interface
71  * @compat_str_list:    Pointer to an array of compatible
72  *                      strings to search for
73  * @num_str:            The number of compatible strings in
74  *                      `compat_str_list`
75  * @iter:               Pointer to the output node iterator
76  *
77  * Return:              An error code reflecting success or failure
78  */
79 int device_tree_idevice_tree_get_compatible_nodes_from_list(
80         struct device_tree_idevice_tree* self,
81         const char** compat_str_list,
82         size_t num_str,
83         struct device_tree_inode_iter** iter);
84 
85 /**
86  * device_tree_inode_iter_get_next_node() - Advance a node iterator
87  *
88  * @iter:    Pointer to the node iterator
89  * @node:    Pointer to the output node
90  *
91  * Return:   An error code reflecting success or failure
92  */
93 int device_tree_inode_iter_get_next_node(struct device_tree_inode_iter* iter,
94                                          struct device_tree_inode** node);
95 
96 /**
97  * device_tree_inode_get_name() - Get a node's name
98  *
99  * @node:    Pointer to the node iterator
100  * @name:    Pointer for the node name output. This pointer is only valid for
101  *           the lifetime of the pointer to the node and will be freed when the
102  *           node is freed.
103  *
104  * Return:   An error code reflecting success or failure
105  */
106 int device_tree_inode_get_name(struct device_tree_inode* node,
107                                const char** name);
108 
109 /**
110  * device_tree_inode_get_subnode() - Get a subnodes of a given node by name
111  *
112  * @parent:          Pointer to the parent node
113  * @subnode_name:    Name of the subnode
114  * @subnode:         Pointer for the output subnode
115  *
116  * Return:           An error code reflecting success or failure
117  */
118 int device_tree_inode_get_subnode(struct device_tree_inode* parent,
119                                   const char* subnode_name,
120                                   struct device_tree_inode** subnode);
121 
122 /**
123  * device_tree_inode_get_subnodes() - Get an iterator over all subnodes of a
124  *                                   given node
125  *
126  * @parent:    Pointer to the parent node
127  * @iter:      Pointer for the output node iterator
128  *
129  * Return:     An error code reflecting success or failure
130  */
131 int device_tree_inode_get_subnodes(struct device_tree_inode* parent,
132                                    struct device_tree_inode_iter** iter);
133 
134 /**
135  * device_tree_inode_get_prop() - Get a node property by name
136  *
137  * @node:    Pointer to the node to search
138  * @name:    Name of the node's property
139  * @prop:    Pointer to the output property
140  *
141  * Return:   An error code reflecting success or failure
142  */
143 int device_tree_inode_get_prop(struct device_tree_inode* node,
144                                const char* name,
145                                struct device_tree_prop** prop);
146 
147 /**
148  * device_tree_inode_get_props() - Get an iterator over all of a node's
149  *                                properties
150  *
151  * @node:     Pointer to the node whose properties are to be iterated over
152  * @prop:     Pointer to the output property iterator
153  *
154  * Return:    An error code reflecting success or failure
155  */
156 int device_tree_inode_get_props(struct device_tree_inode* node,
157                                 struct device_tree_iprop_iter** prop);
158 
159 /**
160  * device_tree_iprop_iter_get_next_prop() - Advance a property iterator
161  *
162  * @iter:     Pointer to the property iterator to advance
163  * @prop:     Pointer to the output property
164  *
165  * Return:    An error code reflecting success or failure
166  */
167 int device_tree_iprop_iter_get_next_prop(struct device_tree_iprop_iter* iter,
168                                          struct device_tree_prop** prop);
169 
170 /**
171  * device_tree_prop_get_name() - Get a property's name
172  *
173  * @prop:    Pointer to property
174  * @name:    Pointer to the output property name. This pointer is only valid for
175  *           the lifetime of the pointer to the property and will be freed when
176  *           the property is freed.
177  *
178  * Return:   An error code reflecting success or failure
179  */
180 int device_tree_prop_get_name(struct device_tree_prop* prop,
181                               const char** name,
182                               size_t* name_len);
183 
184 /**
185  * device_tree_prop_get_value() - Get a property's value
186  *
187  * @prop:     Pointer to the property
188  * @value:    Pointer to the output property value. This pointer is only valid
189  *            for the lifetime of the pointer to the property and will be freed
190  *            when the property is freed. The property value is a big-endian
191  *            byte array. There is no alignment guarantee.
192  * @size:     Pointer to a size value set by the function
193  *
194  * Return:    An error code reflecting success or failure
195  */
196 int device_tree_prop_get_value(struct device_tree_prop* prop,
197                                uint8_t** value,
198                                size_t* size);
199 
200 /**
201  * device_tree_prop_get_u32() - Get a property as a uint32_t
202  *
203  * @prop:     Pointer to the property. The property's value must be 4 bytes, but
204  *            otherwise no type-checking is done so it's the caller's
205  *            responsibility to ensure that the property is an integer.
206  * @value:    Pointer to the output value. The value is returned in the host's
207  *            endianness, not necessarily big-endian.
208  *
209  * Return:    An error code reflecting success or failure.
210  */
211 int device_tree_prop_get_u32(struct device_tree_prop* prop, uint32_t* value);
212 
213 /**
214  * device_tree_prop_get_u64() - Get a property as a uint64_t
215  *
216  * @prop:     Pointer to the property. The property's value must be 8 bytes, but
217  *            otherwise no type-checking is done so it's the caller's
218  *            responsibility to ensure that the property is an integer.
219  * @value:    Pointer to the output value. The value is returned in the hosts
220  *            endianness, not necessarily big-endian.
221  *
222  * Return:    An error code reflecting success or failure.
223  */
224 int device_tree_prop_get_u64(struct device_tree_prop* prop, uint64_t* value);
225 
226 /**
227  * device_tree_inode_release() - Release the reference to the
228  * struct device_tree_inode*.
229  *
230  * @self:     Pointer to the struct device_tree_inode* to be released
231  *
232  */
233 void device_tree_inode_release(struct device_tree_inode** self);
234 
235 /**
236  * device_tree_inode_iter_release() - Release the reference to the
237  * struct device_tree_inode_iter*.
238  *
239  * @self:     Pointer to the struct struct device_tree_inode_iter*
240  *            to be released.
241  *
242  */
243 void device_tree_inode_iter_release(struct device_tree_inode_iter** self);
244 
245 /**
246  * device_tree_idevice_tree_release() - Release the reference to the
247  * struct device_tree_idevice_tree*.
248  *
249  * @self:     Pointer to the struct struct device_tree_idevice_tree*
250  *            to be released.
251  *
252  */
253 void device_tree_idevice_tree_release(struct device_tree_idevice_tree** self);
254 
255 /**
256  * device_tree_iprop_iter_release() - Release the reference to the
257  * struct device_tree_iprop_iter*.
258  *
259  * @self:     Pointer to the struct struct device_tree_iprop_iter*
260  *            to be released.
261  *
262  */
263 void device_tree_iprop_iter_release(struct device_tree_iprop_iter** self);
264 
265 /**
266  * device_tree_prop_release() - Release the reference to the
267  * struct device_tree_prop*.
268  *
269  * @self:     Pointer to the struct struct device_tree_prop*
270  *            to be released.
271  *
272  */
273 void device_tree_prop_release(struct device_tree_prop** self);
274 
275 __END_CDECLS
276