Skip to content

Commit 430ec4c

Browse files
authored
Merge pull request #1339 from jeromebrunet/dev/matched
Resource: add udev based Sysfs GPIO support
2 parents 51ea81f + 63873ee commit 430ec4c

File tree

5 files changed

+85
-20
lines changed

5 files changed

+85
-20
lines changed

doc/configuration.rst

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,48 @@ NetworkHIDRelay
526526
+++++++++++++++
527527
A :any:`NetworkHIDRelay` describes an `HIDRelay`_ exported over the network.
528528

529+
SysfsGPIO
530+
+++++++++
531+
532+
A :any:`SysfsGPIO` resource describes a GPIO line.
533+
534+
.. code-block:: yaml
535+
536+
SysfsGPIO:
537+
index: 12
538+
539+
Arguments:
540+
- index (int): index of the GPIO line
541+
542+
Used by:
543+
- `GpioDigitalOutputDriver`_
544+
545+
MatchedSysfsGpio
546+
++++++++++++++++
547+
A MatchedSysfsGpio resource describes a GPIO line, like a SysfsGPIO.
548+
The gpiochip is identified by matching udev properties. This allows
549+
identification through hot-plugging or rebooting for controllers like
550+
USB based gpiochips.
551+
552+
.. code-block:: yaml
553+
554+
MatchedSysfsGpio:
555+
match:
556+
'@SUBSYSTEM': 'usb'
557+
'@ID_SERIAL_SHORT': 'D38EJ8LF'
558+
pin: 0
559+
560+
The example would search for a USB gpiochip with the key `ID_SERIAL_SHORT`
561+
and the value `D38EJ8LF` and use the pin 0 of this device.
562+
The `ID_SERIAL_SHORT` property is set by the usb_id builtin helper program.
563+
564+
Arguments:
565+
- match (dict): key and value pairs for a udev match, see `udev Matching`_
566+
- pin (int): gpio pin number within the matched gpiochip.
567+
568+
Used by:
569+
- `GpioDigitalOutputDriver`_
570+
529571
NetworkService
530572
~~~~~~~~~~~~~~
531573
A :any:`NetworkService` describes a remote SSH connection.
@@ -958,21 +1000,6 @@ Arguments:
9581000
Used by:
9591001
- `USBVideoDriver`_
9601002

961-
SysfsGPIO
962-
~~~~~~~~~
963-
A :any:`SysfsGPIO` resource describes a GPIO line.
964-
965-
.. code-block:: yaml
966-
967-
SysfsGPIO:
968-
index: 12
969-
970-
Arguments:
971-
- index (int): index of the GPIO line
972-
973-
Used by:
974-
- `GpioDigitalOutputDriver`_
975-
9761003
NetworkUSBVideo
9771004
~~~~~~~~~~~~~~~
9781005
A :any:`NetworkUSBVideo` resource describes a `USBVideo`_ resource available
@@ -2142,6 +2169,7 @@ While the driver automatically exports the GPIO, it does not configure it in any
21422169
Binds to:
21432170
gpio:
21442171
- `SysfsGPIO`_
2172+
- `MatchedSysfsGPIO`_
21452173
- NetworkSysfsGPIO
21462174

21472175
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
@@ -718,3 +718,32 @@ def filter_match(self, device):
718718
return False
719719

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

0 commit comments

Comments
 (0)