Message ID | 20190822114833.29885-1-alex@alexanderweb.de (mailing list archive) |
---|---|
State | Accepted, archived |
Delegated to: | Andy Shevchenko |
Headers | show |
Series | platform/x86: Add Lenovo ThinkPad PrivacyGuard. | expand |
On Thu, Aug 22, 2019 at 2:48 PM Alexander Schremmer <alex@alexanderweb.de> wrote: > > This feature is found optionally in T480s, T490, T490s. > > The feature is called lcdshadow and visible via > /proc/acpi/ibm/lcdshadow. > > The ACPI methods \_SB.PCI0.LPCB.EC.HKEY.{GSSS,SSSS,TSSS,CSSS} are > available in these machines. They get, set, toggle or change the state > apparently. > > The patch was tested on a 5.0 series kernel on a T480s. > Pushed to my review and testing queue, thanks! > Signed-off-by: Alexander Schremmer <alex@alexanderweb.de> > --- > .../admin-guide/laptops/thinkpad-acpi.rst | 23 ++++ > drivers/platform/x86/thinkpad_acpi.c | 112 ++++++++++++++++++ > 2 files changed, 135 insertions(+) > > diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst > index adea0bf2acc5..822907dcc845 100644 > --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst > +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst > @@ -49,6 +49,7 @@ detailed description): > - Fan control and monitoring: fan speed, fan enable/disable > - WAN enable and disable > - UWB enable and disable > + - LCD Shadow (PrivacyGuard) enable and disable > > A compatibility table by model and feature is maintained on the web > site, http://ibm-acpi.sf.net/. I appreciate any success or failure > @@ -1409,6 +1410,28 @@ Sysfs notes > Documentation/driver-api/rfkill.rst for details. > > > +LCD Shadow control > +------------------ > + > +procfs: /proc/acpi/ibm/lcdshadow > + > +Some newer T480s and T490s ThinkPads provide a feature called > +PrivacyGuard. By turning this feature on, the usable vertical and > +horizontal viewing angles of the LCD can be limited (as if some privacy > +screen was applied manually in front of the display). > + > +procfs notes > +^^^^^^^^^^^^ > + > +The available commands are:: > + > + echo '0' >/proc/acpi/ibm/lcdshadow > + echo '1' >/proc/acpi/ibm/lcdshadow > + > +The first command ensures the best viewing angle and the latter one turns > +on the feature, restricting the viewing angles. > + > + > EXPERIMENTAL: UWB > ----------------- > > diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c > index 7bde4640ef34..12bf573c6568 100644 > --- a/drivers/platform/x86/thinkpad_acpi.c > +++ b/drivers/platform/x86/thinkpad_acpi.c > @@ -9714,6 +9714,114 @@ static struct ibm_struct battery_driver_data = { > .exit = tpacpi_battery_exit, > }; > > +/************************************************************************* > + * LCD Shadow subdriver, for the Lenovo PrivacyGuard feature > + */ > + > + > +static int lcdshadow_state; > + > +static int lcdshadow_on_off(bool state) > +{ > + acpi_handle set_shadow_handle; > + int output; > + > + if (ACPI_FAILURE(acpi_get_handle( > + hkey_handle, > + "SSSS", > + &set_shadow_handle))) { > + pr_warn("Thinkpad ACPI has no %s interface.\n", "SSSS"); > + return -EIO; > + } > + > + if (!acpi_evalf(set_shadow_handle, &output, NULL, "dd", (int)state)) > + return -EIO; > + > + lcdshadow_state = state; > + return 0; > +} > + > +static int lcdshadow_set(bool on) > +{ > + if (lcdshadow_state < 0) > + return lcdshadow_state; > + if (lcdshadow_state == on) > + return 0; > + return lcdshadow_on_off(on); > +} > + > +static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm) > +{ > + acpi_handle get_shadow_handle; > + int output; > + > + if (ACPI_FAILURE(acpi_get_handle( > + hkey_handle, > + "GSSS", > + &get_shadow_handle))) { > + lcdshadow_state = -ENODEV; > + return 0; > + } > + > + if (!acpi_evalf(get_shadow_handle, &output, NULL, "dd", 0)) { > + lcdshadow_state = -EIO; > + return -EIO; > + } > + if (!(output & 0x10000)) { > + lcdshadow_state = -ENODEV; > + return 0; > + } > + lcdshadow_state = output & 0x1; > + > + return 0; > +} > + > +static void lcdshadow_resume(void) > +{ > + if (lcdshadow_state >= 0) > + lcdshadow_on_off(lcdshadow_state); > +} > + > +static int lcdshadow_read(struct seq_file *m) > +{ > + if (lcdshadow_state < 0) { > + seq_puts(m, "status:\t\tnot supported\n"); > + } else { > + seq_printf(m, "status:\t\t%d\n", lcdshadow_state); > + seq_puts(m, "commands:\t0, 1\n"); > + } > + > + return 0; > +} > + > +static int lcdshadow_write(char *buf) > +{ > + char *cmd; > + int state = -1; > + > + if (lcdshadow_state < 0) > + return -ENODEV; > + > + while ((cmd = next_cmd(&buf))) { > + if (strlencmp(cmd, "0") == 0) > + state = 0; > + else if (strlencmp(cmd, "1") == 0) > + state = 1; > + } > + > + if (state == -1) > + return -EINVAL; > + > + return lcdshadow_set(state); > +} > + > +static struct ibm_struct lcdshadow_driver_data = { > + .name = "lcdshadow", > + .resume = lcdshadow_resume, > + .read = lcdshadow_read, > + .write = lcdshadow_write, > +}; > + > /**************************************************************************** > **************************************************************************** > * > @@ -10195,6 +10303,10 @@ static struct ibm_init_struct ibms_init[] __initdata = { > .init = tpacpi_battery_init, > .data = &battery_driver_data, > }, > + { > + .init = tpacpi_lcdshadow_init, > + .data = &lcdshadow_driver_data, > + }, > }; > > static int __init set_ibm_param(const char *val, const struct kernel_param *kp) > -- > 2.20.1 > -- With Best Regards, Andy Shevchenko
On Thursday 22 August 2019 13:48:33 Alexander Schremmer wrote: > This feature is found optionally in T480s, T490, T490s. > > The feature is called lcdshadow and visible via > /proc/acpi/ibm/lcdshadow. > > The ACPI methods \_SB.PCI0.LPCB.EC.HKEY.{GSSS,SSSS,TSSS,CSSS} are > available in these machines. They get, set, toggle or change the state > apparently. > > The patch was tested on a 5.0 series kernel on a T480s. > > Signed-off-by: Alexander Schremmer <alex@alexanderweb.de> > --- > .../admin-guide/laptops/thinkpad-acpi.rst | 23 ++++ > drivers/platform/x86/thinkpad_acpi.c | 112 ++++++++++++++++++ > 2 files changed, 135 insertions(+) > > diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst > index adea0bf2acc5..822907dcc845 100644 > --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst > +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst > @@ -49,6 +49,7 @@ detailed description): > - Fan control and monitoring: fan speed, fan enable/disable > - WAN enable and disable > - UWB enable and disable > + - LCD Shadow (PrivacyGuard) enable and disable > > A compatibility table by model and feature is maintained on the web > site, http://ibm-acpi.sf.net/. I appreciate any success or failure > @@ -1409,6 +1410,28 @@ Sysfs notes > Documentation/driver-api/rfkill.rst for details. > > > +LCD Shadow control > +------------------ > + > +procfs: /proc/acpi/ibm/lcdshadow > + > +Some newer T480s and T490s ThinkPads provide a feature called > +PrivacyGuard. By turning this feature on, the usable vertical and > +horizontal viewing angles of the LCD can be limited (as if some privacy > +screen was applied manually in front of the display). > + > +procfs notes > +^^^^^^^^^^^^ > + > +The available commands are:: > + > + echo '0' >/proc/acpi/ibm/lcdshadow > + echo '1' >/proc/acpi/ibm/lcdshadow > + > +The first command ensures the best viewing angle and the latter one turns > +on the feature, restricting the viewing angles. > + > + > EXPERIMENTAL: UWB > ----------------- Hello! Is not the whole /proc/apci/ibm API for new things obsoleted or deprecated? And should not rather it use platform driver in /sys/ (class?) namespace?
On Fri, Oct 25, 2019 at 2:33 PM Pali Rohár <pali.rohar@gmail.com> wrote: > On Thursday 22 August 2019 13:48:33 Alexander Schremmer wrote: > > This feature is found optionally in T480s, T490, T490s. > > > > The feature is called lcdshadow and visible via > > /proc/acpi/ibm/lcdshadow. > > > > The ACPI methods \_SB.PCI0.LPCB.EC.HKEY.{GSSS,SSSS,TSSS,CSSS} are > > available in these machines. They get, set, toggle or change the state > > apparently. > > > > The patch was tested on a 5.0 series kernel on a T480s. > > + echo '0' >/proc/acpi/ibm/lcdshadow > > + echo '1' >/proc/acpi/ibm/lcdshadow > Hello! Is not the whole /proc/apci/ibm API for new things obsoleted or deprecated? > And should not rather it use platform driver in /sys/ (class?) namespace? There is an ongoing discussion about API to this kind of devices somewhere in GPU mailing lists. This interface is custom and probably shall never have been appeared. However no-one prevented this from happening.
diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst index adea0bf2acc5..822907dcc845 100644 --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst @@ -49,6 +49,7 @@ detailed description): - Fan control and monitoring: fan speed, fan enable/disable - WAN enable and disable - UWB enable and disable + - LCD Shadow (PrivacyGuard) enable and disable A compatibility table by model and feature is maintained on the web site, http://ibm-acpi.sf.net/. I appreciate any success or failure @@ -1409,6 +1410,28 @@ Sysfs notes Documentation/driver-api/rfkill.rst for details. +LCD Shadow control +------------------ + +procfs: /proc/acpi/ibm/lcdshadow + +Some newer T480s and T490s ThinkPads provide a feature called +PrivacyGuard. By turning this feature on, the usable vertical and +horizontal viewing angles of the LCD can be limited (as if some privacy +screen was applied manually in front of the display). + +procfs notes +^^^^^^^^^^^^ + +The available commands are:: + + echo '0' >/proc/acpi/ibm/lcdshadow + echo '1' >/proc/acpi/ibm/lcdshadow + +The first command ensures the best viewing angle and the latter one turns +on the feature, restricting the viewing angles. + + EXPERIMENTAL: UWB ----------------- diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 7bde4640ef34..12bf573c6568 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9714,6 +9714,114 @@ static struct ibm_struct battery_driver_data = { .exit = tpacpi_battery_exit, }; +/************************************************************************* + * LCD Shadow subdriver, for the Lenovo PrivacyGuard feature + */ + + +static int lcdshadow_state; + +static int lcdshadow_on_off(bool state) +{ + acpi_handle set_shadow_handle; + int output; + + if (ACPI_FAILURE(acpi_get_handle( + hkey_handle, + "SSSS", + &set_shadow_handle))) { + pr_warn("Thinkpad ACPI has no %s interface.\n", "SSSS"); + return -EIO; + } + + if (!acpi_evalf(set_shadow_handle, &output, NULL, "dd", (int)state)) + return -EIO; + + lcdshadow_state = state; + return 0; +} + +static int lcdshadow_set(bool on) +{ + if (lcdshadow_state < 0) + return lcdshadow_state; + if (lcdshadow_state == on) + return 0; + return lcdshadow_on_off(on); +} + +static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm) +{ + acpi_handle get_shadow_handle; + int output; + + if (ACPI_FAILURE(acpi_get_handle( + hkey_handle, + "GSSS", + &get_shadow_handle))) { + lcdshadow_state = -ENODEV; + return 0; + } + + if (!acpi_evalf(get_shadow_handle, &output, NULL, "dd", 0)) { + lcdshadow_state = -EIO; + return -EIO; + } + if (!(output & 0x10000)) { + lcdshadow_state = -ENODEV; + return 0; + } + lcdshadow_state = output & 0x1; + + return 0; +} + +static void lcdshadow_resume(void) +{ + if (lcdshadow_state >= 0) + lcdshadow_on_off(lcdshadow_state); +} + +static int lcdshadow_read(struct seq_file *m) +{ + if (lcdshadow_state < 0) { + seq_puts(m, "status:\t\tnot supported\n"); + } else { + seq_printf(m, "status:\t\t%d\n", lcdshadow_state); + seq_puts(m, "commands:\t0, 1\n"); + } + + return 0; +} + +static int lcdshadow_write(char *buf) +{ + char *cmd; + int state = -1; + + if (lcdshadow_state < 0) + return -ENODEV; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "0") == 0) + state = 0; + else if (strlencmp(cmd, "1") == 0) + state = 1; + } + + if (state == -1) + return -EINVAL; + + return lcdshadow_set(state); +} + +static struct ibm_struct lcdshadow_driver_data = { + .name = "lcdshadow", + .resume = lcdshadow_resume, + .read = lcdshadow_read, + .write = lcdshadow_write, +}; + /**************************************************************************** **************************************************************************** * @@ -10195,6 +10303,10 @@ static struct ibm_init_struct ibms_init[] __initdata = { .init = tpacpi_battery_init, .data = &battery_driver_data, }, + { + .init = tpacpi_lcdshadow_init, + .data = &lcdshadow_driver_data, + }, }; static int __init set_ibm_param(const char *val, const struct kernel_param *kp)
This feature is found optionally in T480s, T490, T490s. The feature is called lcdshadow and visible via /proc/acpi/ibm/lcdshadow. The ACPI methods \_SB.PCI0.LPCB.EC.HKEY.{GSSS,SSSS,TSSS,CSSS} are available in these machines. They get, set, toggle or change the state apparently. The patch was tested on a 5.0 series kernel on a T480s. Signed-off-by: Alexander Schremmer <alex@alexanderweb.de> --- .../admin-guide/laptops/thinkpad-acpi.rst | 23 ++++ drivers/platform/x86/thinkpad_acpi.c | 112 ++++++++++++++++++ 2 files changed, 135 insertions(+)