2020-08-21 18:19:16

by Kenneth Chan

[permalink] [raw]
Subject: [PATCH 0/9] platform/x86: panasonic-laptop: add optical drive, brightness and battery charging threshold


This patch series is to follow up https://lkml.org/lkml/2020/8/19/186

Martin Lucina <[email protected]> added a platform device to power on/off the
optical drive. The patch somehow never made its way to upstream.
This patch merges his work.

The Panasonic Let's Note series have firmware registers that store the
state of mute, AC/DC brightness, current brightness and battery charging
threshold (ECO mode). This patch series also add support to them.


Kenneth Chan (9):
add support for optical driver power in Y and W series
replace ACPI prints with pr_*() macros
split MODULE_AUTHOR() by one author per macro call
fix naming of platform files for consistency with other modules
fix sticky key init bug
add write support to mute
resolve hotkey double trigger bug
add support for battery charging threshold (eco mode)
add platform devices for firmware brightness registers

drivers/platform/x86/panasonic-laptop.c | 509 +++++++++++++++++++++---
1 file changed, 454 insertions(+), 55 deletions(-)


base-commit: 06a4ec1d9dc652e17ee3ac2ceb6c7cf6c2b75cdd
--
2.17.5


2020-08-21 18:19:37

by Kenneth Chan

[permalink] [raw]
Subject: [PATCH 7/9] resolve hotkey double trigger bug

Sometimes double ACPI events are triggered for brightness, vol and mute hotkeys. This
patch fixes it.


Signed-off-by: Kenneth Chan <[email protected]>
---
drivers/platform/x86/panasonic-laptop.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index 3b0294ee9d3e..6779099a3ec9 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -13,6 +13,7 @@
*
* ChangeLog:
* Aug.18, 2020 Kenneth Chan <[email protected]>
+ * resolve hotkey double trigger
* add write support to mute
* fix sticky_key init bug
* fix naming of platform files for consistency with other
@@ -597,9 +598,11 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
result & 0xf, 0x80, false);
}

- if (!sparse_keymap_report_event(hotk_input_dev,
- result & 0xf, result & 0x80, false))
- pr_err("Unknown hotkey event: 0x%04llx\n", result);
+ if ((result & 0xf) == 0x7 || (result & 0xf) == 0x9 || (result & 0xf) == 0xa) {
+ if (!sparse_keymap_report_event(hotk_input_dev,
+ result & 0xf, result & 0x80, false))
+ pr_err("Unknown hotkey event: 0x%04llx\n", result);
+ }
}

static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
--
2.17.5

2020-08-21 18:20:24

by Kenneth Chan

[permalink] [raw]
Subject: [PATCH 9/9] add platform devices for firmware brightness registers

Panasonic laptops (at least from CF-W4 onwards) have dedicated firmware
registers for saving ac/dc and current brightness. They are a bit confusing
so here's some explanations:

AC_MIN_BRIGHT, AC_MAX_BRIGHT, DC_MIN_BRIGHT, DC_MAX_BRIGHT:
Read-only. Values: 0x01 and 0x15 respectively.

AC_CUR_BRIGHT, DC_CUR_BRIGHT:
Read-Write. 0x00-0xFF. Store user-defined AC/DC brightness. However, they do
not represent current brightness so they should be named AC_BRIGHT and
DC_BRIGHT instead.

CUR_BRIGHT (present since CF-W4):
Read-Write. 0x00-0xFF. It sets the current brightness. It won't update itself
if brightness is changed via other means, e.g. acpi_video0.

Another CUR_BRIGHT (added since CF-W5):
Read-Write. 0x01-0x15. Its value always synchronizes with current brightness.
Not implemented in this version.

