linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Lenovo lap and palm sensor support
@ 2020-10-15 13:57 Mark Pearson
  2020-10-15 13:57 ` [PATCH 1/3] Adding event codes for Lenovo lap and palm sensors Mark Pearson
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Mark Pearson @ 2020-10-15 13:57 UTC (permalink / raw)
  To: markpearson
  Cc: njoshi1, hdegoede, dmitry.torokhov, platform-driver-x86,
	linux-input, jeff, anthony.wong, hadess

This patch series is to add support for the Lenovo lap and palm sensors. 
The original lap sensor implementation used a sysfs API but after
consultation with the kernel maintainers we agreed on using the input
subsystem instead.
The first patch just adds the new defines needed.
The second patch adds the implementation needed for the palm sensor.
The third patch adds the implementation needed for the lap sensor. 

This means currently thinkpad_acpi.c has both the sysfs and input dev
implementations. I will add a follow-on patch to remove the sysfs
interface once I've confirmed this is OK with the few people who are
using this in user space and given them some time to migrate to the
input dev implementation.

Mark Pearson (3):
  Adding event codes for Lenovo lap and palm sensors
  Add support for Lenovo palm sensor.
  Add support for Lenovo lap sensor

 drivers/platform/x86/thinkpad_acpi.c   | 144 ++++++++++++++++++++++++-
 include/linux/mod_devicetable.h        |   2 +-
 include/uapi/linux/input-event-codes.h |   4 +-
 3 files changed, 145 insertions(+), 5 deletions(-)

-- 
2.28.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] Adding event codes for Lenovo lap and palm sensors
  2020-10-15 13:57 [PATCH 0/3] Lenovo lap and palm sensor support Mark Pearson
@ 2020-10-15 13:57 ` Mark Pearson
  2020-10-15 13:57 ` [PATCH 2/3] Add support for Lenovo palm sensor Mark Pearson
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Mark Pearson @ 2020-10-15 13:57 UTC (permalink / raw)
  To: markpearson
  Cc: njoshi1, hdegoede, dmitry.torokhov, platform-driver-x86,
	linux-input, jeff, anthony.wong, hadess

These sensors are used for thermal mode changes and modifying WWAN
transmitter power.

Signed-off-by: Nitin Joshi <njoshi1@lenovo.com>
Signed-off-by: Mark Pearson <markpearson@lenovo.com>
---
 include/linux/mod_devicetable.h        | 2 +-
 include/uapi/linux/input-event-codes.h | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 5b08a473cdba..897f5a3e7721 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -320,7 +320,7 @@ struct pcmcia_device_id {
 #define INPUT_DEVICE_ID_LED_MAX		0x0f
 #define INPUT_DEVICE_ID_SND_MAX		0x07
 #define INPUT_DEVICE_ID_FF_MAX		0x7f
-#define INPUT_DEVICE_ID_SW_MAX		0x10
+#define INPUT_DEVICE_ID_SW_MAX		0x12
 #define INPUT_DEVICE_ID_PROP_MAX	0x1f
 
 #define INPUT_DEVICE_ID_MATCH_BUS	1
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 0c2e27d28e0a..26f71a9a6936 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -889,7 +889,9 @@
 #define SW_MUTE_DEVICE		0x0e  /* set = device disabled */
 #define SW_PEN_INSERTED		0x0f  /* set = pen inserted */
 #define SW_MACHINE_COVER	0x10  /* set = cover closed */
-#define SW_MAX			0x10
+#define SW_LAP_PROXIMITY        0x11  /* set = lap proximity sensor active */
+#define SW_PALMREST_PROXIMITY   0x12  /* set = palmrest proximity sensor active */
+#define SW_MAX			0x12
 #define SW_CNT			(SW_MAX+1)
 
 /*
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] Add support for Lenovo palm sensor
  2020-10-15 13:57 [PATCH 0/3] Lenovo lap and palm sensor support Mark Pearson
  2020-10-15 13:57 ` [PATCH 1/3] Adding event codes for Lenovo lap and palm sensors Mark Pearson
