Skip to content

Commit 5306747

Browse files
gwendalcrEnric Balletbo i Serra
authored andcommitted
iio / platform: cros_ec: Add cros-ec-sensorhub driver
Similar to HID sensor stack, the new driver sits between cros-ec-dev and the IIO device drivers: The EC based IIO device topology would be: iio:device1 -> ...0/0000:00:1f.0/PNP0C09:00/GOOG0004:00/cros-ec-dev.6.auto/ cros-ec-sensorhub.7.auto/ cros-ec-accel.15.auto/ iio:device1 It will be expanded to control EC sensor FIFO. Signed-off-by: Gwendal Grignou <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> [Fix "unknown type name 'uint32_t'" type errors] Reported-by: kbuild test robot <[email protected]> Signed-off-by: Enric Balletbo i Serra <[email protected]>
1 parent a16b2e2 commit 5306747

File tree

5 files changed

+235
-1
lines changed

5 files changed

+235
-1
lines changed

drivers/iio/common/cros_ec_sensors/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
config IIO_CROS_EC_SENSORS_CORE
66
tristate "ChromeOS EC Sensors Core"
7-
depends on SYSFS && CROS_EC
7+
depends on SYSFS && CROS_EC_SENSORHUB
88
select IIO_BUFFER
99
select IIO_TRIGGERED_BUFFER
1010
help

drivers/platform/chrome/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ config CROS_EC_DEBUGFS
190190
To compile this driver as a module, choose M here: the
191191
module will be called cros_ec_debugfs.
192192

193+
config CROS_EC_SENSORHUB
194+
tristate "ChromeOS EC MEMS Sensor Hub"
195+
depends on CROS_EC
196+
help
197+
Allow loading IIO sensors. This driver is loaded by MFD and will in
198+
turn query the EC and register the sensors.
199+
It also spreads the sensor data coming from the EC to the IIO sensor
200+
object.
201+
202+
To compile this driver as a module, choose M here: the
203+
module will be called cros_ec_sensorhub.
204+
193205
config CROS_EC_SYSFS
194206
tristate "ChromeOS EC control and information through sysfs"
195207
depends on MFD_CROS_EC_DEV && SYSFS