Currently the backlight API interacts with AC_CUR_BRIGHT (probably because
it's the only bl register available in earlier models?). This patch adds
platform devices for AC_CUR_BRIGHT, DC_CUR_BRIGHT and CUR_BRIGHT.

It also fixes the error of https://lkml.org/lkml/2020/8/19/1264.


PS: I think the backlight API should interact with CUR_BRIGHT instead of
AC_CUR_BRIGHT. But it involves complications like mapping between 0x01-0x15
or 0x00-0x14 (the backlight API) and 0x00-0xFF (CUR_BRIGHT). I'll leave the
discussion for a later version.


Signed-off-by: Kenneth Chan <[email protected]>
---
drivers/platform/x86/panasonic-laptop.c | 109 ++++++++++++++++++++++++
1 file changed, 109 insertions(+)

diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index 6355d60dc3eb..6388c3c705a6 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -13,6 +13,7 @@
*
* ChangeLog:
* Aug.18, 2020 Kenneth Chan <[email protected]>
+ * -v0.98 add platform devices for firmware brightness registers
* add support for battery charging threshold (eco mode)
* resolve hotkey double trigger
* add write support to mute
@@ -132,6 +133,7 @@
#include <linux/input/sparse-keymap.h>
#include <linux/platform_device.h>

+
MODULE_AUTHOR("Hiroshi Miura <[email protected]>");
MODULE_AUTHOR("David Bronaugh <[email protected]>");
MODULE_AUTHOR("Harald Welte <[email protected]>");
@@ -173,6 +175,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,
SINF_MUTE,
SINF_RESERVED,
SINF_ECO_MODE = 0x0A,
+ SINF_CUR_BRIGHT = 0x0D,
SINF_STICKY_KEY = 0x80,
};
/* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */
@@ -228,6 +231,9 @@ struct pcc_acpi {
int sticky_key;
int eco_mode;
int mute;
+ int ac_brightness;
+ int dc_brightness;
+ int current_brightness;
u32 *sinf;
struct acpi_device *device;
struct input_dev *input_dev;
@@ -610,6 +616,97 @@ static ssize_t eco_mode_store(struct device *dev, struct device_attribute *attr,
return count;
}

+static ssize_t ac_brightness_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+ if (!acpi_pcc_retrieve_biosdata(pcc))
+ return -EIO;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_AC_CUR_BRIGHT]);
+}
+
+static ssize_t ac_brightness_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pcc_acpi *pcc = acpi_driver_data(acpi);
+ int err, val;
+
+ err = kstrtoint(buf, 0, &val);
+ if (err)
+ return err;
+ if (val >= 0 && val <= 255) {
+ acpi_pcc_write_sset(pcc, SINF_AC_CUR_BRIGHT, val);
+ pcc->ac_brightness = val;
+ }
+
+ return count;
+}
+
+static ssize_t dc_brightness_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+ if (!acpi_pcc_retrieve_biosdata(pcc))
+ return -EIO;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_DC_CUR_BRIGHT]);
+}
+
+static ssize_t dc_brightness_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pcc_acpi *pcc = acpi_driver_data(acpi);
+ int err, val;
+
+ err = kstrtoint(buf, 0, &val);
+ if (err)
+ return err;
+ if (val >= 0 && val <= 255) {
+ acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, val);
+ pcc->dc_brightness = val;
+ }
+
+ return count;
+}
+
+static ssize_t current_brightness_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pcc_acpi *pcc = acpi_driver_data(acpi);
+
+ if (!acpi_pcc_retrieve_biosdata(pcc))
+ return -EIO;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_CUR_BRIGHT]);
+}
+
+static ssize_t current_brightness_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pcc_acpi *pcc = acpi_driver_data(acpi);
+ int err, val;
+
+ err = kstrtoint(buf, 0, &val);
+ if (err)
+ return err;
+
+ if (val >= 0 && val <= 255) {
+ err = acpi_pcc_write_sset(pcc, SINF_CUR_BRIGHT, val);
+ pcc->current_brightness = val;
+ }
+
+ return count;
+}
+
static ssize_t cdpower_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -633,6 +730,9 @@ static DEVICE_ATTR_RO(lcdtype);
static DEVICE_ATTR_RW(mute);
static DEVICE_ATTR_RW(sticky_key);
static DEVICE_ATTR_RW(eco_mode);
+static DEVICE_ATTR_RW(ac_brightness);
+static DEVICE_ATTR_RW(dc_brightness);
+static DEVICE_ATTR_RW(current_brightness);
static DEVICE_ATTR_RW(cdpower);

static struct attribute *pcc_sysfs_entries[] = {
@@ -641,6 +741,9 @@ static struct attribute *pcc_sysfs_entries[] = {
&dev_attr_mute.attr,
&dev_attr_sticky_key.attr,
&dev_attr_eco_mode.attr,
+ &dev_attr_ac_brightness.attr,
+ &dev_attr_dc_brightness.attr,
+ &dev_attr_current_brightness.attr,
&dev_attr_cdpower.attr,
NULL,
};
@@ -794,6 +897,9 @@ static int acpi_pcc_hotkey_resume(struct device *dev)
acpi_pcc_write_sset(pcc, SINF_MUTE, pcc->mute);
acpi_pcc_write_sset(pcc, SINF_ECO_MODE, pcc->eco_mode);
acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_key);
+ acpi_pcc_write_sset(pcc, SINF_AC_CUR_BRIGHT, pcc->ac_brightness);
+ acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, pcc->dc_brightness);
+ acpi_pcc_write_sset(pcc, SINF_CUR_BRIGHT, pcc->current_brightness);

