svn commit: r357402 - stable/12/sys/dev/acpi_support

Philip Paeps philip at FreeBSD.org
Sun Feb 2 08:46:30 UTC 2020


Author: philip
Date: Sun Feb  2 08:46:29 2020
New Revision: 357402
URL: https://svnweb.freebsd.org/changeset/base/357402

Log:
  MFC r357292:
  
    acpi_ibm: add support for ThinkPad PrivacyGuard
  
    ThinkPad PrivacyGuard is a built-in toggleable privacy filter that
    restricts viewing angles when on. It is an available on some new
    ThinkPad models such as the X1 Carbon 7th gen (as an optional HW
    upgrade).
  
    The privacy filter can be enabled/disabled via an ACPI call. This commit
    adds a sysctl under dev.acpi_ibm that allows for getting and setting the
    PrivacyGuard state.
  
  Submitted by:   Kamila Součková <kamila at ksp.sk>
  Reviewed By:    cem, philip
  Differential Revision: https://reviews.freebsd.org/D23370
  
  _M   .
  M    sys/dev/acpi_support/acpi_ibm.c

Modified:
  stable/12/sys/dev/acpi_support/acpi_ibm.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/acpi_support/acpi_ibm.c
==============================================================================
--- stable/12/sys/dev/acpi_support/acpi_ibm.c	Sun Feb  2 08:27:26 2020	(r357401)
+++ stable/12/sys/dev/acpi_support/acpi_ibm.c	Sun Feb  2 08:46:29 2020	(r357402)
@@ -75,6 +75,7 @@ ACPI_MODULE_NAME("IBM")
 #define ACPI_IBM_METHOD_THERMAL		13
 #define ACPI_IBM_METHOD_HANDLEREVENTS	14
 #define ACPI_IBM_METHOD_MIC_LED		15
+#define ACPI_IBM_METHOD_PRIVACYGUARD	16
 
 /* Hotkeys/Buttons */
 #define IBM_RTC_HOTKEY1			0x64
@@ -123,6 +124,8 @@ ACPI_MODULE_NAME("IBM")
 #define   IBM_NAME_MASK_WLAN		(1 << 2)
 #define IBM_NAME_THERMAL_GET		"TMP7"
 #define IBM_NAME_THERMAL_UPDT		"UPDT"
+#define IBM_NAME_PRIVACYGUARD_GET	"GSSS"
+#define IBM_NAME_PRIVACYGUARD_SET	"SSSS"
 
 #define IBM_NAME_EVENTS_STATUS_GET	"DHKC"
 #define IBM_NAME_EVENTS_MASK_GET	"DHKN"
@@ -146,6 +149,10 @@ ACPI_MODULE_NAME("IBM")
 #define IBM_EVENT_MUTE			0x17
 #define IBM_EVENT_ACCESS_IBM_BUTTON	0x18
 
+/* Device-specific register flags */
+#define IBM_FLAG_PRIVACYGUARD_DEVICE_PRESENT	0x10000
+#define IBM_FLAG_PRIVACYGUARD_ON	0x1
+
 #define ABS(x) (((x) < 0)? -(x) : (x))
 
 struct acpi_ibm_softc {
@@ -268,6 +275,11 @@ static struct {
 		.method		= ACPI_IBM_METHOD_MIC_LED,
 		.description	= "Mic led",
 	},
+	{
+	 .name		= "privacyguard",
+	 .method	= ACPI_IBM_METHOD_PRIVACYGUARD,
+	 .description	= "PrivacyGuard enable",
+	},
 	{ NULL, 0, NULL, 0 }
 };
 
@@ -327,7 +339,12 @@ static int	acpi_ibm_bluetooth_set(struct acpi_ibm_soft
 static int	acpi_ibm_thinklight_set(struct acpi_ibm_softc *sc, int arg);
 static int	acpi_ibm_volume_set(struct acpi_ibm_softc *sc, int arg);
 static int	acpi_ibm_mute_set(struct acpi_ibm_softc *sc, int arg);
+static int	acpi_ibm_privacyguard_get(struct acpi_ibm_softc *sc);
+static ACPI_STATUS	acpi_ibm_privacyguard_set(struct acpi_ibm_softc *sc, int arg);
+static ACPI_STATUS	acpi_ibm_privacyguard_acpi_call(struct acpi_ibm_softc *sc, bool write, int *arg);
 
+static int	acpi_status_to_errno(ACPI_STATUS status);
+
 static device_method_t acpi_ibm_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe, acpi_ibm_probe),
