Skip to content

Commit a2fd46c

Browse files
jwrdegoededtor
authored andcommitted
Input: goodix - try not to touch the reset-pin on x86/ACPI devices
Unless the controller is not responding at boot or after suspend/resume, the driver never resets the controller on x86/ACPI platforms. The driver still requesting the reset pin at probe() though in case it needs it. Until now the driver has always requested the reset pin with GPIOD_IN as type. The idea being to put the pin in high-impedance mode to save power until the driver actually wants to issue a reset. But this means that just requesting the pin can cause issues, since requesting it in another mode then GPIOD_ASIS may cause the pinctrl driver to touch the pin settings. We have already had issues before due to a bug in the pinctrl-cherryview.c driver which has been fixed in commit 921daee ("pinctrl: cherryview: Preserve CHV_PADCTRL1_INVRXTX_TXDATA flag on GPIOs"). And now it turns out that requesting the reset-pin as GPIOD_IN also stops the touchscreen from working on the GPD P2 max mini-laptop. The behavior of putting the pin in high-impedance mode relies on there being some external pull-up to keep it high and there seems to be no pull-up on the GPD P2 max, causing things to break. This commit fixes this by requesting the reset pin as is when using the x86/ACPI code paths to lookup the GPIOs; and by not dropping it back into input-mode in case the driver does end up issuing a reset for error-recovery. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=209061 Fixes: a7d4b17 ("Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices") Cc: [email protected] Signed-off-by: Hans de Goede <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 44ee250 commit a2fd46c

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

drivers/input/touchscreen/goodix.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -695,10 +695,16 @@ int goodix_reset_no_int_sync(struct goodix_ts_data *ts)
695695

696696
usleep_range(6000, 10000); /* T4: > 5ms */
697697

698-
/* end select I2C slave addr */
699-
error = gpiod_direction_input(ts->gpiod_rst);
700-
if (error)
701-
goto error;
698+
/*
699+
* Put the reset pin back in to input / high-impedance mode to save
700+
* power. Only do this in the non ACPI case since some ACPI boards
701+
* don't have a pull-up, so there the reset pin must stay active-high.
702+
*/
703+
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) {
704+
error = gpiod_direction_input(ts->gpiod_rst);
705+
if (error)
706+
goto error;
707+
}
702708

703709
return 0;
704710

@@ -832,6 +838,14 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
832838
return -EINVAL;
833839
}
834840

841+
/*
842+
* Normally we put the reset pin in input / high-impedance mode to save
843+
* power. But some x86/ACPI boards don't have a pull-up, so for the ACPI
844+
* case, leave the pin as is. This results in the pin not being touched
845+
* at all on x86/ACPI boards, except when needed for error-recover.
846+
*/
847+
ts->gpiod_rst_flags = GPIOD_ASIS;
848+
835849
return devm_acpi_dev_add_driver_gpios(dev, gpio_mapping);
836850
}
837851
#else
@@ -857,6 +871,12 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
857871
return -EINVAL;
858872
dev = &ts->client->dev;
859873

874+
/*
875+
* By default we request the reset pin as input, leaving it in
876+
* high-impedance when not resetting the controller to save power.
877+
*/
878+
ts->gpiod_rst_flags = GPIOD_IN;
879+
860880
ts->avdd28 = devm_regulator_get(dev, "AVDD28");
861881
if (IS_ERR(ts->avdd28)) {
862882
error = PTR_ERR(ts->avdd28);
@@ -894,7 +914,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
894914
ts->gpiod_int = gpiod;
895915

896916
/* Get the reset line GPIO pin number */
897-
gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, GPIOD_IN);
917+
gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, ts->gpiod_rst_flags);
898918
if (IS_ERR(gpiod)) {
899919
error = PTR_ERR(gpiod);
900920
if (error != -EPROBE_DEFER)

drivers/input/touchscreen/goodix.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct goodix_ts_data {
8787
struct gpio_desc *gpiod_rst;
8888
int gpio_count;
8989
int gpio_int_idx;
90+
enum gpiod_flags gpiod_rst_flags;
9091
char id[GOODIX_ID_MAX_LEN + 1];
9192
char cfg_name[64];
9293
u16 version;

0 commit comments

Comments
 (0)