drivers/platform/chrome/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_chardev.o
1919
obj-$(CONFIG_CROS_EC_LIGHTBAR) += cros_ec_lightbar.o
2020
obj-$(CONFIG_CROS_EC_VBC) += cros_ec_vbc.o
2121
obj-$(CONFIG_CROS_EC_DEBUGFS) += cros_ec_debugfs.o
22+
obj-$(CONFIG_CROS_EC_SENSORHUB) += cros_ec_sensorhub.o
2223
obj-$(CONFIG_CROS_EC_SYSFS) += cros_ec_sysfs.o
2324
obj-$(CONFIG_CROS_USBPD_LOGGER) += cros_usbpd_logger.o
2425

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Sensor HUB driver that discovers sensors behind a ChromeOS Embedded
4+
* Controller.
5+
*
6+
* Copyright 2019 Google LLC
7+
*/
8+
9+
#include <linux/init.h>
10+
#include <linux/device.h>
11+
#include <linux/module.h>
12+
#include <linux/mfd/cros_ec.h>
13+
#include <linux/platform_data/cros_ec_commands.h>
14+
#include <linux/platform_data/cros_ec_proto.h>
15+
#include <linux/platform_data/cros_ec_sensorhub.h>
16+
#include <linux/platform_device.h>
17+
#include <linux/slab.h>
18+
#include <linux/types.h>
19+
20+
#define DRV_NAME "cros-ec-sensorhub"
21+
22+
static void cros_ec_sensorhub_free_sensor(void *arg)
23+
{
24+
struct platform_device *pdev = arg;
25+
26+
platform_device_unregister(pdev);
27+
}
28+
29+
static int cros_ec_sensorhub_allocate_sensor(struct device *parent,
30+
char *sensor_name,
31+
int sensor_num)
32+
{
33+
struct cros_ec_sensor_platform sensor_platforms = {
34+
.sensor_num = sensor_num,
35+
};
36+
struct platform_device *pdev;
37+
38+
pdev = platform_device_register_data(parent, sensor_name,
39+
PLATFORM_DEVID_AUTO,
40+
&sensor_platforms,
41+
sizeof(sensor_platforms));
42+
if (IS_ERR(pdev))
43+
return PTR_ERR(pdev);
44+
45+
return devm_add_action_or_reset(parent,
46+
cros_ec_sensorhub_free_sensor,
47+
pdev);
48+
}
49+
50+
static int cros_ec_sensorhub_register(struct device *dev,
51+
struct cros_ec_sensorhub *sensorhub)
52+
{
53+
int sensor_type[MOTIONSENSE_TYPE_MAX] = { 0 };
54+
struct cros_ec_dev *ec = sensorhub->ec;
55+
struct ec_params_motion_sense *params;
56+
struct ec_response_motion_sense *resp;
57+
struct cros_ec_command *msg;
58+
int ret, i, sensor_num;
59+
char *name;
60+
61+
sensor_num = cros_ec_get_sensor_count(ec);
62+
if (sensor_num < 0) {
63+
dev_err(dev,
64+
"Unable to retrieve sensor information (err:%d)\n",
65+
sensor_num);
66+
return sensor_num;
67+
}
68+
69+
if (sensor_num == 0) {
70+
dev_err(dev, "Zero sensors reported.\n");
71+
return -EINVAL;
72+
}
73+
74+
/* Prepare a message to send INFO command to each sensor. */
75+
msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*resp)),
76+
GFP_KERNEL);
77+
if (!msg)
78+
return -ENOMEM;
79+
80+
msg->version = 1;
81+
msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
82+
msg->outsize = sizeof(*params);
83+
msg->insize = sizeof(*resp);
84+
params = (struct ec_params_motion_sense *)msg->data;
85+
resp = (struct ec_response_motion_sense *)msg->data;
86+
87+
for (i = 0; i < sensor_num; i++) {
88+
params->cmd = MOTIONSENSE_CMD_INFO;
89+
params->info.sensor_num = i;
90+
91+
ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
92+
if (ret < 0) {
93+
dev_warn(dev, "no info for EC sensor %d : %d/%d\n",
94+
i, ret, msg->result);
95+
continue;
96+
}
97+
98+
switch (resp->info.type) {
99+
case MOTIONSENSE_TYPE_ACCEL:
100+
name = "cros-ec-accel";
101+
break;
102+
case MOTIONSENSE_TYPE_BARO:
103+
name = "cros-ec-baro";
104+
break;
105+
case MOTIONSENSE_TYPE_GYRO:
106+
name = "cros-ec-gyro";
107+
break;
108+
case MOTIONSENSE_TYPE_MAG:
109+
name = "cros-ec-mag";
110+
break;
111+
case MOTIONSENSE_TYPE_PROX:
112+
name = "cros-ec-prox";
113+
break;
114+
case MOTIONSENSE_TYPE_LIGHT:
115+
name = "cros-ec-light";
116+
break;
117+
case MOTIONSENSE_TYPE_ACTIVITY:
118+
name = "cros-ec-activity";
119+
break;
120+
default:
121+
dev_warn(dev, "unknown type %d\n", resp->info.type);
122+
continue;
123+
}
124+
125+
ret = cros_ec_sensorhub_allocate_sensor(dev, name, i);
126+
if (ret)
127+
goto error;
128+
129+
sensor_type[resp->info.type]++;
130+
}
131+
132+
if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2)
133+
ec->has_kb_wake_angle = true;
134+
135+
if (cros_ec_check_features(ec,
136+
EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS)) {
137+
ret = cros_ec_sensorhub_allocate_sensor(dev,
138+
"cros-ec-lid-angle",
139+
0);
140+
if (ret)
141+
goto error;
142+
}
143+
144+
kfree(msg);
145+
return 0;
146+
147+
error:
148+
kfree(msg);
149+
return ret;
150+
}
151+
152+
static int cros_ec_sensorhub_probe(struct platform_device *pdev)
153+
{
154+
struct device *dev = &pdev->dev;
155+
struct cros_ec_sensorhub *data;
156+
int ret;
157+
int i;
158+
159+
data = devm_kzalloc(dev, sizeof(struct cros_ec_sensorhub), GFP_KERNEL);
160+
if (!data)
161+
return -ENOMEM;
162+
163+
data->ec = dev_get_drvdata(dev->parent);
164+
dev_set_drvdata(dev, data);
165+
166+
/* Check whether this EC is a sensor hub. */
167+
if (cros_ec_check_features(data->ec, EC_FEATURE_MOTION_SENSE)) {
168+
ret = cros_ec_sensorhub_register(dev, data);
169+
if (ret)
170+
return ret;
171+
} else {
172+
/*
173+
* If the device has sensors but does not claim to
174+
* be a sensor hub, we are in legacy mode.
175+
*/
176+
for (i = 0; i < 2; i++) {
177+
ret = cros_ec_sensorhub_allocate_sensor(dev,
178+
"cros-ec-accel-legacy", i);
179+
if (ret)
180+
return ret;
181+
}
182+
}
183+
184+
return 0;
185+
}
186+
187+
static struct platform_driver cros_ec_sensorhub_driver = {
188+
.driver = {
189+
.name = DRV_NAME,
190+
},
191+
.probe = cros_ec_sensorhub_probe,
192+
};
193+
194+
module_platform_driver(cros_ec_sensorhub_driver);
195+
196+
MODULE_ALIAS("platform:" DRV_NAME);
197+
MODULE_AUTHOR("Gwendal Grignou <[email protected]>");
198+
MODULE_DESCRIPTION("ChromeOS EC MEMS Sensor Hub Driver");
199+
MODULE_LICENSE("GPL");
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Chrome OS EC MEMS Sensor Hub driver.
4+
*
5+
* Copyright 2019 Google LLC
6+
*/
7+
8+
#ifndef __LINUX_PLATFORM_DATA_CROS_EC_SENSORHUB_H
9+
#define __LINUX_PLATFORM_DATA_CROS_EC_SENSORHUB_H
10+
11+
#include <linux/platform_data/cros_ec_commands.h>
12+
13+
/**
14+
* struct cros_ec_sensorhub - Sensor Hub device data.
15+
*
16+
* @ec: Embedded Controller where the hub is located.
17+
*/
18+
struct cros_ec_sensorhub {
19+
struct cros_ec_dev *ec;
20+
};
21+
22+
#endif /* __LINUX_PLATFORM_DATA_CROS_EC_SENSORHUB_H */

0 commit comments

Comments
 (0)