Use input device event support for notifying userspace of lap mode sensor state changes. Reviewed-by: Nitin Joshi <njoshi1@xxxxxxxxxx> Signed-off-by: Mark Pearson <markpearson@xxxxxxxxxx> --- Changes in V2: - Update commit message to be correct Changes in V3: - Update lap sensor code with same fixes applied to palm sensor code. - Correct error handling in init so returns an error if one encountered. drivers/platform/x86/thinkpad_acpi.c | 61 ++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 3cb07c12a705..fe438a5e1dbe 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9928,6 +9928,22 @@ static struct ibm_struct dytc_driver_data = { struct input_dev *tpacpi_sw_dev; bool has_palmsensor; +bool has_lapsensor; + +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) { @@ -9958,21 +9974,40 @@ static void palmsensor_refresh(void) } } +static void lapsensor_refresh(void) +{ + bool state; + int err; + + if (has_lapsensor) { + err = lapsensor_get(&has_lapsensor, &state); + if (err) + return; + input_report_switch(tpacpi_sw_dev, SW_LAP_PROXIMITY, state); + input_sync(tpacpi_sw_dev); + } +} + static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) { - int palm_err, err; - bool palm_state; + int palm_err, lap_err, err; + bool palm_state, lap_state; palm_err = palmsensor_get(&has_palmsensor, &palm_state); - /* If support isn't available (ENODEV) then quit, but don't return an error */ - if (palm_err == -ENODEV) + lap_err = lapsensor_get(&has_lapsensor, &lap_state); + /* + * If support isn't available (ENODEV) for both devices then quit, but + * don't return an error. + */ + if ((palm_err == -ENODEV) && (lap_err == -ENODEV)) return 1; - /* Otherwise, if there was an error return it */ if (palm_err && (palm_err != ENODEV)) return palm_err; + if (lap_err && (lap_err != ENODEV)) + return lap_err; - if (has_palmsensor) { + if (has_palmsensor || has_lapsensor) { tpacpi_sw_dev = input_allocate_device(); if (!tpacpi_sw_dev) return -ENOMEM; @@ -9984,8 +10019,14 @@ static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) tpacpi_sw_dev->id.version = TPACPI_HKEY_INPUT_VERSION; tpacpi_sw_dev->dev.parent = &tpacpi_pdev->dev; - input_set_capability(tpacpi_sw_dev, EV_SW, SW_PALMREST_PROXIMITY); - input_report_switch(tpacpi_sw_dev, SW_PALMREST_PROXIMITY, palm_state); + if (has_palmsensor) { + input_set_capability(tpacpi_sw_dev, EV_SW, SW_PALMREST_PROXIMITY); + input_report_switch(tpacpi_sw_dev, SW_PALMREST_PROXIMITY, palm_state); + } + if (has_lapsensor) { + input_set_capability(tpacpi_sw_dev, EV_SW, SW_LAP_PROXIMITY); + input_report_switch(tpacpi_sw_dev, SW_LAP_PROXIMITY, lap_state); + } err = input_register_device(tpacpi_sw_dev); if (err) { input_free_device(tpacpi_sw_dev); @@ -10053,8 +10094,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(); + lapsensor_refresh(); + } } -- 2.28.0