From patchwork Sat Mar 7 12:14:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425203 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 360CC14E3 for ; Sat, 7 Mar 2020 12:15:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0E1092075A for ; Sat, 7 Mar 2020 12:15:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LeNILuGJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726134AbgCGMPP (ORCPT ); Sat, 7 Mar 2020 07:15:15 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:56193 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726065AbgCGMPP (ORCPT ); Sat, 7 Mar 2020 07:15:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583314; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=MGn3sS5Coc011eZD68ygqWoytHfSDgGTKJeqUj3CCa0=; b=LeNILuGJswm8OcANIuaG8j3PH2iuKUR2ZZq0w1qopuYgZYu9v7WnbdikaWdDDxgLAL7DMH k1deOa9fU01GB9awKi4OwG/WcRVtY4Vpoij9/VzQwaU/WpVTPCw4P9BlFTMHmDTAwACdp3 dDsJ1wiUTxuhKvD9PwhmW3hjfIKsQwo= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-337-7wzhLG11OnKc5oKHxDyLFg-1; Sat, 07 Mar 2020 07:15:09 -0500 X-MC-Unique: 7wzhLG11OnKc5oKHxDyLFg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AD1BC800D50; Sat, 7 Mar 2020 12:15:08 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7ED327388A; Sat, 7 Mar 2020 12:15:07 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 01/11] Input: goodix - Refactor IRQ pin GPIO accesses Date: Sat, 7 Mar 2020 13:14:55 +0100 Message-Id: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Suspending Goodix touchscreens requires changing the interrupt pin to output before sending them a power-down command. Followed by wiggling the interrupt pin to wake the device up, after which it is put back in input mode. So far we have only effectively supported this on devices which use devicetree. On X86 ACPI platforms both looking up the pins; and using a pin as both IRQ and GPIO is a bit more complicated. E.g. on some devices we cannot directly access the IRQ pin as GPIO and we need to call ACPI methods to control it instead. This commit adds a new irq_pin_access_method field to the goodix_chip_data struct and adds goodix_irq_direction_output and goodix_irq_direction_input helpers which together abstract the GPIO accesses to the IRQ pin. This is a preparation patch for adding support for properly suspending the touchscreen on X86 ACPI platforms. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Signed-off-by: Hans de Goede Reviewed-by: Bastien Nocera --- Changes in v2: - Make enum member names upper-case --- drivers/input/touchscreen/goodix.c | 62 ++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 0403102e807e..9cfbcf3cbca8 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -31,6 +31,11 @@ struct goodix_ts_data; +enum goodix_irq_pin_access_method { + IRQ_PIN_ACCESS_NONE, + IRQ_PIN_ACCESS_GPIO, +}; + struct goodix_chip_data { u16 config_addr; int config_len; @@ -53,6 +58,7 @@ struct goodix_ts_data { const char *cfg_name; struct completion firmware_loading_complete; unsigned long irq_flags; + enum goodix_irq_pin_access_method irq_pin_access_method; unsigned int contact_size; }; @@ -502,17 +508,48 @@ static int goodix_send_cfg(struct goodix_ts_data *ts, return 0; } +static int goodix_irq_direction_output(struct goodix_ts_data *ts, + int value) +{ + switch (ts->irq_pin_access_method) { + case IRQ_PIN_ACCESS_NONE: + dev_err(&ts->client->dev, + "%s called without an irq_pin_access_method set\n", + __func__); + return -EINVAL; + case IRQ_PIN_ACCESS_GPIO: + return gpiod_direction_output(ts->gpiod_int, value); + } + + return -EINVAL; /* Never reached */ +} + +static int goodix_irq_direction_input(struct goodix_ts_data *ts) +{ + switch (ts->irq_pin_access_method) { + case IRQ_PIN_ACCESS_NONE: + dev_err(&ts->client->dev, + "%s called without an irq_pin_access_method set\n", + __func__); + return -EINVAL; + case IRQ_PIN_ACCESS_GPIO: + return gpiod_direction_input(ts->gpiod_int); + } + + return -EINVAL; /* Never reached */ +} + static int goodix_int_sync(struct goodix_ts_data *ts) { int error; - error = gpiod_direction_output(ts->gpiod_int, 0); + error = goodix_irq_direction_output(ts, 0); if (error) return error; msleep(50); /* T5: 50ms */ - error = gpiod_direction_input(ts->gpiod_int); + error = goodix_irq_direction_input(ts); if (error) return error; @@ -536,7 +573,7 @@ static int goodix_reset(struct goodix_ts_data *ts) msleep(20); /* T2: > 10ms */ /* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */ - error = gpiod_direction_output(ts->gpiod_int, ts->client->addr == 0x14); + error = goodix_irq_direction_output(ts, ts->client->addr == 0x14); if (error) return error; @@ -617,6 +654,9 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) ts->gpiod_rst = gpiod; + if (ts->gpiod_int && ts->gpiod_rst) + ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO; + return 0; } @@ -889,7 +929,7 @@ static int goodix_ts_probe(struct i2c_client *client, if (error) return error; - if (ts->gpiod_int && ts->gpiod_rst) { + if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) { /* reset the controller */ error = goodix_reset(ts); if (error) { @@ -912,7 +952,7 @@ static int goodix_ts_probe(struct i2c_client *client, ts->chip = goodix_get_chip_data(ts->id); - if (ts->gpiod_int && ts->gpiod_rst) { + if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) { /* update device config */ ts->cfg_name = devm_kasprintf(&client->dev, GFP_KERNEL, "goodix_%d_cfg.bin", ts->id); @@ -943,7 +983,7 @@ static int goodix_ts_remove(struct i2c_client *client) { struct goodix_ts_data *ts = i2c_get_clientdata(client); - if (ts->gpiod_int && ts->gpiod_rst) + if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) wait_for_completion(&ts->firmware_loading_complete); return 0; @@ -956,7 +996,7 @@ static int __maybe_unused goodix_suspend(struct device *dev) int error; /* We need gpio pins to suspend/resume */ - if (!ts->gpiod_int || !ts->gpiod_rst) { + if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) { disable_irq(client->irq); return 0; } @@ -967,7 +1007,7 @@ static int __maybe_unused goodix_suspend(struct device *dev) goodix_free_irq(ts); /* Output LOW on the INT pin for 5 ms */ - error = gpiod_direction_output(ts->gpiod_int, 0); + error = goodix_irq_direction_output(ts, 0); if (error) { goodix_request_irq(ts); return error; @@ -979,7 +1019,7 @@ static int __maybe_unused goodix_suspend(struct device *dev) GOODIX_CMD_SCREEN_OFF); if (error) { dev_err(&ts->client->dev, "Screen off command failed\n"); - gpiod_direction_input(ts->gpiod_int); + goodix_irq_direction_input(ts); goodix_request_irq(ts); return -EAGAIN; } @@ -999,7 +1039,7 @@ static int __maybe_unused goodix_resume(struct device *dev) struct goodix_ts_data *ts = i2c_get_clientdata(client); int error; - if (!ts->gpiod_int || !ts->gpiod_rst) { + if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) { enable_irq(client->irq); return 0; } @@ -1008,7 +1048,7 @@ static int __maybe_unused goodix_resume(struct device *dev) * Exit sleep mode by outputting HIGH level to INT pin * for 2ms~5ms. */ - error = gpiod_direction_output(ts->gpiod_int, 1); + error = goodix_irq_direction_output(ts, 1); if (error) return error; From patchwork Sat Mar 7 12:14:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425207 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8424684B9 for ; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 655FF2073D for ; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="E+fljemj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726281AbgCGMPS (ORCPT ); Sat, 7 Mar 2020 07:15:18 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:46562 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726267AbgCGMPS (ORCPT ); Sat, 7 Mar 2020 07:15:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583316; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IeX35ro3L3qLaaRbmmVjKgYMbo9pGR4L5TWmj0PdHRg=; b=E+fljemjrRji4CqtvyveO3TKEuZBhKXSCerkhGtfAk0J/zyKQ49mcZd2wazAitAEDjK8hz QsOxPhM9MjgLgkNLPtfVzYJKfGdTWemTLH0YVLO210lvjUf/YxNiE7Mr5oBD60iguiXNdo 9Gq07AYDsH4hJXP8ez8wQf2DLiMLyQg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-321-uaZ4Ml3FOU6nPC_EUiw_uw-1; Sat, 07 Mar 2020 07:15:11 -0500 X-MC-Unique: uaZ4Ml3FOU6nPC_EUiw_uw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1CC21107ACCA; Sat, 7 Mar 2020 12:15:10 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 00F497A411; Sat, 7 Mar 2020 12:15:08 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 02/11] Input: goodix - Make loading the config from disk independent from the GPIO setup Date: Sat, 7 Mar 2020 13:14:56 +0100 Message-Id: <20200307121505.3707-2-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org At least on X86 ACPI platforms it is not necessary to load the touchscreen controller config from disk, if it needs to be loaded this has already been done by the BIOS / UEFI firmware. Even on other (e.g. devicetree) platforms the config-loading as currently done has the issue that the loaded cfg file is based on the controller model, but the actual cfg is device specific, so the cfg files are not part of linux-firmware and this can only work with a device specific OS image which includes the cfg file. And we do not need access to the GPIOs at all to load the config, if we do not have access we can still load the config. So all in all tying the decision to try to load the config from disk to being able to access the GPIOs is not desirable. This commit adds a new load_cfg_from_disk boolean to control the firmware loading instead. This commits sets the new bool to true when we set irq_pin_access_method to IRQ_PIN_ACCESS_GPIO, so there are no functional changes. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- Changes in v3: - Move the wait_for_completion(&ts->firmware_loading_complete); in goodix_suspend() to above the early exit case for ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE --- drivers/input/touchscreen/goodix.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 9cfbcf3cbca8..95cac14369a8 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -56,6 +56,7 @@ struct goodix_ts_data { u16 id; u16 version; const char *cfg_name; + bool load_cfg_from_disk; struct completion firmware_loading_complete; unsigned long irq_flags; enum goodix_irq_pin_access_method irq_pin_access_method; @@ -654,8 +655,10 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) ts->gpiod_rst = gpiod; - if (ts->gpiod_int && ts->gpiod_rst) + if (ts->gpiod_int && ts->gpiod_rst) { + ts->load_cfg_from_disk = true; ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO; + } return 0; } @@ -952,7 +955,7 @@ static int goodix_ts_probe(struct i2c_client *client, ts->chip = goodix_get_chip_data(ts->id); - if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) { + if (ts->load_cfg_from_disk) { /* update device config */ ts->cfg_name = devm_kasprintf(&client->dev, GFP_KERNEL, "goodix_%d_cfg.bin", ts->id); @@ -983,7 +986,7 @@ static int goodix_ts_remove(struct i2c_client *client) { struct goodix_ts_data *ts = i2c_get_clientdata(client); - if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) + if (ts->load_cfg_from_disk) wait_for_completion(&ts->firmware_loading_complete); return 0; @@ -995,14 +998,15 @@ static int __maybe_unused goodix_suspend(struct device *dev) struct goodix_ts_data *ts = i2c_get_clientdata(client); int error; + if (ts->load_cfg_from_disk) + wait_for_completion(&ts->firmware_loading_complete); + /* We need gpio pins to suspend/resume */ if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) { disable_irq(client->irq); return 0; } - wait_for_completion(&ts->firmware_loading_complete); - /* Free IRQ as IRQ pin is used as output in the suspend sequence */ goodix_free_irq(ts); From patchwork Sat Mar 7 12:14:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425205 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5CCCB921 for ; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3CAAA206D5 for ; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="S0l4XkKe" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726267AbgCGMPS (ORCPT ); Sat, 7 Mar 2020 07:15:18 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:50911 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726073AbgCGMPR (ORCPT ); Sat, 7 Mar 2020 07:15:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583316; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Bsy0eOMbiepVqaOl6PH06jflS2kc5r+7UY4tDhqUCFA=; b=S0l4XkKegr2Vg0vYnCSdeh51OLKokY5N83+mOLWMYWVrghfi2oh22wNrJT5d7o4YGEDYp+ SOzgahBNfMCDfpHPN34qqBrcO4xNSalb5mmJHIdmY2+vh3zQv6tiqvtfD2GU5KtJDX47cb 9wUTCPVnLTZnO7+46LepruX8ZNf9q4o= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-329-aYxVVXRMOsadrCJJc5aIgQ-1; Sat, 07 Mar 2020 07:15:12 -0500 X-MC-Unique: aYxVVXRMOsadrCJJc5aIgQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9016E1005513; Sat, 7 Mar 2020 12:15:11 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5E1181BC6D; Sat, 7 Mar 2020 12:15:10 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 03/11] Input: goodix - Make resetting the controller at probe independent from the GPIO setup Date: Sat, 7 Mar 2020 13:14:57 +0100 Message-Id: <20200307121505.3707-3-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Before this commit we would always reset the controller at probe when we have access to the GPIOs which are necessary to do a reset. Doing the reset requires access to the GPIOs, but just because we have access to the GPIOs does not mean that we should always reset the controller at probe. On X86 ACPI platforms the BIOS / UEFI firmware will already have reset the controller and it will have loaded the device specific config into the controller. Doing the reset sometimes causes the controller to lose its configuration, so on X86 ACPI platforms this is not a good idea. This commit adds a new reset_controller_at_probe boolean to control the reset at probe behavior. This commits sets the new bool to true when we set irq_pin_access_method to IRQ_PIN_ACCESS_GPIO, so there are no functional changes. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- drivers/input/touchscreen/goodix.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 95cac14369a8..43c61f7c6f1e 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -56,6 +56,7 @@ struct goodix_ts_data { u16 id; u16 version; const char *cfg_name; + bool reset_controller_at_probe; bool load_cfg_from_disk; struct completion firmware_loading_complete; unsigned long irq_flags; @@ -656,6 +657,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) ts->gpiod_rst = gpiod; if (ts->gpiod_int && ts->gpiod_rst) { + ts->reset_controller_at_probe = true; ts->load_cfg_from_disk = true; ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO; } @@ -932,7 +934,7 @@ static int goodix_ts_probe(struct i2c_client *client, if (error) return error; - if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) { + if (ts->reset_controller_at_probe) { /* reset the controller */ error = goodix_reset(ts); if (error) { From patchwork Sat Mar 7 12:14:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425211 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AD126174A for ; Sat, 7 Mar 2020 12:15:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 859652073D for ; Sat, 7 Mar 2020 12:15:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="EHgOdFrb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726283AbgCGMPU (ORCPT ); Sat, 7 Mar 2020 07:15:20 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:55859 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726269AbgCGMPT (ORCPT ); Sat, 7 Mar 2020 07:15:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583317; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cnKcbPphidtkGabSjX8PIDIAcAA8gL63iT1b05D7Ej0=; b=EHgOdFrbxxaFG3fX1CGo/8vqwpnrk922R+P99HWHUHLu72oSyztvu1D/Co9VE+CxbO5m3J zdcW9ckUQdjR7gR70o5o+llBAIZiCtCi9FEq2jahXExmLuGihKeDU+0Wb5BmgnSmFKnPqD RIpXob9ZRHf3dKPUOzyYHcGhC8wNJnw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-489-36hDPot7MqSKGsUoOqJkPw-1; Sat, 07 Mar 2020 07:15:14 -0500 X-MC-Unique: 36hDPot7MqSKGsUoOqJkPw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F284B13EA; Sat, 7 Mar 2020 12:15:12 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id D5E6A1BC6D; Sat, 7 Mar 2020 12:15:11 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 04/11] Input: goodix - Add support for getting IRQ + reset GPIOs on Cherry Trail devices Date: Sat, 7 Mar 2020 13:14:58 +0100 Message-Id: <20200307121505.3707-4-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org 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: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Signed-off-by: Hans de Goede Reviewed-by: Bastien Nocera --- Changes in v2: - Add example _CRS method to commit message - Add some extra comments to clarify the code --- drivers/input/touchscreen/goodix.c | 128 ++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 43c61f7c6f1e..794617a57910 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -34,6 +34,7 @@ struct goodix_ts_data; enum goodix_irq_pin_access_method { IRQ_PIN_ACCESS_NONE, IRQ_PIN_ACCESS_GPIO, + IRQ_PIN_ACCESS_ACPI_GPIO, }; struct goodix_chip_data { @@ -53,6 +54,8 @@ struct goodix_ts_data { struct regulator *vddio; struct gpio_desc *gpiod_int; struct gpio_desc *gpiod_rst; + int gpio_count; + int gpio_int_idx; u16 id; u16 version; const char *cfg_name; @@ -521,6 +524,12 @@ static int goodix_irq_direction_output(struct goodix_ts_data *ts, return -EINVAL; case IRQ_PIN_ACCESS_GPIO: return gpiod_direction_output(ts->gpiod_int, value); + case IRQ_PIN_ACCESS_ACPI_GPIO: + /* + * The IRQ pin triggers on a falling edge, so its gets marked + * as active-low, use output_raw to avoid the value inversion. + */ + return gpiod_direction_output_raw(ts->gpiod_int, value); } return -EINVAL; /* Never reached */ @@ -535,6 +544,7 @@ static int goodix_irq_direction_input(struct goodix_ts_data *ts) __func__); return -EINVAL; case IRQ_PIN_ACCESS_GPIO: + case IRQ_PIN_ACCESS_ACPI_GPIO: return gpiod_direction_input(ts->gpiod_int); } @@ -599,6 +609,94 @@ static int goodix_reset(struct goodix_ts_data *ts) return 0; } +#if defined CONFIG_X86 && defined CONFIG_ACPI +static const struct acpi_gpio_params first_gpio = { 0, 0, false }; +static const struct acpi_gpio_params second_gpio = { 1, 0, false }; + +static const struct acpi_gpio_mapping acpi_goodix_int_first_gpios[] = { + { GOODIX_GPIO_INT_NAME "-gpios", &first_gpio, 1 }, + { GOODIX_GPIO_RST_NAME "-gpios", &second_gpio, 1 }, + { }, +}; + +static const struct acpi_gpio_mapping acpi_goodix_int_last_gpios[] = { + { GOODIX_GPIO_RST_NAME "-gpios", &first_gpio, 1 }, + { GOODIX_GPIO_INT_NAME "-gpios", &second_gpio, 1 }, + { }, +}; + +static int goodix_resource(struct acpi_resource *ares, void *data) +{ + struct goodix_ts_data *ts = data; + struct device *dev = &ts->client->dev; + struct acpi_resource_gpio *gpio; + + switch (ares->type) { + case ACPI_RESOURCE_TYPE_GPIO: + gpio = &ares->data.gpio; + if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) { + if (ts->gpio_int_idx == -1) { + ts->gpio_int_idx = ts->gpio_count; + } else { + dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n"); + ts->gpio_int_idx = -2; + } + } + ts->gpio_count++; + break; + default: + break; + } + + return 0; +} + +/* + * This function gets called in case we fail to get the irq GPIO directly + * because the ACPI tables lack GPIO-name to APCI _CRS index mappings + * (no _DSD UUID daffd814-6eba-4d8c-8a91-bc9bbf4aa301 data). + * In that case we add our own mapping and then goodix_get_gpio_config() + * retries to get the GPIOs based on the added mapping. + */ +static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) +{ + const struct acpi_gpio_mapping *gpio_mapping = NULL; + struct device *dev = &ts->client->dev; + LIST_HEAD(resources); + int ret; + + ts->gpio_count = 0; + ts->gpio_int_idx = -1; + ret = acpi_dev_get_resources(ACPI_COMPANION(dev), &resources, + goodix_resource, ts); + if (ret < 0) { + dev_err(dev, "Error getting ACPI resources: %d\n", ret); + return ret; + } + + acpi_dev_free_resource_list(&resources); + + if (ts->gpio_count == 2 && ts->gpio_int_idx == 0) { + ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; + gpio_mapping = acpi_goodix_int_first_gpios; + } else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) { + ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; + gpio_mapping = acpi_goodix_int_last_gpios; + } else { + dev_warn(dev, "Unexpected ACPI resources: gpio_count %d, gpio_int_idx %d\n", + ts->gpio_count, ts->gpio_int_idx); + return -EINVAL; + } + + return devm_acpi_dev_add_driver_gpios(dev, gpio_mapping); +} +#else +static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) +{ + return -EINVAL; +} +#endif /* CONFIG_X86 && CONFIG_ACPI */ + /** * goodix_get_gpio_config - Get GPIO config from ACPI/DT * @@ -609,6 +707,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) int error; struct device *dev; struct gpio_desc *gpiod; + bool added_acpi_mappings = false; if (!ts->client) return -EINVAL; @@ -632,6 +731,7 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) return error; } +retry_get_irq_gpio: /* Get the interrupt GPIO pin number */ gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN); if (IS_ERR(gpiod)) { @@ -641,6 +741,11 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) GOODIX_GPIO_INT_NAME, error); return error; } + if (!gpiod && has_acpi_companion(dev) && !added_acpi_mappings) { + added_acpi_mappings = true; + if (goodix_add_acpi_gpio_mappings(ts) == 0) + goto retry_get_irq_gpio; + } ts->gpiod_int = gpiod; @@ -656,10 +761,25 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) ts->gpiod_rst = gpiod; - if (ts->gpiod_int && ts->gpiod_rst) { - ts->reset_controller_at_probe = true; - ts->load_cfg_from_disk = true; - ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO; + switch (ts->irq_pin_access_method) { + case IRQ_PIN_ACCESS_ACPI_GPIO: + /* + * We end up here if goodix_add_acpi_gpio_mappings() has + * called devm_acpi_dev_add_driver_gpios() because the ACPI + * tables did not contain name to index mappings. + * Check that we successfully got both GPIOs after we've + * added our own acpi_gpio_mapping and if we did not get both + * GPIOs reset irq_pin_access_method to IRQ_PIN_ACCESS_NONE. + */ + if (!ts->gpiod_int || !ts->gpiod_rst) + ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE; + break; + default: + if (ts->gpiod_int && ts->gpiod_rst) { + ts->reset_controller_at_probe = true; + ts->load_cfg_from_disk = true; + ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO; + } } return 0; From patchwork Sat Mar 7 12:14:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425209 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BCB47174A for ; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9DE0B206D5 for ; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="M1dK+bO6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726073AbgCGMPT (ORCPT ); Sat, 7 Mar 2020 07:15:19 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:31256 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726271AbgCGMPS (ORCPT ); Sat, 7 Mar 2020 07:15:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583317; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Lhcq6LRizjEua8gQSbb+w6xt3NkGmx1pnL3KYQZlPng=; b=M1dK+bO6dBwchfwYpQP5mJrMS2MyEpKKPCbJRGp2dL9f3s73MTl5BUn4pVGN7YuTTx60mL 65P0oHlAb8XdmJ3FJlZuTzNIbmGLXBVtLRHYwE6YaA83PvIrgpUrRODq2JVUilg8w3FDOm N2EZx8E8EJgO0JTFNbYLjALbjVlz4ag= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-397-LyU5iIhKOrKshuNEwGLXQw-1; Sat, 07 Mar 2020 07:15:15 -0500 X-MC-Unique: LyU5iIhKOrKshuNEwGLXQw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5CDA9184C800; Sat, 7 Mar 2020 12:15:14 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 43D761BC6D; Sat, 7 Mar 2020 12:15:13 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 05/11] Input: goodix - Add support for getting IRQ + reset GPIOs on Bay Trail devices Date: Sat, 7 Mar 2020 13:14:59 +0100 Message-Id: <20200307121505.3707-5-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org On most Bay 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 2 GpioIo resource in their _CRS table, on all 4 such devices which I have access to, the order of the 2 GPIOs is reset, int. Note that the GPIO to which the touchscreen controller irq pin is connected is configured in direct-irq mode on these Bay Trail devices, the pinctrl-baytrail.c driver still allows controlling the pin as a GPIO in this case, but this is not necessarily the case on other X86 ACPI platforms, nor do we have a guarantee that the GPIO order is the same elsewhere, so we limit the use of a _CRS table with 2 GpioIo resources to Bay Trail devices only. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- drivers/input/touchscreen/goodix.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 794617a57910..712ca0273cfc 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -610,6 +610,21 @@ static int goodix_reset(struct goodix_ts_data *ts) } #if defined CONFIG_X86 && defined CONFIG_ACPI +#include +#include + +static const struct x86_cpu_id baytrail_cpu_ids[] = { + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT, X86_FEATURE_ANY, }, + {} +}; + +static inline bool is_byt(void) +{ + const struct x86_cpu_id *id = x86_match_cpu(baytrail_cpu_ids); + + return !!id; +} + static const struct acpi_gpio_params first_gpio = { 0, 0, false }; static const struct acpi_gpio_params second_gpio = { 1, 0, false }; @@ -682,6 +697,10 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) } else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) { ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; gpio_mapping = acpi_goodix_int_last_gpios; + } else if (is_byt() && ts->gpio_count == 2 && ts->gpio_int_idx == -1) { + dev_info(dev, "No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n"); + ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; + gpio_mapping = acpi_goodix_int_last_gpios; } else { dev_warn(dev, "Unexpected ACPI resources: gpio_count %d, gpio_int_idx %d\n", ts->gpio_count, ts->gpio_int_idx); From patchwork Sat Mar 7 12:15:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425213 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A0B414E3 for ; Sat, 7 Mar 2020 12:15:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1B7942073D for ; Sat, 7 Mar 2020 12:15:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Z2JHOtxf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726284AbgCGMPU (ORCPT ); Sat, 7 Mar 2020 07:15:20 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:42958 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726271AbgCGMPU (ORCPT ); Sat, 7 Mar 2020 07:15:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583318; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tou7V5bOOjk/BEzM4E4MQAoR4VhA2W0il1PSCWAthwg=; b=Z2JHOtxfX0zFv0S+lfLbOMB74focprIbZL7G+GTI7giHR77vQLRN48RDm+Y2uhjHMS/zjh N4d1yJ8WzVX7qWYVVkCg9xthG9i+BctN62KcKR2q1qg9ilTonPsA1QVsjvLC88NPTFGCUS jc/ytFgfxp0HKKOPLNUehZzYDB4Hx/o= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-348-yOSyjbA6M-Klg75K4Rqbjg-1; Sat, 07 Mar 2020 07:15:17 -0500 X-MC-Unique: yOSyjbA6M-Klg75K4Rqbjg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BE508800D50; Sat, 7 Mar 2020 12:15:15 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id A33121BC6D; Sat, 7 Mar 2020 12:15:14 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 06/11] Input: goodix - Add support for controlling the IRQ pin through ACPI methods Date: Sat, 7 Mar 2020 13:15:00 +0100 Message-Id: <20200307121505.3707-6-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Some Apollo Lake (x86, UEFI + ACPI) devices only list the reset GPIO in their _CRS table and the bit-banging of the IRQ line necessary to wake-up the controller from suspend can be done by calling 2 Goodix custom / specific ACPI methods. This commit adds support for controlling the IRQ line in this matter, allowing us to properly suspend the touchscreen controller on such devices. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- drivers/input/touchscreen/goodix.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 712ca0273cfc..3ff05a35ac1e 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -35,6 +35,7 @@ enum goodix_irq_pin_access_method { IRQ_PIN_ACCESS_NONE, IRQ_PIN_ACCESS_GPIO, IRQ_PIN_ACCESS_ACPI_GPIO, + IRQ_PIN_ACCESS_ACPI_METHOD, }; struct goodix_chip_data { @@ -516,6 +517,9 @@ static int goodix_send_cfg(struct goodix_ts_data *ts, static int goodix_irq_direction_output(struct goodix_ts_data *ts, int value) { + struct device *dev = &ts->client->dev; + acpi_status status; + switch (ts->irq_pin_access_method) { case IRQ_PIN_ACCESS_NONE: dev_err(&ts->client->dev, @@ -530,6 +534,10 @@ static int goodix_irq_direction_output(struct goodix_ts_data *ts, * as active-low, use output_raw to avoid the value inversion. */ return gpiod_direction_output_raw(ts->gpiod_int, value); + case IRQ_PIN_ACCESS_ACPI_METHOD: + status = acpi_execute_simple_method(ACPI_HANDLE(dev), + "INTO", value); + return ACPI_SUCCESS(status) ? 0 : -EIO; } return -EINVAL; /* Never reached */ @@ -537,6 +545,9 @@ static int goodix_irq_direction_output(struct goodix_ts_data *ts, static int goodix_irq_direction_input(struct goodix_ts_data *ts) { + struct device *dev = &ts->client->dev; + acpi_status status; + switch (ts->irq_pin_access_method) { case IRQ_PIN_ACCESS_NONE: dev_err(&ts->client->dev, @@ -546,6 +557,10 @@ static int goodix_irq_direction_input(struct goodix_ts_data *ts) case IRQ_PIN_ACCESS_GPIO: case IRQ_PIN_ACCESS_ACPI_GPIO: return gpiod_direction_input(ts->gpiod_int); + case IRQ_PIN_ACCESS_ACPI_METHOD: + status = acpi_evaluate_object(ACPI_HANDLE(dev), "INTI", + NULL, NULL); + return ACPI_SUCCESS(status) ? 0 : -EIO; } return -EINVAL; /* Never reached */ @@ -640,6 +655,11 @@ static const struct acpi_gpio_mapping acpi_goodix_int_last_gpios[] = { { }, }; +static const struct acpi_gpio_mapping acpi_goodix_reset_only_gpios[] = { + { GOODIX_GPIO_RST_NAME "-gpios", &first_gpio, 1 }, + { }, +}; + static int goodix_resource(struct acpi_resource *ares, void *data) { struct goodix_ts_data *ts = data; @@ -697,6 +717,12 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) } else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) { ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; gpio_mapping = acpi_goodix_int_last_gpios; + } else if (ts->gpio_count == 1 && ts->gpio_int_idx == -1 && + acpi_has_method(ACPI_HANDLE(dev), "INTI") && + acpi_has_method(ACPI_HANDLE(dev), "INTO")) { + dev_info(dev, "Using ACPI INTI and INTO methods for IRQ pin access\n"); + ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_METHOD; + gpio_mapping = acpi_goodix_reset_only_gpios; } else if (is_byt() && ts->gpio_count == 2 && ts->gpio_int_idx == -1) { dev_info(dev, "No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n"); ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; @@ -793,6 +819,10 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) if (!ts->gpiod_int || !ts->gpiod_rst) ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE; break; + case IRQ_PIN_ACCESS_ACPI_METHOD: + if (!ts->gpiod_rst) + ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE; + break; default: if (ts->gpiod_int && ts->gpiod_rst) { ts->reset_controller_at_probe = true; From patchwork Sat Mar 7 12:15:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425215 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E927E921 for ; Sat, 7 Mar 2020 12:15:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CA9D62073D for ; Sat, 7 Mar 2020 12:15:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Ce+RB21M" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726109AbgCGMPV (ORCPT ); Sat, 7 Mar 2020 07:15:21 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:39461 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726269AbgCGMPU (ORCPT ); Sat, 7 Mar 2020 07:15:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583320; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kf++EnFvZfVOwQMSq2NUrycmIDxE9TIKcWZrVTM6tXA=; b=Ce+RB21M33E7g9bu+Z84M+csaAkhf8NUYeBdkLOJm/LhGRDWoSZ7dW+gtMRdaiL4RDKRPy MRnPCsz3zEMxewiTgmG+GhMLxY88jUIlF3j/+XmU6/rpzuAa6ZzRagGB/YUGU0Vs4e3e53 NwXHqEHHEjMhamgOU+86hrstMzpT+BQ= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-212--_CQSUOaP6ew9kurWed-_A-1; Sat, 07 Mar 2020 07:15:18 -0500 X-MC-Unique: -_CQSUOaP6ew9kurWed-_A-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 23AF4184C800; Sat, 7 Mar 2020 12:15:17 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0A3571BC6D; Sat, 7 Mar 2020 12:15:15 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 07/11] Input: goodix - Move defines to above struct goodix_ts_data declaration Date: Sat, 7 Mar 2020 13:15:01 +0100 Message-Id: <20200307121505.3707-7-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Move the defines to above the struct goodix_ts_data declaration, so that the MAX defines can be used inside the struct goodix_ts_data declaration. No functional changes, just moving a block of code. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- drivers/input/touchscreen/goodix.c | 60 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 3ff05a35ac1e..035e133830a2 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -29,6 +29,36 @@ #include #include +#define GOODIX_GPIO_INT_NAME "irq" +#define GOODIX_GPIO_RST_NAME "reset" + +#define GOODIX_MAX_HEIGHT 4096 +#define GOODIX_MAX_WIDTH 4096 +#define GOODIX_INT_TRIGGER 1 +#define GOODIX_CONTACT_SIZE 8 +#define GOODIX_MAX_CONTACT_SIZE 9 +#define GOODIX_MAX_CONTACTS 10 + +#define GOODIX_CONFIG_MAX_LENGTH 240 +#define GOODIX_CONFIG_911_LENGTH 186 +#define GOODIX_CONFIG_967_LENGTH 228 + +/* Register defines */ +#define GOODIX_REG_COMMAND 0x8040 +#define GOODIX_CMD_SCREEN_OFF 0x05 + +#define GOODIX_READ_COOR_ADDR 0x814E +#define GOODIX_GT1X_REG_CONFIG_DATA 0x8050 +#define GOODIX_GT9X_REG_CONFIG_DATA 0x8047 +#define GOODIX_REG_ID 0x8140 + +#define GOODIX_BUFFER_STATUS_READY BIT(7) +#define GOODIX_BUFFER_STATUS_TIMEOUT 20 + +#define RESOLUTION_LOC 1 +#define MAX_CONTACTS_LOC 5 +#define TRIGGER_LOC 6 + struct goodix_ts_data; enum goodix_irq_pin_access_method { @@ -68,36 +98,6 @@ struct goodix_ts_data { unsigned int contact_size; }; -#define GOODIX_GPIO_INT_NAME "irq" -#define GOODIX_GPIO_RST_NAME "reset" - -#define GOODIX_MAX_HEIGHT 4096 -#define GOODIX_MAX_WIDTH 4096 -#define GOODIX_INT_TRIGGER 1 -#define GOODIX_CONTACT_SIZE 8 -#define GOODIX_MAX_CONTACT_SIZE 9 -#define GOODIX_MAX_CONTACTS 10 - -#define GOODIX_CONFIG_MAX_LENGTH 240 -#define GOODIX_CONFIG_911_LENGTH 186 -#define GOODIX_CONFIG_967_LENGTH 228 - -/* Register defines */ -#define GOODIX_REG_COMMAND 0x8040 -#define GOODIX_CMD_SCREEN_OFF 0x05 - -#define GOODIX_READ_COOR_ADDR 0x814E -#define GOODIX_GT1X_REG_CONFIG_DATA 0x8050 -#define GOODIX_GT9X_REG_CONFIG_DATA 0x8047 -#define GOODIX_REG_ID 0x8140 - -#define GOODIX_BUFFER_STATUS_READY BIT(7) -#define GOODIX_BUFFER_STATUS_TIMEOUT 20 - -#define RESOLUTION_LOC 1 -#define MAX_CONTACTS_LOC 5 -#define TRIGGER_LOC 6 - static int goodix_check_cfg_8(struct goodix_ts_data *ts, const struct firmware *cfg); static int goodix_check_cfg_16(struct goodix_ts_data *ts, From patchwork Sat Mar 7 12:15:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425217 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C156921 for ; Sat, 7 Mar 2020 12:15:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4481A2073D for ; Sat, 7 Mar 2020 12:15:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="e0+5dA5O" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726271AbgCGMPW (ORCPT ); Sat, 7 Mar 2020 07:15:22 -0500 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:20352 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726269AbgCGMPW (ORCPT ); Sat, 7 Mar 2020 07:15:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583321; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7gKAt/awFe9kC49u5UQMt9T3H8ULlEgxXSXYVBn+EeE=; b=e0+5dA5O0r8rcYzY+/07v9GAP72aK4y9yI08xeW3RuwGnzdb5g3kyAIKXQ3I4xFy6CwQBG /ujjC1yJFsqrMr5KlmVJTI7Frr8uPqI4fT2ONrwSXUVBD8OyR8tA3H12srNtgELaZaMOXI rbn6sgtdwTBVkdfN0eOOw5ottQ/wGKA= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-473-SjFAK3-eOx-h1s7Pu1y1TQ-1; Sat, 07 Mar 2020 07:15:19 -0500 X-MC-Unique: SjFAK3-eOx-h1s7Pu1y1TQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8446D8017CC; Sat, 7 Mar 2020 12:15:18 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 675451BC6D; Sat, 7 Mar 2020 12:15:17 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 08/11] Input: goodix - Save a copy of the config from goodix_read_config() Date: Sat, 7 Mar 2020 13:15:02 +0100 Message-Id: <20200307121505.3707-8-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Save a copy of the config in goodix_read_config(), this is a preparation patch for restoring the config if it was lost after a supend/resume cycle. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- Changes in v2: - s/fix_config/calc_config_checksum/ - Add a comment explaining that the "ts->config[raw_cfg_len + 1] = 1" lines are setting the "config_fresh" bit --- drivers/input/touchscreen/goodix.c | 47 ++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 035e133830a2..eb57c39dc55b 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -72,6 +72,7 @@ struct goodix_chip_data { u16 config_addr; int config_len; int (*check_config)(struct goodix_ts_data *, const struct firmware *); + void (*calc_config_checksum)(struct goodix_ts_data *ts); }; struct goodix_ts_data { @@ -96,35 +97,42 @@ struct goodix_ts_data { unsigned long irq_flags; enum goodix_irq_pin_access_method irq_pin_access_method; unsigned int contact_size; + u8 config[GOODIX_CONFIG_MAX_LENGTH]; }; static int goodix_check_cfg_8(struct goodix_ts_data *ts, const struct firmware *cfg); static int goodix_check_cfg_16(struct goodix_ts_data *ts, const struct firmware *cfg); +static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts); +static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts); static const struct goodix_chip_data gt1x_chip_data = { .config_addr = GOODIX_GT1X_REG_CONFIG_DATA, .config_len = GOODIX_CONFIG_MAX_LENGTH, .check_config = goodix_check_cfg_16, + .calc_config_checksum = goodix_calc_cfg_checksum_16, }; static const struct goodix_chip_data gt911_chip_data = { .config_addr = GOODIX_GT9X_REG_CONFIG_DATA, .config_len = GOODIX_CONFIG_911_LENGTH, .check_config = goodix_check_cfg_8, + .calc_config_checksum = goodix_calc_cfg_checksum_8, }; static const struct goodix_chip_data gt967_chip_data = { .config_addr = GOODIX_GT9X_REG_CONFIG_DATA, .config_len = GOODIX_CONFIG_967_LENGTH, .check_config = goodix_check_cfg_8, + .calc_config_checksum = goodix_calc_cfg_checksum_8, }; static const struct goodix_chip_data gt9x_chip_data = { .config_addr = GOODIX_GT9X_REG_CONFIG_DATA, .config_len = GOODIX_CONFIG_MAX_LENGTH, .check_config = goodix_check_cfg_8, + .calc_config_checksum = goodix_calc_cfg_checksum_8, }; static const unsigned long goodix_irq_flags[] = { @@ -442,6 +450,19 @@ static int goodix_check_cfg_8(struct goodix_ts_data *ts, return 0; } +static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts) +{ + int i, raw_cfg_len = ts->chip->config_len - 2; + u8 check_sum = 0; + + for (i = 0; i < raw_cfg_len; i++) + check_sum += ts->config[i]; + check_sum = (~check_sum) + 1; + + ts->config[raw_cfg_len] = check_sum; + ts->config[raw_cfg_len + 1] = 1; /* Set "config_fresh" bit */ +} + static int goodix_check_cfg_16(struct goodix_ts_data *ts, const struct firmware *cfg) { @@ -466,6 +487,19 @@ static int goodix_check_cfg_16(struct goodix_ts_data *ts, return 0; } +static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts) +{ + int i, raw_cfg_len = ts->chip->config_len - 3; + u16 check_sum = 0; + + for (i = 0; i < raw_cfg_len; i += 2) + check_sum += get_unaligned_be16(&ts->config[i]); + check_sum = (~check_sum) + 1; + + put_unaligned_be16(check_sum, &ts->config[raw_cfg_len]); + ts->config[raw_cfg_len + 2] = 1; /* Set "config_fresh" bit */ +} + /** * goodix_check_cfg - Checks if config fw is valid * @@ -843,12 +877,11 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) */ static void goodix_read_config(struct goodix_ts_data *ts) { - u8 config[GOODIX_CONFIG_MAX_LENGTH]; int x_max, y_max; int error; error = goodix_i2c_read(ts->client, ts->chip->config_addr, - config, ts->chip->config_len); + ts->config, ts->chip->config_len); if (error) { dev_warn(&ts->client->dev, "Error reading config: %d\n", error); @@ -857,15 +890,17 @@ static void goodix_read_config(struct goodix_ts_data *ts) return; } - ts->int_trigger_type = config[TRIGGER_LOC] & 0x03; - ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f; + ts->int_trigger_type = ts->config[TRIGGER_LOC] & 0x03; + ts->max_touch_num = ts->config[MAX_CONTACTS_LOC] & 0x0f; - x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); - y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); + x_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC]); + y_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC + 2]); if (x_max && y_max) { input_abs_set_max(ts->input_dev, ABS_MT_POSITION_X, x_max - 1); input_abs_set_max(ts->input_dev, ABS_MT_POSITION_Y, y_max - 1); } + + ts->chip->calc_config_checksum(ts); } /** From patchwork Sat Mar 7 12:15:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425219 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A0A1714E3 for ; Sat, 7 Mar 2020 12:15:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 80F3C206D5 for ; Sat, 7 Mar 2020 12:15:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="i2SxSzNd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726289AbgCGMPZ (ORCPT ); Sat, 7 Mar 2020 07:15:25 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:38992 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726269AbgCGMPY (ORCPT ); Sat, 7 Mar 2020 07:15:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583323; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RyU3poUl9nZ5y2UwhwOXIx6LwbbKNvQHVlMqaG+24tw=; b=i2SxSzNdbwuZJqeLsxUic2YaFR3BmBdpcRfFALTwPU24MCHUDHaQ410caCVzUA7RFiXqPS viMGF83Lkaz+aND5WyK/Vz3VFSe0VQ0JB9YQFPP5MX0UkJmx/BJ1FeKYkntfOLL1L3pQPx MtFCTj2BA20cOGX/Bld3WGAEV0bS+mc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-163-y5VFxs-ZMMK76VOZZqNLJg-1; Sat, 07 Mar 2020 07:15:20 -0500 X-MC-Unique: y5VFxs-ZMMK76VOZZqNLJg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B8909184C800; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id C60241BC6D; Sat, 7 Mar 2020 12:15:18 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org Subject: [PATCH v3 09/11] Input: goodix - Add minimum firmware size check Date: Sat, 7 Mar 2020 13:15:03 +0100 Message-Id: <20200307121505.3707-9-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Our goodix_check_cfg_* helpers do things like: int i, raw_cfg_len = cfg->size - 2; ... if (check_sum != cfg->data[raw_cfg_len]) { When cfg->size < 2, this will end up indexing the cfg->data array with a negative value, which will not end well. To fix this this commit adds a new GOODIX_CONFIG_MIN_LENGTH define and adds a minimum size check for firmware-config files using this new define. For consistency this commit also adds a new GOODIX_CONFIG_GT9X_LENGTH for the length used for recent gt9xx and gt1xxx chips, instead of using GOODIX_CONFIG_MAX_LENGTH for this, so that if other length defines get added in the future it will be clear that the MIN and MAX defines should contain the min and max values of all the other defines. Signed-off-by: Hans de Goede Reviewed-by: Bastien Nocera --- Changes in v2: - New patch in v2 of this patch series --- drivers/input/touchscreen/goodix.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index eb57c39dc55b..5227223e666b 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -39,9 +39,11 @@ #define GOODIX_MAX_CONTACT_SIZE 9 #define GOODIX_MAX_CONTACTS 10 -#define GOODIX_CONFIG_MAX_LENGTH 240 +#define GOODIX_CONFIG_MIN_LENGTH 186 #define GOODIX_CONFIG_911_LENGTH 186 #define GOODIX_CONFIG_967_LENGTH 228 +#define GOODIX_CONFIG_GT9X_LENGTH 240 +#define GOODIX_CONFIG_MAX_LENGTH 240 /* Register defines */ #define GOODIX_REG_COMMAND 0x8040 @@ -109,7 +111,7 @@ static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts); static const struct goodix_chip_data gt1x_chip_data = { .config_addr = GOODIX_GT1X_REG_CONFIG_DATA, - .config_len = GOODIX_CONFIG_MAX_LENGTH, + .config_len = GOODIX_CONFIG_GT9X_LENGTH, .check_config = goodix_check_cfg_16, .calc_config_checksum = goodix_calc_cfg_checksum_16, }; @@ -130,7 +132,7 @@ static const struct goodix_chip_data gt967_chip_data = { static const struct goodix_chip_data gt9x_chip_data = { .config_addr = GOODIX_GT9X_REG_CONFIG_DATA, - .config_len = GOODIX_CONFIG_MAX_LENGTH, + .config_len = GOODIX_CONFIG_GT9X_LENGTH, .check_config = goodix_check_cfg_8, .calc_config_checksum = goodix_calc_cfg_checksum_8, }; @@ -509,7 +511,8 @@ static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts) static int goodix_check_cfg(struct goodix_ts_data *ts, const struct firmware *cfg) { - if (cfg->size > GOODIX_CONFIG_MAX_LENGTH) { + if (cfg->size < GOODIX_CONFIG_MIN_LENGTH || + cfg->size > GOODIX_CONFIG_MAX_LENGTH) { dev_err(&ts->client->dev, "The length of the config fw is not correct"); return -EINVAL; From patchwork Sat Mar 7 12:15:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425221 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 969B314E3 for ; Sat, 7 Mar 2020 12:15:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 77DD72073D for ; Sat, 7 Mar 2020 12:15:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="e0LxUVp/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726293AbgCGMP0 (ORCPT ); Sat, 7 Mar 2020 07:15:26 -0500 Received: from us-smtp-2.mimecast.com ([207.211.31.81]:26759 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726269AbgCGMPZ (ORCPT ); Sat, 7 Mar 2020 07:15:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583324; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=b/o+ADmp79J6fOsPh3EqWFkKa4brKaoTW4iJBCG8nGc=; b=e0LxUVp/Vlt8xInBCPCKEnhcW/L+u7Y3yCUL0GwgBxWhd8BIVKVPu0O7g1J/YA4fdgBlEw 1t2P+7Go+qYg/+VBlmb/i9vl6wYJ6OFerqRekPf+yh8FqAOShaWh2qYyDJ9C0Vn1hV1WaI gUZAmgkaZlw4i3snfD+y1WBldyNC6Wk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-189-iEuT03LdPj6cRHuepxyVlA-1; Sat, 07 Mar 2020 07:15:22 -0500 X-MC-Unique: iEuT03LdPj6cRHuepxyVlA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2529F107ACC4; Sat, 7 Mar 2020 12:15:21 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0CA557389B; Sat, 7 Mar 2020 12:15:19 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 10/11] Input: goodix - Make goodix_send_cfg() take a raw buffer as argument Date: Sat, 7 Mar 2020 13:15:04 +0100 Message-Id: <20200307121505.3707-10-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Make goodix_send_cfg() take a raw buffer as argument instead of a struct firmware *cfg, so that it can also be used to restore the config on resume if necessary. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- drivers/input/touchscreen/goodix.c | 48 ++++++++++++++---------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 5227223e666b..3c53f7fd1dfa 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -73,7 +73,7 @@ enum goodix_irq_pin_access_method { struct goodix_chip_data { u16 config_addr; int config_len; - int (*check_config)(struct goodix_ts_data *, const struct firmware *); + int (*check_config)(struct goodix_ts_data *ts, const u8 *cfg, int len); void (*calc_config_checksum)(struct goodix_ts_data *ts); }; @@ -103,9 +103,9 @@ struct goodix_ts_data { }; static int goodix_check_cfg_8(struct goodix_ts_data *ts, - const struct firmware *cfg); + const u8 *cfg, int len); static int goodix_check_cfg_16(struct goodix_ts_data *ts, - const struct firmware *cfg); + const u8 *cfg, int len); static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts); static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts); @@ -428,22 +428,21 @@ static int goodix_request_irq(struct goodix_ts_data *ts) ts->irq_flags, ts->client->name, ts); } -static int goodix_check_cfg_8(struct goodix_ts_data *ts, - const struct firmware *cfg) +static int goodix_check_cfg_8(struct goodix_ts_data *ts, const u8 *cfg, int len) { - int i, raw_cfg_len = cfg->size - 2; + int i, raw_cfg_len = len - 2; u8 check_sum = 0; for (i = 0; i < raw_cfg_len; i++) - check_sum += cfg->data[i]; + check_sum += cfg[i]; check_sum = (~check_sum) + 1; - if (check_sum != cfg->data[raw_cfg_len]) { + if (check_sum != cfg[raw_cfg_len]) { dev_err(&ts->client->dev, "The checksum of the config fw is not correct"); return -EINVAL; } - if (cfg->data[raw_cfg_len + 1] != 1) { + if (cfg[raw_cfg_len + 1] != 1) { dev_err(&ts->client->dev, "Config fw must have Config_Fresh register set"); return -EINVAL; @@ -465,22 +464,22 @@ static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts) ts->config[raw_cfg_len + 1] = 1; /* Set "config_fresh" bit */ } -static int goodix_check_cfg_16(struct goodix_ts_data *ts, - const struct firmware *cfg) +static int goodix_check_cfg_16(struct goodix_ts_data *ts, const u8 *cfg, + int len) { - int i, raw_cfg_len = cfg->size - 3; + int i, raw_cfg_len = len - 3; u16 check_sum = 0; for (i = 0; i < raw_cfg_len; i += 2) - check_sum += get_unaligned_be16(&cfg->data[i]); + check_sum += get_unaligned_be16(&cfg[i]); check_sum = (~check_sum) + 1; - if (check_sum != get_unaligned_be16(&cfg->data[raw_cfg_len])) { + if (check_sum != get_unaligned_be16(&cfg[raw_cfg_len])) { dev_err(&ts->client->dev, "The checksum of the config fw is not correct"); return -EINVAL; } - if (cfg->data[raw_cfg_len + 2] != 1) { + if (cfg[raw_cfg_len + 2] != 1) { dev_err(&ts->client->dev, "Config fw must have Config_Fresh register set"); return -EINVAL; @@ -508,17 +507,16 @@ static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts) * @ts: goodix_ts_data pointer * @cfg: firmware config data */ -static int goodix_check_cfg(struct goodix_ts_data *ts, - const struct firmware *cfg) +static int goodix_check_cfg(struct goodix_ts_data *ts, const u8 *cfg, int len) { - if (cfg->size < GOODIX_CONFIG_MIN_LENGTH || - cfg->size > GOODIX_CONFIG_MAX_LENGTH) { + if (len < GOODIX_CONFIG_MIN_LENGTH || + len > GOODIX_CONFIG_MAX_LENGTH) { dev_err(&ts->client->dev, "The length of the config fw is not correct"); return -EINVAL; } - return ts->chip->check_config(ts, cfg); + return ts->chip->check_config(ts, cfg, len); } /** @@ -527,17 +525,15 @@ static int goodix_check_cfg(struct goodix_ts_data *ts, * @ts: goodix_ts_data pointer * @cfg: config firmware to write to device */ -static int goodix_send_cfg(struct goodix_ts_data *ts, - const struct firmware *cfg) +static int goodix_send_cfg(struct goodix_ts_data *ts, const u8 *cfg, int len) { int error; - error = goodix_check_cfg(ts, cfg); + error = goodix_check_cfg(ts, cfg, len); if (error) return error; - error = goodix_i2c_write(ts->client, ts->chip->config_addr, cfg->data, - cfg->size); + error = goodix_i2c_write(ts->client, ts->chip->config_addr, cfg, len); if (error) { dev_err(&ts->client->dev, "Failed to write config data: %d", error); @@ -1072,7 +1068,7 @@ static void goodix_config_cb(const struct firmware *cfg, void *ctx) if (cfg) { /* send device configuration to the firmware */ - error = goodix_send_cfg(ts, cfg); + error = goodix_send_cfg(ts, cfg->data, cfg->size); if (error) goto err_release_cfg; } From patchwork Sat Mar 7 12:15:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11425223 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 359E7921 for ; Sat, 7 Mar 2020 12:15:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 16133206D5 for ; Sat, 7 Mar 2020 12:15:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="fUjXMiE7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726269AbgCGMP0 (ORCPT ); Sat, 7 Mar 2020 07:15:26 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:32621 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726292AbgCGMP0 (ORCPT ); Sat, 7 Mar 2020 07:15:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1583583325; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WlHKsRL9rU1iClYwn7oCPfzZzhJPPyRN7KpXJlo6K5c=; b=fUjXMiE7F4SdcQHcnyCIzGHLQM6rixJf032CLbWS937bYMzSFidQMH8pqx0HD4rWO0wX+1 J0YvxR+/zrT2vJKpepSDHhTHH2/Xpa+9yQzSak41saREw7lw2sudXJ23/+taKFNzNqLxw/ GAgyFyRfJJAo1fihTkQcTLXqCaaakJE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-233-FEQFMBhHPAu11FvToahblA-1; Sat, 07 Mar 2020 07:15:23 -0500 X-MC-Unique: FEQFMBhHPAu11FvToahblA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 84207107ACCA; Sat, 7 Mar 2020 12:15:22 +0000 (UTC) Received: from x1.localdomain.com (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6BE7F1BC6D; Sat, 7 Mar 2020 12:15:21 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Bastien Nocera Cc: Hans de Goede , linux-input@vger.kernel.org, Dmitry Mastykin Subject: [PATCH v3 11/11] Input: goodix - Restore config on resume if necessary Date: Sat, 7 Mar 2020 13:15:05 +0100 Message-Id: <20200307121505.3707-11-hdegoede@redhat.com> In-Reply-To: <20200307121505.3707-1-hdegoede@redhat.com> References: <20200307121505.3707-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Some devices, e.g the Trekstor Primetab S11B, lose there config over a suspend/resume cycle (likely the controller loses power during suspend). This commit reads back the config version on resume and if matches the expected config version it resets the controller and resends the config we read back and saved at probe time. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317 BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207 Cc: Dmitry Mastykin Reviewed-by: Bastien Nocera Signed-off-by: Hans de Goede --- Changes in v2: - Replace dev_warn on version mismatch on resume with dev_info --- drivers/input/touchscreen/goodix.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 3c53f7fd1dfa..15e07870c767 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -1246,6 +1246,7 @@ static int __maybe_unused goodix_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct goodix_ts_data *ts = i2c_get_clientdata(client); + u8 config_ver; int error; if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) { @@ -1267,6 +1268,27 @@ static int __maybe_unused goodix_resume(struct device *dev) if (error) return error; + error = goodix_i2c_read(ts->client, ts->chip->config_addr, + &config_ver, 1); + if (error) + dev_warn(dev, "Error reading config version: %d, resetting controller\n", + error); + else if (config_ver != ts->config[0]) + dev_info(dev, "Config version mismatch %d != %d, resetting controller\n", + config_ver, ts->config[0]); + + if (error != 0 || config_ver != ts->config[0]) { + error = goodix_reset(ts); + if (error) { + dev_err(dev, "Controller reset failed.\n"); + return error; + } + + error = goodix_send_cfg(ts, ts->config, ts->chip->config_len); + if (error) + return error; + } + error = goodix_request_irq(ts); if (error) return error;