Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * cros_ec_baro - Driver for barometer sensor behind CrosEC.
0004  *
0005  * Copyright (C) 2017 Google, Inc
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/iio/buffer.h>
0010 #include <linux/iio/common/cros_ec_sensors_core.h>
0011 #include <linux/iio/iio.h>
0012 #include <linux/iio/kfifo_buf.h>
0013 #include <linux/iio/trigger.h>
0014 #include <linux/iio/triggered_buffer.h>
0015 #include <linux/iio/trigger_consumer.h>
0016 #include <linux/kernel.h>
0017 #include <linux/mod_devicetable.h>
0018 #include <linux/module.h>
0019 #include <linux/slab.h>
0020 #include <linux/platform_data/cros_ec_commands.h>
0021 #include <linux/platform_data/cros_ec_proto.h>
0022 #include <linux/platform_device.h>
0023 
0024 /*
0025  * One channel for pressure, the other for timestamp.
0026  */
0027 #define CROS_EC_BARO_MAX_CHANNELS (1 + 1)
0028 
0029 /* State data for ec_sensors iio driver. */
0030 struct cros_ec_baro_state {
0031     /* Shared by all sensors */
0032     struct cros_ec_sensors_core_state core;
0033 
0034     struct iio_chan_spec channels[CROS_EC_BARO_MAX_CHANNELS];
0035 };
0036 
0037 static int cros_ec_baro_read(struct iio_dev *indio_dev,
0038                  struct iio_chan_spec const *chan,
0039                  int *val, int *val2, long mask)
0040 {
0041     struct cros_ec_baro_state *st = iio_priv(indio_dev);
0042     u16 data = 0;
0043     int ret;
0044     int idx = chan->scan_index;
0045 
0046     mutex_lock(&st->core.cmd_lock);
0047 
0048     switch (mask) {
0049     case IIO_CHAN_INFO_RAW:
0050         ret = cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
0051                          (s16 *)&data);
0052         if (ret)
0053             break;
0054 
0055         *val = data;
0056         ret = IIO_VAL_INT;
0057         break;
0058     case IIO_CHAN_INFO_SCALE:
0059         st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
0060         st->core.param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;
0061 
0062         ret = cros_ec_motion_send_host_cmd(&st->core, 0);
0063         if (ret)
0064             break;
0065 
0066         *val = st->core.resp->sensor_range.ret;
0067 
0068         /* scale * in_pressure_raw --> kPa */
0069         *val2 = 10 << CROS_EC_SENSOR_BITS;
0070         ret = IIO_VAL_FRACTIONAL;
0071         break;
0072     default:
0073         ret = cros_ec_sensors_core_read(&st->core, chan, val, val2,
0074                         mask);
0075         break;
0076     }
0077 
0078     mutex_unlock(&st->core.cmd_lock);
0079 
0080     return ret;
0081 }
0082 
0083 static int cros_ec_baro_write(struct iio_dev *indio_dev,
0084                   struct iio_chan_spec const *chan,
0085                   int val, int val2, long mask)
0086 {
0087     struct cros_ec_baro_state *st = iio_priv(indio_dev);
0088     int ret = 0;
0089 
0090     mutex_lock(&st->core.cmd_lock);
0091 
0092     switch (mask) {
0093     case IIO_CHAN_INFO_SCALE:
0094         st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
0095         st->core.param.sensor_range.data = val;
0096 
0097         /* Always roundup, so caller gets at least what it asks for. */
0098         st->core.param.sensor_range.roundup = 1;
0099 
0100         ret = cros_ec_motion_send_host_cmd(&st->core, 0);
0101         if (ret == 0) {
0102             st->core.range_updated = true;
0103             st->core.curr_range = val;
0104         }
0105         break;
0106     default:
0107         ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
0108                          mask);
0109         break;
0110     }
0111 
0112     mutex_unlock(&st->core.cmd_lock);
0113 
0114     return ret;
0115 }
0116 
0117 static const struct iio_info cros_ec_baro_info = {
0118     .read_raw = &cros_ec_baro_read,
0119     .write_raw = &cros_ec_baro_write,
0120     .read_avail = &cros_ec_sensors_core_read_avail,
0121 };
0122 
0123 static int cros_ec_baro_probe(struct platform_device *pdev)
0124 {
0125     struct device *dev = &pdev->dev;
0126     struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
0127     struct iio_dev *indio_dev;
0128     struct cros_ec_baro_state *state;
0129     struct iio_chan_spec *channel;
0130     int ret;
0131 
0132     if (!ec_dev || !ec_dev->ec_dev) {
0133         dev_warn(dev, "No CROS EC device found.\n");
0134         return -EINVAL;
0135     }
0136 
0137     indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
0138     if (!indio_dev)
0139         return -ENOMEM;
0140 
0141     ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
0142                     cros_ec_sensors_capture);
0143     if (ret)
0144         return ret;
0145 
0146     indio_dev->info = &cros_ec_baro_info;
0147     state = iio_priv(indio_dev);
0148     channel = state->channels;
0149     /* Common part */
0150     channel->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
0151     channel->info_mask_shared_by_all =
0152         BIT(IIO_CHAN_INFO_SCALE) |
0153         BIT(IIO_CHAN_INFO_SAMP_FREQ);
0154     channel->info_mask_shared_by_all_available =
0155         BIT(IIO_CHAN_INFO_SAMP_FREQ);
0156     channel->scan_type.realbits = CROS_EC_SENSOR_BITS;
0157     channel->scan_type.storagebits = CROS_EC_SENSOR_BITS;
0158     channel->scan_type.shift = 0;
0159     channel->scan_index = 0;
0160     channel->ext_info = cros_ec_sensors_ext_info;
0161     channel->scan_type.sign = 'u';
0162 
0163     /* Sensor specific */
0164     switch (state->core.type) {
0165     case MOTIONSENSE_TYPE_BARO:
0166         channel->type = IIO_PRESSURE;
0167         break;
0168     default:
0169         dev_warn(dev, "Unknown motion sensor\n");
0170         return -EINVAL;
0171     }
0172 
0173     /* Timestamp */
0174     channel++;
0175     channel->type = IIO_TIMESTAMP;
0176     channel->channel = -1;
0177     channel->scan_index = 1;
0178     channel->scan_type.sign = 's';
0179     channel->scan_type.realbits = 64;
0180     channel->scan_type.storagebits = 64;
0181 
0182     indio_dev->channels = state->channels;
0183     indio_dev->num_channels = CROS_EC_BARO_MAX_CHANNELS;
0184 
0185     state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
0186 
0187     return cros_ec_sensors_core_register(dev, indio_dev,
0188                          cros_ec_sensors_push_data);
0189 }
0190 
0191 static const struct platform_device_id cros_ec_baro_ids[] = {
0192     {
0193         .name = "cros-ec-baro",
0194     },
0195     { /* sentinel */ }
0196 };
0197 MODULE_DEVICE_TABLE(platform, cros_ec_baro_ids);
0198 
0199 static struct platform_driver cros_ec_baro_platform_driver = {
0200     .driver = {
0201         .name   = "cros-ec-baro",
0202         .pm = &cros_ec_sensors_pm_ops,
0203     },
0204     .probe      = cros_ec_baro_probe,
0205     .id_table   = cros_ec_baro_ids,
0206 };
0207 module_platform_driver(cros_ec_baro_platform_driver);
0208 
0209 MODULE_DESCRIPTION("ChromeOS EC barometer sensor driver");
0210 MODULE_LICENSE("GPL v2");