From: Darren Hart <dvhart@infradead.org>
To: "Pali Rohár" <pali.rohar@gmail.com>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>,
platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org, libsmbios-devel@lists.us.dell.com,
Srinivas_G_Gowda@dell.com, Michael_E_Brown@dell.com,
Gabriele Mazzotta <gabriele.mzt@gmail.com>
Subject: Re: [PATCH v2] platform: x86: dell-laptop: Add support for keyboard backlight
Date: Wed, 3 Dec 2014 00:43:21 -0800 [thread overview]
Message-ID: <20141203084319.GA52608@vmdeb7> (raw)
In-Reply-To: <1416754245-15550-1-git-send-email-pali.rohar@gmail.com>
On Sun, Nov 23, 2014 at 03:50:45PM +0100, Pali Rohár wrote:
> This patch adds support for configuring keyboard backlight settings on supported
> Dell laptops. It exports kernel leds interface and uses Dell SMBIOS tokens or
> keyboard class interface.
>
> With this patch it is possible to set:
> * keyboard backlight level
> * timeout after which will be backlight automatically turned off
> * input activity triggers (keyboard, touchpad, mouse) which enable backlight
> * ambient light settings
>
> Settings are exported via sysfs:
> /sys/class/leds/dell::kbd_backlight/
>
> Code is based on newly released documentation by Dell in libsmbios project.
>
Hi Pali,
I would really like to see this broken up. Possibly adding levels and timeouts
as separate patches for example. It is quite difficult to review this all at
once in a reasonable amount of time.
During this review I caught a few more CodingStyle violations, and raised some
questions about the timeout and levels mechanisms.
> @@ -62,6 +71,10 @@ struct calling_interface_structure {
>
> struct quirk_entry {
> u8 touchpad_led;
> +
> + /* Ordered list of timeouts expressed in seconds.
> + * The list must end with -1 */
Despite other instances in this file, block comments are documented in
CodingStyle as:
/*
* Comment text.
*/
The old ones should be cleaned up eventually, but new ones need to be done
according to CodingStyle. Please correct throughout.
> + int kbd_timeouts[];
> };
>
> static struct quirk_entry *quirks;
> @@ -76,6 +89,10 @@ static int __init dmi_matched(const struct dmi_system_id *dmi)
> return 1;
> }
>
> +static struct quirk_entry quirk_dell_xps13_9333 = {
> + .kbd_timeouts = { 0, 5, 15, 60, 5*60, 15*60, -1 },
Where did these values come from? Were they documented in the libsmbios project?
Can you provide a URL to that? These really should be described by the firmware,
but if they aren't, nothing we can do about it.
> @@ -790,6 +842,964 @@ static void touchpad_led_exit(void)
> led_classdev_unregister(&touchpad_led);
> }
>
> +/* Derived from information in smbios-keyboard-ctl:
See block comment above.
> +
> + cbClass 4
> + cbSelect 11
> + Keyboar illumination
Keyboard
> + cbArg1 determines the function to be performed
> +
> + cbArg1 0x0 = Get Feature Information
> + cbRES1 Standard return codes (0, -1, -2)
> + cbRES2, word0 Bitmap of user-selectable modes
> + bit 0 Always off (All systems)
> + bit 1 Always on (Travis ATG, Siberia)
> + bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG)
> + bit 3 Auto: ALS- and input-activity-based On; input-activity based Off
> + bit 4 Auto: Input-activity-based On; input-activity based Off
> + bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off
> + bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off
> + bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off
> + bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off
> + bits 9-15 Reserved for future use
> + cbRES2, byte2 Reserved for future use
> + cbRES2, byte3 Keyboard illumination type
> + 0 Reserved
> + 1 Tasklight
> + 2 Backlight
> + 3-255 Reserved for future use
> + cbRES3, byte0 Supported auto keyboard illumination trigger bitmap.
> + bit 0 Any keystroke
> + bit 1 Touchpad activity
> + bit 2 Pointing stick
> + bit 3 Any mouse
> + bits 4-7 Reserved for future use
> + cbRES3, byte1 Supported timeout unit bitmap
> + bit 0 Seconds
> + bit 1 Minutes
> + bit 2 Hours
> + bit 3 Days
> + bits 4-7 Reserved for future use
> + cbRES3, byte2 Number of keyboard light brightness levels
> + cbRES4, byte0 Maximum acceptable seconds value (0 if seconds not supported).
> + cbRES4, byte1 Maximum acceptable minutes value (0 if minutes not supported).
> + cbRES4, byte2 Maximum acceptable hours value (0 if hours not supported).
> + cbRES4, byte3 Maxiomum acceptable days value (0 if days not supported)
Maximum ^
This interface appears to define all possible values for the timeout between
cbRES3[1] and cbRES4[*]. Why is the kbd_timeouts[] array a quirk with fixed
values? It seems it could indeed be dynamically determined.
> +
> +struct kbd_info {
> + u16 modes;
> + u8 type;
> + u8 triggers;
> + u8 levels;
> + u8 seconds;
> + u8 minutes;
> + u8 hours;
> + u8 days;
> +};
> +
> +
> +static u8 kbd_mode_levels[16];
> +static int kbd_mode_levels_count;
I'm confused by these. How are they different from kbd_info.levels?
We seem to check the latter first and fall back to these if that is 0.... why?
> +static int kbd_get_info(struct kbd_info *info)
> +{
> + u8 units;
> + int ret;
> +
> + get_buffer();
> +
> + buffer->input[0] = 0x0;
> + dell_send_request(buffer, 4, 11);
> + ret = buffer->output[0];
> +
> + if (ret) {
> + ret = dell_smi_error(ret);
> + goto out;
> + }
> +
> + info->modes = buffer->output[1] & 0xFFFF;
> + info->type = (buffer->output[1] >> 24) & 0xFF;
> + info->triggers = buffer->output[2] & 0xFF;
> + units = (buffer->output[2] >> 8) & 0xFF;
> + info->levels = (buffer->output[2] >> 16) & 0xFF;
> +
> + if (units & BIT(0))
> + info->seconds = (buffer->output[3] >> 0) & 0xFF;
> + if (units & BIT(1))
> + info->minutes = (buffer->output[3] >> 8) & 0xFF;
> + if (units & BIT(2))
> + info->hours = (buffer->output[3] >> 16) & 0xFF;
> + if (units & BIT(3))
> + info->days = (buffer->output[3] >> 24) & 0xFF;
> +
> +out:
Please indent gotos by one space. This improves diffs context by not treating the goto label
like a function.
> + release_buffer();
> + return ret;
> +}
> +
> +static unsigned int kbd_get_max_level(void)
> +{
> + if (kbd_info.levels != 0)
> + return kbd_info.levels;
> + if (kbd_mode_levels_count > 0)
> + return kbd_mode_levels_count - 1;
Here for example. In what scenario does this happen?
> + return 0;
> +}
> +
> +static inline int kbd_init_info(void)
> +{
> + struct kbd_state state;
> + int ret;
> + int i;
> +
> + ret = kbd_get_info(&kbd_info);
> + if (ret)
> + return ret;
> +
> + kbd_get_state(&state);
> +
> + /* NOTE: timeout value is stored in 6 bits so max value is 63 */
> + if (kbd_info.seconds > 63)
> + kbd_info.seconds = 63;
> + if (kbd_info.minutes > 63)
> + kbd_info.minutes = 63;
> + if (kbd_info.hours > 63)
> + kbd_info.hours = 63;
> + if (kbd_info.days > 63)
> + kbd_info.days = 63;
> +
> + /* NOTE: On tested machines ON mode did not work and caused
> + * problems (turned backlight off) so do not use it
> + */
> + kbd_info.modes &= ~BIT(KBD_MODE_BIT_ON);
> +
> + kbd_previous_level = kbd_get_level(&state);
> + kbd_previous_mode_bit = state.mode_bit;
> +
> + if (kbd_previous_level == 0 && kbd_get_max_level() != 0)
> + kbd_previous_level = 1;
> +
> + if (kbd_previous_mode_bit == KBD_MODE_BIT_OFF) {
> + kbd_previous_mode_bit =
> + ffs(kbd_info.modes & ~BIT(KBD_MODE_BIT_OFF));
> + if (kbd_previous_mode_bit != 0)
> + kbd_previous_mode_bit--;
> + }
> +
> + if (kbd_info.modes & (BIT(KBD_MODE_BIT_ALS) |
> + BIT(KBD_MODE_BIT_TRIGGER_ALS)))
> + kbd_als_supported = true;
> +
> + if (kbd_info.modes & (
> + BIT(KBD_MODE_BIT_TRIGGER_ALS) | BIT(KBD_MODE_BIT_TRIGGER) |
> + BIT(KBD_MODE_BIT_TRIGGER_25) | BIT(KBD_MODE_BIT_TRIGGER_50) |
> + BIT(KBD_MODE_BIT_TRIGGER_75) | BIT(KBD_MODE_BIT_TRIGGER_100)
> + ))
> + kbd_triggers_supported = true;
> +
> + for (i = 0; i < 16; ++i)
Doesn't this only apply to bits 5-8? Why not just loop through those?
for (i = KBD_MODE_BIT_TRIGGER_25; i <= KBD_MODE_BIT_TRIGGER_100)
The level_mode_bit check becomes unecessary.
> + if (kbd_is_level_mode_bit(i) && (BIT(i) & kbd_info.modes))
> + kbd_mode_levels[1+kbd_mode_levels_count++] = i;
One space around operators like + please.
What is kbd_mode_levels[0] reserved for? The current level? Isn't that what
kbd_state.level is for?
> +
> + if (kbd_mode_levels_count > 0) {
> + for (i = 0; i < 16; ++i) {
If 0-4 don't apply here, why loop through them? Should we just set levels[0] to
0 if it isn't one of 5-8?
If bits 9-16 are reserved, it seems it would be best to avoid checking for them
as they might return a false positive, and we'd be setting kbd_mode_levels to an
undefined value.
> + if (BIT(i) & kbd_info.modes) {
> + kbd_mode_levels[0] = i;
> + break;
> + }
> + }
> + kbd_mode_levels_count++;
> + }
> +
> + return 0;
--
Darren Hart
Intel Open Source Technology Center
next prev parent reply other threads:[~2014-12-04 5:34 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-14 12:23 [PATCH] platform: x86: dell-laptop: Add support for keyboard backlight Pali Rohár
2014-11-19 18:34 ` Darren Hart
2014-11-19 19:23 ` Matthew Garrett
2014-11-19 19:51 ` Pali Rohár
2014-11-19 19:12 ` Darren Hart
2014-11-19 20:41 ` Pali Rohár
2014-11-21 20:39 ` Darren Hart
2014-11-22 18:46 ` Pali Rohár
2014-11-21 22:09 ` Darren Hart
2014-11-23 14:48 ` Pali Rohár
2014-11-23 14:50 ` [PATCH v2] " Pali Rohár
2014-11-25 23:01 ` Darren Hart
2014-12-01 17:35 ` Pali Rohár
2014-12-03 8:43 ` Darren Hart [this message]
2014-12-04 8:50 ` Gabriele Mazzotta
2014-12-03 11:51 ` Darren Hart
2014-12-05 1:53 ` Pali Rohár
2014-12-04 10:16 ` Pali Rohár
2014-12-03 12:35 ` Darren Hart
2014-12-05 2:03 ` Pali Rohár
2014-12-03 12:49 ` Darren Hart
2014-12-05 11:53 ` [PATCH v3] " Pali Rohár
2014-12-03 18:00 ` Darren Hart
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=20141203084319.GA52608@vmdeb7 \
--to=dvhart@infradead.org \
--cc=Michael_E_Brown@dell.com \
--cc=Srinivas_G_Gowda@dell.com \
--cc=gabriele.mzt@gmail.com \
--cc=libsmbios-devel@lists.us.dell.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mjg59@srcf.ucam.org \
--cc=pali.rohar@gmail.com \
--cc=platform-driver-x86@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
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