Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * mpl3115.c - Support for Freescale MPL3115A2 pressure/temperature sensor
0004  *
0005  * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
0006  *
0007  * (7-bit I2C slave address 0x60)
0008  *
0009  * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode,
0010  * interrupts, user offset correction, raw mode
0011  */
0012 
0013 #include <linux/module.h>
0014 #include <linux/i2c.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/iio/sysfs.h>
0017 #include <linux/iio/trigger_consumer.h>
0018 #include <linux/iio/buffer.h>
0019 #include <linux/iio/triggered_buffer.h>
0020 #include <linux/delay.h>
0021 
0022 #define MPL3115_STATUS 0x00
0023 #define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */
0024 #define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */
0025 #define MPL3115_WHO_AM_I 0x0c
0026 #define MPL3115_CTRL_REG1 0x26
0027 
0028 #define MPL3115_DEVICE_ID 0xc4
0029 
0030 #define MPL3115_STATUS_PRESS_RDY BIT(2)
0031 #define MPL3115_STATUS_TEMP_RDY BIT(1)
0032 
0033 #define MPL3115_CTRL_RESET BIT(2) /* software reset */
0034 #define MPL3115_CTRL_OST BIT(1) /* initiate measurement */
0035 #define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */
0036 #define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */
0037 
0038 struct mpl3115_data {
0039     struct i2c_client *client;
0040     struct mutex lock;
0041     u8 ctrl_reg1;
0042 };
0043 
0044 static int mpl3115_request(struct mpl3115_data *data)
0045 {
0046     int ret, tries = 15;
0047 
0048     /* trigger measurement */
0049     ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
0050         data->ctrl_reg1 | MPL3115_CTRL_OST);
0051     if (ret < 0)
0052         return ret;
0053 
0054     while (tries-- > 0) {
0055         ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG1);
0056         if (ret < 0)
0057             return ret;
0058         /* wait for data ready, i.e. OST cleared */
0059         if (!(ret & MPL3115_CTRL_OST))
0060             break;
0061         msleep(20);
0062     }
0063 
0064     if (tries < 0) {
0065         dev_err(&data->client->dev, "data not ready\n");
0066         return -EIO;
0067     }
0068 
0069     return 0;
0070 }
0071 
0072 static int mpl3115_read_raw(struct iio_dev *indio_dev,
0073                 struct iio_chan_spec const *chan,
0074                 int *val, int *val2, long mask)
0075 {
0076     struct mpl3115_data *data = iio_priv(indio_dev);
0077     int ret;
0078 
0079     switch (mask) {
0080     case IIO_CHAN_INFO_RAW:
0081         ret = iio_device_claim_direct_mode(indio_dev);
0082         if (ret)
0083             return ret;
0084 
0085         switch (chan->type) {
0086         case IIO_PRESSURE: { /* in 0.25 pascal / LSB */
0087             __be32 tmp = 0;
0088 
0089             mutex_lock(&data->lock);
0090             ret = mpl3115_request(data);
0091             if (ret < 0) {
0092                 mutex_unlock(&data->lock);
0093                 break;
0094             }
0095             ret = i2c_smbus_read_i2c_block_data(data->client,
0096                 MPL3115_OUT_PRESS, 3, (u8 *) &tmp);
0097             mutex_unlock(&data->lock);
0098             if (ret < 0)
0099                 break;
0100             *val = be32_to_cpu(tmp) >> chan->scan_type.shift;
0101             ret = IIO_VAL_INT;
0102             break;
0103         }
0104         case IIO_TEMP: { /* in 0.0625 celsius / LSB */
0105             __be16 tmp;
0106 
0107             mutex_lock(&data->lock);
0108             ret = mpl3115_request(data);
0109             if (ret < 0) {
0110                 mutex_unlock(&data->lock);
0111                 break;
0112             }
0113             ret = i2c_smbus_read_i2c_block_data(data->client,
0114                 MPL3115_OUT_TEMP, 2, (u8 *) &tmp);
0115             mutex_unlock(&data->lock);
0116             if (ret < 0)
0117                 break;
0118             *val = sign_extend32(be16_to_cpu(tmp) >> chan->scan_type.shift,
0119                          chan->scan_type.realbits - 1);
0120             ret = IIO_VAL_INT;
0121             break;
0122         }
0123         default:
0124             ret = -EINVAL;
0125             break;
0126         }
0127 
0128         iio_device_release_direct_mode(indio_dev);
0129         return ret;
0130 
0131     case IIO_CHAN_INFO_SCALE:
0132         switch (chan->type) {
0133         case IIO_PRESSURE:
0134             *val = 0;
0135             *val2 = 250; /* want kilopascal */
0136             return IIO_VAL_INT_PLUS_MICRO;
0137         case IIO_TEMP:
0138             *val = 0;
0139             *val2 = 62500;
0140             return IIO_VAL_INT_PLUS_MICRO;
0141         default:
0142             return -EINVAL;
0143         }
0144     }
0145     return -EINVAL;
0146 }
0147 
0148 static irqreturn_t mpl3115_trigger_handler(int irq, void *p)
0149 {
0150     struct iio_poll_func *pf = p;
0151     struct iio_dev *indio_dev = pf->indio_dev;
0152     struct mpl3115_data *data = iio_priv(indio_dev);
0153     /*
0154      * 32-bit channel + 16-bit channel + padding + ts
0155      * Note that it is possible for only one of the first 2
0156      * channels to be enabled. If that happens, the first element
0157      * of the buffer may be either 16 or 32-bits.  As such we cannot
0158      * use a simple structure definition to express this data layout.
0159      */
0160     u8 buffer[16] __aligned(8);
0161     int ret, pos = 0;
0162 
0163     mutex_lock(&data->lock);
0164     ret = mpl3115_request(data);
0165     if (ret < 0) {
0166         mutex_unlock(&data->lock);
0167         goto done;
0168     }
0169 
0170     memset(buffer, 0, sizeof(buffer));
0171     if (test_bit(0, indio_dev->active_scan_mask)) {
0172         ret = i2c_smbus_read_i2c_block_data(data->client,
0173             MPL3115_OUT_PRESS, 3, &buffer[pos]);
0174         if (ret < 0) {
0175             mutex_unlock(&data->lock);
0176             goto done;
0177         }
0178         pos += 4;
0179     }
0180 
0181     if (test_bit(1, indio_dev->active_scan_mask)) {
0182         ret = i2c_smbus_read_i2c_block_data(data->client,
0183             MPL3115_OUT_TEMP, 2, &buffer[pos]);
0184         if (ret < 0) {
0185             mutex_unlock(&data->lock);
0186             goto done;
0187         }
0188     }
0189     mutex_unlock(&data->lock);
0190 
0191     iio_push_to_buffers_with_timestamp(indio_dev, buffer,
0192         iio_get_time_ns(indio_dev));
0193 
0194 done:
0195     iio_trigger_notify_done(indio_dev->trig);
0196     return IRQ_HANDLED;
0197 }
0198 
0199 static const struct iio_chan_spec mpl3115_channels[] = {
0200     {
0201         .type = IIO_PRESSURE,
0202         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0203         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
0204         .scan_index = 0,
0205         .scan_type = {
0206             .sign = 'u',
0207             .realbits = 20,
0208             .storagebits = 32,
0209             .shift = 12,
0210             .endianness = IIO_BE,
0211         }
0212     },
0213     {
0214         .type = IIO_TEMP,
0215         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0216         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
0217         .scan_index = 1,
0218         .scan_type = {
0219             .sign = 's',
0220             .realbits = 12,
0221             .storagebits = 16,
0222             .shift = 4,
0223             .endianness = IIO_BE,
0224         }
0225     },
0226     IIO_CHAN_SOFT_TIMESTAMP(2),
0227 };
0228 
0229 static const struct iio_info mpl3115_info = {
0230     .read_raw = &mpl3115_read_raw,
0231 };
0232 
0233 static int mpl3115_probe(struct i2c_client *client,
0234              const struct i2c_device_id *id)
0235 {
0236     struct mpl3115_data *data;
0237     struct iio_dev *indio_dev;
0238     int ret;
0239 
0240     ret = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I);
0241     if (ret < 0)
0242         return ret;
0243     if (ret != MPL3115_DEVICE_ID)
0244         return -ENODEV;
0245 
0246     indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0247     if (!indio_dev)
0248         return -ENOMEM;
0249 
0250     data = iio_priv(indio_dev);
0251     data->client = client;
0252     mutex_init(&data->lock);
0253 
0254     i2c_set_clientdata(client, indio_dev);
0255     indio_dev->info = &mpl3115_info;
0256     indio_dev->name = id->name;
0257     indio_dev->modes = INDIO_DIRECT_MODE;
0258     indio_dev->channels = mpl3115_channels;
0259     indio_dev->num_channels = ARRAY_SIZE(mpl3115_channels);
0260 
0261     /* software reset, I2C transfer is aborted (fails) */
0262     i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
0263         MPL3115_CTRL_RESET);
0264     msleep(50);
0265 
0266     data->ctrl_reg1 = MPL3115_CTRL_OS_258MS;
0267     ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
0268         data->ctrl_reg1);
0269     if (ret < 0)
0270         return ret;
0271 
0272     ret = iio_triggered_buffer_setup(indio_dev, NULL,
0273         mpl3115_trigger_handler, NULL);
0274     if (ret < 0)
0275         return ret;
0276 
0277     ret = iio_device_register(indio_dev);
0278     if (ret < 0)
0279         goto buffer_cleanup;
0280     return 0;
0281 
0282 buffer_cleanup:
0283     iio_triggered_buffer_cleanup(indio_dev);
0284     return ret;
0285 }
0286 
0287 static int mpl3115_standby(struct mpl3115_data *data)
0288 {
0289     return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
0290         data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE);
0291 }
0292 
0293 static int mpl3115_remove(struct i2c_client *client)
0294 {
0295     struct iio_dev *indio_dev = i2c_get_clientdata(client);
0296 
0297     iio_device_unregister(indio_dev);
0298     iio_triggered_buffer_cleanup(indio_dev);
0299     mpl3115_standby(iio_priv(indio_dev));
0300 
0301     return 0;
0302 }
0303 
0304 static int mpl3115_suspend(struct device *dev)
0305 {
0306     return mpl3115_standby(iio_priv(i2c_get_clientdata(
0307         to_i2c_client(dev))));
0308 }
0309 
0310 static int mpl3115_resume(struct device *dev)
0311 {
0312     struct mpl3115_data *data = iio_priv(i2c_get_clientdata(
0313         to_i2c_client(dev)));
0314 
0315     return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
0316         data->ctrl_reg1);
0317 }
0318 
0319 static DEFINE_SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend,
0320                 mpl3115_resume);
0321 
0322 static const struct i2c_device_id mpl3115_id[] = {
0323     { "mpl3115", 0 },
0324     { }
0325 };
0326 MODULE_DEVICE_TABLE(i2c, mpl3115_id);
0327 
0328 static const struct of_device_id mpl3115_of_match[] = {
0329     { .compatible = "fsl,mpl3115" },
0330     { }
0331 };
0332 MODULE_DEVICE_TABLE(of, mpl3115_of_match);
0333 
0334 static struct i2c_driver mpl3115_driver = {
0335     .driver = {
0336         .name   = "mpl3115",
0337         .of_match_table = mpl3115_of_match,
0338         .pm = pm_sleep_ptr(&mpl3115_pm_ops),
0339     },
0340     .probe = mpl3115_probe,
0341     .remove = mpl3115_remove,
0342     .id_table = mpl3115_id,
0343 };
0344 module_i2c_driver(mpl3115_driver);
0345 
0346 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
0347 MODULE_DESCRIPTION("Freescale MPL3115 pressure/temperature driver");
0348 MODULE_LICENSE("GPL");