Skip to content

Commit a7d4b17

Browse files
jwrdegoededtor
authored andcommitted
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding "irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name without first manually adding mappings ourselves. These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table: Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { Name (RBUF, ResourceTemplate () { I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.PCI0.I2C2", 0x00, ResourceConsumer, , Exclusive, ) GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000, "\\_SB.GPO1", 0x00, ResourceConsumer, , ) { // Pin list 0x0013 } GpioIo (Shared, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly, "\\_SB.GPO1", 0x00, ResourceConsumer, , ) { // Pin list 0x0019 } }) Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */ } There is no fixed order for these 2. This commit adds code to check that there is 1 of each as expected and then registers a mapping matching their order using devm_acpi_dev_add_driver_gpios(). This gives us access to both GPIOs allowing us to properly suspend the controller during suspend, and making it possible to reset the controller if necessary. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: nexus511/gpd-ubuntu-packages#10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Signed-off-by: Hans de Goede <[email protected]> Reviewed-by: Bastien Nocera <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 1921dac commit a7d4b17

File tree

1 file changed

+124
-4
lines changed

1 file changed

+124
-4
lines changed

drivers/input/touchscreen/goodix.c

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct goodix_ts_data;
3434
enum goodix_irq_pin_access_method {
3535
IRQ_PIN_ACCESS_NONE,
3636
IRQ_PIN_ACCESS_GPIO,
37+
IRQ_PIN_ACCESS_ACPI_GPIO,
3738
};
3839

3940
struct goodix_chip_data {
@@ -53,6 +54,8 @@ struct goodix_ts_data {
5354
struct regulator *vddio;
5455
struct gpio_desc *gpiod_int;
5556
struct gpio_desc *gpiod_rst;
57+
int gpio_count;
58+
int gpio_int_idx;
5659
u16 id;
5760
u16 version;
5861
const char *cfg_name;
@@ -537,6 +540,12 @@ static int goodix_irq_direction_output(struct goodix_ts_data *ts,
537540
return -EINVAL;
538541
case IRQ_PIN_ACCESS_GPIO:
539542
return gpiod_direction_output(ts->gpiod_int, value);
543+
case IRQ_PIN_ACCESS_ACPI_GPIO:
544+
/*
545+
* The IRQ pin triggers on a falling edge, so its gets marked
546+
* as active-low, use output_raw to avoid the value inversion.
547+
*/
548+
return gpiod_direction_output_raw(ts->gpiod_int, value);
540549
}
541550

542551
return -EINVAL; /* Never reached */
@@ -551,6 +560,7 @@ static int goodix_irq_direction_input(struct goodix_ts_data *ts)
551560
__func__);
552561
return -EINVAL;
553562
case IRQ_PIN_ACCESS_GPIO:
563+
case IRQ_PIN_ACCESS_ACPI_GPIO:
554564
return gpiod_direction_input(ts->gpiod_int);
555565
}
556566

@@ -615,6 +625,94 @@ static int goodix_reset(struct goodix_ts_data *ts)
615625
return 0;
616626
}
617627

