root/drivers/iio/pressure/cros_ec_baro.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cros_ec_baro_read
  2. cros_ec_baro_write
  3. cros_ec_baro_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * cros_ec_baro - Driver for barometer sensor behind CrosEC.
   4  *
   5  * Copyright (C) 2017 Google, Inc
   6  */
   7 
   8 #include <linux/device.h>
   9 #include <linux/iio/buffer.h>
  10 #include <linux/iio/common/cros_ec_sensors_core.h>
  11 #include <linux/iio/iio.h>
  12 #include <linux/iio/kfifo_buf.h>
  13 #include <linux/iio/trigger.h>
  14 #include <linux/iio/triggered_buffer.h>
  15 #include <linux/iio/trigger_consumer.h>
  16 #include <linux/kernel.h>
  17 #include <linux/mfd/cros_ec.h>
  18 #include <linux/module.h>
  19 #include <linux/slab.h>
  20 #include <linux/platform_data/cros_ec_commands.h>
  21 #include <linux/platform_data/cros_ec_proto.h>
  22 #include <linux/platform_device.h>
  23 
  24 /*
  25  * One channel for pressure, the other for timestamp.
  26  */
  27 #define CROS_EC_BARO_MAX_CHANNELS (1 + 1)
  28 
  29 /* State data for ec_sensors iio driver. */
  30 struct cros_ec_baro_state {
  31         /* Shared by all sensors */
  32         struct cros_ec_sensors_core_state core;
  33 
  34         struct iio_chan_spec channels[CROS_EC_BARO_MAX_CHANNELS];
  35 };
  36 
  37 static int cros_ec_baro_read(struct iio_dev *indio_dev,
  38                              struct iio_chan_spec const *chan,
  39                              int *val, int *val2, long mask)
  40 {
  41         struct cros_ec_baro_state *st = iio_priv(indio_dev);
  42         u16 data = 0;
  43         int ret;
  44         int idx = chan->scan_index;
  45 
  46         mutex_lock(&st->core.cmd_lock);
  47 
  48         switch (mask) {
  49         case IIO_CHAN_INFO_RAW:
  50                 ret = cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
  51                                              (s16 *)&data);
  52                 if (ret)
  53                         break;
  54 
  55                 *val = data;
  56                 ret = IIO_VAL_INT;
  57                 break;
  58         case IIO_CHAN_INFO_SCALE:
  59                 st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
  60                 st->core.param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;
  61 
  62                 ret = cros_ec_motion_send_host_cmd(&st->core, 0);
  63                 if (ret)
  64                         break;
  65 
  66                 *val = st->core.resp->sensor_range.ret;
  67 
  68                 /* scale * in_pressure_raw --> kPa */
  69                 *val2 = 10 << CROS_EC_SENSOR_BITS;
  70                 ret = IIO_VAL_FRACTIONAL;
  71                 break;
  72         default:
  73                 ret = cros_ec_sensors_core_read(&st->core, chan, val, val2,
  74                                                 mask);
  75                 break;
  76         }
  77 
  78         mutex_unlock(&st->core.cmd_lock);
  79 
  80         return ret;
  81 }
  82 
  83 static int cros_ec_baro_write(struct iio_dev *indio_dev,
  84                               struct iio_chan_spec const *chan,
  85                               int val, int val2, long mask)
  86 {
  87         struct cros_ec_baro_state *st = iio_priv(indio_dev);
  88         int ret = 0;
  89 
  90         mutex_lock(&st->core.cmd_lock);
  91 
  92         switch (mask) {
  93         case IIO_CHAN_INFO_SCALE:
  94                 st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
  95                 st->core.param.sensor_range.data = val;
  96 
  97                 /* Always roundup, so caller gets at least what it asks for. */
  98                 st->core.param.sensor_range.roundup = 1;
  99 
 100                 if (cros_ec_motion_send_host_cmd(&st->core, 0))
 101                         ret = -EIO;
 102                 break;
 103         default:
 104                 ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
 105                                                  mask);
 106                 break;
 107         }
 108 
 109         mutex_unlock(&st->core.cmd_lock);
 110 
 111         return ret;
 112 }
 113 
 114 static const struct iio_info cros_ec_baro_info = {
 115         .read_raw = &cros_ec_baro_read,
 116         .write_raw = &cros_ec_baro_write,
 117         .read_avail = &cros_ec_sensors_core_read_avail,
 118 };
 119 
 120 static int cros_ec_baro_probe(struct platform_device *pdev)
 121 {
 122         struct device *dev = &pdev->dev;
 123         struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
 124         struct iio_dev *indio_dev;
 125         struct cros_ec_baro_state *state;
 126         struct iio_chan_spec *channel;
 127         int ret;
 128 
 129         if (!ec_dev || !ec_dev->ec_dev) {
 130                 dev_warn(dev, "No CROS EC device found.\n");
 131                 return -EINVAL;
 132         }
 133 
 134         indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
 135         if (!indio_dev)
 136                 return -ENOMEM;
 137 
 138         ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
 139         if (ret)
 140                 return ret;
 141 
 142         indio_dev->info = &cros_ec_baro_info;
 143         state = iio_priv(indio_dev);
 144         state->core.type = state->core.resp->info.type;
 145         state->core.loc = state->core.resp->info.location;
 146         channel = state->channels;
 147         /* Common part */
 148         channel->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
 149         channel->info_mask_shared_by_all =
 150                 BIT(IIO_CHAN_INFO_SCALE) |
 151                 BIT(IIO_CHAN_INFO_SAMP_FREQ) |
 152                 BIT(IIO_CHAN_INFO_FREQUENCY);
 153         channel->info_mask_shared_by_all_available =
 154                 BIT(IIO_CHAN_INFO_SAMP_FREQ);
 155         channel->scan_type.realbits = CROS_EC_SENSOR_BITS;
 156         channel->scan_type.storagebits = CROS_EC_SENSOR_BITS;
 157         channel->scan_type.shift = 0;
 158         channel->scan_index = 0;
 159         channel->ext_info = cros_ec_sensors_ext_info;
 160         channel->scan_type.sign = 'u';
 161 
 162         /* Sensor specific */
 163         switch (state->core.type) {
 164         case MOTIONSENSE_TYPE_BARO:
 165                 channel->type = IIO_PRESSURE;
 166                 break;
 167         default:
 168                 dev_warn(dev, "Unknown motion sensor\n");
 169                 return -EINVAL;
 170         }
 171 
 172         /* Timestamp */
 173         channel++;
 174         channel->type = IIO_TIMESTAMP;
 175         channel->channel = -1;
 176         channel->scan_index = 1;
 177         channel->scan_type.sign = 's';
 178         channel->scan_type.realbits = 64;
 179         channel->scan_type.storagebits = 64;
 180 
 181         indio_dev->channels = state->channels;
 182         indio_dev->num_channels = CROS_EC_BARO_MAX_CHANNELS;
 183 
 184         state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
 185 
 186         ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
 187                                               cros_ec_sensors_capture, NULL);
 188         if (ret)
 189                 return ret;
 190 
 191         return devm_iio_device_register(dev, indio_dev);
 192 }
 193 
 194 static const struct platform_device_id cros_ec_baro_ids[] = {
 195         {
 196                 .name = "cros-ec-baro",
 197         },
 198         { /* sentinel */ }
 199 };
 200 MODULE_DEVICE_TABLE(platform, cros_ec_baro_ids);
 201 
 202 static struct platform_driver cros_ec_baro_platform_driver = {
 203         .driver = {
 204                 .name   = "cros-ec-baro",
 205         },
 206         .probe          = cros_ec_baro_probe,
 207         .id_table       = cros_ec_baro_ids,
 208 };
 209 module_platform_driver(cros_ec_baro_platform_driver);
 210 
 211 MODULE_DESCRIPTION("ChromeOS EC barometer sensor driver");
 212 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */