From: Hans de Goede <hdegoede@redhat.com>
To: "Eray Orçunus" <erayorcunus@gmail.com>,
platform-driver-x86@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
ike.pan@canonical.com, jikos@kernel.org,
benjamin.tissoires@redhat.com, dmitry.torokhov@gmail.com,
mgross@linux.intel.com, pobrn@protonmail.com
Subject: Re: [PATCH v2 6/7] platform/x86: ideapad-laptop: Keyboard backlight support for more IdeaPads
Date: Tue, 15 Nov 2022 21:59:57 +0100 [thread overview]
Message-ID: <69f78d53-aca5-c866-d436-6b5e7b1589d0@redhat.com> (raw)
In-Reply-To: <20221029120311.11152-7-erayorcunus@gmail.com>
Hi Eray,
On 10/29/22 14:03, Eray Orçunus wrote:
> IdeaPads with HALS_KBD_BL_SUPPORT_BIT have full keyboard light support,
> and they send an event via ACPI on light state change. Whereas some
> IdeaPads that don't have this bit set, i.e. 520-15ikb, 330-17ich and
> 5 (15), don't send an event, yet they still support switching keyboard
> light via KBLO object on DSDT. Detect these IdeaPads with searching for
> KBLO object, set their kbd_bl_partial to true and register led device
> for them. Tested on 520-15ikb.
>
> Signed-off-by: Eray Orçunus <erayorcunus@gmail.com>
> ---
> drivers/platform/x86/ideapad-laptop.c | 79 ++++++++++++++++++++++++---
> 1 file changed, 70 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
> index e8c088e7a53d..b34fbc4d741c 100644
> --- a/drivers/platform/x86/ideapad-laptop.c
> +++ b/drivers/platform/x86/ideapad-laptop.c
> @@ -149,6 +149,7 @@ struct ideapad_private {
> bool fn_lock : 1;
> bool hw_rfkill_switch : 1;
> bool kbd_bl : 1;
> + bool kbd_bl_partial : 1;
> bool cam_ctrl_via_ec : 1;
> bool touchpad_ctrl_via_ec : 1;
> bool usb_charging : 1;
> @@ -157,6 +158,9 @@ struct ideapad_private {
> bool initialized;
> struct led_classdev led;
> unsigned int last_brightness;
> + /* Below are used only if kbd_bl_partial is set */
> + acpi_handle lfcm_mutex;
> + acpi_handle kblo_obj;
> } kbd_bl;
> };
>
> @@ -1300,19 +1304,52 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv)
> backlight_force_update(priv->blightdev, BACKLIGHT_UPDATE_HOTKEY);
> }
>
> +#define IDEAPAD_ACPI_MUTEX_TIMEOUT 1500
> +
> /*
> * keyboard backlight
> */
> static int ideapad_kbd_bl_brightness_get(struct ideapad_private *priv)
> {
> - unsigned long hals;
> + unsigned long ret_val;
> int err;
> + acpi_status status;
>
> - err = eval_hals(priv->adev->handle, &hals);
> + /*
> + * Some IdeaPads with partially implemented keyboard lights don't give
> + * us the light state on HALS_KBD_BL_STATE_BIT in the return value of HALS,
> + * i.e. 5 (15) and 330-17ich. Fortunately we know how to gather it.
> + * Even if it won't work, we will still give HALS a try, because
> + * some IdeaPads with kbd_bl_partial, i.e. 520-15ikb,
> + * correctly sets HALS_KBD_BL_STATE_BIT in HALS return value.
> + */
> +
> + if (priv->features.kbd_bl_partial &&
> + priv->kbd_bl.lfcm_mutex != NULL && priv->kbd_bl.kblo_obj != NULL) {
IMHO it would be better to only set kbd_bl_partial when both handles
are not NULL, then you can drop the handle checks here.
> +
> + status = acpi_acquire_mutex(priv->kbd_bl.lfcm_mutex, NULL,
> + IDEAPAD_ACPI_MUTEX_TIMEOUT);
> +
> + if (ACPI_SUCCESS(status)) {
This code now ends up still going through the normal kbd-bl path
when it fails to acquire the mutex.
Instead it should do:
if (ACPI_FAILURE(status))
return -EIO;
And then have the rest of the code one indentation level less
deep.
> + err = eval_int(priv->kbd_bl.kblo_obj, NULL, &ret_val);
> +
> + status = acpi_release_mutex(priv->kbd_bl.lfcm_mutex, NULL);
> + if (ACPI_FAILURE(status))
> + dev_err(&priv->platform_device->dev,
> + "Failed to release LFCM mutex");
I'm pretty sure that the ACPI core will already log an error if things
fail, I would change this to just a single line:
acpi_release_mutex(priv->kbd_bl.lfcm_mutex, NULL);
> +
> + if (err)
> + return err;
> +
> + return !!ret_val;
!!ret_val turns it into a boolean, does that mean it is always either on
or off with no level in between ?
> + }
> + }
> +
> + err = eval_hals(priv->adev->handle, &ret_val);
> if (err)
> return err;
>
> - return !!test_bit(HALS_KBD_BL_STATE_BIT, &hals);
> + return !!test_bit(HALS_KBD_BL_STATE_BIT, &ret_val);
> }
>
> static enum led_brightness ideapad_kbd_bl_led_cdev_brightness_get(struct led_classdev *led_cdev)
> @@ -1329,7 +1366,8 @@ static int ideapad_kbd_bl_brightness_set(struct ideapad_private *priv, unsigned
> if (err)
> return err;
>
> - priv->kbd_bl.last_brightness = brightness;
> + if (!priv->features.kbd_bl_partial)
> + priv->kbd_bl.last_brightness = brightness;
>
> return 0;
> }
I don't understand this change, you change ideapad_kbd_bl_brightness_get()
to do an int eval of KBLO, but here you now still do a
exec_sals(SALS_KBD_BL_ON / SALS_KBD_BL_OFF) ?
Also there is no reason not to update last_brightness here ...
> @@ -1349,6 +1387,9 @@ static void ideapad_kbd_bl_notify(struct ideapad_private *priv)
> if (!priv->kbd_bl.initialized)
> return;
>
> + if (priv->features.kbd_bl_partial)
> + return;
> +
Why? If we do happen to get a notify on one of these devices and
the brightness has changed, then it would be good to let userspace
know and if never get a notify then this function won't run so
we don't need the if.
> brightness = ideapad_kbd_bl_brightness_get(priv);
> if (brightness < 0)
> return;
> @@ -1371,17 +1412,20 @@ static int ideapad_kbd_bl_init(struct ideapad_private *priv)
> if (WARN_ON(priv->kbd_bl.initialized))
> return -EEXIST;
>
> - brightness = ideapad_kbd_bl_brightness_get(priv);
> - if (brightness < 0)
> - return brightness;
> + /* IdeaPads with kbd_bl_partial don't have keyboard backlight event */
> + if (!priv->features.kbd_bl_partial) {
> + brightness = ideapad_kbd_bl_brightness_get(priv);
> + if (brightness < 0)
> + return brightness;
>
> - priv->kbd_bl.last_brightness = brightness;
> + priv->kbd_bl.last_brightness = brightness;
> + priv->kbd_bl.led.flags = LED_BRIGHT_HW_CHANGED;
> + }
Again no need to for the if here. Setting last_brightness and advertising
LED_BRIGHT_HW_CHANGED unconditionally won't hurt and not making this difference
keeps the code simpler.
>
> priv->kbd_bl.led.name = "platform::" LED_FUNCTION_KBD_BACKLIGHT;
> priv->kbd_bl.led.max_brightness = 1;
> priv->kbd_bl.led.brightness_get = ideapad_kbd_bl_led_cdev_brightness_get;
> priv->kbd_bl.led.brightness_set_blocking = ideapad_kbd_bl_led_cdev_brightness_set;
> - priv->kbd_bl.led.flags = LED_BRIGHT_HW_CHANGED;
>
> err = led_classdev_register(&priv->platform_device->dev, &priv->kbd_bl.led);
> if (err)
> @@ -1594,8 +1638,25 @@ static void ideapad_check_features(struct ideapad_private *priv)
> if (test_bit(HALS_FNLOCK_SUPPORT_BIT, &val))
> priv->features.fn_lock = true;
>
> + /*
> + * IdeaPads with HALS_KBD_BL_SUPPORT_BIT have full keyboard
> + * light support, and they send an event via ACPI on light
> + * state change. Whereas some IdeaPads, at least 520-15ikb
> + * and 5 (15), don't send an event, yet they still have
> + * KBLO object. In this case, set kbd_bl_partial to true
> + * and cache the LFCM mutex, it might be useful while
> + * getting the brightness.
> + */
> +
> if (test_bit(HALS_KBD_BL_SUPPORT_BIT, &val))
> priv->features.kbd_bl = true;
> + else if (ACPI_SUCCESS(acpi_get_handle(handle, "^KBLO",
> + &priv->kbd_bl.kblo_obj))) {
As mentioned above I would change this to:
else if (ACPI_SUCCESS(acpi_get_handle(handle, "^KBLO",
&priv->kbd_bl.kblo_obj)) &&
ACPI_SUCCESS(acpi_get_handle(handle, "^LFCM",
&priv->kbd_bl.lfcm_mutex))) {
> + priv->features.kbd_bl = true;
> + priv->features.kbd_bl_partial = true;
> + (void)acpi_get_handle(handle, "^LFCM",
> + &priv->kbd_bl.lfcm_mutex);
And then drop the acpi_get_handle() here.
> + }
>
> if (test_bit(HALS_USB_CHARGING_SUPPORT_BIT, &val))
> priv->features.usb_charging = true;
Regards,
Hans
next prev parent reply other threads:[~2022-11-15 21:01 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-29 12:03 [PATCH v2 0/7] Add camera access keys, IdeaPad driver improvements Eray Orçunus
2022-10-29 12:03 ` [PATCH v2 1/7] Revert "platform/x86: ideapad-laptop: check for touchpad support in _CFG" Eray Orçunus
2022-11-15 20:25 ` Hans de Goede
2022-10-29 12:03 ` [PATCH v2 2/7] HID: add mapping for camera access keys Eray Orçunus
2022-11-04 8:36 ` Jiri Kosina
2022-11-15 20:33 ` Hans de Goede
2022-11-23 1:56 ` Dmitry Torokhov
2023-06-27 17:35 ` Dmitry Torokhov
2022-10-29 12:03 ` [PATCH v2 3/7] platform/x86: ideapad-laptop: Report KEY_CAMERA_ACCESS_TOGGLE instead of KEY_CAMERA Eray Orçunus
2022-11-15 20:31 ` Hans de Goede
2022-10-29 12:03 ` [PATCH v2 4/7] platform/x86: ideapad-laptop: Add new _CFG bit numbers for future use Eray Orçunus
2022-11-15 20:36 ` Hans de Goede
2022-10-29 12:03 ` [PATCH v2 5/7] platform/x86: ideapad-laptop: Expose camera_power only if supported Eray Orçunus
2022-11-15 20:43 ` Hans de Goede
2022-11-16 15:39 ` Hans de Goede
2022-10-29 12:03 ` [PATCH v2 6/7] platform/x86: ideapad-laptop: Keyboard backlight support for more IdeaPads Eray Orçunus
2022-11-15 20:59 ` Hans de Goede [this message]
2022-10-29 12:03 ` [PATCH v2 7/7] platform/x86: ideapad-laptop: Don't expose touchpad attr on IdeaPads with SYNA2B33 Eray Orçunus
2022-11-15 21:00 ` Hans de Goede
2022-11-08 3:56 ` [PATCH v2 0/7] Add camera access keys, IdeaPad driver improvements Ike Panhc
2022-11-09 12:58 ` Eray Orçunus
2022-11-09 16:38 ` Hans de Goede
2022-11-09 23:30 ` Eray Orçunus
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=69f78d53-aca5-c866-d436-6b5e7b1589d0@redhat.com \
--to=hdegoede@redhat.com \
--cc=benjamin.tissoires@redhat.com \
--cc=dmitry.torokhov@gmail.com \
--cc=erayorcunus@gmail.com \
--cc=ike.pan@canonical.com \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mgross@linux.intel.com \
--cc=platform-driver-x86@vger.kernel.org \
--cc=pobrn@protonmail.com \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).