Skip to content

Commit 63873ee

Browse files
jbrun3tjluebbe
authored andcommitted
resource: matchedsysfsgpio: add udev matched gpios
Add a support gpio line for which the gpiochip is identified by udev and pin number provided is local the identified gpiochip. This is useful when there is several gpio controller and the order in which the controller are probed is not predictable. An common example are the GPIOs provided by some USB FTDI chips. This resouce re-use most the support already done for SysfsGPIO. The global gpio index is computed at runtime, based on the udev properties of the matched gpiochip. Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
1 parent f9f6ba3 commit 63873ee

5 files changed

Lines changed: 69 additions & 5 deletions

File tree

doc/configuration.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,32 @@ Arguments:
539539
Used by:
540540
- `GpioDigitalOutputDriver`_
541541

542+
MatchedSysfsGpio
543+
++++++++++++++++
544+
A MatchedSysfsGpio resource describes a GPIO line, like a SysfsGPIO.
545+
The gpiochip is identified by matching udev properties. This allows
546+
identification through hot-plugging or rebooting for controllers like
547+
USB based gpiochips.
548+
549+
.. code-block:: yaml
550+
551+
MatchedSysfsGpio:
552+
match:
553+
'@SUBSYSTEM': 'usb'
554+
'@ID_SERIAL_SHORT': 'D38EJ8LF'
555+
pin: 0
556+
557+
The example would search for a USB gpiochip with the key `ID_SERIAL_SHORT`
558+
and the value `D38EJ8LF` and use the pin 0 of this device.
559+
The `ID_SERIAL_SHORT` property is set by the usb_id builtin helper program.
560+
561+
Arguments:
562+
- match (dict): key and value pairs for a udev match, see `udev Matching`_
563+
- pin (int): gpio pin number within the matched gpiochip.
564+
565+
Used by:
566+
- `GpioDigitalOutputDriver`_
567+
542568
NetworkService
543569
~~~~~~~~~~~~~~
544570
A :any:`NetworkService` describes a remote SSH connection.
@@ -2139,6 +2165,7 @@ While the driver automatically exports the GPIO, it does not configure it in any
21392165
Binds to:
21402166
gpio:
21412167
- `SysfsGPIO`_
2168+
- `MatchedSysfsGPIO`_
21422169
- NetworkSysfsGPIO
21432170

21442171
Implements:

labgrid/remote/exporter.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -579,11 +579,13 @@ class GPIOSysFSExport(ResourceExport):
579579

580580
def __attrs_post_init__(self):
581581
super().__attrs_post_init__()
582-
local_cls_name = self.cls
583-
self.data['cls'] = f"Network{self.cls}"
584-
from ..resource import base
585-
local_cls = getattr(base, local_cls_name)
586-
self.local = local_cls(target=None, name=None, **self.local_params)
582+
if self.cls == "SysfsGPIO":
583+
from ..resource.base import SysfsGPIO
584+
self.local = SysfsGPIO(target=None, name=None, **self.local_params)
585+
elif self.cls == "MatchedSysfsGPIO":
586+
from ..resource.udev import MatchedSysfsGPIO
587+
self.local = MatchedSysfsGPIO(target=None, name=None, **self.local_params)
588+
self.data['cls'] = "NetworkSysfsGPIO"
587589
self.export_path = Path(GPIOSysFSExport._gpio_sysfs_path_prefix,
588590
f'gpio{self.local.index}')
589591
self.system_exported = False
@@ -624,6 +626,7 @@ def _stop(self, start_params):
624626
unexport.write(str(index).encode('utf-8'))
625627

626628
exports["SysfsGPIO"] = GPIOSysFSExport
629+
exports["MatchedSysfsGPIO"] = GPIOSysFSExport
627630

628631

629632
@attr.s

labgrid/resource/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
HIDRelay,
1616
IMXUSBLoader,
1717
LXAUSBMux,
18+
MatchedSysfsGPIO,
1819
MXSUSBLoader,
1920
RKUSBLoader,
2021
SiSPMPowerPort,

labgrid/resource/suggest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
HIDRelay,
2424
USBDebugger,
2525
USBPowerPort,
26+
MatchedSysfsGPIO
2627
)
2728
from ..util import dump
2829

@@ -56,6 +57,7 @@ def __init__(self, args):
5657
self.resources.append(HIDRelay(**args))
5758
self.resources.append(USBDebugger(**args))
5859
self.resources.append(USBPowerPort(**args, index=0))
60+
self.resources.append(MatchedSysfsGPIO(**args, pin=0))
5961

6062
def suggest_callback(self, resource, meta, suggestions):
6163
cls = type(resource).__name__
@@ -84,6 +86,8 @@ def suggest_callback(self, resource, meta, suggestions):
8486
))
8587
if cls == 'USBPowerPort':
8688
print(' index: ?')
89+
if cls == 'MatchedSysfsGPIO':
90+
print(' pin: ?')
8791
print(" ---")
8892
print()
8993

labgrid/resource/udev.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,3 +708,32 @@ def filter_match(self, device):
708708
return False
709709

710710
return super().filter_match(device)
711+
712+
@target_factory.reg_resource
713+
@attr.s(eq=False)
714+
class MatchedSysfsGPIO(USBResource):
715+
"""The MatchedSysfsGPIO described a SysfsGPIO matched by Udev
716+
717+
Args:
718+
pin (int): gpio pin number within the matched gpiochip."""
719+
pin = attr.ib(default=None, validator=attr.validators.instance_of(int))
720+
index = None
721+
722+
def __attrs_post_init__(self):
723+
self.match['SUBSYSTEM'] = 'gpio'
724+
super().__attrs_post_init__()
725+
726+
def filter_match(self, device):
727+
# Filter out the char device
728+
if device.properties.get('DEVNAME') is not None:
729+
return False
730+
return super().filter_match(device)
731+
732+
def update(self):
733+
super().update()
734+
if self.device is not None:
735+
if self.pin >= int(self.read_attr('ngpio')):
736+
raise ValueError("MatchedSysfsGPIO pin out of bound")
737+
self.index = int(self.read_attr('base')) + self.pin
738+
else:
739+
self.index = None

0 commit comments

Comments
 (0)