@ 2020-10-15 13:57 ` Mark Pearson
  2020-10-15 13:57 ` [PATCH 3/3] Add support for Lenovo lap sensor Mark Pearson
  2020-10-19 18:49 ` [PATCH 0/3] Lenovo lap and palm sensor support Hans de Goede
  3 siblings, 0 replies; 6+ messages in thread
From: Mark Pearson @ 2020-10-15 13:57 UTC (permalink / raw)
  To: markpearson
  Cc: njoshi1, hdegoede, dmitry.torokhov, platform-driver-x86,
	linux-input, jeff, anthony.wong, hadess

Use input device event support for palm sensor state changes.

Co-developed-by: Nitin Joshi <njoshi1@lenovo.com>
Signed-off-by: Nitin Joshi <njoshi1@lenovo.com>
Signed-off-by: Mark Pearson <markpearson@lenovo.com>
---
 drivers/platform/x86/thinkpad_acpi.c | 99 +++++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index eae3579f106f..5ddf2775fb06 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -4013,6 +4013,7 @@ static bool hotkey_notify_usrevent(const u32 hkey,
 }
 
 static void thermal_dump_all_sensors(void);
+static void proxsensor_refresh(void);
 
 static bool hotkey_notify_6xxx(const u32 hkey,
 				 bool *send_acpi_ev,
@@ -4079,8 +4080,8 @@ static bool hotkey_notify_6xxx(const u32 hkey,
 
 	case TP_HKEY_EV_PALM_DETECTED:
 	case TP_HKEY_EV_PALM_UNDETECTED:
-		/* palm detected hovering the keyboard, forward to user-space
-		 * via netlink for consumption */
+		/* palm detected  - pass on to event handler */
+		proxsensor_refresh();
 		return true;
 
 	default:
@@ -9918,6 +9919,96 @@ static struct ibm_struct dytc_driver_data = {
 	.exit = dytc_exit,
 };
 
+/*************************************************************************
+ * Proximity sensor subdriver
+ */
+
+#define PALMSENSOR_PRESENT_BIT 0 /* Determine if psensor present */
+#define PALMSENSOR_ON_BIT      1 /* psensor status */
+
+struct input_dev *tpacpi_sw_dev;
+bool has_palmsensor;
+bool palmsensor_state;
+
+static int palmsensor_get(bool *present, bool *state)
+{
+	acpi_handle psensor_handle;
+	int output;
+
+	if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GPSS", &psensor_handle)))
+		return -ENODEV;
+	if (!acpi_evalf(psensor_handle, &output, NULL, "d"))
+		return -EIO;
+
+	*present = output & BIT(PALMSENSOR_PRESENT_BIT) ? true : false;
+	*state = output & BIT(PALMSENSOR_ON_BIT) ? true : false;
+	return 0;
+}
+
+static void proxsensor_refresh(void)
+{
+	bool new_state;
+	int err;
+
+	if (has_palmsensor) {
+		err = palmsensor_get(&has_palmsensor, &new_state);
+		if (err)
+			return;
+		if (new_state != palmsensor_state) {
+			input_report_switch(tpacpi_sw_dev, SW_PALMREST_PROXIMITY, new_state);
+			input_sync(tpacpi_sw_dev);
+			palmsensor_state = new_state;
+		}
+	}
+}
+
+static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm)
+{
+	int palm_err;
+
+	palm_err = palmsensor_get(&has_palmsensor, &palmsensor_state);
+	/* If support isn't available (ENODEV) then don't return an error */
+	if (palm_err == -ENODEV)
+		return 0;
+	/* For all other errors we can flag the failure */
+	if (palm_err)
+		return palm_err;
+
+	if (has_palmsensor) {
+		tpacpi_sw_dev = input_allocate_device();
+		if (!tpacpi_sw_dev)
+			return -ENOMEM;
+		tpacpi_sw_dev->name = "Thinkpad proximity switches";
+		tpacpi_sw_dev->phys = TPACPI_DRVR_NAME "/input1";
+		tpacpi_sw_dev->id.bustype = BUS_HOST;
+		tpacpi_sw_dev->id.vendor = thinkpad_id.vendor;
+		tpacpi_sw_dev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
+		tpacpi_sw_dev->id.version = TPACPI_HKEY_INPUT_VERSION;
+		tpacpi_sw_dev->dev.parent = &tpacpi_pdev->dev;
+
+		if (has_palmsensor) {
+			input_set_capability(tpacpi_sw_dev, EV_SW, SW_PALMREST_PROXIMITY);
+			input_report_switch(tpacpi_sw_dev, SW_PALMREST_PROXIMITY, palmsensor_state);
+		}
+		palm_err = input_register_device(tpacpi_sw_dev);
+		if (palm_err) {
+			input_free_device(tpacpi_sw_dev);
+			return palm_err;
+		}
+	}
+	return 0;
+}
+
+static void proxsensor_exit(void)
+{
+	input_unregister_device(tpacpi_sw_dev);
+	input_free_device(tpacpi_sw_dev);
+}
+
+static struct ibm_struct proxsensor_driver_data = {
+	.name = "proximity-sensor",
+	.exit = proxsensor_exit,
+};
 /****************************************************************************
  ****************************************************************************
  *
@@ -10411,6 +10502,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {
 		.init = tpacpi_dytc_init,
 		.data = &dytc_driver_data,
 	},
+	{
+		.init = tpacpi_proxsensor_init,
+		.data = &proxsensor_driver_data,
+	},
 };
 
 static int __init set_ibm_param(const char *val, const struct kernel_param *kp)
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] Add support for Lenovo lap sensor
  2020-10-15 13:57 [PATCH 0/3] Lenovo lap and palm sensor support Mark Pearson
  2020-10-15 13:57 ` [PATCH 1/3] Adding event codes for Lenovo lap and palm sensors Mark Pearson
  2020-10-15 13:57 ` [PATCH 2/3] Add support for Lenovo palm sensor Mark Pearson
@ 2020-10-15 13:57 ` Mark Pearson
  2020-10-19 18:49 ` [PATCH 0/3] Lenovo lap and palm sensor support Hans de Goede
  3 siblings, 0 replies; 6+ messages in thread
From: Mark Pearson @ 2020-10-15 13:57 UTC (permalink / raw)
  To: markpearson
  Cc: njoshi1, hdegoede, dmitry.torokhov, platform-driver-x86,
	linux-input, jeff, anthony.wong, hadess

This adds the Lenovo lap sensor to the input_sw_dev event sensor
alongside the previously added palmsensor.

Signed-off-by: Nitin Joshi <njoshi1@lenovo.com>
Signed-off-by: Mark Pearson <markpearson@lenovo.com>
---
 drivers/platform/x86/thinkpad_acpi.c | 75 ++++++++++++++++++++++------
 1 file changed, 59 insertions(+), 16 deletions(-)

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 5ddf2775fb06..c20b9902270b 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -4013,7 +4013,7 @@ static bool hotkey_notify_usrevent(const u32 hkey,
 }
 
 static void thermal_dump_all_sensors(void);
-static void proxsensor_refresh(void);
+static void proxsensor_refresh(bool palm, bool lap);
 
 static bool hotkey_notify_6xxx(const u32 hkey,
 				 bool *send_acpi_ev,
@@ -4081,7 +4081,7 @@ static bool hotkey_notify_6xxx(const u32 hkey,
 	case TP_HKEY_EV_PALM_DETECTED:
 	case TP_HKEY_EV_PALM_UNDETECTED:
 		/* palm detected  - pass on to event handler */
-		proxsensor_refresh();
+		proxsensor_refresh(true /* palm */, false /* lap */);
 		return true;
 
 	default:
@@ -9929,6 +9929,23 @@ static struct ibm_struct dytc_driver_data = {
 struct input_dev *tpacpi_sw_dev;
 bool has_palmsensor;
 bool palmsensor_state;
+bool has_lapsensor;
+bool lapsensor_state;
+
+static int lapsensor_get(bool *present, bool *state)
+{
+	acpi_handle dytc_handle;
+	int output;
+
+	*present = false;
+	if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "DYTC", &dytc_handle)))
+		return -ENODEV;
+	if (!acpi_evalf(dytc_handle, &output, NULL, "dd", DYTC_CMD_GET))
+		return -EIO;
+	*present = true; /* If we get his far, we have lapmode support */
+	*state = output & BIT(DYTC_GET_LAPMODE_BIT) ? true : false;
+	return 0;
+}
 
 static int palmsensor_get(bool *present, bool *state)
 {
@@ -9945,36 +9962,56 @@ static int palmsensor_get(bool *present, bool *state)
 	return 0;
 }
 
-static void proxsensor_refresh(void)
+static void proxsensor_refresh(bool palm, bool lap)
 {
 	bool new_state;
 	int err;
 
-	if (has_palmsensor) {
+	if (palm && has_palmsensor) {
 		err = palmsensor_get(&has_palmsensor, &new_state);
-		if (err)
-			return;
-		if (new_state != palmsensor_state) {
+		if (!err && (new_state != palmsensor_state)) {
 			input_report_switch(tpacpi_sw_dev, SW_PALMREST_PROXIMITY, new_state);
 			input_sync(tpacpi_sw_dev);
 			palmsensor_state = new_state;
 		}
 	}
+
+	if (lap && has_lapsensor) {
+		err = lapsensor_get(&has_lapsensor, &new_state);
+		if (!err && (new_state != lapsensor_state)) {
+			input_report_switch(tpacpi_sw_dev, SW_LAP_PROXIMITY, new_state);
+			input_sync(tpacpi_sw_dev);
+			lapsensor_state = new_state;
+		}
+	}
 }
 
 static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm)
 {
-	int palm_err;
+	int palm_err, lap_err, err;
 
+	/* Make sure globals are set to a sensible initial value */
+	has_palmsensor = false;
+	has_lapsensor = false;
 	palm_err = palmsensor_get(&has_palmsensor, &palmsensor_state);
+	lap_err = lapsensor_get(&has_lapsensor, &lapsensor_state);
+
 	/* If support isn't available (ENODEV) then don't return an error */
-	if (palm_err == -ENODEV)
+	if ((palm_err == -ENODEV) && (lap_err == -ENODEV))
 		return 0;
-	/* For all other errors we can flag the failure */
+	/* If both sensors error out - return an error */
+	if (palm_err && lap_err)
+		return palm_err ? palm_err : lap_err;
+	/*
+	 * If just one sensor not available, we still want the input device,
+	 * so just flag it and carry on
+	 */
 	if (palm_err)
-		return palm_err;
+		pr_info("Palm sensor returned error %d", palm_err);
+	if (lap_err)
+		pr_info("Lap sensor returned error %d", lap_err);
 
-	if (has_palmsensor) {
+	if (has_palmsensor || has_lapsensor) {
 		tpacpi_sw_dev = input_allocate_device();
 		if (!tpacpi_sw_dev)
 			return -ENOMEM;
@@ -9990,10 +10027,14 @@ static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm)
 			input_set_capability(tpacpi_sw_dev, EV_SW, SW_PALMREST_PROXIMITY);
 			input_report_switch(tpacpi_sw_dev, SW_PALMREST_PROXIMITY, palmsensor_state);
 		}
-		palm_err = input_register_device(tpacpi_sw_dev);
-		if (palm_err) {
+		if (has_lapsensor) {
+			input_set_capability(tpacpi_sw_dev, EV_SW, SW_LAP_PROXIMITY);
+			input_report_switch(tpacpi_sw_dev, SW_LAP_PROXIMITY, lapsensor_state);
+		}
+		err = input_register_device(tpacpi_sw_dev);
+		if (err) {
 			input_free_device(tpacpi_sw_dev);
-			return palm_err;
+			return err;
 		}
 	}
 	return 0;
@@ -10057,8 +10098,10 @@ static void tpacpi_driver_event(const unsigned int hkey_event)
 		mutex_unlock(&kbdlight_mutex);
 	}
 
-	if (hkey_event == TP_HKEY_EV_THM_CSM_COMPLETED)
+	if (hkey_event == TP_HKEY_EV_THM_CSM_COMPLETED) {
 		dytc_lapmode_refresh();
+		proxsensor_refresh(false /* palm */, true /* lap */);
+	}
 
 }
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] Lenovo lap and palm sensor support
  2020-10-15 13:57 [PATCH 0/3] Lenovo lap and palm sensor support Mark Pearson
                   ` (2 preceding siblings ...)
  2020-10-15 13:57 ` [PATCH 3/3] Add support for Lenovo lap sensor Mark Pearson
@ 2020-10-19 18:49 ` Hans de Goede
  2020-10-20  0:15   ` [External] " Mark Pearson
  3 siblings, 1 reply; 6+ messages in thread
From: Hans de Goede @ 2020-10-19 18:49 UTC (permalink / raw)
  To: Mark Pearson
  Cc: njoshi1, dmitry.torokhov, platform-driver-x86, linux-input, jeff,
	anthony.wong, hadess

Hi,

On 10/15/20 3:57 PM, Mark Pearson wrote:
> This patch series is to add support for the Lenovo lap and palm sensors. 
> The original lap sensor implementation used a sysfs API but after
> consultation with the kernel maintainers we agreed on using the input
> subsystem instead.
> The first patch just adds the new defines needed.
> The second patch adds the implementation needed for the palm sensor.
> The third patch adds the implementation needed for the lap sensor. 
> 
> This means currently thinkpad_acpi.c has both the sysfs and input dev
> implementations. I will add a follow-on patch to remove the sysfs
> interface once I've confirmed this is OK with the few people who are
> using this in user space and given them some time to migrate to the
> input dev implementation.
> 
> Mark Pearson (3):
>   Adding event codes for Lenovo lap and palm sensors
>   Add support for Lenovo palm sensor.
>   Add support for Lenovo lap sensor

Not a full review, but one short remark, all your patch
subjects e.g. "Adding event codes for Lenovo lap and palm sensors"
are missing subsystem prefixes, if you do e.g.

git log include/uapi/linux/input-event-codes.h

You see subjects like "Input: allocate keycode for Fn + right shift",
etc. and for the the thinkpad_acpi.c code you get:
"platform/x86: thinkpad_acpi: Map Clipping tool hotkey to KEY_SELECTIVE_SCREENSHOT"

So your patch subjects should look something like this:

"Input: add event codes for lap and palmrest proximity switches"
(note I fixed more here then just the missing prefix)

"platform/x86: thinkpad_acpi: Add support for Lenovo palm sensor"
(note no . at the end)

"platform/x86: thinkpad_acpi: Add support for Lenovo lap sensor"

If you can send out a v2 with this fixed, that might help to
go Dmitry's attention for the first patch.

Regards,

Hans


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [External] Re: [PATCH 0/3] Lenovo lap and palm sensor support
  2020-10-19 18:49 ` [PATCH 0/3] Lenovo lap and palm sensor support Hans de Goede