return 0;
}
@@ -865,6 +971,9 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)

pcc->eco_mode = pcc->sinf[SINF_ECO_MODE];
pcc->mute = pcc->sinf[SINF_MUTE];
+ pcc->ac_brightness = pcc->sinf[SINF_AC_CUR_BRIGHT];
+ pcc->dc_brightness = pcc->sinf[SINF_DC_CUR_BRIGHT];
+ result = pcc->current_brightness = pcc->sinf[SINF_CUR_BRIGHT];

/* add sysfs attributes */
result = sysfs_create_group(&device->dev.kobj, &pcc_attr_group);
--
2.17.5

2020-08-21 18:21:24

by Kenneth Chan

[permalink] [raw]
Subject: [PATCH 6/9] add write support to mute

Add write support to the mute platform device


Signed-off-by: Kenneth Chan <[email protected]>
---
drivers/platform/x86/panasonic-laptop.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index c77292588a8a..3b0294ee9d3e 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -13,6 +13,7 @@
*
* ChangeLog:
* Aug.18, 2020 Kenneth Chan <[email protected]>
+ * add write support to mute
* fix sticky_key init bug
* fix naming of platform files for consistency with other
* modules
@@ -220,6 +221,7 @@ struct pcc_acpi {
acpi_handle handle;
unsigned long num_sifr;
int sticky_key;
+ int mute;
u32 *sinf;
struct acpi_device *device;
struct input_dev *input_dev;
@@ -483,6 +485,24 @@ static ssize_t mute_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]);
}

+static ssize_t mute_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pcc_acpi *pcc = acpi_driver_data(acpi);
+ int err, val;
+
+ err = kstrtoint(buf, 0, &val);
+ if (err)
+ return err;
+ if (val == 0 || val == 1) {
+ acpi_pcc_write_sset(pcc, SINF_MUTE, val);
+ pcc->mute = val;
+ }
+
+ return count;
+}
+
static ssize_t sticky_key_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -533,7 +553,7 @@ static ssize_t cdpower_store(struct device *dev, struct device_attribute *attr,

static DEVICE_ATTR_RO(numbatt);
static DEVICE_ATTR_RO(lcdtype);
-static DEVICE_ATTR_RO(mute);
+static DEVICE_ATTR_RW(mute);
static DEVICE_ATTR_RW(sticky_key);
static DEVICE_ATTR_RW(cdpower);

@@ -690,6 +710,7 @@ static int acpi_pcc_hotkey_resume(struct device *dev)
if (!pcc)
return -EINVAL;

+ acpi_pcc_write_sset(pcc, SINF_MUTE, pcc->mute);
acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_key);

return 0;
@@ -760,6 +781,8 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, 0);
pcc->sticky_key = 0;

+ pcc->mute = pcc->sinf[SINF_MUTE];
+
/* add sysfs attributes */
result = sysfs_create_group(&device->dev.kobj, &pcc_attr_group);
if (result)
--
2.17.5

2020-08-22 07:54:54

by Harald Welte

[permalink] [raw]
Subject: Re: [PATCH 0/9] platform/x86: panasonic-laptop: add optical drive, brightness and battery charging threshold

Dear Keneth and Linux kernel developers,

as I have discontinued maintenance of the panasonic-laptop driver (and
recently sent a related MAINTAINERS update to that fact), I would like
to suggest Kenneth as the new maintainer for this driver.

Regards,
Harald
--
- Harald Welte <[email protected]> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)

2020-08-22 08:22:44

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 0/9] platform/x86: panasonic-laptop: add optical drive, brightness and battery charging threshold

On Sat, Aug 22, 2020 at 10:53 AM Harald Welte <[email protected]> wrote:
>
> Dear Keneth and Linux kernel developers,
>
> as I have discontinued maintenance of the panasonic-laptop driver (and
> recently sent a related MAINTAINERS update to that fact), I would like
> to suggest Kenneth as the new maintainer for this driver.

Kenneth may send a corresponding MAINTAINERS update which you may Acknowledge.


--
With Best Regards,
Andy Shevchenko

2022-06-12 16:21:05

by Stefan Seyfried

[permalink] [raw]
Subject: [PATCH 0/2] fix panasonic-laptop hotkey regression

Hi Kenneth,

commit ed83c9171829 broke the hotkeys on my Toughbook CF-51, this adds a
module option to make them work again.
The first patch in the series is a small cleanup to allow the actual fix
to be much more obvious.

drivers/platform/x86/panasonic-laptop.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)