1 /* 2 * cros_ec_sensors - Driver for Chrome OS Embedded Controller sensors. 3 * 4 * Copyright (C) 2016 Google, Inc 5 * 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. 9 * 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. 14 * 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. 17 */ 18 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> 33 34 #include "cros_ec_sensors_core.h" 35 36 #define CROS_EC_SENSORS_MAX_CHANNELS 4 37 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; 42 43 struct iio_chan_spec channels[CROS_EC_SENSORS_MAX_CHANNELS]; 44 }; 45 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) 49 { 50 struct cros_ec_sensors_state *st = iio_priv(indio_dev); 51 s16 data = 0; 52 s64 val64; 53 int i; 54 int ret; 55 int idx = chan->scan_index; 56 57 mutex_lock(&st->core.cmd_lock); 58 59 switch (mask) { 60 case IIO_CHAN_INFO_RAW: 61 ret = st->core.read_ec_sensors_data(indio_dev, 1 << idx, &data); 62 if (ret < 0) 63 break; 64 ret = IIO_VAL_INT; 65 *val = data; 66 break; 67 case IIO_CHAN_INFO_CALIBBIAS: 68 st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET; 69 st->core.param.sensor_offset.flags = 0; 70 71 ret = cros_ec_motion_send_host_cmd(&st->core, 0); 72 if (ret < 0) 73 break; 74 75 /* Save values */ 76 for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++) 77 st->core.calib[i] = 78 st->core.resp->sensor_offset.offset[i]; 79 ret = IIO_VAL_INT; 80 *val = st->core.calib[idx]; 81 break; 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; 85 86 ret = cros_ec_motion_send_host_cmd(&st->core, 0); 87 if (ret < 0) 88 break; 89 90 val64 = st->core.resp->sensor_range.ret; 91 switch (st->core.type) { 92 case MOTIONSENSE_TYPE_ACCEL: 93 /* 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. 96 */ 97 *val = div_s64(val64 * 980665, 10); 98 *val2 = 10000 << (CROS_EC_SENSOR_BITS - 1); 99 ret = IIO_VAL_FRACTIONAL; 100 break; 101 case MOTIONSENSE_TYPE_GYRO: 102 /* 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. 106 */ 107 *val = div_s64(val64 * 314159 + 9000000ULL, 1000); 108 *val2 = 18000 << (CROS_EC_SENSOR_BITS - 1); 109 ret = IIO_VAL_FRACTIONAL; 110 break; 111 case MOTIONSENSE_TYPE_MAG: 112 /* 113 * EC returns data in 16LSB / uT, 114 * iio expects Gauss 115 */ 116 *val = val64; 117 *val2 = 100 << (CROS_EC_SENSOR_BITS - 1); 118 ret = IIO_VAL_FRACTIONAL; 119 break; 120 default: 121 ret = -EINVAL; 122 } 123 break; 124 default: 125 ret = cros_ec_sensors_core_read(&st->core, chan, val, val2, 126 mask); 127 break; 128 } 129 mutex_unlock(&st->core.cmd_lock); 130 131 return ret; 132 } 133 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) 137 { 138 struct cros_ec_sensors_state *st = iio_priv(indio_dev); 139 int i; 140 int ret; 141 int idx = chan->scan_index; 142 143 mutex_lock(&st->core.cmd_lock); 144 145 switch (mask) { 146 case IIO_CHAN_INFO_CALIBBIAS: 147 st->core.calib[idx] = val; 148 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] = 155 st->core.calib[i]; 156 st->core.param.sensor_offset.temp = 157 EC_MOTION_SENSE_INVALID_CALIB_TEMP; 158 159 ret = cros_ec_motion_send_host_cmd(&st->core, 0); 160 break; 161 case IIO_CHAN_INFO_SCALE: 162 if (st->core.type == MOTIONSENSE_TYPE_MAG) { 163 ret = -EINVAL; 164 break; 165 } 166 st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE; 167 st->core.param.sensor_range.data = val; 168 169 /* Always roundup, so caller gets at least what it asks for. */ 170 st->core.param.sensor_range.roundup = 1; 171 172 ret = cros_ec_motion_send_host_cmd(&st->core, 0); 173 break; 174 default: 175 ret = cros_ec_sensors_core_write( 176 &st->core, chan, val, val2, mask); 177 break; 178 } 179 180 mutex_unlock(&st->core.cmd_lock); 181 182 return ret; 183 } 184 185 static const struct iio_info ec_sensors_info = { 186 .read_raw = &cros_ec_sensors_read, 187 .write_raw = &cros_ec_sensors_write, 188 }; 189 190 static int cros_ec_sensors_probe(struct platform_device *pdev) 191 { 192 struct device *dev = &pdev->dev; 193 struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); 194 struct iio_dev *indio_dev; 195 struct cros_ec_sensors_state *state; 196 struct iio_chan_spec *channel; 197 int ret, i; 198 199 if (!ec_dev || !ec_dev->ec_dev) { 200 dev_warn(&pdev->dev, "No CROS EC device found.\n"); 201 return -EINVAL; 202 } 203 204 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*state)); 205 if (!indio_dev) 206 return -ENOMEM; 207 208 ret = cros_ec_sensors_core_init(pdev, indio_dev, true); 209 if (ret) 210 return ret; 211 212 indio_dev->info = &ec_sensors_info; 213 state = iio_priv(indio_dev); 214 for (channel = state->channels, i = CROS_EC_SENSOR_X; 215 i < CROS_EC_SENSOR_MAX_AXIS; i++, channel++) { 216 /* Common part */ 217 channel->info_mask_separate = 218 BIT(IIO_CHAN_INFO_RAW) | 219 BIT(IIO_CHAN_INFO_CALIBBIAS); 220 channel->info_mask_shared_by_all = 221 BIT(IIO_CHAN_INFO_SCALE) | 222 BIT(IIO_CHAN_INFO_FREQUENCY) | 223 BIT(IIO_CHAN_INFO_SAMP_FREQ); 224 channel->scan_type.realbits = CROS_EC_SENSOR_BITS; 225 channel->scan_type.storagebits = CROS_EC_SENSOR_BITS; 226 channel->scan_index = i; 227 channel->ext_info = cros_ec_sensors_ext_info; 228 channel->modified = 1; 229 channel->channel2 = IIO_MOD_X + i; 230 channel->scan_type.sign = 's'; 231 232 /* Sensor specific */ 233 switch (state->core.type) { 234 case MOTIONSENSE_TYPE_ACCEL: 235 channel->type = IIO_ACCEL; 236 break; 237 case MOTIONSENSE_TYPE_GYRO: 238 channel->type = IIO_ANGL_VEL; 239 break; 240 case MOTIONSENSE_TYPE_MAG: 241 channel->type = IIO_MAGN; 242 break; 243 default: 244 dev_err(&pdev->dev, "Unknown motion sensor\n"); 245 return -EINVAL; 246 } 247 } 248 249 /* Timestamp */ 250 channel->type = IIO_TIMESTAMP; 251 channel->channel = -1; 252 channel->scan_index = CROS_EC_SENSOR_MAX_AXIS; 253 channel->scan_type.sign = 's'; 254 channel->scan_type.realbits = 64; 255 channel->scan_type.storagebits = 64; 256 257 indio_dev->channels = state->channels; 258 indio_dev->num_channels = CROS_EC_SENSORS_MAX_CHANNELS; 259 260 /* There is only enough room for accel and gyro in the io space */ 261 if ((state->core.ec->cmd_readmem != NULL) && 262 (state->core.type != MOTIONSENSE_TYPE_MAG)) 263 state->core.read_ec_sensors_data = cros_ec_sensors_read_lpc; 264 else 265 state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; 266 267 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, 268 cros_ec_sensors_capture, NULL); 269 if (ret) 270 return ret; 271 272 return devm_iio_device_register(dev, indio_dev); 273 } 274 275 static const struct platform_device_id cros_ec_sensors_ids[] = { 276 { 277 .name = "cros-ec-accel", 278 }, 279 { 280 .name = "cros-ec-gyro", 281 }, 282 { 283 .name = "cros-ec-mag", 284 }, 285 { /* sentinel */ } 286 }; 287 MODULE_DEVICE_TABLE(platform, cros_ec_sensors_ids); 288 289 static struct platform_driver cros_ec_sensors_platform_driver = { 290 .driver = { 291 .name = "cros-ec-sensors", 292 }, 293 .probe = cros_ec_sensors_probe, 294 .id_table = cros_ec_sensors_ids, 295 }; 296 module_platform_driver(cros_ec_sensors_platform_driver); 297 298 MODULE_DESCRIPTION("ChromeOS EC 3-axis sensors driver"); 299 MODULE_LICENSE("GPL v2"); 300