@@ -114,8 +114,21 @@ class Binding:
114
114
path:
115
115
The absolute path to the file defining the binding.
116
116
117
+ title:
118
+ The free-form title of the binding (optional).
119
+
120
+ When the content in the 'description:' is too long, the 'title:' can
121
+ be used as a heading for the extended description. Typically, it serves
122
+ as a description of the hardware model. For example:
123
+
124
+ title: Nordic GPIO
125
+
126
+ description: |
127
+ Descriptions and example nodes related to GPIO.
128
+ ...
129
+
117
130
description:
118
- The free-form description of the binding, or None .
131
+ The free-form description of the binding.
119
132
120
133
compatible:
121
134
The compatible string the binding matches.
@@ -173,7 +186,7 @@ class Binding:
173
186
174
187
def __init__ (self , path : Optional [str ], fname2path : dict [str , str ],
175
188
raw : Any = None , require_compatible : bool = True ,
176
- require_description : bool = True ):
189
+ require_description : bool = True , require_title : bool = False ):
177
190
"""
178
191
Binding constructor.
179
192
@@ -201,6 +214,12 @@ def __init__(self, path: Optional[str], fname2path: dict[str, str],
201
214
"description:" line. If False, a missing "description:" is
202
215
not an error. Either way, "description:" must be a string
203
216
if it is present in the binding.
217
+
218
+ require_title:
219
+ If True, it is an error if the binding does not contain a
220
+ "title:" line. If False, a missing "title:" is not an error.
221
+ Either way, "title:" must be a string if it is present in
222
+ the binding.
204
223
"""
205
224
self .path : Optional [str ] = path
206
225
self ._fname2path : dict [str , str ] = fname2path
@@ -217,8 +236,8 @@ def __init__(self, path: Optional[str], fname2path: dict[str, str],
217
236
self .raw : dict = self ._merge_includes (raw , self .path )
218
237
219
238
# Recursively initialize any child bindings. These don't
220
- # require a 'compatible' or 'description ' to be well defined,
221
- # but they must be dicts.
239
+ # require a 'compatible', 'description' or 'title ' to be well
240
+ # defined, but they must be dicts.
222
241
if "child-binding" in raw :
223
242
if not isinstance (raw ["child-binding" ], dict ):
224
243
_err (f"malformed 'child-binding:' in { self .path } , "
@@ -232,7 +251,7 @@ def __init__(self, path: Optional[str], fname2path: dict[str, str],
232
251
self .child_binding = None
233
252
234
253
# Make sure this is a well defined object.
235
- self ._check (require_compatible , require_description )
254
+ self ._check (require_compatible , require_description , require_title )
236
255
237
256
# Initialize look up tables.
238
257
self .prop2specs : dict [str , PropertySpec ] = {}
@@ -251,6 +270,11 @@ def __repr__(self) -> str:
251
270
basename = os .path .basename (self .path or "" )
252
271
return f"<Binding { basename } " + compat + ">"
253
272
273
+ @property
274
+ def title (self ) -> Optional [str ]:
275
+ "See the class docstring"
276
+ return self .raw .get ('title' )
277
+
254
278
@property
255
279
def description (self ) -> Optional [str ]:
256
280
"See the class docstring"
@@ -364,7 +388,8 @@ def _load_raw(self, fname: str) -> dict:
364
388
365
389
return self ._merge_includes (contents , path )
366
390
367
- def _check (self , require_compatible : bool , require_description : bool ):
391
+ def _check (self , require_compatible : bool , require_description : bool ,
392
+ require_title : bool ):
368
393
# Does sanity checking on the binding.
369
394
370
395
raw = self .raw
@@ -378,6 +403,13 @@ def _check(self, require_compatible: bool, require_description: bool):
378
403
elif require_compatible :
379
404
_err (f"missing 'compatible' in { self .path } " )
380
405
406
+ if "title" in raw :
407
+ title = raw ["title" ]
408
+ if not isinstance (title , str ) or not title :
409
+ _err (f"malformed or empty 'title' in { self .path } " )
410
+ elif require_title :
411
+ _err (f"missing 'title' in { self .path } " )
412
+
381
413
if "description" in raw :
382
414
description = raw ["description" ]
383
415
if not isinstance (description , str ) or not description :
@@ -387,8 +419,8 @@ def _check(self, require_compatible: bool, require_description: bool):
387
419
388
420
# Allowed top-level keys. The 'include' key should have been
389
421
# removed by _load_raw() already.
390
- ok_top = {"description " , "compatible " , "bus " , "on- bus" ,
391
- "properties" , "child-binding" }
422
+ ok_top = {"title " , "description " , "compatible " , "bus" ,
423
+ "on-bus" , " properties" , "child-binding" }
392
424
393
425
# Descriptive errors for legacy bindings.
394
426
legacy_errors = {
@@ -398,7 +430,6 @@ def _check(self, require_compatible: bool, require_description: bool):
398
430
"parent" : "use 'on-bus: <bus>' instead" ,
399
431
"parent-bus" : "use 'on-bus: <bus>' instead" ,
400
432
"sub-node" : "use 'child-binding' instead" ,
401
- "title" : "use 'description' instead" ,
402
433
}
403
434
404
435
for key in raw :
@@ -3328,7 +3359,8 @@ def _raw_default_property_for(
3328
3359
for name in _DEFAULT_PROP_TYPES
3329
3360
},
3330
3361
},
3331
- require_compatible = False , require_description = False ,
3362
+ require_compatible = False ,
3363
+ require_description = False ,
3332
3364
)
3333
3365
3334
3366
_DEFAULT_PROP_SPECS : dict [str , PropertySpec ] = {
0 commit comments