2 * cros_ec_sensors - Driver for Chrome OS Embedded Controller sensors.
4 * Copyright (C) 2016 Google, Inc
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * This driver uses the cros-ec interface to communicate with the Chrome OS
16 * EC about sensors data. Data access is presented through iio sysfs.
19 #include <linux/delay.h>
20 #include <linux/device.h>
21 #include <linux/iio/buffer.h>
22 #include <linux/iio/iio.h>
23 #include <linux/iio/kfifo_buf.h>
24 #include <linux/iio/trigger_consumer.h>
25 #include <linux/iio/triggered_buffer.h>
26 #include <linux/kernel.h>
27 #include <linux/mfd/cros_ec.h>
28 #include <linux/mfd/cros_ec_commands.h>
29 #include <linux/module.h>
30 #include <linux/platform_device.h>
31 #include <linux/slab.h>
32 #include <linux/sysfs.h>
34 #include "cros_ec_sensors_core.h"
36 #define CROS_EC_SENSORS_MAX_CHANNELS 4
38 /* State data for ec_sensors iio driver. */
39 struct cros_ec_sensors_state
{
40 /* Shared by all sensors */
41 struct cros_ec_sensors_core_state core
;
43 struct iio_chan_spec channels
[CROS_EC_SENSORS_MAX_CHANNELS
];
46 static int cros_ec_sensors_read(struct iio_dev
*indio_dev
,
47 struct iio_chan_spec
const *chan
,
48 int *val
, int *val2
, long mask
)
50 struct cros_ec_sensors_state
*st
= iio_priv(indio_dev
);
55 int idx
= chan
->scan_index
;
57 mutex_lock(&st
->core
.cmd_lock
);
60 case IIO_CHAN_INFO_RAW
:
61 ret
= st
->core
.read_ec_sensors_data(indio_dev
, 1 << idx
, &data
);
67 case IIO_CHAN_INFO_CALIBBIAS
:
68 st
->core
.param
.cmd
= MOTIONSENSE_CMD_SENSOR_OFFSET
;
69 st
->core
.param
.sensor_offset
.flags
= 0;
71 ret
= cros_ec_motion_send_host_cmd(&st
->core
, 0);
76 for (i
= CROS_EC_SENSOR_X
; i
< CROS_EC_SENSOR_MAX_AXIS
; i
++)
78 st
->core
.resp
->sensor_offset
.offset
[i
];
80 *val
= st
->core
.calib
[idx
];
82 case IIO_CHAN_INFO_SCALE
:
83 st
->core
.param
.cmd
= MOTIONSENSE_CMD_SENSOR_RANGE
;
84 st
->core
.param
.sensor_range
.data
= EC_MOTION_SENSE_NO_VALUE
;
86 ret
= cros_ec_motion_send_host_cmd(&st
->core
, 0);
90 val64
= st
->core
.resp
->sensor_range
.ret
;
91 switch (st
->core
.type
) {
92 case MOTIONSENSE_TYPE_ACCEL
:
94 * EC returns data in g, iio exepects m/s^2.
95 * Do not use IIO_G_TO_M_S_2 to avoid precision loss.
97 *val
= div_s64(val64
* 980665, 10);
98 *val2
= 10000 << (CROS_EC_SENSOR_BITS
- 1);
99 ret
= IIO_VAL_FRACTIONAL
;
101 case MOTIONSENSE_TYPE_GYRO
:
103 * EC returns data in dps, iio expects rad/s.
104 * Do not use IIO_DEGREE_TO_RAD to avoid precision
105 * loss. Round to the nearest integer.
107 *val
= div_s64(val64
* 314159 + 9000000ULL, 1000);
108 *val2
= 18000 << (CROS_EC_SENSOR_BITS
- 1);
109 ret
= IIO_VAL_FRACTIONAL
;
111 case MOTIONSENSE_TYPE_MAG
:
113 * EC returns data in 16LSB / uT,
117 *val2
= 100 << (CROS_EC_SENSOR_BITS
- 1);
118 ret
= IIO_VAL_FRACTIONAL
;
125 ret
= cros_ec_sensors_core_read(&st
->core
, chan
, val
, val2
,
129 mutex_unlock(&st
->core
.cmd_lock
);
134 static int cros_ec_sensors_write(struct iio_dev
*indio_dev
,
135 struct iio_chan_spec
const *chan
,
136 int val
, int val2
, long mask
)
138 struct cros_ec_sensors_state
*st
= iio_priv(indio_dev
);
141 int idx
= chan
->scan_index
;
143 mutex_lock(&st
->core
.cmd_lock
);
146 case IIO_CHAN_INFO_CALIBBIAS
:
147 st
->core
.calib
[idx
] = val
;
149 /* Send to EC for each axis, even if not complete */
150 st
->core
.param
.cmd
= MOTIONSENSE_CMD_SENSOR_OFFSET
;
151 st
->core
.param
.sensor_offset
.flags
=
152 MOTION_SENSE_SET_OFFSET
;
153 for (i
= CROS_EC_SENSOR_X
; i
< CROS_EC_SENSOR_MAX_AXIS
; i
++)
154 st
->core
.param
.sensor_offset
.offset
[i
] =
156 st
->core
.param
.sensor_offset
.temp
=
157 EC_MOTION_SENSE_INVALID_CALIB_TEMP
;
159 ret
= cros_ec_motion_send_host_cmd(&st
->core
, 0);
161 case IIO_CHAN_INFO_SCALE
:
162 if (st
->core
.type
== MOTIONSENSE_TYPE_MAG
) {
166 st
->core
.param
.cmd
= MOTIONSENSE_CMD_SENSOR_RANGE
;
167 st
->core
.param
.sensor_range
.data
= val
;
169 /* Always roundup, so caller gets at least what it asks for. */
170 st
->core
.param
.sensor_range
.roundup
= 1;
172 ret
= cros_ec_motion_send_host_cmd(&st
->core
, 0);
175 ret
= cros_ec_sensors_core_write(
176 &st
->core
, chan
, val
, val2
, mask
);
180 mutex_unlock(&st
->core
.cmd_lock
);
185 static const struct iio_info ec_sensors_info
= {
186 .read_raw
= &cros_ec_sensors_read
,
187 .write_raw
= &cros_ec_sensors_write
,
188 .driver_module
= THIS_MODULE
,
191 static int cros_ec_sensors_probe(struct platform_device
*pdev
)
193 struct device
*dev
= &pdev
->dev
;
194 struct cros_ec_dev
*ec_dev
= dev_get_drvdata(dev
->parent
);
195 struct cros_ec_device
*ec_device
;
196 struct iio_dev
*indio_dev
;
197 struct cros_ec_sensors_state
*state
;
198 struct iio_chan_spec
*channel
;
201 if (!ec_dev
|| !ec_dev
->ec_dev
) {
202 dev_warn(&pdev
->dev
, "No CROS EC device found.\n");
205 ec_device
= ec_dev
->ec_dev
;
207 indio_dev
= devm_iio_device_alloc(&pdev
->dev
, sizeof(*state
));
211 ret
= cros_ec_sensors_core_init(pdev
, indio_dev
, true);
215 indio_dev
->info
= &ec_sensors_info
;
216 state
= iio_priv(indio_dev
);
217 for (channel
= state
->channels
, i
= CROS_EC_SENSOR_X
;
218 i
< CROS_EC_SENSOR_MAX_AXIS
; i
++, channel
++) {
220 channel
->info_mask_separate
=
221 BIT(IIO_CHAN_INFO_RAW
) |
222 BIT(IIO_CHAN_INFO_CALIBBIAS
);
223 channel
->info_mask_shared_by_all
=
224 BIT(IIO_CHAN_INFO_SCALE
) |
225 BIT(IIO_CHAN_INFO_FREQUENCY
) |
226 BIT(IIO_CHAN_INFO_SAMP_FREQ
);
227 channel
->scan_type
.realbits
= CROS_EC_SENSOR_BITS
;
228 channel
->scan_type
.storagebits
= CROS_EC_SENSOR_BITS
;
229 channel
->scan_index
= i
;
230 channel
->ext_info
= cros_ec_sensors_ext_info
;
231 channel
->modified
= 1;
232 channel
->channel2
= IIO_MOD_X
+ i
;
233 channel
->scan_type
.sign
= 's';
235 /* Sensor specific */
236 switch (state
->core
.type
) {
237 case MOTIONSENSE_TYPE_ACCEL
:
238 channel
->type
= IIO_ACCEL
;
240 case MOTIONSENSE_TYPE_GYRO
:
241 channel
->type
= IIO_ANGL_VEL
;
243 case MOTIONSENSE_TYPE_MAG
:
244 channel
->type
= IIO_MAGN
;
247 dev_err(&pdev
->dev
, "Unknown motion sensor\n");
253 channel
->type
= IIO_TIMESTAMP
;
254 channel
->channel
= -1;
255 channel
->scan_index
= CROS_EC_SENSOR_MAX_AXIS
;
256 channel
->scan_type
.sign
= 's';
257 channel
->scan_type
.realbits
= 64;
258 channel
->scan_type
.storagebits
= 64;
260 indio_dev
->channels
= state
->channels
;
261 indio_dev
->num_channels
= CROS_EC_SENSORS_MAX_CHANNELS
;
263 /* There is only enough room for accel and gyro in the io space */
264 if ((state
->core
.ec
->cmd_readmem
!= NULL
) &&
265 (state
->core
.type
!= MOTIONSENSE_TYPE_MAG
))
266 state
->core
.read_ec_sensors_data
= cros_ec_sensors_read_lpc
;
268 state
->core
.read_ec_sensors_data
= cros_ec_sensors_read_cmd
;
270 ret
= iio_triggered_buffer_setup(indio_dev
, NULL
,
271 cros_ec_sensors_capture
, NULL
);
275 ret
= iio_device_register(indio_dev
);
277 goto error_uninit_buffer
;
282 iio_triggered_buffer_cleanup(indio_dev
);
287 static int cros_ec_sensors_remove(struct platform_device
*pdev
)
289 struct iio_dev
*indio_dev
= platform_get_drvdata(pdev
);
291 iio_device_unregister(indio_dev
);
292 iio_triggered_buffer_cleanup(indio_dev
);
297 static const struct platform_device_id cros_ec_sensors_ids
[] = {
299 .name
= "cros-ec-accel",
302 .name
= "cros-ec-gyro",
305 .name
= "cros-ec-mag",
309 MODULE_DEVICE_TABLE(platform
, cros_ec_sensors_ids
);
311 static struct platform_driver cros_ec_sensors_platform_driver
= {
313 .name
= "cros-ec-sensors",
315 .probe
= cros_ec_sensors_probe
,
316 .remove
= cros_ec_sensors_remove
,
317 .id_table
= cros_ec_sensors_ids
,
319 module_platform_driver(cros_ec_sensors_platform_driver
);
321 MODULE_DESCRIPTION("ChromeOS EC 3-axis sensors driver");
322 MODULE_LICENSE("GPL v2");