Linux Input Archive on lore.kernel.org
 help / color / Atom feed
From: "Barnabás Pőcze" <pobrn@protonmail.com>
To: Jiri Kosina <jikos@kernel.org>,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>,
	"linux-input@vger.kernel.org" <linux-input@vger.kernel.org>
Subject: [PATCH 1/2] HID: multitouch: export {surface,button}_switch to sysfs
Date: Fri, 31 Jul 2020 22:36:38 +0000
Message-ID: <46x0ZulX2qWADzBaU_UWUW7qQX-azKvbS40ooWaLKhIZ-NkUZDy51EfE6f1ViuUAEGPmBLYVTONaipsGosR0WczAt_OIFbW-8CkK42hXdfo=@protonmail.com> (raw)

Some touchpads have an LED that tells the user whether
the touchpad is disabled/enabled. Sometimes this LED
may only be controlled by the touchpad hardware.

In such cases disabling the touchpad simply via X.Org
(or other similar means) cannot take advantage of the
available LED to signal the state of the touchpad to
the user. Thus users may choose to disable their
touchpad via these two attributes (instead of xinput, etc.)
so that they can take advantage of the visual cue provided
by the LED.

This commit also changes all exported attributes to use
the DEVICE_ATTR_RW() macro (hence mt_{show,set}_quirks() functions
have been renamed).

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
---
 drivers/hid/hid-multitouch.c | 96 ++++++++++++++++++++++++++++++++----
 1 file changed, 86 insertions(+), 10 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 3f94b4954225..051c78c37603 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -164,6 +164,8 @@ struct mt_device {
 	__u8 maxcontacts;
 	bool is_buttonpad;	/* is this device a button pad? */
 	bool serial_maybe;	/* need to check for serial protocol */
+	enum latency_mode latency;
+	bool surface_switch, button_switch;

 	struct list_head applications;
 	struct list_head reports;
@@ -370,7 +372,7 @@ static const struct mt_class mt_classes[] = {
 	{ }
 };

-static ssize_t mt_show_quirks(struct device *dev,
+static ssize_t quirks_show(struct device *dev,
 			   struct device_attribute *attr,
 			   char *buf)
 {
@@ -380,7 +382,7 @@ static ssize_t mt_show_quirks(struct device *dev,
 	return sprintf(buf, "%u\n", td->mtclass.quirks);
 }

-static ssize_t mt_set_quirks(struct device *dev,
+static ssize_t quirks_store(struct device *dev,
 			  struct device_attribute *attr,
 			  const char *buf, size_t count)
 {
@@ -404,10 +406,72 @@ static ssize_t mt_set_quirks(struct device *dev,
 	return count;
 }

-static DEVICE_ATTR(quirks, S_IWUSR | S_IRUGO, mt_show_quirks, mt_set_quirks);
+static void mt_set_modes(struct mt_device *td);
+
+static ssize_t surface_switch_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	struct hid_device *hdev = to_hid_device(dev);
+	struct mt_device *td = hid_get_drvdata(hdev);
+
+	return sprintf(buf, "%d\n", (int) td->surface_switch);
+}
+
+static ssize_t surface_switch_store(struct device *dev,
+			  struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct hid_device *hdev = to_hid_device(dev);
+	struct mt_device *td = hid_get_drvdata(hdev);
+
+	bool val;
+
+	if (kstrtobool(buf, &val))
+		return -EINVAL;
+
+	td->surface_switch = val;
+	mt_set_modes(td);
+
+	return count;
+}
+
+static ssize_t button_switch_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	struct hid_device *hdev = to_hid_device(dev);
+	struct mt_device *td = hid_get_drvdata(hdev);
+
+	return sprintf(buf, "%d\n", (int) td->button_switch);
+}
+
+static ssize_t button_switch_store(struct device *dev,
+			  struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct hid_device *hdev = to_hid_device(dev);
+	struct mt_device *td = hid_get_drvdata(hdev);
+
+	bool val;
+
+	if (kstrtobool(buf, &val))
+		return -EINVAL;
+
+	td->button_switch = val;
+	mt_set_modes(td);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(quirks);
+static DEVICE_ATTR_RW(surface_switch);
+static DEVICE_ATTR_RW(button_switch);

 static struct attribute *sysfs_attrs[] = {
 	&dev_attr_quirks.attr,
+	&dev_attr_surface_switch.attr,
+	&dev_attr_button_switch.attr,
 	NULL
 };

@@ -1470,9 +1534,9 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
 	return false; /* no need to update the report */
 }

-static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
-			 bool surface_switch, bool button_switch)
+static void mt_set_modes(struct mt_device *td)
 {
+	struct hid_device *hdev = td->hdev;
 	struct hid_report_enum *rep_enum;
 	struct hid_report *rep;
 	struct hid_usage *usage;
@@ -1495,9 +1559,9 @@ static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
 				if (mt_need_to_apply_feature(hdev,
 							     rep->field[i],
 							     usage,
-							     latency,
-							     surface_switch,
-							     button_switch,
+							     td->latency,
+							     td->surface_switch,
+							     td->button_switch,
 							     &inputmode_found))
 					update_report = true;
 			}
@@ -1738,7 +1802,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s\n",
 				hdev->name);

-	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
+	td->latency = HID_LATENCY_NORMAL;
+	td->surface_switch = true;
+	td->button_switch = true;
+
+	mt_set_modes(td);

 	return 0;
 }
@@ -1746,8 +1814,16 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 #ifdef CONFIG_PM
 static int mt_reset_resume(struct hid_device *hdev)
 {
+	struct mt_device *td = hid_get_drvdata(hdev);
+
 	mt_release_contacts(hdev);
-	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
+
+	td->latency = HID_LATENCY_NORMAL;
+	td->surface_switch = true;
+	td->button_switch = true;
+
+	mt_set_modes(td);
+
 	return 0;
 }

--
2.27.0


                 reply index

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='46x0ZulX2qWADzBaU_UWUW7qQX-azKvbS40ooWaLKhIZ-NkUZDy51EfE6f1ViuUAEGPmBLYVTONaipsGosR0WczAt_OIFbW-8CkK42hXdfo=@protonmail.com' \
    --to=pobrn@protonmail.com \
    --cc=benjamin.tissoires@redhat.com \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux Input Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-input/0 linux-input/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-input linux-input/ https://lore.kernel.org/linux-input \
		linux-input@vger.kernel.org
	public-inbox-index linux-input

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-input


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git