root/drivers/iio/pressure/mpl3115.c

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

DEFINITIONS

This source file includes following definitions.
  1. mpl3115_request
  2. mpl3115_read_raw
  3. mpl3115_trigger_handler
  4. mpl3115_probe
  5. mpl3115_standby
  6. mpl3115_remove
  7. mpl3115_suspend
  8. mpl3115_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * mpl3115.c - Support for Freescale MPL3115A2 pressure/temperature sensor
   4  *
   5  * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
   6  *
   7  * (7-bit I2C slave address 0x60)
   8  *
   9  * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode,
  10  * interrupts, user offset correction, raw mode
  11  */
  12 
  13 #include <linux/module.h>
  14 #include <linux/i2c.h>
  15 #include <linux/iio/iio.h>
  16 #include <linux/iio/sysfs.h>
  17 #include <linux/iio/trigger_consumer.h>
  18 #include <linux/iio/buffer.h>
  19 #include <linux/iio/triggered_buffer.h>
  20 #include <linux/delay.h>
  21 
  22 #define MPL3115_STATUS 0x00
  23 #define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */
  24 #define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */
  25 #define MPL3115_WHO_AM_I 0x0c
  26 #define MPL3115_CTRL_REG1 0x26
  27 
  28 #define MPL3115_DEVICE_ID 0xc4
  29 
  30 #define MPL3115_STATUS_PRESS_RDY BIT(2)
  31 #define MPL3115_STATUS_TEMP_RDY BIT(1)
  32 
  33 #define MPL3115_CTRL_RESET BIT(2) /* software reset */
  34 #define MPL3115_CTRL_OST BIT(1) /* initiate measurement */
  35 #define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */
  36 #define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */
  37 
  38 struct mpl3115_data {
  39         struct i2c_client *client;
  40         struct mutex lock;
  41         u8 ctrl_reg1;
  42 };
  43 
  44 static int mpl3115_request(struct mpl3115_data *data)
  45 {
  46         int ret, tries = 15;
  47 
  48         /* trigger measurement */
  49         ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
  50                 data->ctrl_reg1 | MPL3115_CTRL_OST);
  51         if (ret < 0)
  52                 return ret;
  53 
  54         while (tries-- > 0) {
  55                 ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG1);
  56                 if (ret < 0)
  57                         return ret;
  58                 /* wait for data ready, i.e. OST cleared */
  59                 if (!(ret & MPL3115_CTRL_OST))
  60                         break;
  61                 msleep(20);
  62         }
  63 
  64         if (tries < 0) {
  65                 dev_err(&data->client->dev, "data not ready\n");
  66                 return -EIO;
  67         }
  68 
  69         return 0;
  70 }
  71 
  72 static int mpl3115_read_raw(struct iio_dev *indio_dev,
  73                             struct iio_chan_spec const *chan,
  74                             int *val, int *val2, long mask)
  75 {
  76         struct mpl3115_data *data = iio_priv(indio_dev);
  77         __be32 tmp = 0;
  78         int ret;
  79 
  80         switch (mask) {
  81         case IIO_CHAN_INFO_RAW:
  82                 ret = iio_device_claim_direct_mode(indio_dev);
  83                 if (ret)
  84                         return ret;
  85 
  86                 switch (chan->type) {
  87                 case IIO_PRESSURE: /* in 0.25 pascal / LSB */
  88                         mutex_lock(&data->lock);
  89                         ret = mpl3115_request(data);
  90                         if (ret < 0) {
  91                                 mutex_unlock(&data->lock);
  92                                 break;
  93                         }
  94                         ret = i2c_smbus_read_i2c_block_data(data->client,
  95                                 MPL3115_OUT_PRESS, 3, (u8 *) &tmp);
  96                         mutex_unlock(&data->lock);
  97                         if (ret < 0)
  98                                 break;
  99                         *val = be32_to_cpu(tmp) >> 12;
 100                         ret = IIO_VAL_INT;
 101                         break;
 102                 case IIO_TEMP: /* in 0.0625 celsius / LSB */
 103                         mutex_lock(&data->lock);
 104                         ret = mpl3115_request(data);
 105                         if (ret < 0) {
 106                                 mutex_unlock(&data->lock);
 107                                 break;
 108                         }
 109                         ret = i2c_smbus_read_i2c_block_data(data->client,
 110                                 MPL3115_OUT_TEMP, 2, (u8 *) &tmp);
 111                         mutex_unlock(&data->lock);
 112                         if (ret < 0)
 113                                 break;
 114                         *val = sign_extend32(be32_to_cpu(tmp) >> 20, 11);
 115                         ret = IIO_VAL_INT;
 116                         break;
 117                 default:
 118                         ret = -EINVAL;
 119                         break;
 120                 }
 121 
 122                 iio_device_release_direct_mode(indio_dev);
 123                 return ret;
 124 
 125         case IIO_CHAN_INFO_SCALE:
 126                 switch (chan->type) {
 127                 case IIO_PRESSURE:
 128                         *val = 0;
 129                         *val2 = 250; /* want kilopascal */
 130                         return IIO_VAL_INT_PLUS_MICRO;
 131                 case IIO_TEMP:
 132                         *val = 0;
 133                         *val2 = 62500;
 134                         return IIO_VAL_INT_PLUS_MICRO;
 135                 default:
 136                         return -EINVAL;
 137                 }
 138         }
 139         return -EINVAL;
 140 }
 141 
 142 static irqreturn_t mpl3115_trigger_handler(int irq, void *p)
 143 {
 144         struct iio_poll_func *pf = p;
 145         struct iio_dev *indio_dev = pf->indio_dev;
 146         struct mpl3115_data *data = iio_priv(indio_dev);
 147         u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */
 148         int ret, pos = 0;
 149 
 150         mutex_lock(&data->lock);
 151         ret = mpl3115_request(data);
 152         if (ret < 0) {
 153                 mutex_unlock(&data->lock);
 154                 goto done;
 155         }
 156 
 157         memset(buffer, 0, sizeof(buffer));
 158         if (test_bit(0, indio_dev->active_scan_mask)) {
 159                 ret = i2c_smbus_read_i2c_block_data(data->client,
 160                         MPL3115_OUT_PRESS, 3, &buffer[pos]);
 161                 if (ret < 0) {
 162                         mutex_unlock(&data->lock);
 163                         goto done;
 164                 }
 165                 pos += 4;
 166         }
 167 
 168         if (test_bit(1, indio_dev->active_scan_mask)) {
 169                 ret = i2c_smbus_read_i2c_block_data(data->client,
 170                         MPL3115_OUT_TEMP, 2, &buffer[pos]);
 171                 if (ret < 0) {
 172                         mutex_unlock(&data->lock);
 173                         goto done;
 174                 }
 175         }
 176         mutex_unlock(&data->lock);
 177 
 178         iio_push_to_buffers_with_timestamp(indio_dev, buffer,
 179                 iio_get_time_ns(indio_dev));
 180 
 181 done:
 182         iio_trigger_notify_done(indio_dev->trig);
 183         return IRQ_HANDLED;
 184 }
 185 
 186 static const struct iio_chan_spec mpl3115_channels[] = {
 187         {
 188                 .type = IIO_PRESSURE,
 189                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 190                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 191                 .scan_index = 0,
 192                 .scan_type = {
 193                         .sign = 'u',
 194                         .realbits = 20,
 195                         .storagebits = 32,
 196                         .shift = 12,
 197                         .endianness = IIO_BE,
 198                 }
 199         },
 200         {
 201                 .type = IIO_TEMP,
 202                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 203                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 204                 .scan_index = 1,
 205                 .scan_type = {
 206                         .sign = 's',
 207                         .realbits = 12,
 208                         .storagebits = 16,
 209                         .shift = 4,
 210                         .endianness = IIO_BE,
 211                 }
 212         },
 213         IIO_CHAN_SOFT_TIMESTAMP(2),
 214 };
 215 
 216 static const struct iio_info mpl3115_info = {
 217         .read_raw = &mpl3115_read_raw,
 218 };
 219 
 220 static int mpl3115_probe(struct i2c_client *client,
 221                          const struct i2c_device_id *id)
 222 {
 223         struct mpl3115_data *data;
 224         struct iio_dev *indio_dev;
 225         int ret;
 226 
 227         ret = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I);
 228         if (ret < 0)
 229                 return ret;
 230         if (ret != MPL3115_DEVICE_ID)
 231                 return -ENODEV;
 232 
 233         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 234         if (!indio_dev)
 235                 return -ENOMEM;
 236 
 237         data = iio_priv(indio_dev);
 238         data->client = client;
 239         mutex_init(&data->lock);
 240 
 241         i2c_set_clientdata(client, indio_dev);
 242         indio_dev->info = &mpl3115_info;
 243         indio_dev->name = id->name;
 244         indio_dev->dev.parent = &client->dev;
 245         indio_dev->modes = INDIO_DIRECT_MODE;
 246         indio_dev->channels = mpl3115_channels;
 247         indio_dev->num_channels = ARRAY_SIZE(mpl3115_channels);
 248 
 249         /* software reset, I2C transfer is aborted (fails) */
 250         i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
 251                 MPL3115_CTRL_RESET);
 252         msleep(50);
 253 
 254         data->ctrl_reg1 = MPL3115_CTRL_OS_258MS;
 255         ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
 256                 data->ctrl_reg1);
 257         if (ret < 0)
 258                 return ret;
 259 
 260         ret = iio_triggered_buffer_setup(indio_dev, NULL,
 261                 mpl3115_trigger_handler, NULL);
 262         if (ret < 0)
 263                 return ret;
 264 
 265         ret = iio_device_register(indio_dev);
 266         if (ret < 0)
 267                 goto buffer_cleanup;
 268         return 0;
 269 
 270 buffer_cleanup:
 271         iio_triggered_buffer_cleanup(indio_dev);
 272         return ret;
 273 }
 274 
 275 static int mpl3115_standby(struct mpl3115_data *data)
 276 {
 277         return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
 278                 data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE);
 279 }
 280 
 281 static int mpl3115_remove(struct i2c_client *client)
 282 {
 283         struct iio_dev *indio_dev = i2c_get_clientdata(client);
 284 
 285         iio_device_unregister(indio_dev);
 286         iio_triggered_buffer_cleanup(indio_dev);
 287         mpl3115_standby(iio_priv(indio_dev));
 288 
 289         return 0;
 290 }
 291 
 292 #ifdef CONFIG_PM_SLEEP
 293 static int mpl3115_suspend(struct device *dev)
 294 {
 295         return mpl3115_standby(iio_priv(i2c_get_clientdata(
 296                 to_i2c_client(dev))));
 297 }
 298 
 299 static int mpl3115_resume(struct device *dev)
 300 {
 301         struct mpl3115_data *data = iio_priv(i2c_get_clientdata(
 302                 to_i2c_client(dev)));
 303 
 304         return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
 305                 data->ctrl_reg1);
 306 }
 307 
 308 static SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume);
 309 #define MPL3115_PM_OPS (&mpl3115_pm_ops)
 310 #else
 311 #define MPL3115_PM_OPS NULL
 312 #endif
 313 
 314 static const struct i2c_device_id mpl3115_id[] = {
 315         { "mpl3115", 0 },
 316         { }
 317 };
 318 MODULE_DEVICE_TABLE(i2c, mpl3115_id);
 319 
 320 static const struct of_device_id mpl3115_of_match[] = {
 321         { .compatible = "fsl,mpl3115" },
 322         { }
 323 };
 324 MODULE_DEVICE_TABLE(of, mpl3115_of_match);
 325 
 326 static struct i2c_driver mpl3115_driver = {
 327         .driver = {
 328                 .name   = "mpl3115",
 329                 .of_match_table = mpl3115_of_match,
 330                 .pm     = MPL3115_PM_OPS,
 331         },
 332         .probe = mpl3115_probe,
 333         .remove = mpl3115_remove,
 334         .id_table = mpl3115_id,
 335 };
 336 module_i2c_driver(mpl3115_driver);
 337 
 338 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
 339 MODULE_DESCRIPTION("Freescale MPL3115 pressure/temperature driver");
 340 MODULE_LICENSE("GPL");

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