All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/1] Add a driver for the ChromeOS screen privacy sensor (HPS)
@ 2022-02-02  4:49 Sami Kyöstilä
  2022-02-02  4:49 ` [PATCH v2 1/1] drivers/misc: add a driver for HPS Sami Kyöstilä
  0 siblings, 1 reply; 4+ messages in thread
From: Sami Kyöstilä @ 2022-02-02  4:49 UTC (permalink / raw)
  To: LKML; +Cc: dtor, gregkh, arnd, evanbenn, Sami Kyöstilä


This series adds a driver for the ChromeOS screen privacy sensor
(a.k.a. HPS) device, attached on the I2C bus. The sensor is a
hardware-isolated module which reports a high-level presence signal,
e.g., whether there is person in front of the computer or not.

The driver exposes the device to userspace as a character device, which
can be used to control the power state of the device. The driver
automatically turns power off to the sensor unless a process is using
it.

More information about HPS, its firmware and communication protocol can
be found at
https://chromium.googlesource.com/chromiumos/platform/hps-firmware.

Changes in v2:
- Removed custom ioctl interface.
- Reworked to use miscdev.

Sami Kyöstilä (1):
  drivers/misc: add a driver for HPS

 MAINTAINERS            |   6 ++
 drivers/misc/Kconfig   |  10 +++
 drivers/misc/Makefile  |   1 +
 drivers/misc/hps-i2c.c | 184 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 201 insertions(+)
 create mode 100644 drivers/misc/hps-i2c.c

-- 
2.35.0.rc2.247.g8bbb082509-goog


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/1] drivers/misc: add a driver for HPS
  2022-02-02  4:49 [PATCH v2 0/1] Add a driver for the ChromeOS screen privacy sensor (HPS) Sami Kyöstilä
@ 2022-02-02  4:49 ` Sami Kyöstilä
  2022-02-04 15:27   ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Sami Kyöstilä @ 2022-02-02  4:49 UTC (permalink / raw)
  To: LKML; +Cc: dtor, gregkh, arnd, evanbenn, Sami Kyöstilä

This patch introduces a driver for the ChromeOS screen privacy
sensor (aka. HPS). The driver supports a sensor connected to the I2C bus
and identified as "GOOG0020" in the ACPI tables.

When loaded, the driver exports the sensor to userspace through a
character device. This device only supports power management, i.e.,
communication with the sensor must be done through regular I2C
transmissions from userspace.

Power management is implemented by enabling the respective power GPIO
while at least one userspace process holds an open fd on the character
device. By default, the device is powered down if there are no active
clients.

Note that the driver makes no effort to preserve the state of the sensor
between power down and power up events. Userspace is responsible for
reinitializing any needed state once power has been restored.

The device firmware, I2C protocol and other documentation is available
at https://chromium.googlesource.com/chromiumos/platform/hps-firmware.

Signed-off-by: Sami Kyöstilä <skyostil@chromium.org>
---

Changes in v2:
- Removed custom ioctl interface.
- Reworked to use miscdev.

 MAINTAINERS            |   6 ++
 drivers/misc/Kconfig   |  10 +++
 drivers/misc/Makefile  |   1 +
 drivers/misc/hps-i2c.c | 184 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 201 insertions(+)
 create mode 100644 drivers/misc/hps-i2c.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f41088418aae..6c164ed84f60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8801,6 +8801,12 @@ S:	Maintained
 W:	http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
 F:	fs/hpfs/
 
+HPS (ChromeOS snooping protection sensor) DRIVER
+M:	Sami Kyöstilä <skyostil@chromium.org>
+R:	Evan Benn <evanbenn@chromium.org>
+S:	Maintained
+F:	drivers/misc/hps-i2c.c
+
 HSI SUBSYSTEM
 M:	Sebastian Reichel <sre@kernel.org>
 S:	Maintained
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0f5a49fc7c9e..44fcf60a67aa 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -244,6 +244,16 @@ config HP_ILO
 	  To compile this driver as a module, choose M here: the
 	  module will be called hpilo.
 