@@ -351,6 +368,19 @@ DRIVER_MODULE(acpi_ibm, acpi, acpi_ibm_driver, acpi_ib
 MODULE_DEPEND(acpi_ibm, acpi, 1, 1, 1);
 static char    *ibm_ids[] = {"IBM0068", "LEN0068", "LEN0268", NULL};
 
+static int
+acpi_status_to_errno(ACPI_STATUS status)
+{
+	switch (status) {
+	case AE_OK:
+		return (0);
+	case AE_BAD_PARAMETER:
+		return (EINVAL);
+	default:
+		return (ENODEV);
+	}
+}
+
 static void
 ibm_led(void *softc, int onoff)
 {
@@ -818,6 +848,11 @@ acpi_ibm_sysctl_get(struct acpi_ibm_softc *sc, int met
 		else
 			val = -1;
 		break;
+
+	case ACPI_IBM_METHOD_PRIVACYGUARD:
+		val = acpi_ibm_privacyguard_get(sc);
+		break;
+
 	}
 
 	return (val);
@@ -874,6 +909,10 @@ acpi_ibm_sysctl_set(struct acpi_ibm_softc *sc, int met
 		return acpi_ibm_bluetooth_set(sc, arg);
 		break;
 
+	case ACPI_IBM_METHOD_PRIVACYGUARD:
+		return (acpi_status_to_errno(acpi_ibm_privacyguard_set(sc, arg)));
+		break;
+
 	case ACPI_IBM_METHOD_FANLEVEL:
 		if (arg < 0 || arg > 7)
 			return (EINVAL);
@@ -1005,6 +1044,10 @@ acpi_ibm_sysctl_init(struct acpi_ibm_softc *sc, int me
 
 	case ACPI_IBM_METHOD_HANDLEREVENTS:
 		return (TRUE);
+
+	case ACPI_IBM_METHOD_PRIVACYGUARD:
+		return (acpi_ibm_privacyguard_get(sc) != -1);
+
 	}
 	return (FALSE);
 }
@@ -1220,6 +1263,60 @@ acpi_ibm_thinklight_set(struct acpi_ibm_softc *sc, int
 	}
 
 	return (0);
+}
+
+/*
+ * Helper function to make a get or set ACPI call to the PrivacyGuard handle.
+ * Only meant to be used internally by the get/set functions below.
+ */
+static ACPI_STATUS
+acpi_ibm_privacyguard_acpi_call(struct acpi_ibm_softc *sc, bool write, int *arg) {
+	ACPI_OBJECT		Arg;
+	ACPI_OBJECT_LIST	Args;
+	ACPI_STATUS		status;
+	ACPI_OBJECT		out_obj;
+	ACPI_BUFFER		result;
+
+	Arg.Type = ACPI_TYPE_INTEGER;
+	Arg.Integer.Value = (write ? *arg : 0);
+	Args.Count = 1;
+	Args.Pointer = &Arg;
+	result.Length = sizeof(out_obj);
+	result.Pointer = &out_obj;
+
+	status = AcpiEvaluateObject(sc->handle,
+	    (write ? IBM_NAME_PRIVACYGUARD_SET : IBM_NAME_PRIVACYGUARD_GET),
+	    &Args, &result);
+	if (ACPI_SUCCESS(status) && !write)
+		*arg = out_obj.Integer.Value;
+
+	return (status);
+}
+
+/*
+ * Returns -1 if the device is not present.
+ */
+static int
+acpi_ibm_privacyguard_get(struct acpi_ibm_softc *sc)
+{
+	ACPI_STATUS status;
+	int val;
+
+	status = acpi_ibm_privacyguard_acpi_call(sc, false, &val);
+	if (ACPI_SUCCESS(status) &&
+	    (val & IBM_FLAG_PRIVACYGUARD_DEVICE_PRESENT))
+		return (val & IBM_FLAG_PRIVACYGUARD_ON);
+
+	return (-1);
+}
+
+static ACPI_STATUS
+acpi_ibm_privacyguard_set(struct acpi_ibm_softc *sc, int arg)
+{
+	if (arg < 0 || arg > 1)
+		return (AE_BAD_PARAMETER);
+
+	return (acpi_ibm_privacyguard_acpi_call(sc, true, &arg));
 }
 
 static int


More information about the svn-src-all mailing list