From patchwork Wed Oct 25 11:32:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcin Niestroj X-Patchwork-Id: 10026557 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 35CF960375 for ; Wed, 25 Oct 2017 11:32:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2A27828B64 for ; Wed, 25 Oct 2017 11:32:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1D99A28B66; Wed, 25 Oct 2017 11:32:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA0FE28B64 for ; Wed, 25 Oct 2017 11:32:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751227AbdJYLc2 (ORCPT ); Wed, 25 Oct 2017 07:32:28 -0400 Received: from smtp.megiteam.pl ([31.186.83.105]:57025 "EHLO smtp.megiteam.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751173AbdJYLc1 (ORCPT ); Wed, 25 Oct 2017 07:32:27 -0400 Received: from [95.143.241.142] (helo=localhost.localdomain) by smtp.megiteam.pl with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1e7Jv5-00085b-Jz; Wed, 25 Oct 2017 13:32:23 +0200 From: Marcin Niestroj To: Dmitry Torokhov Cc: Bastien Nocera , Antonio Ospite , linux-input@vger.kernel.org, Marcin Niestroj Subject: [PATCH] Input: goodix - use generic touchscreen_properties Date: Wed, 25 Oct 2017 13:32:17 +0200 Message-Id: <20171025113217.7814-1-m.niestroj@grinn-global.com> X-Mailer: git-send-email 2.14.2 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Use touchscreen_properties structure instead of implementing all properties by our own. It allows to reuse generic code for parsing device-tree properties (which was implemented manually in the driver for now). Additionally, it allows us to report events using generic touchscreen_report_pos(), which automatically handles inverted and swapped axes. There was also bug in driver in touch position calculation, when axes were configured as inverted and swapped in the same time. This is however fixed now, by using touchscreen_report_pos() function, which handles inversion+swapping correctly. Signed-off-by: Marcin Niestroj --- Patch was developed and tested on top of v4.14-rc6 with [1] ("Input: goodix - support gt1151 touchpanel") applied. [1] https://www.spinics.net/lists/devicetree/msg199945.html drivers/input/touchscreen/goodix.c | 87 +++++++++++++++----------------------- 1 file changed, 33 insertions(+), 54 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 69d0b8cbc71f..f82101cd9c04 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,11 +44,7 @@ struct goodix_ts_data { struct i2c_client *client; struct input_dev *input_dev; const struct goodix_chip_data *chip; - int abs_x_max; - int abs_y_max; - bool swapped_x_y; - bool inverted_x; - bool inverted_y; + struct touchscreen_properties prop; unsigned int max_touch_num; unsigned int int_trigger_type; struct gpio_desc *gpiod_int; @@ -295,18 +292,10 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) int input_y = get_unaligned_le16(&coor_data[3]); int input_w = get_unaligned_le16(&coor_data[5]); - /* Inversions have to happen before axis swapping */ - if (ts->inverted_x) - input_x = ts->abs_x_max - input_x; - if (ts->inverted_y) - input_y = ts->abs_y_max - input_y; - if (ts->swapped_x_y) - swap(input_x, input_y); - input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); + touchscreen_report_pos(ts->input_dev, &ts->prop, input_x, input_y, + true); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); } @@ -579,6 +568,7 @@ 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, @@ -587,37 +577,34 @@ static void goodix_read_config(struct goodix_ts_data *ts) dev_warn(&ts->client->dev, "Error reading config (%d), using defaults\n", error); - ts->abs_x_max = GOODIX_MAX_WIDTH; - ts->abs_y_max = GOODIX_MAX_HEIGHT; - if (ts->swapped_x_y) - swap(ts->abs_x_max, ts->abs_y_max); + x_max = GOODIX_MAX_WIDTH; + y_max = GOODIX_MAX_HEIGHT; ts->int_trigger_type = GOODIX_INT_TRIGGER; ts->max_touch_num = GOODIX_MAX_CONTACTS; - return; + goto input_set_params; } - ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); - ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); - if (ts->swapped_x_y) - swap(ts->abs_x_max, ts->abs_y_max); + x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); + y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); ts->int_trigger_type = config[TRIGGER_LOC] & 0x03; ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f; - if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) { + if (!x_max || !y_max || !ts->max_touch_num) { dev_err(&ts->client->dev, "Invalid config, using defaults\n"); - ts->abs_x_max = GOODIX_MAX_WIDTH; - ts->abs_y_max = GOODIX_MAX_HEIGHT; - if (ts->swapped_x_y) - swap(ts->abs_x_max, ts->abs_y_max); + x_max = GOODIX_MAX_WIDTH; + y_max = GOODIX_MAX_HEIGHT; ts->max_touch_num = GOODIX_MAX_CONTACTS; } - if (dmi_check_system(rotated_screen)) { - ts->inverted_x = true; - ts->inverted_y = true; - dev_dbg(&ts->client->dev, - "Applying '180 degrees rotated screen' quirk\n"); - } +input_set_params: + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, + 0, x_max - 1, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, + 0, y_max - 1, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_mt_init_slots(ts->input_dev, ts->max_touch_num, + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); } /** @@ -692,16 +679,6 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts) return -ENOMEM; } - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, - 0, ts->abs_x_max, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, - 0, ts->abs_y_max, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - - input_mt_init_slots(ts->input_dev, ts->max_touch_num, - INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); - ts->input_dev->name = "Goodix Capacitive TouchScreen"; ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; @@ -736,19 +713,21 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) { int error; - ts->swapped_x_y = device_property_read_bool(&ts->client->dev, - "touchscreen-swapped-x-y"); - ts->inverted_x = device_property_read_bool(&ts->client->dev, - "touchscreen-inverted-x"); - ts->inverted_y = device_property_read_bool(&ts->client->dev, - "touchscreen-inverted-y"); - - goodix_read_config(ts); - error = goodix_request_input_dev(ts); if (error) return error; + goodix_read_config(ts); + + touchscreen_parse_properties(ts->input_dev, true, &ts->prop); + + if (dmi_check_system(rotated_screen)) { + ts->prop.invert_x = true; + ts->prop.invert_y = true; + dev_dbg(&ts->client->dev, + "Applying '180 degrees rotated screen' quirk\n"); + } + ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; error = goodix_request_irq(ts); if (error) {