+config HPS_I2C
+	tristate "ChromeOS HPS device"
+	depends on HID && I2C && PM
+	help
+	  Say Y here if you want to enable support for the ChromeOS
+	  anti-snooping sensor (HPS), attached via I2C. The driver supports a
+	  sensor connected to the I2C bus and exposes it as a character device.
+	  To save power, the sensor is automatically powered down when no
+	  clients are accessing it.
+
 config QCOM_COINCELL
 	tristate "Qualcomm coincell charger support"
 	depends on MFD_SPMI_PMIC || COMPILE_TEST
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a086197af544..162a7d530dab 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_CS5535_MFGPT)	+= cs5535-mfgpt.o
 obj-$(CONFIG_GEHC_ACHC)		+= gehc-achc.o
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
+obj-$(CONFIG_HPS_I2C)		+= hps-i2c.o
 obj-$(CONFIG_APDS9802ALS)	+= apds9802als.o
 obj-$(CONFIG_ISL29003)		+= isl29003.o
 obj-$(CONFIG_ISL29020)		+= isl29020.o
diff --git a/drivers/misc/hps-i2c.c b/drivers/misc/hps-i2c.c
new file mode 100644
index 000000000000..9071c9324fa7
--- /dev/null
+++ b/drivers/misc/hps-i2c.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the ChromeOS screen privacy sensor (HPS), attached via I2C.
+ *
+ * The driver exposes HPS as a character device, although currently no read or
+ * write operations are supported. Instead, the driver only controls the power
+ * state of the sensor, keeping it on only while userspace holds an open file
+ * descriptor to the HPS device.
+ *
+ * Copyright 2022 Google LLC.
+ */
+
+#include <linux/acpi.h>
+#include <linux/fs.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+
+#define HPS_ACPI_ID		"GOOG0020"
+
+struct hps_drvdata {
+	struct i2c_client *client;
+	struct miscdevice misc_device;
+	struct gpio_desc *enable_gpio;
+};
+
+static void hps_set_power(struct hps_drvdata *hps, bool state)
+{
+	if (!IS_ERR_OR_NULL(hps->enable_gpio))
+		gpiod_set_value_cansleep(hps->enable_gpio, state);
+}
+
+static void hps_unload(void *drv_data)
+{
+	struct hps_drvdata *hps = drv_data;
+
+	hps_set_power(hps, true);
+}
+
+static int hps_open(struct inode *inode, struct file *file)
+{
+	struct hps_drvdata *hps = container_of(file->private_data,
+					       struct hps_drvdata, misc_device);
+	struct device *dev = &hps->client->dev;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0)
+		goto pm_get_fail;
+	return 0;
+
+pm_get_fail:
+	pm_runtime_put(dev);
+	pm_runtime_disable(dev);
+	return ret;
+}
+
+static int hps_release(struct inode *inode, struct file *file)
+{
+	struct hps_drvdata *hps = container_of(file->private_data,
+					       struct hps_drvdata, misc_device);
+	struct device *dev = &hps->client->dev;
+	int ret;
+
+	ret = pm_runtime_put(dev);
+	if (ret < 0)
+		goto pm_put_fail;
+	return 0;
+
+pm_put_fail:
+	pm_runtime_disable(dev);
+	return ret;
+}
+
+const struct file_operations hps_fops = {
+	.owner = THIS_MODULE,
+	.open = hps_open,
+	.release = hps_release,
+};
+
+static int hps_i2c_probe(struct i2c_client *client)
+{
+	struct hps_drvdata *hps;
+	int ret = 0;
+
+	hps = devm_kzalloc(&client->dev, sizeof(*hps), GFP_KERNEL);
+	if (!hps)
+		return -ENOMEM;
+
+	memset(&hps->misc_device, 0, sizeof(hps->misc_device));
+	hps->misc_device.parent = &client->dev;
+	hps->misc_device.minor = MISC_DYNAMIC_MINOR;
+	hps->misc_device.name = "hps";
+	hps->misc_device.fops = &hps_fops;
+
+	i2c_set_clientdata(client, hps);
+	hps->client = client;
+	hps->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_HIGH);
+	if (IS_ERR(hps->enable_gpio)) {
+		ret = PTR_ERR(hps->enable_gpio);
+		dev_err(&client->dev, "failed to get enable gpio: %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_add_action(&client->dev, &hps_unload, hps);
+	if (ret) {
+		dev_err(&client->dev,
+			"failed to install unload action: %d\n", ret);
+		return ret;
+	}
+
+	ret = misc_register(&hps->misc_device);
+	if (ret) {
+		dev_err(&client->dev, "failed to initialize misc device: %d\n", ret);
+		return ret;
+	}
+
+	hps_set_power(hps, false);
+	pm_runtime_enable(&client->dev);
+	return ret;
+}
+
+static int hps_i2c_remove(struct i2c_client *client)
+{
+	struct hps_drvdata *hps = i2c_get_clientdata(client);
+
+	pm_runtime_disable(&client->dev);
+	misc_deregister(&hps->misc_device);
+	return 0;
+}
+
+static int hps_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct hps_drvdata *hps = i2c_get_clientdata(client);
+
+	hps_set_power(hps, false);
+	return 0;
+}
+
+static int hps_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct hps_drvdata *hps = i2c_get_clientdata(client);
+
+	hps_set_power(hps, true);
+	return 0;
+}
+static UNIVERSAL_DEV_PM_OPS(hps_pm_ops, hps_suspend, hps_resume, NULL);
+
+static const struct i2c_device_id hps_i2c_id[] = {
+	{ "hps", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, hps_i2c_id);
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id hps_acpi_id[] = {
+	{ HPS_ACPI_ID, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, hps_acpi_id);
+#endif /* CONFIG_ACPI */
+
+static struct i2c_driver hps_i2c_driver = {
+	.probe_new = hps_i2c_probe,
+	.remove = hps_i2c_remove,
+	.id_table = hps_i2c_id,
+	.driver = {
+		.name = "hps",
+		.pm = &hps_pm_ops,
+#ifdef CONFIG_ACPI
+		.acpi_match_table = ACPI_PTR(hps_acpi_id),
+#endif
+	},
+};
+module_i2c_driver(hps_i2c_driver);
+
+MODULE_ALIAS("acpi:" HPS_ACPI_ID);
+MODULE_AUTHOR("Sami Kyöstilä <skyostil@chromium.org>");
+MODULE_DESCRIPTION("Driver for ChromeOS HPS");
+MODULE_LICENSE("GPL");
-- 
2.35.0.rc2.247.g8bbb082509-goog


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/1] drivers/misc: add a driver for HPS
  2022-02-02  4:49 ` [PATCH v2 1/1] drivers/misc: add a driver for HPS Sami Kyöstilä
@ 2022-02-04 15:27   ` Greg KH
  2022-02-07  1:08     ` Sami Kyostila
  0 siblings, 1 reply; 4+ messages in thread
From: Greg KH @ 2022-02-04 15:27 UTC (permalink / raw)
  To: Sami Kyöstilä; +Cc: LKML, dtor, arnd, evanbenn

On Wed, Feb 02, 2022 at 03:49:37PM +1100, Sami Kyöstilä wrote:
> This patch introduces a driver for the ChromeOS screen privacy
> sensor (aka. HPS). The driver supports a sensor connected to the I2C bus
> and identified as "GOOG0020" in the ACPI tables.
> 
> When loaded, the driver exports the sensor to userspace through a
> character device. This device only supports power management, i.e.,
> communication with the sensor must be done through regular I2C
> transmissions from userspace.
> 
> Power management is implemented by enabling the respective power GPIO
> while at least one userspace process holds an open fd on the character
> device. By default, the device is powered down if there are no active
> clients.
> 
> Note that the driver makes no effort to preserve the state of the sensor
> between power down and power up events. Userspace is responsible for
> reinitializing any needed state once power has been restored.
> 
> The device firmware, I2C protocol and other documentation is available
> at https://chromium.googlesource.com/chromiumos/platform/hps-firmware.
> 
> Signed-off-by: Sami Kyöstilä <skyostil@chromium.org>
> ---
> 
> Changes in v2:
> - Removed custom ioctl interface.
> - Reworked to use miscdev.
> 
>  MAINTAINERS            |   6 ++
>  drivers/misc/Kconfig   |  10 +++
>  drivers/misc/Makefile  |   1 +
>  drivers/misc/hps-i2c.c | 184 +++++++++++++++++++++++++++++++++++++++++

Why isn't this in drivers/platform/chrome/ instead?

And what can you do with this hardware when it is enabled?  What
userspace tool uses it?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/1] drivers/misc: add a driver for HPS
  2022-02-04 15:27   ` Greg KH
@ 2022-02-07  1:08     ` Sami Kyostila
  0 siblings, 0 replies; 4+ messages in thread
From: Sami Kyostila @ 2022-02-07  1:08 UTC (permalink / raw)
  To: Greg KH; +Cc: LKML, dtor, arnd, evanbenn

la 5. helmik. 2022 klo 2.27 Greg KH (gregkh@linuxfoundation.org) kirjoitti:
>
> On Wed, Feb 02, 2022 at 03:49:37PM +1100, Sami Kyöstilä wrote:
> > This patch introduces a driver for the ChromeOS screen privacy
> > sensor (aka. HPS). The driver supports a sensor connected to the I2C bus
> > and identified as "GOOG0020" in the ACPI tables.
> >
> > When loaded, the driver exports the sensor to userspace through a
> > character device. This device only supports power management, i.e.,
> > communication with the sensor must be done through regular I2C
> > transmissions from userspace.
> >
> > Power management is implemented by enabling the respective power GPIO
> > while at least one userspace process holds an open fd on the character
> > device. By default, the device is powered down if there are no active
> > clients.
> >
> > Note that the driver makes no effort to preserve the state of the sensor
> > between power down and power up events. Userspace is responsible for
> > reinitializing any needed state once power has been restored.
> >
> > The device firmware, I2C protocol and other documentation is available
> > at https://chromium.googlesource.com/chromiumos/platform/hps-firmware.
> >
> > Signed-off-by: Sami Kyöstilä <skyostil@chromium.org>
> > ---
> >
> > Changes in v2:
> > - Removed custom ioctl interface.
> > - Reworked to use miscdev.
> >
> >  MAINTAINERS            |   6 ++
> >  drivers/misc/Kconfig   |  10 +++
> >  drivers/misc/Makefile  |   1 +
> >  drivers/misc/hps-i2c.c | 184 +++++++++++++++++++++++++++++++++++++++++
>
> Why isn't this in drivers/platform/chrome/ instead?

Only because I didn't realize that was a thing :) Will move it there instead.

> And what can you do with this hardware when it is enabled?  What
> userspace tool uses it?

The hardware is basically an isolated computer vision sensor that
computes a high level inference result (e.g., whether there is a
person in the image) while making sure the raw sensor data (e.g.,
camera images) aren't accessible to the host. It's driven by a
userspace daemon (hpsd) which exposes this functionality to other
ChromeOS components through dbus. There are also some more
developer-oriented userspace tools for updating firmware, reading
debug registers, etc.

Source code for the userspace tools is available at
https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/hps, and
the sensor firmware is at
https://chromium.googlesource.com/chromiumos/platform/hps-firmware.

- Sami

>
> thanks,
>
> greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-02-07  1:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-02  4:49 [PATCH v2 0/1] Add a driver for the ChromeOS screen privacy sensor (HPS) Sami Kyöstilä
2022-02-02  4:49 ` [PATCH v2 1/1] drivers/misc: add a driver for HPS Sami Kyöstilä
2022-02-04 15:27   ` Greg KH
2022-02-07  1:08     ` Sami Kyostila

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.