Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4057015pxj; Mon, 24 May 2021 22:47:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxFgVwftnN+QYkcRl4XSJBoKZKv1o1KCt7H948E0cPrzbhtnfeMnf8bt0et9UVg9Ft6QpYi X-Received: by 2002:a5e:c708:: with SMTP id f8mr19171541iop.198.1621921656430; Mon, 24 May 2021 22:47:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621921656; cv=none; d=google.com; s=arc-20160816; b=OK91NArMqm6FjP3wD4EEEiqZi2lIuU9g6/xwBnX4Vgxj7E9vM33BWKBWQARhi1s7uN erWGwGl6oN9eubBLyWH4UqjUQIx5QlsFzcOxupef429blRyAxMXoF18OkLA2ZPLFqUEM lY7mwATJeRyO2dJHrCSFkst38IrvsLf3Xwtx2hHEgGh3i2B2Le6c1x1bTlpkNiUxFvBm ASOy5VdYQvNhWadTlxv+nXCouqRYJ0oSr2khpugznhZNrIyM7lFwW9LMND0WmA8vxOc6 Lx3cyVuGfvY+8NRToBUqOjDuSdbo0JxKbfERWnUMMVdUdaEu714RAoKLoSv9Smg1am51 xJ9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=KqdWBIznrv4JKghcz8DM8ON/xOnhchRJT2GYeAFjAi4=; b=NE3VilnE6z3j0n+LsAK16XeQ5s8hrngAMVxkPKJ45q9ybw2CPY28tnDOKHntfe7H8h pdcJKyGJ2kVtqexzkanRwQSRa7geKHJDN7Jq4yMQNp6afoUrZjbYKpNCQWXHDGooLdgu WM+sVAPXY6M4Xmk1/nmZPKNdnj8npKiDa7YU8Ng/OoIBt+7SYluI3TlrDqqKboPngC+g qz7ChqyWqQnhlwFl6DbSdaFkZKspJdc4i6jsnDMW/HFAIkXYkaV+ZhrAcKwng4QwAENZ AOOYeFA4dYLmA9ZLNnpkyr3gI+c/ZVFnBpI1GtP+rnbASfO2KqQjM+/oGsril5SKZk8U Bwzg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k8si15729731iov.91.2021.05.24.22.47.23; Mon, 24 May 2021 22:47:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231126AbhEYFsT (ORCPT + 99 others); Tue, 25 May 2021 01:48:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230286AbhEYFsR (ORCPT ); Tue, 25 May 2021 01:48:17 -0400 Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DAF02C061574 for ; Mon, 24 May 2021 22:46:47 -0700 (PDT) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1llPtm-0000Au-0N; Tue, 25 May 2021 07:46:38 +0200 Received: from ore by dude.hi.pengutronix.de with local (Exim 4.92) (envelope-from ) id 1llPtk-0002Ps-65; Tue, 25 May 2021 07:46:36 +0200 From: Oleksij Rempel To: Dmitry Torokhov , Rob Herring , Jonathan Cameron Cc: Oleksij Rempel , Jonathan Cameron , kernel@pengutronix.de, linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, David Jander , devicetree@vger.kernel.org Subject: [PATCH v6 4/4] Input: resistive-adc-touch: add support for z1 and z2 channels Date: Tue, 25 May 2021 07:46:34 +0200 Message-Id: <20210525054634.9134-5-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210525054634.9134-1-o.rempel@pengutronix.de> References: <20210525054634.9134-1-o.rempel@pengutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds support for the z1 and z2 channels. These are used to calculate the applied pressure. As there is no common order of the individual channels of a resistive touch ADC, support for io-channel-names is added (although the DT bindings stated the driver already supports these). Signed-off-by: Oleksij Rempel Reviewed-by: Jonathan Cameron --- .../input/touchscreen/resistive-adc-touch.c | 140 ++++++++++++++++-- 1 file changed, 126 insertions(+), 14 deletions(-) diff --git a/drivers/input/touchscreen/resistive-adc-touch.c b/drivers/input/touchscreen/resistive-adc-touch.c index e50af30183f4..0939c0e97efb 100644 --- a/drivers/input/touchscreen/resistive-adc-touch.c +++ b/drivers/input/touchscreen/resistive-adc-touch.c @@ -20,7 +20,18 @@ #define DRIVER_NAME "resistive-adc-touch" #define GRTS_DEFAULT_PRESSURE_MIN 50000 +#define GRTS_DEFAULT_PRESSURE_MAX 65535 #define GRTS_MAX_POS_MASK GENMASK(11, 0) +#define GRTS_MAX_CHANNELS 4 + +enum grts_ch_type { + GRTS_CH_NONE = 0, + GRTS_CH_X, + GRTS_CH_Y, + GRTS_CH_PRESSURE, + GRTS_CH_Z1, + GRTS_CH_Z2, +}; /** * struct grts_state - generic resistive touch screen information struct @@ -33,24 +44,59 @@ */ struct grts_state { u32 pressure_min; + u32 x_plate_ohms; bool pressure; struct iio_channel *iio_chans; struct iio_cb_buffer *iio_cb; struct input_dev *input; struct touchscreen_properties prop; + u8 ch[GRTS_MAX_CHANNELS]; }; static int grts_cb(const void *data, void *private) { const u16 *touch_info = data; struct grts_state *st = private; - unsigned int x, y, press = 0x0; + unsigned int x, y, press = 0, z1 = 0, z2; + unsigned int Rt, i; + + for (i = 0; i < ARRAY_SIZE(st->ch) && st->ch[i] != GRTS_CH_NONE; i++) { + switch (st->ch[i]) { + case GRTS_CH_X: + x = touch_info[i]; + break; + case GRTS_CH_Y: + y = touch_info[i]; + break; + case GRTS_CH_PRESSURE: + press = touch_info[i]; + break; + case GRTS_CH_Z1: + z1 = touch_info[i]; + break; + case GRTS_CH_Z2: + z2 = touch_info[i]; + break; + } + } - /* channel data coming in buffer in the order below */ - x = touch_info[0]; - y = touch_info[1]; - if (st->pressure) - press = touch_info[2]; + if (z1) { + Rt = z2; + Rt -= z1; + Rt *= st->x_plate_ohms; + Rt = DIV_ROUND_CLOSEST(Rt, 16); + Rt *= x; + Rt /= z1; + Rt = DIV_ROUND_CLOSEST(Rt, 256); + /* + * On increased pressure the resistance (Rt) is decreasing + * so, convert values to make it looks as real pressure. + */ + if (Rt < GRTS_DEFAULT_PRESSURE_MAX) + press = GRTS_DEFAULT_PRESSURE_MAX - Rt; + else + press = 0; + } if ((!x && !y) || (st->pressure && (press < st->pressure_min))) { /* report end of touch */ @@ -94,12 +140,77 @@ static void grts_disable(void *data) iio_channel_release_all_cb(data); } +static int grts_get_properties(struct grts_state *st, struct device *dev) +{ + int idx, error; + + idx = device_property_match_string(dev, "io-channel-names", "x"); + if (idx < 0) + return idx; + + if (idx >= ARRAY_SIZE(st->ch)) + return -EOVERFLOW; + + st->ch[idx] = GRTS_CH_X; + + idx = device_property_match_string(dev, "io-channel-names", "y"); + if (idx < 0) + return idx; + + if (idx >= ARRAY_SIZE(st->ch)) + return -EOVERFLOW; + + st->ch[idx] = GRTS_CH_Y; + + /* pressure is optional */ + idx = device_property_match_string(dev, "io-channel-names", "pressure"); + if (idx >= 0) { + if (idx >= ARRAY_SIZE(st->ch)) + return -EOVERFLOW; + + st->ch[idx] = GRTS_CH_PRESSURE; + st->pressure = true; + + return 0; + } + + /* if no pressure is defined, try optional z1 + z2 */ + idx = device_property_match_string(dev, "io-channel-names", "z1"); + if (idx < 0) + return 0; + + if (idx >= ARRAY_SIZE(st->ch)) + return -EOVERFLOW; + + st->ch[idx] = GRTS_CH_Z1; + + /* if z1 is provided z2 is not optional */ + idx = device_property_match_string(dev, "io-channel-names", "z2"); + if (idx < 0) + return idx; + + if (idx >= ARRAY_SIZE(st->ch)) + return -EOVERFLOW; + + st->ch[idx] = GRTS_CH_Z2; + st->pressure = true; + + error = device_property_read_u32(dev, + "touchscreen-x-plate-ohms", + &st->x_plate_ohms); + if (error) { + dev_err(dev, "can't get touchscreen-x-plate-ohms property\n"); + return error; + } + + return 0; +} + static int grts_probe(struct platform_device *pdev) { struct grts_state *st; struct input_dev *input; struct device *dev = &pdev->dev; - struct iio_channel *chan; int error; st = devm_kzalloc(dev, sizeof(struct grts_state), GFP_KERNEL); @@ -115,12 +226,13 @@ static int grts_probe(struct platform_device *pdev) return error; } - chan = &st->iio_chans[0]; - st->pressure = false; - while (chan && chan->indio_dev) { - if (!strcmp(chan->channel->datasheet_name, "pressure")) - st->pressure = true; - chan++; + if (!device_property_present(dev, "io-channel-names")) + return -ENODEV; + + error = grts_get_properties(st, dev); + if (error) { + dev_err(dev, "Failed to parse properties\n"); + return error; } if (st->pressure) { @@ -148,7 +260,7 @@ static int grts_probe(struct platform_device *pdev) input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0); if (st->pressure) input_set_abs_params(input, ABS_PRESSURE, st->pressure_min, - 0xffff, 0, 0); + GRTS_DEFAULT_PRESSURE_MAX, 0, 0); input_set_capability(input, EV_KEY, BTN_TOUCH); -- 2.29.2