@ 2020-10-20  0:15   ` Mark Pearson
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Pearson @ 2020-10-20  0:15 UTC (permalink / raw)
  To: Hans de Goede
  Cc: njoshi1, dmitry.torokhov, platform-driver-x86, linux-input, jeff,
	anthony.wong, hadess

On 19/10/2020 14:49, Hans de Goede wrote:
> Hi,
> 
> On 10/15/20 3:57 PM, Mark Pearson wrote:
>> This patch series is to add support for the Lenovo lap and palm sensors.
>> The original lap sensor implementation used a sysfs API but after
>> consultation with the kernel maintainers we agreed on using the input
>> subsystem instead.
>> The first patch just adds the new defines needed.
>> The second patch adds the implementation needed for the palm sensor.
>> The third patch adds the implementation needed for the lap sensor.
>>
>> This means currently thinkpad_acpi.c has both the sysfs and input dev
>> implementations. I will add a follow-on patch to remove the sysfs
>> interface once I've confirmed this is OK with the few people who are
>> using this in user space and given them some time to migrate to the
>> input dev implementation.
>>
>> Mark Pearson (3):
>>    Adding event codes for Lenovo lap and palm sensors
>>    Add support for Lenovo palm sensor.
>>    Add support for Lenovo lap sensor
> 
> Not a full review, but one short remark, all your patch
> subjects e.g. "Adding event codes for Lenovo lap and palm sensors"
> are missing subsystem prefixes, if you do e.g.
> 
> git log include/uapi/linux/input-event-codes.h
> 
> You see subjects like "Input: allocate keycode for Fn + right shift",
> etc. and for the the thinkpad_acpi.c code you get:
> "platform/x86: thinkpad_acpi: Map Clipping tool hotkey to KEY_SELECTIVE_SCREENSHOT"
> 
> So your patch subjects should look something like this:
> 
> "Input: add event codes for lap and palmrest proximity switches"
> (note I fixed more here then just the missing prefix)
> 
> "platform/x86: thinkpad_acpi: Add support for Lenovo palm sensor"
> (note no . at the end)
> 
> "platform/x86: thinkpad_acpi: Add support for Lenovo lap sensor"
> 
> If you can send out a v2 with this fixed, that might help to
> go Dmitry's attention for the first patch.
> 
> Regards,
> 
> Hans
> 
Thanks Hans,
I knew about that too detail, so slap on the wrist for me. I was too 
focused on doing a series of patches for the first time...

Updated version coming out shortly.

Mark
Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-10-20  0:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-15 13:57 [PATCH 0/3] Lenovo lap and palm sensor support Mark Pearson
2020-10-15 13:57 ` [PATCH 1/3] Adding event codes for Lenovo lap and palm sensors Mark Pearson
2020-10-15 13:57 ` [PATCH 2/3] Add support for Lenovo palm sensor Mark Pearson
2020-10-15 13:57 ` [PATCH 3/3] Add support for Lenovo lap sensor Mark Pearson
2020-10-19 18:49 ` [PATCH 0/3] Lenovo lap and palm sensor support Hans de Goede
2020-10-20  0:15   ` [External] " Mark Pearson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).