Re: How to use an ACPI declared GPIO in a userspace ...
From: Andy Shevchenko <hidden>
Date: 2020-09-29 16:27:48
Also in:
linux-acpi, lkml
On Tue, Sep 29, 2020 at 7:21 PM Flavio Suligoi [off-list ref] wrote:
quoted
quoted
quoted
I need to expose to the userspace a GPIO, physically connected to aboardquoted
quoted
push-button. This GPIO must expose a pre-defined name, such as "user-push-button", so that the userspace applications can use itwithoutquoted
quoted
know any physical GPIO details. I can customize the board BIOS and so my goal is to add an ACPI tablewithquoted
quoted
a content like this: ... Scope (\_SB.GPO1) { Device (BTNS) { Name (_HID, "PRP0001") Name (_DDN, "GPIO buttons device") Name (_CRS, ResourceTemplate () { GpioIo ( Exclusive, // Not shared PullNone, // No needfor pullsquoted
quoted
0, // Debouncetimeoutquoted
quoted
0, // Drivestrengthquoted
quoted
IoRestrictionInputOnly, // Only usedas inputquoted
quoted
"\\_SB.GPO1", // GPIOcontrollerquoted
quoted
0, ResourceConsumer, , ) // Must be 0 { 25, // GPIOnumberquoted
quoted
} ... I know that this GPIO can be used from other drivers. For example I successfully tested it using the "gpio-keys" devicedriver,quoted
quoted
giving to my GPIO a key-code and emulating in this way a keyboard key. This could be a possible solution. But I prefer to expose my GPIO as a classic GPIO, not as a keyboardkey.quoted
quoted
I was wondering if there is a generic GPIO driver that I can use toexposequoted
quoted
this GPIO with its pre-defined name (caming from the ACPI tabledeclaration),quoted
quoted
to the userspace...Unfortunately what you are describing in the second part is rather property of the controller which can hog the line, but this is not what you want in the first part. The Linux kernel, in many ways, is designed that you need a driver (I²C user space device node is rather a mistake, but compromise for that time when most of the devices have access from user space drivers). So, the proper way is to define this as gpio-keys (either interrupt version or polling one) and connect a listener to the event. Summarize: you need to describe pin(s) via "gpio-line-names" property of the controller (it's not so easy task if ACPI tables already have parts of it, but I think your case should be feasible). And either provide a gpio-keys device, or use line directly by name as (libgpiod example): gpiodetect gpioinfo gpiochipX gpiofind $GPIO_LINE_NAME gpiomon gpiochipX $(gpiofind $GPIO_LINE_NAME) & Examples of ACPI are here [1] for controller part (look at the name list) and for device part [2]. You may look into other folders as well, though they are not so reach of examples. [1]: https://github.com/westeri/meta-acpi/blob/master/recipes-bsp/acpi- tables/samples/edison/arduino.asli [2]: https://github.com/westeri/meta-acpi/blob/master/recipes-bsp/acpi- tables/samples/edison/buttons.asliI have already written and ACPI table, not in the BIOS but as separate SSDT, loaded manually at runtime, using the gpio-keys (with interrupt) and in this way all works good. So I have already tested this solution. But I prefer obtain this result in the classic way, with GPIO... So I think I'll write a device driver for it. A device driver which reads the ACPI table and publishes the GPIO, with its name, in sysfs...
Maybe I was not so clear, but as Bart mentioned the least you can do is simply define line name via "gpio-line-names" property. The problem here is when and how you would like to have them incorporated. When: if ACPI tables are being provided by firmware which you may not alter, then you must use initramfs type of solution (no configfs, don't know about EFI var though). How: In that case you might have a chance to incorporate _DSD() method into *existing* _CRS() one. Possible impediments: if ACPI table from firmware already has a _DSD() defined or above is not working for some reason. In such a case you must upgrade entire DSDT via initramfs.
quoted
quoted
Adding Andy who knows ACPI GPIO well.Thanks.quoted
In general, the "gpio-line-names" property is used for that and it's supported both for device tree as well as ACPI, although I have only ever used the former.Right. ACPI supports properties via _DSD() method.
-- With Best Regards, Andy Shevchenko