From patchwork Thu Feb 20 13:09:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Mastykin X-Patchwork-Id: 13983921 Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 877161F7076; Thu, 20 Feb 2025 13:09:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740057000; cv=none; b=ZXc2PubfEm99HkUBmBwgkeZpNeF69qsRoAd42FeETvD6PRytH9QBbZZqGBKF3loDx/YNseZHf3djs/PKWIEhaiC4EzlH1JDEw+MqiUK9jqArURgl10N4H5QPD+wVSV0PjPu9xi4i0ErovXU1wYD4pcw5QB7GWoOYNgMoQHBnn5I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740057000; c=relaxed/simple; bh=FuyaBFCtVG8QDfo2+uDDqvYUgSY8Zj4Vf6m3km7K6XA=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=BU8lWIVgOyFsLqnmyegMc/VBXeXvzc6GDYnVa9DhgNdLYJt5MH+4De2NBMI9ByczFQ0SWHVQzsEAW99uY2aXXoP0K7ZEhZ8DzleD2lW2B4pCMWLzFNHzvajcIS09J+tmhn9299zjyuR3d91cA0S7qaZG9y6TPvm7KlUXPZ14ulE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=U/Kf5ZHb; arc=none smtp.client-ip=209.85.208.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="U/Kf5ZHb" Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-30762598511so8518021fa.0; Thu, 20 Feb 2025 05:09:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740056996; x=1740661796; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=i3a6wLnxZzyaVT9CGz7P1ZX4RPkOR4DtkW51/j2nfMA=; b=U/Kf5ZHboBzNemelyTO0xkmi1FJH+b6hV86gfIJy1lPTcck1IB+gQ4H1Ml307gY6KU nHBQmJ6/rb8qNHoxt7Ipz/ehcVxHfgDLXh81Ii/c2/WL9lABvCcNfaB6hsWrwa1TPPKc I3ttf7W2HQ3UsHQUfKrpuSAgST5R3FAQ9xxa/sKF2V9gO6qiu2FT8xBaYBrw4X8Wqzzr UUtYpI8HU8M1hvFmIMHcF+88t9wpD1JNzNtr76NCisWu1Dwjqu7JKCBNzpmEMwet5Qth 0FLaGkg8DuEJj3+rnmQL/Xq+BbrPgszxoduPXmyqHzydEPvWCSvZmw6sg/eVShNWMlQk l1AA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740056996; x=1740661796; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=i3a6wLnxZzyaVT9CGz7P1ZX4RPkOR4DtkW51/j2nfMA=; b=dJLpPbmN/ZURn0FKHBoD77rqsYyPftQ8u2+C1tg+d5sg1/JFRHKkdH2VChSwV/mJ75 5U1VMc0Y85Wgf64ElOz76gVqVLH43udUPZzcWJJQW9nwuG6m6iW7zSqlWR8XodpQezjG SfEvXVKP34V2ATb2Tjb1ns8aG8Sj5hPora5JTni85Nn2vZYU2BNPRYA4rdDlHwXqqHnF aLFCBEWucgKg6ft6CQMDmw5riB2T88VZxVNbULeNn2UFHrkVVK+7Ke/NxZKUhY6yHmV/ wy7ulJ8JechR4ODIzsSHcv3ENzNmmQV3qlQTvGpzJPu6EeO13O5IwTqq7lnRXcoATCFm 46BQ== X-Forwarded-Encrypted: i=1; AJvYcCUKSdR1qbDWKSFlTNNdFYJxWEYdpf19dSVm+SGsd3N07vUGPrXHVD2gHsKCwsQ8qIjeiosTW4MlFSgOXftU@vger.kernel.org, AJvYcCVjUwW22+O/dGE9+n+zZ3YH0uUfdZ8VHi963TRQasJaCL/yu7WolX4uRDp0K7SYFg2b6OYW+1odiY/fgQ==@vger.kernel.org X-Gm-Message-State: AOJu0YwFWKBon9Eeb7IGPuUB7UnUXyv7qfqBHPC/sqIjDZYVsNXrXgo5 A8fnjM/OGsHfoOCeJykCWieeUYGLSbUA85OgAWO0Zt++6n8uKMld X-Gm-Gg: ASbGnct6roV9GhkRjMiQib43imL/U1jMzKVuintrt2DkPw0o3wQNhk2Y6x9LeMzPc0w yUCvAo/IKZVvn2LRiPVxlAuEMl41sv3LnVtEFMeHUZAcvDVTITZY9rPeMMJzGQtbnfAZ54LzfYt TZr4qiFGjyloE9+wEKA29DIMbPEOAgsreUxeNv/QItVgU9QlIYNLjD5Iet4LUOFLTg/sA/JFh4Z DArrYFcxt2YjBeoRqIKny3ITW4KS/NeO2DXTb9UwGwDdjImuMMcLZlp6zztZVmcNBWCn+IDUJRf sCg3/NNLn5AApZfe5dsiLboYckzyfY0eniQicazr X-Google-Smtp-Source: AGHT+IFpiHbMgPYRkK3amTIIC6/fQP/OElyD8DSkv9bft3f92vAok+DKDJ/dHYRbJWovBP7pvPpoWA== X-Received: by 2002:a2e:9a89:0:b0:308:ed4d:629f with SMTP id 38308e7fff4ca-30927ad512fmr65367321fa.27.1740056995903; Thu, 20 Feb 2025 05:09:55 -0800 (PST) Received: from NB-5917.corp.yadro.com (avpn01.yadro.com. [89.207.88.243]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3091029b75esm25510721fa.103.2025.02.20.05.09.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 05:09:55 -0800 (PST) From: Dmitry Mastykin To: job@noorman.info, dmitry.torokhov@gmail.com, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, felix@kaechele.ca Cc: Dmitry Mastykin Subject: [PATCH 1/2] Input: of_touchscreen - support device-properties with other prefixes Date: Thu, 20 Feb 2025 16:09:39 +0300 Message-Id: <20250220130940.2019784-1-mastichi@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Introduce touchscreen_parse_properties_prefix() function, that can parse device-properties with given prefix. E.g. both touchscreen-swapped-x-y and pen-swapped-x-y may be parsed. Some touchscreens may have different pen axis orientation, and that should be set in the device tree. Separate set of device-properties with prefix "pen-" or "stylus-" will be used to set pen resolution and axis orientation. Signed-off-by: Dmitry Mastykin --- drivers/input/touchscreen.c | 83 +++++++++++++++++++------------ include/linux/input/touchscreen.h | 3 ++ 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/drivers/input/touchscreen.c b/drivers/input/touchscreen.c index 4620e20d0190..0ed6b85b1ded 100644 --- a/drivers/input/touchscreen.c +++ b/drivers/input/touchscreen.c @@ -64,12 +64,35 @@ static void touchscreen_set_params(struct input_dev *dev, */ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, struct touchscreen_properties *prop) +{ + touchscreen_parse_properties_prefix(input, multitouch, prop, "touchscreen"); +} +EXPORT_SYMBOL(touchscreen_parse_properties); + +static char *prefix_prop(const char *property, const char *prefix, char *buf, size_t len) +{ + ssize_t n, ret; + + n = strscpy(buf, prefix, len); + if (n > 0) { + ret = strscpy(buf + n, "-", len - n); + if (ret > 0) { + n += ret; + strscpy(buf + n, property, len - n); + } + } + return buf; +} + +void touchscreen_parse_properties_prefix(struct input_dev *input, bool multitouch, + struct touchscreen_properties *prop, const char *prefix) { struct device *dev = input->dev.parent; struct input_absinfo *absinfo; unsigned int axis, axis_x, axis_y; unsigned int minimum, maximum, fuzz; bool data_present; + char buf[64]; input_alloc_absinfo(input); if (!input->absinfo) @@ -78,41 +101,37 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, axis_x = multitouch ? ABS_MT_POSITION_X : ABS_X; axis_y = multitouch ? ABS_MT_POSITION_Y : ABS_Y; - data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-x", - input_abs_get_min(input, axis_x), - &minimum); - data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-x", - input_abs_get_max(input, - axis_x) + 1, - &maximum); - data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x", - input_abs_get_fuzz(input, axis_x), - &fuzz); + data_present = + touchscreen_get_prop_u32(dev, prefix_prop("min-x", prefix, buf, sizeof(buf)), + input_abs_get_min(input, axis_x), &minimum); + data_present |= + touchscreen_get_prop_u32(dev, prefix_prop("size-x", prefix, buf, sizeof(buf)), + input_abs_get_max(input, axis_x) + 1, &maximum); + data_present |= + touchscreen_get_prop_u32(dev, prefix_prop("fuzz-x", prefix, buf, sizeof(buf)), + input_abs_get_fuzz(input, axis_x), &fuzz); if (data_present) touchscreen_set_params(input, axis_x, minimum, maximum - 1, fuzz); - data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-y", - input_abs_get_min(input, axis_y), - &minimum); - data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-y", - input_abs_get_max(input, - axis_y) + 1, - &maximum); - data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y", - input_abs_get_fuzz(input, axis_y), - &fuzz); + data_present = + touchscreen_get_prop_u32(dev, prefix_prop("min-y", prefix, buf, sizeof(buf)), + input_abs_get_min(input, axis_y), &minimum); + data_present |= + touchscreen_get_prop_u32(dev, prefix_prop("size-y", prefix, buf, sizeof(buf)), + input_abs_get_max(input, axis_y) + 1, &maximum); + data_present |= + touchscreen_get_prop_u32(dev, prefix_prop("fuzz-y", prefix, buf, sizeof(buf)), + input_abs_get_fuzz(input, axis_y), &fuzz); if (data_present) touchscreen_set_params(input, axis_y, minimum, maximum - 1, fuzz); axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE; - data_present = touchscreen_get_prop_u32(dev, - "touchscreen-max-pressure", - input_abs_get_max(input, axis), - &maximum); - data_present |= touchscreen_get_prop_u32(dev, - "touchscreen-fuzz-pressure", - input_abs_get_fuzz(input, axis), - &fuzz); + data_present = + touchscreen_get_prop_u32(dev, prefix_prop("max-pressure", prefix, buf, sizeof(buf)), + input_abs_get_max(input, axis), &maximum); + data_present |= + touchscreen_get_prop_u32(dev, prefix_prop("fuzz-pressure", prefix, buf, sizeof(buf)), + input_abs_get_fuzz(input, axis), &fuzz); if (data_present) touchscreen_set_params(input, axis, 0, maximum, fuzz); @@ -123,7 +142,7 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, prop->max_y = input_abs_get_max(input, axis_y); prop->invert_x = - device_property_read_bool(dev, "touchscreen-inverted-x"); + device_property_read_bool(dev, prefix_prop("inverted-x", prefix, buf, sizeof(buf))); if (prop->invert_x) { absinfo = &input->absinfo[axis_x]; absinfo->maximum -= absinfo->minimum; @@ -131,7 +150,7 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, } prop->invert_y = - device_property_read_bool(dev, "touchscreen-inverted-y"); + device_property_read_bool(dev, prefix_prop("inverted-y", prefix, buf, sizeof(buf))); if (prop->invert_y) { absinfo = &input->absinfo[axis_y]; absinfo->maximum -= absinfo->minimum; @@ -139,11 +158,11 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, } prop->swap_x_y = - device_property_read_bool(dev, "touchscreen-swapped-x-y"); + device_property_read_bool(dev, prefix_prop("swapped-x-y", prefix, buf, sizeof(buf))); if (prop->swap_x_y) swap(input->absinfo[axis_x], input->absinfo[axis_y]); } -EXPORT_SYMBOL(touchscreen_parse_properties); +EXPORT_SYMBOL(touchscreen_parse_properties_prefix); static void touchscreen_apply_prop_to_x_y(const struct touchscreen_properties *prop, diff --git a/include/linux/input/touchscreen.h b/include/linux/input/touchscreen.h index fe66e2b58f62..42aed1ccc2cd 100644 --- a/include/linux/input/touchscreen.h +++ b/include/linux/input/touchscreen.h @@ -20,6 +20,9 @@ struct touchscreen_properties { void touchscreen_parse_properties(struct input_dev *input, bool multitouch, struct touchscreen_properties *prop); +void touchscreen_parse_properties_prefix(struct input_dev *input, bool multitouch, + struct touchscreen_properties *prop, const char *prefix); + void touchscreen_set_mt_pos(struct input_mt_pos *pos, const struct touchscreen_properties *prop, unsigned int x, unsigned int y); From patchwork Thu Feb 20 13:09:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Mastykin X-Patchwork-Id: 13983922 Received: from mail-lj1-f182.google.com (mail-lj1-f182.google.com [209.85.208.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97F7E1F8672; Thu, 20 Feb 2025 13:10:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740057007; cv=none; b=WDK8ZDbf7+9OmjA8oGfIGvZSo/RG5nlGDsG4E9GMwD698WJirSKYSStY8eESrHTshRNn6QjOBtNPjqXGbkbccwwyI+Pfl2tyF/PJ7tA+p8czuN0aYqKEcmLFiw2j3lNf76VWiEwkulWvWFXY049AjRnS/j1iWQCcoignsmgCDlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740057007; c=relaxed/simple; bh=PlZuN6lokaVTZxUX3MEc3kP4uFyWBmAY7HEBlNuA+No=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GZ8HATaXDCfxF4Vke2wOB9jcYYT1/5ZRxRI6w4ac1PFz1XiVGpDhKddnlCXvJSbWafejTx9j0dLXAMg51bRPoqWjKbZwyUOGTKGwN6MI/n4SvlMiNnhD8OY4xRC9EPqyymZsLSUX4tofoY/HWEjWmjMXRRTJQUs6TTTbddi0hGM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Kqm3fOy4; arc=none smtp.client-ip=209.85.208.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Kqm3fOy4" Received: by mail-lj1-f182.google.com with SMTP id 38308e7fff4ca-30a303a656aso9072581fa.0; Thu, 20 Feb 2025 05:10:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740057004; x=1740661804; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nfLSKOTa7yyc/7LvwUHFg6MR+Jam9EaH0/4MKy/NpD4=; b=Kqm3fOy4aXnQFdhbO4UZqDgnJB/A168fkyRtHSegsmUgt1/Af2NV18i2biRPyAzDss wtDSVGV2AwoW/LJq8gywL1NVbNbTMMxQKSctJrZwKvHmWmaAlVeXpZtO5Ldcb6GPVtj1 mWZOOT6GrK/xtmuvpP9OeXOhkvxH3omkzXcBNsKcCxMiZPe79Zhu3oGrZU3xN1wtloGq YB6Ev+o5JbYKB6aW7Jq41vPoGAV1w8ctLtsIbStio4lgBQSR1PD/jIw/Gypx83CrJzl1 tRJXj0zzX0tuPpph3yYfCgi0w00gJVqPdFZsVi+20O6DGnbLNyO1tpiv6NCb1GadhnBb 8apw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740057004; x=1740661804; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nfLSKOTa7yyc/7LvwUHFg6MR+Jam9EaH0/4MKy/NpD4=; b=v5ORYiObBwm8ACNod8t4S9XxJrLOGcrB2h7T8lKA39gWsYEju1xOegiVgnRDR5tFWl gbLOlWtK92j9BSlkQvFZ0MfqVz9hca0uHYT4Puoxe/98HD3ENhJ8eRdUo7H2Nv2i/7Nm EgqorPvC7KsEZlEyJ98ZyDMlea7gpHJnNLThU7LiGBv/h4F3kpkHqxPx5IsMYse1eCaS n7Al4Ci8+AmHLl0SLJA4ot2GxczGCmTLsqZW5x2B373lXo8XWoxwo8CtsA24m90Du8Ct dztyOvpVYZjqfTIbSR0mj6NlXEFByEnNdZ2Q53B2K0RVyRmA7RFpbRXOlCMga3tBEE+g JpYQ== X-Forwarded-Encrypted: i=1; AJvYcCV7iw28W1TgJCtnkjyA2bkcK17XMhE1wvyCNzyou2oOC5uvTg4gDMnIi6OAABMBs54JHhW0f94GpE60ekNn@vger.kernel.org, AJvYcCX8lwrrwyX+l3wxYjzXyq3xs0WrkqVFiKqKGZR5aTvBPpIMMcuFpZiozUYeALliMy1l6brqs4xH9WHv1Q==@vger.kernel.org X-Gm-Message-State: AOJu0Yy/1DkwLtAkBiL9qW+WlH/TWZ+cTxle7KUCcjm8LrR9QXVG356+ nhwfFLK+skuBmL7AsTFhTGVr9W2jahgK62bhZJJtIVIM+RdYP+AYnOAjLQ5X X-Gm-Gg: ASbGncv1PjmcBcmwrPNssPQkQalal7MIs4i1gNS5O19nt4q8ElYt1YjPMlxbvXvWXf7 3kea2XXoPZ27JyRqPZaOiA6EamxY9C7b4p1DcCMtaQ29odFQFaqyuh9/wgvIi5IwtKpNxAknBfG 8N5e4bjp1BLIDxs9UJfuHgQiNt4oUpg/iz/52GExRPnsghGsO1/0b1lLhimozwqzbWwgk1+lhA/ zIPMgN1XoE+3TfRP0GpHzjlr9akzBv3drvMD0FrfpIVxbVxzmc2H16+noCtPYMG2NFNCqpnD0V7 0WBpR/FY7W424mpYqpDPmoclwUhbSRPSzQLKqX1V X-Google-Smtp-Source: AGHT+IGU2d50kLZ3mLqizMb/8wIsicUHRVZydM8BivNiqhueplDN8nkYIG6oyZJPxJSE7NmKaYbS5w== X-Received: by 2002:a05:651c:a:b0:2ff:8e69:77d7 with SMTP id 38308e7fff4ca-30927a64cacmr63670511fa.20.1740057003048; Thu, 20 Feb 2025 05:10:03 -0800 (PST) Received: from NB-5917.corp.yadro.com (avpn01.yadro.com. [89.207.88.243]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-3091029b75esm25510721fa.103.2025.02.20.05.10.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Feb 2025 05:10:02 -0800 (PST) From: Dmitry Mastykin To: job@noorman.info, dmitry.torokhov@gmail.com, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, felix@kaechele.ca Cc: Dmitry Mastykin Subject: [PATCH 2/2] Input: himax_hx83112b - add pen support Date: Thu, 20 Feb 2025 16:09:40 +0300 Message-Id: <20250220130940.2019784-2-mastichi@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250220130940.2019784-1-mastichi@gmail.com> References: <20250220130940.2019784-1-mastichi@gmail.com> Precedence: bulk X-Mailing-List: linux-input@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add pen support based on Himax Android driver, that provides two versions of pen data structure. Pen support is activated in device-tree by "pen-present" property. Its value is the version number. We tested with: pen-present = <1>; Additional set of device-properties must be used to set pen resolution and axis orientation: pen-size-x = <2000>; pen-size-y = <1200>; ... Touchscreen size device-properties may be added for pen points/mm calculation: touchscreen-x-mm = <239>; touchscreen-y-mm = <143>; Tested on: Starry Electronic XR109IA2T LCM (HX83102J) Signed-off-by: Dmitry Mastykin --- drivers/input/touchscreen/himax_hx83112b.c | 135 ++++++++++++++++++++- 1 file changed, 131 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c index 8f112e3038dd..6cabc0fadb68 100644 --- a/drivers/input/touchscreen/himax_hx83112b.c +++ b/drivers/input/touchscreen/himax_hx83112b.c @@ -42,6 +42,11 @@ #define HIMAX_INVALID_COORD 0xffff +/* default resolution in points/mm */ +#define HIMAX_RESOLUTION 10 + +#define HIMAX_SENSING_CHANNELS 1600 + struct himax_event_point { __be16 x; __be16 y; @@ -54,9 +59,32 @@ struct himax_event { u8 num_points; u8 pad1[2]; u8 checksum_fix; + __be16 p_x; + __be16 p_y; + __be16 p_w; + union { + struct { + s8 tilt_x; + u8 hover; + u8 btn; + u8 btn2; + s8 tilt_y; + u8 pad; + } p_v1; + struct { + s8 tilt_x; + s8 tilt_y; + u8 status; + u8 pad[3]; + } p_v2; + }; } __packed; -static_assert(sizeof(struct himax_event) == 56); +#define HIMAX_PEN_HOVER BIT(0) +#define HIMAX_PEN_BTN BIT(1) +#define HIMAX_PEN_BTN2 BIT(2) + +static_assert(sizeof(struct himax_event) == 68); struct himax_ts_data; struct himax_chip { @@ -70,9 +98,12 @@ struct himax_ts_data { const struct himax_chip *chip; struct gpio_desc *gpiod_rst; struct input_dev *input_dev; + struct input_dev *pen_input_dev; struct i2c_client *client; struct regmap *regmap; + u32 pen; struct touchscreen_properties props; + struct touchscreen_properties pen_props; }; static const struct regmap_config himax_regmap_config = { @@ -214,6 +245,52 @@ static int himax_input_register(struct himax_ts_data *ts) return 0; } +static int himax_pen_input_register(struct himax_ts_data *ts) +{ + struct input_dev *input; + int error; + u32 x_mm, y_mm; + + input = devm_input_allocate_device(&ts->client->dev); + if (!input) { + dev_err(&ts->client->dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + ts->pen_input_dev = input; + + input->name = "Himax Pen Input"; + + if (device_property_read_u32(&ts->client->dev, "touchscreen-x-mm", &x_mm) || + device_property_read_u32(&ts->client->dev, "touchscreen-y-mm", &y_mm)) { + input_abs_set_res(input, ABS_X, HIMAX_RESOLUTION); + input_abs_set_res(input, ABS_Y, HIMAX_RESOLUTION); + } else { + input_abs_set_res(input, ABS_X, HIMAX_SENSING_CHANNELS / x_mm); + input_abs_set_res(input, ABS_Y, HIMAX_SENSING_CHANNELS / y_mm); + } + + input_set_capability(input, EV_ABS, ABS_X); + input_set_capability(input, EV_ABS, ABS_Y); + input_set_abs_params(input, ABS_PRESSURE, 0, 4095, 0, 0); + input_set_abs_params(input, ABS_TILT_X, -60, 60, 0, 0); + input_set_abs_params(input, ABS_TILT_Y, -60, 60, 0, 0); + input_set_capability(input, EV_KEY, BTN_TOUCH); + input_set_capability(input, EV_KEY, BTN_STYLUS); + input_set_capability(input, EV_KEY, BTN_STYLUS2); + input_set_capability(input, EV_KEY, BTN_TOOL_PEN); + + touchscreen_parse_properties_prefix(ts->pen_input_dev, false, &ts->pen_props, "pen"); + + error = input_register_device(input); + if (error) { + dev_err(&ts->client->dev, + "Failed to register input device: %d\n", error); + return error; + } + + return 0; +} + static u8 himax_event_get_num_points(const struct himax_event *event) { if (event->num_points == 0xff) @@ -257,6 +334,45 @@ static void himax_process_event(struct himax_ts_data *ts, input_sync(ts->input_dev); } +static void himax_process_pen(struct himax_ts_data *ts, + const struct himax_event *event) +{ + struct input_dev *dev = ts->pen_input_dev; + s8 tilt_x, tilt_y; + bool hover, btn, btn2; + u16 x = be16_to_cpu(event->p_x); + u16 y = be16_to_cpu(event->p_y); + bool valid = x < ts->pen_props.max_x && y < ts->pen_props.max_y; + + if (ts->pen == 2) { + tilt_x = event->p_v2.tilt_x; + tilt_y = event->p_v2.tilt_y; + hover = event->p_v2.status & HIMAX_PEN_HOVER; + btn = event->p_v2.status & HIMAX_PEN_BTN; + btn2 = event->p_v2.status & HIMAX_PEN_BTN2; + } else { + tilt_x = event->p_v1.tilt_x; + tilt_y = event->p_v1.tilt_y; + hover = event->p_v1.hover; + btn = event->p_v1.btn; + btn2 = event->p_v1.btn2; + } + + input_report_key(dev, BTN_TOOL_PEN, valid); + + if (valid) { + input_report_key(dev, BTN_TOUCH, !hover); + touchscreen_report_pos(dev, &ts->pen_props, x, y, false); + input_report_abs(dev, ABS_PRESSURE, be16_to_cpu(event->p_w)); + input_report_abs(dev, ABS_TILT_X, tilt_x); + input_report_abs(dev, ABS_TILT_Y, tilt_y); + input_report_key(dev, BTN_STYLUS, btn); + input_report_key(dev, BTN_STYLUS2, btn2); + } + + input_sync(dev); +} + static bool himax_verify_checksum(struct himax_ts_data *ts, const struct himax_event *event) { @@ -264,7 +380,7 @@ static bool himax_verify_checksum(struct himax_ts_data *ts, int i; u16 checksum = 0; - for (i = 0; i < sizeof(*event); i++) + for (i = 0; i <= offsetof(struct himax_event, checksum_fix); i++) checksum += data[i]; if ((checksum & 0x00ff) != 0) { @@ -293,8 +409,9 @@ static int himax_handle_input(struct himax_ts_data *ts) { int error; struct himax_event event; + size_t length = ts->pen ? sizeof(event) : offsetof(struct himax_event, p_x); - error = ts->chip->read_events(ts, &event, sizeof(event)); + error = ts->chip->read_events(ts, &event, length); if (error) { dev_err(&ts->client->dev, "Failed to read input event: %d\n", error); @@ -305,8 +422,11 @@ static int himax_handle_input(struct himax_ts_data *ts) * Only process the current event when it has a valid checksum but * don't consider it a fatal error when it doesn't. */ - if (himax_verify_checksum(ts, &event)) + if (himax_verify_checksum(ts, &event)) { himax_process_event(ts, &event); + if (ts->pen) + himax_process_pen(ts, &event); + } return 0; } @@ -368,6 +488,13 @@ static int himax_probe(struct i2c_client *client) if (error) return error; + device_property_read_u32(dev, "pen-present", &ts->pen); + if (ts->pen) { + error = himax_pen_input_register(ts); + if (error) + return error; + } + error = devm_request_threaded_irq(dev, client->irq, NULL, himax_irq_handler, IRQF_ONESHOT, client->name, ts);