linux/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * cros_ec_sensors_core - Common function for Chrome OS EC sensor driver.
   4 *
   5 * Copyright (C) 2016 Google, Inc
   6 */
   7
   8#include <linux/delay.h>
   9#include <linux/device.h>
  10#include <linux/iio/buffer.h>
  11#include <linux/iio/common/cros_ec_sensors_core.h>
  12#include <linux/iio/iio.h>
  13#include <linux/iio/kfifo_buf.h>
  14#include <linux/iio/sysfs.h>
  15#include <linux/iio/trigger.h>
  16#include <linux/iio/trigger_consumer.h>
  17#include <linux/iio/triggered_buffer.h>
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/slab.h>
  21#include <linux/platform_data/cros_ec_commands.h>
  22#include <linux/platform_data/cros_ec_proto.h>
  23#include <linux/platform_data/cros_ec_sensorhub.h>
  24#include <linux/platform_device.h>
  25
  26/*
  27 * Hard coded to the first device to support sensor fifo.  The EC has a 2048
  28 * byte fifo and will trigger an interrupt when fifo is 2/3 full.
  29 */
  30#define CROS_EC_FIFO_SIZE (2048 * 2 / 3)
  31
  32static char *cros_ec_loc[] = {
  33        [MOTIONSENSE_LOC_BASE] = "base",
  34        [MOTIONSENSE_LOC_LID] = "lid",
  35        [MOTIONSENSE_LOC_MAX] = "unknown",
  36};
  37
  38static int cros_ec_get_host_cmd_version_mask(struct cros_ec_device *ec_dev,
  39                                             u16 cmd_offset, u16 cmd, u32 *mask)
  40{
  41        int ret;
  42        struct {
  43                struct cros_ec_command msg;
  44                union {
  45                        struct ec_params_get_cmd_versions params;
  46                        struct ec_response_get_cmd_versions resp;
  47                };
  48        } __packed buf = {
  49                .msg = {
  50                        .command = EC_CMD_GET_CMD_VERSIONS + cmd_offset,
  51                        .insize = sizeof(struct ec_response_get_cmd_versions),
  52                        .outsize = sizeof(struct ec_params_get_cmd_versions)
  53                        },
  54                .params = {.cmd = cmd}
  55        };
  56
  57        ret = cros_ec_cmd_xfer_status(ec_dev, &buf.msg);
  58        if (ret >= 0)
  59                *mask = buf.resp.version_mask;
  60        return ret;
  61}
  62
  63static void get_default_min_max_freq(enum motionsensor_type type,
  64                                     u32 *min_freq,
  65                                     u32 *max_freq,
  66                                     u32 *max_fifo_events)
  67{
  68        /*
  69         * We don't know fifo size, set to size previously used by older
  70         * hardware.
  71         */
  72        *max_fifo_events = CROS_EC_FIFO_SIZE;
  73
  74        switch (type) {
  75        case MOTIONSENSE_TYPE_ACCEL:
  76                *min_freq = 12500;
  77                *max_freq = 100000;
  78                break;
  79        case MOTIONSENSE_TYPE_GYRO:
  80                *min_freq = 25000;
  81                *max_freq = 100000;
  82                break;
  83        case MOTIONSENSE_TYPE_MAG:
  84                *min_freq = 5000;
  85                *max_freq = 25000;
  86                break;
  87        case MOTIONSENSE_TYPE_PROX:
  88        case MOTIONSENSE_TYPE_LIGHT:
  89                *min_freq = 100;
  90                *max_freq = 50000;
  91                break;
  92        case MOTIONSENSE_TYPE_BARO:
  93                *min_freq = 250;
  94                *max_freq = 20000;
  95                break;
  96        case MOTIONSENSE_TYPE_ACTIVITY:
  97        default:
  98                *min_freq = 0;
  99                *max_freq = 0;
 100                break;
 101        }
 102}
 103
 104static int cros_ec_sensor_set_ec_rate(struct cros_ec_sensors_core_state *st,
 105                                      int rate)
 106{
 107        int ret;
 108
 109        if (rate > U16_MAX)
 110                rate = U16_MAX;
 111
 112        mutex_lock(&st->cmd_lock);
 113        st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
 114        st->param.ec_rate.data = rate;
 115        ret = cros_ec_motion_send_host_cmd(st, 0);
 116        mutex_unlock(&st->cmd_lock);
 117        return ret;
 118}
 119
 120static ssize_t cros_ec_sensor_set_report_latency(struct device *dev,
 121                                                 struct device_attribute *attr,
 122                                                 const char *buf, size_t len)
 123{
 124        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 125        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 126        int integer, fract, ret;
 127        int latency;
 128
 129        ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
 130        if (ret)
 131                return ret;
 132
 133        /* EC rate is in ms. */
 134        latency = integer * 1000 + fract / 1000;
 135        ret = cros_ec_sensor_set_ec_rate(st, latency);
 136        if (ret < 0)
 137                return ret;
 138
 139        return len;
 140}
 141
 142static ssize_t cros_ec_sensor_get_report_latency(struct device *dev,
 143                                                 struct device_attribute *attr,
 144                                                 char *buf)
 145{
 146        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 147        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 148        int latency, ret;
 149
 150        mutex_lock(&st->cmd_lock);
 151        st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
 152        st->param.ec_rate.data = EC_MOTION_SENSE_NO_VALUE;
 153
 154        ret = cros_ec_motion_send_host_cmd(st, 0);
 155        latency = st->resp->ec_rate.ret;
 156        mutex_unlock(&st->cmd_lock);
 157        if (ret < 0)
 158                return ret;
 159
 160        return sprintf(buf, "%d.%06u\n",
 161                       latency / 1000,
 162                       (latency % 1000) * 1000);
 163}
 164
 165static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
 166                       cros_ec_sensor_get_report_latency,
 167                       cros_ec_sensor_set_report_latency, 0);
 168
 169static ssize_t hwfifo_watermark_max_show(struct device *dev,
 170                                         struct device_attribute *attr,
 171                                         char *buf)
 172{
 173        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 174        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 175
 176        return sprintf(buf, "%d\n", st->fifo_max_event_count);
 177}
 178
 179static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
 180
 181static const struct attribute *cros_ec_sensor_fifo_attributes[] = {
 182        &iio_dev_attr_hwfifo_timeout.dev_attr.attr,
 183        &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
 184        NULL,
 185};
 186
 187int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
 188                              s16 *data,
 189                              s64 timestamp)
 190{
 191        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 192        s16 *out;
 193        s64 delta;
 194        unsigned int i;
 195
 196        /*
 197         * Ignore samples if the buffer is not set: it is needed if the ODR is
 198         * set but the buffer is not enabled yet.
 199         */
 200        if (!iio_buffer_enabled(indio_dev))
 201                return 0;
 202
 203        out = (s16 *)st->samples;
 204        for_each_set_bit(i,
 205                         indio_dev->active_scan_mask,
 206                         indio_dev->masklength) {
 207                *out = data[i];
 208                out++;
 209        }
 210
 211        if (iio_device_get_clock(indio_dev) != CLOCK_BOOTTIME)
 212                delta = iio_get_time_ns(indio_dev) - cros_ec_get_time_ns();
 213        else
 214                delta = 0;
 215
 216        iio_push_to_buffers_with_timestamp(indio_dev, st->samples,
 217                                           timestamp + delta);
 218
 219        return 0;
 220}
 221EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data);
 222
 223static void cros_ec_sensors_core_clean(void *arg)
 224{
 225        struct platform_device *pdev = (struct platform_device *)arg;
 226        struct cros_ec_sensorhub *sensor_hub =
 227                dev_get_drvdata(pdev->dev.parent);
 228        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 229        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 230        u8 sensor_num = st->param.info.sensor_num;
 231
 232        cros_ec_sensorhub_unregister_push_data(sensor_hub, sensor_num);
 233}
 234
 235/**
 236 * cros_ec_sensors_core_init() - basic initialization of the core structure
 237 * @pdev:               platform device created for the sensors
 238 * @indio_dev:          iio device structure of the device
 239 * @physical_device:    true if the device refers to a physical device
 240 * @trigger_capture:    function pointer to call buffer is triggered,
 241 *    for backward compatibility.
 242 * @push_data:          function to call when cros_ec_sensorhub receives
 243 *    a sample for that sensor.
 244 *
 245 * Return: 0 on success, -errno on failure.
 246 */
 247int cros_ec_sensors_core_init(struct platform_device *pdev,
 248                              struct iio_dev *indio_dev,
 249                              bool physical_device,
 250                              cros_ec_sensors_capture_t trigger_capture,
 251                              cros_ec_sensorhub_push_data_cb_t push_data)
 252{
 253        struct device *dev = &pdev->dev;
 254        struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
 255        struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent);
 256        struct cros_ec_dev *ec = sensor_hub->ec;
 257        struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
 258        u32 ver_mask, temp;
 259        int frequencies[ARRAY_SIZE(state->frequencies) / 2] = { 0 };
 260        int ret, i;
 261
 262        platform_set_drvdata(pdev, indio_dev);
 263
 264        state->ec = ec->ec_dev;
 265        state->msg = devm_kzalloc(&pdev->dev,
 266                                max((u16)sizeof(struct ec_params_motion_sense),
 267                                state->ec->max_response), GFP_KERNEL);
 268        if (!state->msg)
 269                return -ENOMEM;
 270
 271        state->resp = (struct ec_response_motion_sense *)state->msg->data;
 272
 273        mutex_init(&state->cmd_lock);
 274
 275        ret = cros_ec_get_host_cmd_version_mask(state->ec,
 276                                                ec->cmd_offset,
 277                                                EC_CMD_MOTION_SENSE_CMD,
 278                                                &ver_mask);
 279        if (ret < 0)
 280                return ret;
 281
 282        /* Set up the host command structure. */
 283        state->msg->version = fls(ver_mask) - 1;
 284        state->msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
 285        state->msg->outsize = sizeof(struct ec_params_motion_sense);
 286
 287        indio_dev->name = pdev->name;
 288
 289        if (physical_device) {
 290                state->param.cmd = MOTIONSENSE_CMD_INFO;
 291                state->param.info.sensor_num = sensor_platform->sensor_num;
 292                ret = cros_ec_motion_send_host_cmd(state, 0);
 293                if (ret) {
 294                        dev_warn(dev, "Can not access sensor info\n");
 295                        return ret;
 296                }
 297                state->type = state->resp->info.type;
 298                state->loc = state->resp->info.location;
 299
 300                /* Set sign vector, only used for backward compatibility. */
 301                memset(state->sign, 1, CROS_EC_SENSOR_MAX_AXIS);
 302
 303                for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
 304                        state->calib[i].scale = MOTION_SENSE_DEFAULT_SCALE;
 305
 306                /* 0 is a correct value used to stop the device */
 307                if (state->msg->version < 3) {
 308                        get_default_min_max_freq(state->resp->info.type,
 309                                                 &frequencies[1],
 310                                                 &frequencies[2],
 311                                                 &state->fifo_max_event_count);
 312                } else {
 313                        if (state->resp->info_3.max_frequency == 0) {
 314                                get_default_min_max_freq(state->resp->info.type,
 315                                                         &frequencies[1],
 316                                                         &frequencies[2],
 317                                                         &temp);
 318                        } else {
 319                                frequencies[1] = state->resp->info_3.min_frequency;
 320                                frequencies[2] = state->resp->info_3.max_frequency;
 321                        }
 322                        state->fifo_max_event_count = state->resp->info_3.fifo_max_event_count;
 323                }
 324                for (i = 0; i < ARRAY_SIZE(frequencies); i++) {
 325                        state->frequencies[2 * i] = frequencies[i] / 1000;
 326                        state->frequencies[2 * i + 1] =
 327                                (frequencies[i] % 1000) * 1000;
 328                }
 329
 330                if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
 331                        /*
 332                         * Create a software buffer, feed by the EC FIFO.
 333                         * We can not use trigger here, as events are generated
 334                         * as soon as sample_frequency is set.
 335                         */
 336                        ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev,
 337                                                              INDIO_BUFFER_SOFTWARE, NULL,
 338                                                              cros_ec_sensor_fifo_attributes);
 339                        if (ret)
 340                                return ret;
 341
 342                        ret = cros_ec_sensorhub_register_push_data(
 343                                        sensor_hub, sensor_platform->sensor_num,
 344                                        indio_dev, push_data);
 345                        if (ret)
 346                                return ret;
 347
 348                        ret = devm_add_action_or_reset(
 349                                        dev, cros_ec_sensors_core_clean, pdev);
 350                        if (ret)
 351                                return ret;
 352
 353                        /* Timestamp coming from FIFO are in ns since boot. */
 354                        ret = iio_device_set_clock(indio_dev, CLOCK_BOOTTIME);
 355                        if (ret)
 356                                return ret;
 357
 358                } else {
 359                        /*
 360                         * The only way to get samples in buffer is to set a
 361                         * software trigger (systrig, hrtimer).
 362                         */
 363                        ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
 364                                        NULL, trigger_capture, NULL);
 365                        if (ret)
 366                                return ret;
 367                }
 368        }
 369
 370        return 0;
 371}
 372EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init);
 373
 374/**
 375 * cros_ec_motion_send_host_cmd() - send motion sense host command
 376 * @state:              pointer to state information for device
 377 * @opt_length: optional length to reduce the response size, useful on the data
 378 *              path. Otherwise, the maximal allowed response size is used
 379 *
 380 * When called, the sub-command is assumed to be set in param->cmd.
 381 *
 382 * Return: 0 on success, -errno on failure.
 383 */
 384int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *state,
 385                                 u16 opt_length)
 386{
 387        int ret;
 388
 389        if (opt_length)
 390                state->msg->insize = min(opt_length, state->ec->max_response);
 391        else
 392                state->msg->insize = state->ec->max_response;
 393
 394        memcpy(state->msg->data, &state->param, sizeof(state->param));
 395
 396        ret = cros_ec_cmd_xfer_status(state->ec, state->msg);
 397        if (ret < 0)
 398                return ret;
 399
 400        if (ret &&
 401            state->resp != (struct ec_response_motion_sense *)state->msg->data)
 402                memcpy(state->resp, state->msg->data, ret);
 403
 404        return 0;
 405}
 406EXPORT_SYMBOL_GPL(cros_ec_motion_send_host_cmd);
 407
 408static ssize_t cros_ec_sensors_calibrate(struct iio_dev *indio_dev,
 409                uintptr_t private, const struct iio_chan_spec *chan,
 410                const char *buf, size_t len)
 411{
 412        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 413        int ret, i;
 414        bool calibrate;
 415
 416        ret = strtobool(buf, &calibrate);
 417        if (ret < 0)
 418                return ret;
 419        if (!calibrate)
 420                return -EINVAL;
 421
 422        mutex_lock(&st->cmd_lock);
 423        st->param.cmd = MOTIONSENSE_CMD_PERFORM_CALIB;
 424        ret = cros_ec_motion_send_host_cmd(st, 0);
 425        if (ret != 0) {
 426                dev_warn(&indio_dev->dev, "Unable to calibrate sensor\n");
 427        } else {
 428                /* Save values */
 429                for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
 430                        st->calib[i].offset = st->resp->perform_calib.offset[i];
 431        }
 432        mutex_unlock(&st->cmd_lock);
 433
 434        return ret ? ret : len;
 435}
 436
 437static ssize_t cros_ec_sensors_id(struct iio_dev *indio_dev,
 438                                  uintptr_t private,
 439                                  const struct iio_chan_spec *chan, char *buf)
 440{
 441        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 442
 443        return snprintf(buf, PAGE_SIZE, "%d\n", st->param.info.sensor_num);
 444}
 445
 446static ssize_t cros_ec_sensors_loc(struct iio_dev *indio_dev,
 447                uintptr_t private, const struct iio_chan_spec *chan,
 448                char *buf)
 449{
 450        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 451
 452        return snprintf(buf, PAGE_SIZE, "%s\n", cros_ec_loc[st->loc]);
 453}
 454
 455const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[] = {
 456        {
 457                .name = "calibrate",
 458                .shared = IIO_SHARED_BY_ALL,
 459                .write = cros_ec_sensors_calibrate
 460        },
 461        {
 462                .name = "id",
 463                .shared = IIO_SHARED_BY_ALL,
 464                .read = cros_ec_sensors_id
 465        },
 466        {
 467                .name = "location",
 468                .shared = IIO_SHARED_BY_ALL,
 469                .read = cros_ec_sensors_loc
 470        },
 471        { },
 472};
 473EXPORT_SYMBOL_GPL(cros_ec_sensors_ext_info);
 474
 475/**
 476 * cros_ec_sensors_idx_to_reg - convert index into offset in shared memory
 477 * @st:         pointer to state information for device
 478 * @idx:        sensor index (should be element of enum sensor_index)
 479 *
 480 * Return:      address to read at
 481 */
 482static unsigned int cros_ec_sensors_idx_to_reg(
 483                                        struct cros_ec_sensors_core_state *st,
 484                                        unsigned int idx)
 485{
 486        /*
 487         * When using LPC interface, only space for 2 Accel and one Gyro.
 488         * First halfword of MOTIONSENSE_TYPE_ACCEL is used by angle.
 489         */
 490        if (st->type == MOTIONSENSE_TYPE_ACCEL)
 491                return EC_MEMMAP_ACC_DATA + sizeof(u16) *
 492                        (1 + idx + st->param.info.sensor_num *
 493                         CROS_EC_SENSOR_MAX_AXIS);
 494
 495        return EC_MEMMAP_GYRO_DATA + sizeof(u16) * idx;
 496}
 497
 498static int cros_ec_sensors_cmd_read_u8(struct cros_ec_device *ec,
 499                                       unsigned int offset, u8 *dest)
 500{
 501        return ec->cmd_readmem(ec, offset, 1, dest);
 502}
 503
 504static int cros_ec_sensors_cmd_read_u16(struct cros_ec_device *ec,
 505                                         unsigned int offset, u16 *dest)
 506{
 507        __le16 tmp;
 508        int ret = ec->cmd_readmem(ec, offset, 2, &tmp);
 509
 510        if (ret >= 0)
 511                *dest = le16_to_cpu(tmp);
 512
 513        return ret;
 514}
 515
 516/**
 517 * cros_ec_sensors_read_until_not_busy() - read until is not busy
 518 *
 519 * @st: pointer to state information for device
 520 *
 521 * Read from EC status byte until it reads not busy.
 522 * Return: 8-bit status if ok, -errno on failure.
 523 */
 524static int cros_ec_sensors_read_until_not_busy(
 525                                        struct cros_ec_sensors_core_state *st)
 526{
 527        struct cros_ec_device *ec = st->ec;
 528        u8 status;
 529        int ret, attempts = 0;
 530
 531        ret = cros_ec_sensors_cmd_read_u8(ec, EC_MEMMAP_ACC_STATUS, &status);
 532        if (ret < 0)
 533                return ret;
 534
 535        while (status & EC_MEMMAP_ACC_STATUS_BUSY_BIT) {
 536                /* Give up after enough attempts, return error. */
 537                if (attempts++ >= 50)
 538                        return -EIO;
 539
 540                /* Small delay every so often. */
 541                if (attempts % 5 == 0)
 542                        msleep(25);
 543
 544                ret = cros_ec_sensors_cmd_read_u8(ec, EC_MEMMAP_ACC_STATUS,
 545                                                  &status);
 546                if (ret < 0)
 547                        return ret;
 548        }
 549
 550        return status;
 551}
 552
 553/**
 554 * cros_ec_sensors_read_data_unsafe() - read acceleration data from EC shared memory
 555 * @indio_dev:  pointer to IIO device
 556 * @scan_mask:  bitmap of the sensor indices to scan
 557 * @data:       location to store data
 558 *
 559 * This is the unsafe function for reading the EC data. It does not guarantee
 560 * that the EC will not modify the data as it is being read in.
 561 *
 562 * Return: 0 on success, -errno on failure.
 563 */
 564static int cros_ec_sensors_read_data_unsafe(struct iio_dev *indio_dev,
 565                         unsigned long scan_mask, s16 *data)
 566{
 567        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 568        struct cros_ec_device *ec = st->ec;
 569        unsigned int i;
 570        int ret;
 571
 572        /* Read all sensors enabled in scan_mask. Each value is 2 bytes. */
 573        for_each_set_bit(i, &scan_mask, indio_dev->masklength) {
 574                ret = cros_ec_sensors_cmd_read_u16(ec,
 575                                             cros_ec_sensors_idx_to_reg(st, i),
 576                                             data);
 577                if (ret < 0)
 578                        return ret;
 579
 580                *data *= st->sign[i];
 581                data++;
 582        }
 583
 584        return 0;
 585}
 586
 587/**
 588 * cros_ec_sensors_read_lpc() - read acceleration data from EC shared memory.
 589 * @indio_dev: pointer to IIO device.
 590 * @scan_mask: bitmap of the sensor indices to scan.
 591 * @data: location to store data.
 592 *
 593 * Note: this is the safe function for reading the EC data. It guarantees
 594 * that the data sampled was not modified by the EC while being read.
 595 *
 596 * Return: 0 on success, -errno on failure.
 597 */
 598int cros_ec_sensors_read_lpc(struct iio_dev *indio_dev,
 599                             unsigned long scan_mask, s16 *data)
 600{
 601        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 602        struct cros_ec_device *ec = st->ec;
 603        u8 samp_id = 0xff, status = 0;
 604        int ret, attempts = 0;
 605
 606        /*
 607         * Continually read all data from EC until the status byte after
 608         * all reads reflects that the EC is not busy and the sample id
 609         * matches the sample id from before all reads. This guarantees
 610         * that data read in was not modified by the EC while reading.
 611         */
 612        while ((status & (EC_MEMMAP_ACC_STATUS_BUSY_BIT |
 613                          EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK)) != samp_id) {
 614                /* If we have tried to read too many times, return error. */
 615                if (attempts++ >= 5)
 616                        return -EIO;
 617
 618                /* Read status byte until EC is not busy. */
 619                ret = cros_ec_sensors_read_until_not_busy(st);
 620                if (ret < 0)
 621                        return ret;
 622
 623                /*
 624                 * Store the current sample id so that we can compare to the
 625                 * sample id after reading the data.
 626                 */
 627                samp_id = ret & EC_MEMMAP_ACC_STATUS_SAMPLE_ID_MASK;
 628
 629                /* Read all EC data, format it, and store it into data. */
 630                ret = cros_ec_sensors_read_data_unsafe(indio_dev, scan_mask,
 631                                                       data);
 632                if (ret < 0)
 633                        return ret;
 634
 635                /* Read status byte. */
 636                ret = cros_ec_sensors_cmd_read_u8(ec, EC_MEMMAP_ACC_STATUS,
 637                                                  &status);
 638                if (ret < 0)
 639                        return ret;
 640        }
 641
 642        return 0;
 643}
 644EXPORT_SYMBOL_GPL(cros_ec_sensors_read_lpc);
 645
 646/**
 647 * cros_ec_sensors_read_cmd() - retrieve data using the EC command protocol
 648 * @indio_dev:  pointer to IIO device
 649 * @scan_mask:  bitmap of the sensor indices to scan
 650 * @data:       location to store data
 651 *
 652 * Return: 0 on success, -errno on failure.
 653 */
 654int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev,
 655                             unsigned long scan_mask, s16 *data)
 656{
 657        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 658        int ret;
 659        unsigned int i;
 660
 661        /* Read all sensor data through a command. */
 662        st->param.cmd = MOTIONSENSE_CMD_DATA;
 663        ret = cros_ec_motion_send_host_cmd(st, sizeof(st->resp->data));
 664        if (ret != 0) {
 665                dev_warn(&indio_dev->dev, "Unable to read sensor data\n");
 666                return ret;
 667        }
 668
 669        for_each_set_bit(i, &scan_mask, indio_dev->masklength) {
 670                *data = st->resp->data.data[i];
 671                data++;
 672        }
 673
 674        return 0;
 675}
 676EXPORT_SYMBOL_GPL(cros_ec_sensors_read_cmd);
 677
 678/**
 679 * cros_ec_sensors_capture() - the trigger handler function
 680 * @irq:        the interrupt number.
 681 * @p:          a pointer to the poll function.
 682 *
 683 * On a trigger event occurring, if the pollfunc is attached then this
 684 * handler is called as a threaded interrupt (and hence may sleep). It
 685 * is responsible for grabbing data from the device and pushing it into
 686 * the associated buffer.
 687 *
 688 * Return: IRQ_HANDLED
 689 */
 690irqreturn_t cros_ec_sensors_capture(int irq, void *p)
 691{
 692        struct iio_poll_func *pf = p;
 693        struct iio_dev *indio_dev = pf->indio_dev;
 694        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 695        int ret;
 696
 697        mutex_lock(&st->cmd_lock);
 698
 699        /* Clear capture data. */
 700        memset(st->samples, 0, indio_dev->scan_bytes);
 701
 702        /* Read data based on which channels are enabled in scan mask. */
 703        ret = st->read_ec_sensors_data(indio_dev,
 704                                       *(indio_dev->active_scan_mask),
 705                                       (s16 *)st->samples);
 706        if (ret < 0)
 707                goto done;
 708
 709        iio_push_to_buffers_with_timestamp(indio_dev, st->samples,
 710                                           iio_get_time_ns(indio_dev));
 711
 712done:
 713        /*
 714         * Tell the core we are done with this trigger and ready for the
 715         * next one.
 716         */
 717        iio_trigger_notify_done(indio_dev->trig);
 718
 719        mutex_unlock(&st->cmd_lock);
 720
 721        return IRQ_HANDLED;
 722}
 723EXPORT_SYMBOL_GPL(cros_ec_sensors_capture);
 724
 725/**
 726 * cros_ec_sensors_core_read() - function to request a value from the sensor
 727 * @st:         pointer to state information for device
 728 * @chan:       channel specification structure table
 729 * @val:        will contain one element making up the returned value
 730 * @val2:       will contain another element making up the returned value
 731 * @mask:       specifies which values to be requested
 732 *
 733 * Return:      the type of value returned by the device
 734 */
 735int cros_ec_sensors_core_read(struct cros_ec_sensors_core_state *st,
 736                          struct iio_chan_spec const *chan,
 737                          int *val, int *val2, long mask)
 738{
 739        int ret, frequency;
 740
 741        switch (mask) {
 742        case IIO_CHAN_INFO_SAMP_FREQ:
 743                st->param.cmd = MOTIONSENSE_CMD_SENSOR_ODR;
 744                st->param.sensor_odr.data =
 745                        EC_MOTION_SENSE_NO_VALUE;
 746
 747                ret = cros_ec_motion_send_host_cmd(st, 0);
 748                if (ret)
 749                        break;
 750
 751                frequency = st->resp->sensor_odr.ret;
 752                *val = frequency / 1000;
 753                *val2 = (frequency % 1000) * 1000;
 754                ret = IIO_VAL_INT_PLUS_MICRO;
 755                break;
 756        default:
 757                ret = -EINVAL;
 758                break;
 759        }
 760
 761        return ret;
 762}
 763EXPORT_SYMBOL_GPL(cros_ec_sensors_core_read);
 764
 765/**
 766 * cros_ec_sensors_core_read_avail() - get available values
 767 * @indio_dev:          pointer to state information for device
 768 * @chan:       channel specification structure table
 769 * @vals:       list of available values
 770 * @type:       type of data returned
 771 * @length:     number of data returned in the array
 772 * @mask:       specifies which values to be requested
 773 *
 774 * Return:      an error code, IIO_AVAIL_RANGE or IIO_AVAIL_LIST
 775 */
 776int cros_ec_sensors_core_read_avail(struct iio_dev *indio_dev,
 777                                    struct iio_chan_spec const *chan,
 778                                    const int **vals,
 779                                    int *type,
 780                                    int *length,
 781                                    long mask)
 782{
 783        struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
 784
 785        switch (mask) {
 786        case IIO_CHAN_INFO_SAMP_FREQ:
 787                *length = ARRAY_SIZE(state->frequencies);
 788                *vals = (const int *)&state->frequencies;
 789                *type = IIO_VAL_INT_PLUS_MICRO;
 790                return IIO_AVAIL_LIST;
 791        }
 792
 793        return -EINVAL;
 794}
 795EXPORT_SYMBOL_GPL(cros_ec_sensors_core_read_avail);
 796
 797/**
 798 * cros_ec_sensors_core_write() - function to write a value to the sensor
 799 * @st:         pointer to state information for device
 800 * @chan:       channel specification structure table
 801 * @val:        first part of value to write
 802 * @val2:       second part of value to write
 803 * @mask:       specifies which values to write
 804 *
 805 * Return:      the type of value returned by the device
 806 */
 807int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
 808                               struct iio_chan_spec const *chan,
 809                               int val, int val2, long mask)
 810{
 811        int ret, frequency;
 812
 813        switch (mask) {
 814        case IIO_CHAN_INFO_SAMP_FREQ:
 815                frequency = val * 1000 + val2 / 1000;
 816                st->param.cmd = MOTIONSENSE_CMD_SENSOR_ODR;
 817                st->param.sensor_odr.data = frequency;
 818
 819                /* Always roundup, so caller gets at least what it asks for. */
 820                st->param.sensor_odr.roundup = 1;
 821
 822                ret = cros_ec_motion_send_host_cmd(st, 0);
 823                break;
 824        default:
 825                ret = -EINVAL;
 826                break;
 827        }
 828        return ret;
 829}
 830EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write);
 831
 832static int __maybe_unused cros_ec_sensors_resume(struct device *dev)
 833{
 834        struct platform_device *pdev = to_platform_device(dev);
 835        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 836        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 837        int ret = 0;
 838
 839        if (st->range_updated) {
 840                mutex_lock(&st->cmd_lock);
 841                st->param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
 842                st->param.sensor_range.data = st->curr_range;
 843                st->param.sensor_range.roundup = 1;
 844                ret = cros_ec_motion_send_host_cmd(st, 0);
 845                mutex_unlock(&st->cmd_lock);
 846        }
 847        return ret;
 848}
 849
 850SIMPLE_DEV_PM_OPS(cros_ec_sensors_pm_ops, NULL, cros_ec_sensors_resume);
 851EXPORT_SYMBOL_GPL(cros_ec_sensors_pm_ops);
 852
 853MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions");
 854MODULE_LICENSE("GPL v2");
 855