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