aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2019-05-17 19:38:56 -0400
committerEnric Balletbo i Serra <enric.balletbo@collabora.com>2019-06-25 09:28:06 -0400
commit0451cc8ce272f50f9fb6569b0ecdedee6e997cea (patch)
tree8483062c366d07e9f955ffefda661ca361d27bd7
parent1d333ef3d599026897fb11b4f89f9f8f30838139 (diff)
iio: cros_ec: Add lid angle driver
Add a IIO driver that reports the angle between the lid and the base for ChromeOS convertible device. Tested on eve with ToT EC firmware. Check driver is loaded and lid angle is correct. Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
-rw-r--r--drivers/iio/common/cros_ec_sensors/Kconfig9
-rw-r--r--drivers/iio/common/cros_ec_sensors/Makefile1
-rw-r--r--drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c139
3 files changed, 149 insertions, 0 deletions
diff --git a/drivers/iio/common/cros_ec_sensors/Kconfig b/drivers/iio/common/cros_ec_sensors/Kconfig
index 135f6825903f..aacc2ab9c34f 100644
--- a/drivers/iio/common/cros_ec_sensors/Kconfig
+++ b/drivers/iio/common/cros_ec_sensors/Kconfig
@@ -20,3 +20,12 @@ config IIO_CROS_EC_SENSORS
20 Accelerometers, Gyroscope and Magnetometer that are 20 Accelerometers, Gyroscope and Magnetometer that are
21 presented by the ChromeOS EC Sensor hub. 21 presented by the ChromeOS EC Sensor hub.
22 Creates an IIO device for each functions. 22 Creates an IIO device for each functions.
23
24config IIO_CROS_EC_SENSORS_LID_ANGLE
25 tristate "ChromeOS EC Sensor for lid angle"
26 depends on IIO_CROS_EC_SENSORS_CORE
27 help
28 Module to report the angle between lid and base for some
29 convertible devices.
30 This module is loaded when the EC can calculate the angle between the base
31 and the lid.
diff --git a/drivers/iio/common/cros_ec_sensors/Makefile b/drivers/iio/common/cros_ec_sensors/Makefile
index ec716ff2a775..a35ee232ac07 100644
--- a/drivers/iio/common/cros_ec_sensors/Makefile
+++ b/drivers/iio/common/cros_ec_sensors/Makefile
@@ -4,3 +4,4 @@
4 4
5obj-$(CONFIG_IIO_CROS_EC_SENSORS_CORE) += cros_ec_sensors_core.o 5obj-$(CONFIG_IIO_CROS_EC_SENSORS_CORE) += cros_ec_sensors_core.o
6obj-$(CONFIG_IIO_CROS_EC_SENSORS) += cros_ec_sensors.o 6obj-$(CONFIG_IIO_CROS_EC_SENSORS) += cros_ec_sensors.o
7obj-$(CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE) += cros_ec_lid_angle.o
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
new file mode 100644
index 000000000000..876dfd176b0e
--- /dev/null
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
@@ -0,0 +1,139 @@
1// SPDX-License-Identifier: GPL-2.0
2
3/*
4 * cros_ec_lid_angle - Driver for CrOS EC lid angle sensor.
5 *
6 * Copyright 2018 Google, Inc
7 *
8 * This driver uses the cros-ec interface to communicate with the Chrome OS
9 * EC about counter sensors. Counters are presented through
10 * iio sysfs.
11 */
12
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/iio/buffer.h>
16#include <linux/iio/common/cros_ec_sensors_core.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/kfifo_buf.h>
19#include <linux/iio/trigger.h>
20#include <linux/iio/triggered_buffer.h>
21#include <linux/iio/trigger_consumer.h>
22#include <linux/kernel.h>
23#include <linux/mfd/cros_ec.h>
24#include <linux/mfd/cros_ec_commands.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28
29#define DRV_NAME "cros-ec-lid-angle"
30
31/*
32 * One channel for the lid angle, the other for timestamp.
33 */
34static const struct iio_chan_spec cros_ec_lid_angle_channels[] = {
35 {
36 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
37 .scan_type.realbits = CROS_EC_SENSOR_BITS,
38 .scan_type.storagebits = CROS_EC_SENSOR_BITS,
39 .scan_type.sign = 'u',
40 .type = IIO_ANGL
41 },
42 IIO_CHAN_SOFT_TIMESTAMP(1)
43};
44
45/* State data for ec_sensors iio driver. */
46struct cros_ec_lid_angle_state {
47 /* Shared by all sensors */
48 struct cros_ec_sensors_core_state core;
49};
50
51static int cros_ec_sensors_read_lid_angle(struct iio_dev *indio_dev,
52 unsigned long scan_mask, s16 *data)
53{
54 struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
55 int ret;
56
57 st->param.cmd = MOTIONSENSE_CMD_LID_ANGLE;
58 ret = cros_ec_motion_send_host_cmd(st, sizeof(st->resp->lid_angle));
59 if (ret) {
60 dev_warn(&indio_dev->dev, "Unable to read lid angle\n");
61 return ret;
62 }
63
64 *data = st->resp->lid_angle.value;
65 return 0;
66}
67
68static int cros_ec_lid_angle_read(struct iio_dev *indio_dev,
69 struct iio_chan_spec const *chan,
70 int *val, int *val2, long mask)
71{
72 struct cros_ec_lid_angle_state *st = iio_priv(indio_dev);
73 s16 data;
74 int ret;
75
76 mutex_lock(&st->core.cmd_lock);
77 ret = cros_ec_sensors_read_lid_angle(indio_dev, 1, &data);
78 if (ret == 0) {
79 *val = data;
80 ret = IIO_VAL_INT;
81 }
82 mutex_unlock(&st->core.cmd_lock);
83 return ret;
84}
85
86static const struct iio_info cros_ec_lid_angle_info = {
87 .read_raw = &cros_ec_lid_angle_read,
88};
89
90static int cros_ec_lid_angle_probe(struct platform_device *pdev)
91{
92 struct device *dev = &pdev->dev;
93 struct iio_dev *indio_dev;
94 struct cros_ec_lid_angle_state *state;
95 int ret;
96
97 indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
98 if (!indio_dev)
99 return -ENOMEM;
100
101 ret = cros_ec_sensors_core_init(pdev, indio_dev, false);
102 if (ret)
103 return ret;
104
105 indio_dev->info = &cros_ec_lid_angle_info;
106 state = iio_priv(indio_dev);
107 indio_dev->channels = cros_ec_lid_angle_channels;
108 indio_dev->num_channels = ARRAY_SIZE(cros_ec_lid_angle_channels);
109
110 state->core.read_ec_sensors_data = cros_ec_sensors_read_lid_angle;
111
112 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
113 cros_ec_sensors_capture, NULL);
114 if (ret)
115 return ret;
116
117 return devm_iio_device_register(dev, indio_dev);
118}
119
120static const struct platform_device_id cros_ec_lid_angle_ids[] = {
121 {
122 .name = DRV_NAME,
123 },
124 { /* sentinel */ }
125};
126MODULE_DEVICE_TABLE(platform, cros_ec_lid_angle_ids);
127
128static struct platform_driver cros_ec_lid_angle_platform_driver = {
129 .driver = {
130 .name = DRV_NAME,
131 .pm = &cros_ec_sensors_pm_ops,
132 },
133 .probe = cros_ec_lid_angle_probe,
134 .id_table = cros_ec_lid_angle_ids,
135};
136module_platform_driver(cros_ec_lid_angle_platform_driver);
137
138MODULE_DESCRIPTION("ChromeOS EC driver for reporting convertible lid angle.");
139MODULE_LICENSE("GPL v2");