628+
#if defined CONFIG_X86 && defined CONFIG_ACPI
629+
static const struct acpi_gpio_params first_gpio = { 0, 0, false };
630+
static const struct acpi_gpio_params second_gpio = { 1, 0, false };
631+
632+
static const struct acpi_gpio_mapping acpi_goodix_int_first_gpios[] = {
633+
{ GOODIX_GPIO_INT_NAME "-gpios", &first_gpio, 1 },
634+
{ GOODIX_GPIO_RST_NAME "-gpios", &second_gpio, 1 },
635+
{ },
636+
};
637+
638+
static const struct acpi_gpio_mapping acpi_goodix_int_last_gpios[] = {
639+
{ GOODIX_GPIO_RST_NAME "-gpios", &first_gpio, 1 },
640+
{ GOODIX_GPIO_INT_NAME "-gpios", &second_gpio, 1 },
641+
{ },
642+
};
643+
644+
static int goodix_resource(struct acpi_resource *ares, void *data)
645+
{
646+
struct goodix_ts_data *ts = data;
647+
struct device *dev = &ts->client->dev;
648+
struct acpi_resource_gpio *gpio;
649+
650+
switch (ares->type) {
651+
case ACPI_RESOURCE_TYPE_GPIO:
652+
gpio = &ares->data.gpio;
653+
if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) {
654+
if (ts->gpio_int_idx == -1) {
655+
ts->gpio_int_idx = ts->gpio_count;
656+
} else {
657+
dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
658+
ts->gpio_int_idx = -2;
659+
}
660+
}
661+
ts->gpio_count++;
662+
break;
663+
default:
664+
break;
665+
}
666+
667+
return 0;
668+
}
669+
670+
/*
671+
* This function gets called in case we fail to get the irq GPIO directly
672+
* because the ACPI tables lack GPIO-name to APCI _CRS index mappings
673+
* (no _DSD UUID daffd814-6eba-4d8c-8a91-bc9bbf4aa301 data).
674+
* In that case we add our own mapping and then goodix_get_gpio_config()
675+
* retries to get the GPIOs based on the added mapping.
676+
*/
677+
static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
678+
{
679+
const struct acpi_gpio_mapping *gpio_mapping = NULL;
680+
struct device *dev = &ts->client->dev;
681+
LIST_HEAD(resources);
682+
int ret;
683+
684+
ts->gpio_count = 0;
685+
ts->gpio_int_idx = -1;
686+
ret = acpi_dev_get_resources(ACPI_COMPANION(dev), &resources,
687+
goodix_resource, ts);
688+
if (ret < 0) {
689+
dev_err(dev, "Error getting ACPI resources: %d\n", ret);
690+
return ret;
691+
}
692+
693+
acpi_dev_free_resource_list(&resources);
694+
695+
if (ts->gpio_count == 2 && ts->gpio_int_idx == 0) {
696+
ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
697+
gpio_mapping = acpi_goodix_int_first_gpios;
698+
} else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) {
699+
ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
700+
gpio_mapping = acpi_goodix_int_last_gpios;
701+
} else {
702+
dev_warn(dev, "Unexpected ACPI resources: gpio_count %d, gpio_int_idx %d\n",
703+
ts->gpio_count, ts->gpio_int_idx);
704+
return -EINVAL;
705+
}
706+
707+
return devm_acpi_dev_add_driver_gpios(dev, gpio_mapping);
708+
}
709+
#else
710+
static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
711+
{
712+
return -EINVAL;
713+
}
714+
#endif /* CONFIG_X86 && CONFIG_ACPI */
715+
618716
/**
619717
* goodix_get_gpio_config - Get GPIO config from ACPI/DT
620718
*
@@ -625,6 +723,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
625723
int error;
626724
struct device *dev;
627725
struct gpio_desc *gpiod;
726+
bool added_acpi_mappings = false;
628727

629728
if (!ts->client)
630729
return -EINVAL;
@@ -648,6 +747,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
648747
return error;
649748
}
650749

750+
retry_get_irq_gpio:
651751
/* Get the interrupt GPIO pin number */
652752
gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN);
653753
if (IS_ERR(gpiod)) {
@@ -657,6 +757,11 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
657757
GOODIX_GPIO_INT_NAME, error);
658758
return error;
659759
}
760+
if (!gpiod && has_acpi_companion(dev) && !added_acpi_mappings) {
761+
added_acpi_mappings = true;
762+
if (goodix_add_acpi_gpio_mappings(ts) == 0)
763+
goto retry_get_irq_gpio;
764+
}
660765

661766
ts->gpiod_int = gpiod;
662767

@@ -672,10 +777,25 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
672777

673778
ts->gpiod_rst = gpiod;
674779

675-
if (ts->gpiod_int && ts->gpiod_rst) {
676-
ts->reset_controller_at_probe = true;
677-
ts->load_cfg_from_disk = true;
678-
ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO;
780+
switch (ts->irq_pin_access_method) {
781+
case IRQ_PIN_ACCESS_ACPI_GPIO:
782+
/*
783+
* We end up here if goodix_add_acpi_gpio_mappings() has
784+
* called devm_acpi_dev_add_driver_gpios() because the ACPI
785+
* tables did not contain name to index mappings.
786+
* Check that we successfully got both GPIOs after we've
787+
* added our own acpi_gpio_mapping and if we did not get both
788+
* GPIOs reset irq_pin_access_method to IRQ_PIN_ACCESS_NONE.
789+
*/
790+
if (!ts->gpiod_int || !ts->gpiod_rst)
791+
ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE;
792+
break;
793+
default:
794+
if (ts->gpiod_int && ts->gpiod_rst) {
795+
ts->reset_controller_at_probe = true;
796+
ts->load_cfg_from_disk = true;
797+
ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO;
798+
}
679799
}
680800

681801
return 0;

0 commit comments

Comments
 (0)