1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for older Chrome OS EC accelerometer 4 * 5 * Copyright 2017 Google, Inc 6 * 7 * This driver uses the memory mapper cros-ec interface to communicate 8 * with the Chrome OS EC about accelerometer data. 9 * Accelerometer access is presented through iio sysfs. 10 */ 11 12 #include <linux/delay.h> 13 #include <linux/device.h> 14 #include <linux/iio/buffer.h> 15 #include <linux/iio/iio.h> 16 #include <linux/iio/kfifo_buf.h> 17 #include <linux/iio/trigger_consumer.h> 18 #include <linux/iio/triggered_buffer.h> 19 #include <linux/kernel.h> 20 #include <linux/mfd/cros_ec.h> 21 #include <linux/mfd/cros_ec_commands.h> 22 #include <linux/module.h> 23 #include <linux/slab.h> 24 #include <linux/platform_device.h> 25 26 #define DRV_NAME "cros-ec-accel-legacy" 27 28 /* 29 * Sensor scale hard coded at 10 bits per g, computed as: 30 * g / (2^10 - 1) = 0.009586168; with g = 9.80665 m.s^-2 31 */ 32 #define ACCEL_LEGACY_NSCALE 9586168 33 34 /* Indices for EC sensor values. */ 35 enum { 36 X, 37 Y, 38 Z, 39 MAX_AXIS, 40 }; 41 42 /* State data for cros_ec_accel_legacy iio driver. */ 43 struct cros_ec_accel_legacy_state { 44 struct cros_ec_device *ec; 45 46 /* 47 * Array holding data from a single capture. 2 bytes per channel 48 * for the 3 channels plus the timestamp which is always last and 49 * 8-bytes aligned. 50 */ 51 s16 capture_data[8]; 52 s8 sign[MAX_AXIS]; 53 u8 sensor_num; 54 }; 55 56 static int ec_cmd_read_u8(struct cros_ec_device *ec, unsigned int offset, 57 u8 *dest) 58 { 59 return ec->cmd_readmem(ec, offset, 1, dest); 60 } 61 62 static int ec_cmd_read_u16(struct cros_ec_device *ec, unsigned int offset, 63 u16 *dest) 64 { 65 __le16 tmp; 66 int ret = ec->cmd_readmem(ec, offset, 2, &tmp); 67 68 *dest = le16_to_cpu(tmp); 69 70 return ret; 71 } 72 73 /** 74 * read_ec_until_not_busy() - Read from EC status byte until it reads not busy. 75 * @st: Pointer to state information for device. 76 * 77 * This function reads EC status until its busy bit gets cleared. It does not 78 * wait indefinitely and returns -EIO if the EC status is still busy after a 79 * few hundreds milliseconds. 80 * 81 * Return: 8-bit status if ok, -EIO on error 82 */ 83 static int read_ec_until_not_busy(struct cros_ec_accel_legacy_state *st) 84 { 85 struct cros_ec_device *ec = st->ec; 86 u8 status; 87 int attempts = 0; 88 89 ec_cmd_read_u8(ec, EC_MEMMAP_ACC_STATUS, &status); 90 while (status & EC_MEMMAP_ACC_STATUS_BUSY_BIT) { 91 /* Give up after enough attempts, return error. */ 92 if (attempts++ >= 50) 93 return -EIO; 94 95 /* Small delay every so often. */ 96 if (attempts % 5 == 0) 97 msleep(25); 98 99 ec_cmd_read_u8(ec, EC_MEMMAP_ACC_STATUS, &status); 100 } 101 102 return status; 103 } 104 105 /** 106 * read_ec_accel_data_unsafe() - Read acceleration data from EC shared memory. 107 * @st: Pointer to state information for device. 108 * @scan_mask: Bitmap of the sensor indices to scan. 109 * @data: Location to store data. 110 * 111 * This is the unsafe function for reading the EC data. It does not guarantee 112 * that the EC will not modify the data as it is being read in. 113 */ 114 static void read_ec_accel_data_unsafe(struct cros_ec_accel_legacy_state *st, 115 unsigned long scan_mask, s16 *data) 116 { 117 int i = 0; 118 int num_enabled = bitmap_weight(&scan_mask, MAX_AXIS); 119 120 /* Read all sensors enabled in scan_mask. Each value is 2 bytes. */ 121 while (num_enabled--) { 122 i = find_next_bit(&scan_mask, MAX_AXIS, i); 123 ec_cmd_read_u16(st->ec, 124 EC_MEMMAP_ACC_DATA + 125 sizeof(s16) * 126 (1 + i + st->sensor_num * MAX_AXIS), 127 data); 128 *data *= st->sign[i]; 129 i++; 130 data++; 131 } 132 } 133 134 /** 135 * read_ec_accel_data() - Read acceleration data from EC shared memory. 136 * @st: Pointer to state information for device. 137 * @scan_mask: Bitmap of the sensor indices to scan. 138 * @data: Location to store data. 139 * 140 * This is the safe function for reading the EC data. It guarantees that 141 * the data sampled was not modified by the EC while being read. 142 * 143 * Return: 0 if ok, -ve on error 144 */ 145 static int read_ec_accel_data(struct cros_ec_accel_legacy_state *st, 146 unsigned long scan_mask, s16 *data) 147 { 148 u8 samp_id = 0xff; 149 u8 status = 0; 150 int ret; 151 int attempts = 0; 152 153 /* 154 * Continually read all data from EC until the status byte after 155 * all reads reflects that the EC is not busy and the sample id 156 * matches the sample id from before all reads. This guarantees 157 * that data read in was not modified by the EC while reading. 158 */ 159 while ((status & (EC_MEMMAP_ACC_STATUS_BUSY_BIT | 160 EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK)) != samp_id) { 161 /* If we have tried to read too many times, return error. */ 162 if (attempts++ >= 5) 163 return -EIO; 164 165 /* Read status byte until EC is not busy. */ 166 ret = read_ec_until_not_busy(st); 167 if (ret < 0) 168 return ret; 169 status = ret; 170 171 /* 172 * Store the current sample id so that we can compare to the 173 * sample id after reading the data. 174 */ 175 samp_id = status & EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK; 176 177 /* Read all EC data, format it, and store it into data. */ 178 read_ec_accel_data_unsafe(st, scan_mask, data); 179 180 /* Read status byte. */ 181 ec_cmd_read_u8(st->ec, EC_MEMMAP_ACC_STATUS, &status); 182 } 183 184 return 0; 185 } 186 187 static int cros_ec_accel_legacy_read(struct iio_dev *indio_dev, 188 struct iio_chan_spec const *chan, 189 int *val, int *val2, long mask) 190 { 191 struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); 192 s16 data = 0; 193 int ret = IIO_VAL_INT; 194 195 switch (mask) { 196 case IIO_CHAN_INFO_RAW: 197 ret = read_ec_accel_data(st, (1 << chan->scan_index), &data); 198 if (ret) 199 return ret; 200 *val = data; 201 return IIO_VAL_INT; 202 case IIO_CHAN_INFO_SCALE: 203 *val = 0; 204 *val2 = ACCEL_LEGACY_NSCALE; 205 return IIO_VAL_INT_PLUS_NANO; 206 case IIO_CHAN_INFO_CALIBBIAS: 207 /* Calibration not supported. */ 208 *val = 0; 209 return IIO_VAL_INT; 210 default: 211 return -EINVAL; 212 } 213 } 214 215 static int cros_ec_accel_legacy_write(struct iio_dev *indio_dev, 216 struct iio_chan_spec const *chan, 217 int val, int val2, long mask) 218 { 219 /* 220 * Do nothing but don't return an error code to allow calibration 221 * script to work. 222 */ 223 if (mask == IIO_CHAN_INFO_CALIBBIAS) 224 return 0; 225 226 return -EINVAL; 227 } 228 229 static const struct iio_info cros_ec_accel_legacy_info = { 230 .read_raw = &cros_ec_accel_legacy_read, 231 .write_raw = &cros_ec_accel_legacy_write, 232 }; 233 234 /** 235 * cros_ec_accel_legacy_capture() - The trigger handler function 236 * @irq: The interrupt number. 237 * @p: Private data - always a pointer to the poll func. 238 * 239 * On a trigger event occurring, if the pollfunc is attached then this 240 * handler is called as a threaded interrupt (and hence may sleep). It 241 * is responsible for grabbing data from the device and pushing it into 242 * the associated buffer. 243 * 244 * Return: IRQ_HANDLED 245 */ 246 static irqreturn_t cros_ec_accel_legacy_capture(int irq, void *p) 247 { 248 struct iio_poll_func *pf = p; 249 struct iio_dev *indio_dev = pf->indio_dev; 250 struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); 251 252 /* Clear capture data. */ 253 memset(st->capture_data, 0, sizeof(st->capture_data)); 254 255 /* 256 * Read data based on which channels are enabled in scan mask. Note 257 * that on a capture we are always reading the calibrated data. 258 */ 259 read_ec_accel_data(st, *indio_dev->active_scan_mask, st->capture_data); 260 261 iio_push_to_buffers_with_timestamp(indio_dev, (void *)st->capture_data, 262 iio_get_time_ns(indio_dev)); 263 264 /* 265 * Tell the core we are done with this trigger and ready for the 266 * next one. 267 */ 268 iio_trigger_notify_done(indio_dev->trig); 269 270 return IRQ_HANDLED; 271 } 272 273 static char *cros_ec_accel_legacy_loc_strings[] = { 274 [MOTIONSENSE_LOC_BASE] = "base", 275 [MOTIONSENSE_LOC_LID] = "lid", 276 [MOTIONSENSE_LOC_MAX] = "unknown", 277 }; 278 279 static ssize_t cros_ec_accel_legacy_loc(struct iio_dev *indio_dev, 280 uintptr_t private, 281 const struct iio_chan_spec *chan, 282 char *buf) 283 { 284 struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); 285 286 return sprintf(buf, "%s\n", 287 cros_ec_accel_legacy_loc_strings[st->sensor_num + 288 MOTIONSENSE_LOC_BASE]); 289 } 290 291 static ssize_t cros_ec_accel_legacy_id(struct iio_dev *indio_dev, 292 uintptr_t private, 293 const struct iio_chan_spec *chan, 294 char *buf) 295 { 296 struct cros_ec_accel_legacy_state *st = iio_priv(indio_dev); 297 298 return sprintf(buf, "%d\n", st->sensor_num); 299 } 300 301 static const struct iio_chan_spec_ext_info cros_ec_accel_legacy_ext_info[] = { 302 { 303 .name = "id", 304 .shared = IIO_SHARED_BY_ALL, 305 .read = cros_ec_accel_legacy_id, 306 }, 307 { 308 .name = "location", 309 .shared = IIO_SHARED_BY_ALL, 310 .read = cros_ec_accel_legacy_loc, 311 }, 312 { } 313 }; 314 315 #define CROS_EC_ACCEL_LEGACY_CHAN(_axis) \ 316 { \ 317 .type = IIO_ACCEL, \ 318 .channel2 = IIO_MOD_X + (_axis), \ 319 .modified = 1, \ 320 .info_mask_separate = \ 321 BIT(IIO_CHAN_INFO_RAW) | \ 322 BIT(IIO_CHAN_INFO_SCALE) | \ 323 BIT(IIO_CHAN_INFO_CALIBBIAS), \ 324 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \ 325 .ext_info = cros_ec_accel_legacy_ext_info, \ 326 .scan_type = { \ 327 .sign = 's', \ 328 .realbits = 16, \ 329 .storagebits = 16, \ 330 }, \ 331 } \ 332 333 static struct iio_chan_spec ec_accel_channels[] = { 334 CROS_EC_ACCEL_LEGACY_CHAN(X), 335 CROS_EC_ACCEL_LEGACY_CHAN(Y), 336 CROS_EC_ACCEL_LEGACY_CHAN(Z), 337 IIO_CHAN_SOFT_TIMESTAMP(MAX_AXIS) 338 }; 339 340 static int cros_ec_accel_legacy_probe(struct platform_device *pdev) 341 { 342 struct device *dev = &pdev->dev; 343 struct cros_ec_dev *ec = dev_get_drvdata(dev->parent); 344 struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); 345 struct iio_dev *indio_dev; 346 struct cros_ec_accel_legacy_state *state; 347 int ret; 348 349 if (!ec || !ec->ec_dev) { 350 dev_warn(&pdev->dev, "No EC device found.\n"); 351 return -EINVAL; 352 } 353 354 if (!ec->ec_dev->cmd_readmem) { 355 dev_warn(&pdev->dev, "EC does not support direct reads.\n"); 356 return -EINVAL; 357 } 358 359 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*state)); 360 if (!indio_dev) 361 return -ENOMEM; 362 363 platform_set_drvdata(pdev, indio_dev); 364 state = iio_priv(indio_dev); 365 state->ec = ec->ec_dev; 366 state->sensor_num = sensor_platform->sensor_num; 367 368 indio_dev->dev.parent = dev; 369 indio_dev->name = pdev->name; 370 indio_dev->channels = ec_accel_channels; 371 /* 372 * Present the channel using HTML5 standard: 373 * need to invert X and Y and invert some lid axis. 374 */ 375 ec_accel_channels[X].scan_index = Y; 376 ec_accel_channels[Y].scan_index = X; 377 ec_accel_channels[Z].scan_index = Z; 378 379 state->sign[Y] = 1; 380 381 if (state->sensor_num == MOTIONSENSE_LOC_LID) 382 state->sign[X] = state->sign[Z] = -1; 383 else 384 state->sign[X] = state->sign[Z] = 1; 385 386 indio_dev->num_channels = ARRAY_SIZE(ec_accel_channels); 387 indio_dev->dev.parent = &pdev->dev; 388 indio_dev->info = &cros_ec_accel_legacy_info; 389 indio_dev->modes = INDIO_DIRECT_MODE; 390 391 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, 392 cros_ec_accel_legacy_capture, 393 NULL); 394 if (ret) 395 return ret; 396 397 return devm_iio_device_register(dev, indio_dev); 398 } 399 400 static struct platform_driver cros_ec_accel_platform_driver = { 401 .driver = { 402 .name = DRV_NAME, 403 }, 404 .probe = cros_ec_accel_legacy_probe, 405 }; 406 module_platform_driver(cros_ec_accel_platform_driver); 407 408 MODULE_DESCRIPTION("ChromeOS EC legacy accelerometer driver"); 409 MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>"); 410 MODULE_LICENSE("GPL v2"); 411 MODULE_ALIAS("platform:" DRV_NAME); 412