@@ -17,7 +17,7 @@ use proc_macro2::{Ident, TokenStream};
17
17
use quote:: { format_ident, quote} ;
18
18
use serde:: { Deserialize , Serialize } ;
19
19
20
- use crate :: devicetree:: { output:: dt_to_lower_id, Word } ;
20
+ use crate :: devicetree:: { output:: dt_to_lower_id, Value , Word } ;
21
21
22
22
use super :: { DeviceTree , Node } ;
23
23
@@ -145,6 +145,13 @@ pub enum Action {
145
145
/// in.
146
146
kconfig : Option < String > ,
147
147
} ,
148
+ /// Generate a getter for a gpio assignment property.
149
+ GpioPins {
150
+ /// The name of the property holding the pins.
151
+ property : String ,
152
+ /// The name of the getter function.
153
+ getter : String ,
154
+ } ,
148
155
/// Generate all of the labels as its own node.
149
156
Labels ,
150
157
}
@@ -155,6 +162,38 @@ impl Action {
155
162
Action :: Instance { raw, device, kconfig } => {
156
163
raw. generate ( node, device, kconfig. as_deref ( ) )
157
164
}
165
+ Action :: GpioPins { property, getter } => {
166
+ let upper_getter = getter. to_uppercase ( ) ;
167
+ let getter = format_ident ! ( "{}" , getter) ;
168
+ // TODO: This isn't actually right, these unique values should be based on the pin
169
+ // definition so that we'll get a compile error if two parts of the DT reference the
170
+ // same pin.
171
+
172
+ let pins = node. get_property ( property) . unwrap ( ) ;
173
+ let npins = pins. len ( ) ;
174
+
175
+ let uniques: Vec < _ > = ( 0 ..npins) . map ( |n| {
176
+ format_ident ! ( "{}_UNIQUE_{}" , upper_getter, n)
177
+ } ) . collect ( ) ;
178
+
179
+ let pins = pins
180
+ . iter ( )
181
+ . zip ( uniques. iter ( ) )
182
+ . map ( |( pin, unique) | decode_gpios_gpio ( unique, pin) ) ;
183
+
184
+ let unique_defs = uniques. iter ( ) . map ( |u| {
185
+ quote ! {
186
+ static #u: crate :: device:: Unique = crate :: device:: Unique :: new( ) ;
187
+ }
188
+ } ) ;
189
+
190
+ quote ! {
191
+ #( #unique_defs) *
192
+ pub fn #getter( ) -> [ Option <crate :: device:: gpio:: GpioPin >; #npins] {
193
+ [ #( #pins) , * ]
194
+ }
195
+ }
196
+ }
158
197
Action :: Labels => {
159
198
let nodes = tree. labels . iter ( ) . map ( |( k, v) | {
160
199
let name = dt_to_lower_id ( k) ;
@@ -180,6 +219,30 @@ impl Action {
180
219
}
181
220
}
182
221
222
+ /// Decode a single gpio entry.
223
+ fn decode_gpios_gpio ( unique : & Ident , entry : & Value ) -> TokenStream {
224
+ let entry = if let Value :: Words ( w) = entry {
225
+ w
226
+ } else {
227
+ panic ! ( "gpios list is not list of <&gpionnn aa bbb>" ) ;
228
+ } ;
229
+ if entry. len ( ) != 3 {
230
+ panic ! ( "gpios currently must be three items" ) ;
231
+ }
232
+ let gpio_route = entry[ 0 ] . get_phandle ( ) . unwrap ( ) . node_ref ( ) . route_to_rust ( ) ;
233
+ let args: Vec < u32 > = entry[ 1 ..] . iter ( ) . map ( |n| n. get_number ( ) . unwrap ( ) ) . collect ( ) ;
234
+
235
+ quote ! {
236
+ // TODO: Don't hard code this but put in yaml file.
237
+ unsafe {
238
+ crate :: device:: gpio:: GpioPin :: new(
239
+ & #unique,
240
+ #gpio_route :: get_instance_raw( ) ,
241
+ #( #args) , * )
242
+ }
243
+ }
244
+ }
245
+
183
246
#[ derive( Debug , Serialize , Deserialize ) ]
184
247
#[ serde( tag = "type" , rename_all = "snake_case" , content = "value" ) ]
185
248
pub enum RawInfo {
0 commit comments