Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.git] / drivers / iio / pressure / mpl3115.c
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
41 struct mpl3115_data {
42         struct i2c_client *client;
43         struct mutex lock;
44         u8 ctrl_reg1;
45 };
46
47 static 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
75 static 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                 ret = iio_device_claim_direct_mode(indio_dev);
86                 if (ret)
87                         return ret;
88
89                 switch (chan->type) {
90                 case IIO_PRESSURE: /* in 0.25 pascal / LSB */
91                         mutex_lock(&data->lock);
92                         ret = mpl3115_request(data);
93                         if (ret < 0) {
94                                 mutex_unlock(&data->lock);
95                                 break;
96                         }
97                         ret = i2c_smbus_read_i2c_block_data(data->client,
98                                 MPL3115_OUT_PRESS, 3, (u8 *) &tmp);
99                         mutex_unlock(&data->lock);
100                         if (ret < 0)
101                                 break;
102                         *val = be32_to_cpu(tmp) >> 12;
103                         ret = IIO_VAL_INT;
104                         break;
105                 case IIO_TEMP: /* in 0.0625 celsius / LSB */
106                         mutex_lock(&data->lock);
107                         ret = mpl3115_request(data);
108                         if (ret < 0) {
109                                 mutex_unlock(&data->lock);
110                                 break;
111                         }
112                         ret = i2c_smbus_read_i2c_block_data(data->client,
113                                 MPL3115_OUT_TEMP, 2, (u8 *) &tmp);
114                         mutex_unlock(&data->lock);
115                         if (ret < 0)
116                                 break;
117                         *val = sign_extend32(be32_to_cpu(tmp) >> 20, 11);
118                         ret = IIO_VAL_INT;
119                         break;
120                 default:
121                         ret = -EINVAL;
122                         break;
123                 }
124
125                 iio_device_release_direct_mode(indio_dev);
126                 return ret;
127
128         case IIO_CHAN_INFO_SCALE:
129                 switch (chan->type) {
130                 case IIO_PRESSURE:
131                         *val = 0;
132                         *val2 = 250; /* want kilopascal */
133                         return IIO_VAL_INT_PLUS_MICRO;
134                 case IIO_TEMP:
135                         *val = 0;
136                         *val2 = 62500;
137                         return IIO_VAL_INT_PLUS_MICRO;
138                 default:
139                         return -EINVAL;
140                 }
141         }
142         return -EINVAL;
143 }
144
145 static irqreturn_t mpl3115_trigger_handler(int irq, void *p)
146 {
147         struct iio_poll_func *pf = p;
148         struct iio_dev *indio_dev = pf->indio_dev;
149         struct mpl3115_data *data = iio_priv(indio_dev);
150         u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */
151         int ret, pos = 0;
152
153         mutex_lock(&data->lock);
154         ret = mpl3115_request(data);
155         if (ret < 0) {
156                 mutex_unlock(&data->lock);
157                 goto done;
158         }
159
160         memset(buffer, 0, sizeof(buffer));
161         if (test_bit(0, indio_dev->active_scan_mask)) {
162                 ret = i2c_smbus_read_i2c_block_data(data->client,
163                         MPL3115_OUT_PRESS, 3, &buffer[pos]);
164                 if (ret < 0) {
165                         mutex_unlock(&data->lock);
166                         goto done;
167                 }
168                 pos += 4;
169         }
170
171         if (test_bit(1, indio_dev->active_scan_mask)) {
172                 ret = i2c_smbus_read_i2c_block_data(data->client,
173                         MPL3115_OUT_TEMP, 2, &buffer[pos]);
174                 if (ret < 0) {
175                         mutex_unlock(&data->lock);
176                         goto done;
177                 }
178         }
179         mutex_unlock(&data->lock);
180
181         iio_push_to_buffers_with_timestamp(indio_dev, buffer,
182                 iio_get_time_ns(indio_dev));
183
184 done:
185         iio_trigger_notify_done(indio_dev->trig);
186         return IRQ_HANDLED;
187 }
188
189 static const struct iio_chan_spec mpl3115_channels[] = {
190         {
191                 .type = IIO_PRESSURE,
192                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
193                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
194                 .scan_index = 0,
195                 .scan_type = {
196                         .sign = 'u',
197                         .realbits = 20,
198                         .storagebits = 32,
199                         .shift = 12,
200                         .endianness = IIO_BE,
201                 }
202         },
203         {
204                 .type = IIO_TEMP,
205                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
206                 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
207                 .scan_index = 1,
208                 .scan_type = {
209                         .sign = 's',
210                         .realbits = 12,
211                         .storagebits = 16,
212                         .shift = 4,
213                         .endianness = IIO_BE,
214                 }
215         },
216         IIO_CHAN_SOFT_TIMESTAMP(2),
217 };
218
219 static const struct iio_info mpl3115_info = {
220         .read_raw = &mpl3115_read_raw,
221 };
222
223 static int mpl3115_probe(struct i2c_client *client,
224                          const struct i2c_device_id *id)
225 {
226         struct mpl3115_data *data;
227         struct iio_dev *indio_dev;
228         int ret;
229
230         ret = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I);
231         if (ret < 0)
232                 return ret;
233         if (ret != MPL3115_DEVICE_ID)
234                 return -ENODEV;
235
236         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
237         if (!indio_dev)
238                 return -ENOMEM;
239
240         data = iio_priv(indio_dev);
241         data->client = client;
242         mutex_init(&data->lock);
243
244         i2c_set_clientdata(client, indio_dev);
245         indio_dev->info = &mpl3115_info;
246         indio_dev->name = id->name;
247         indio_dev->dev.parent = &client->dev;
248         indio_dev->modes = INDIO_DIRECT_MODE;
249         indio_dev->channels = mpl3115_channels;
250         indio_dev->num_channels = ARRAY_SIZE(mpl3115_channels);
251
252         /* software reset, I2C transfer is aborted (fails) */
253         i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
254                 MPL3115_CTRL_RESET);
255         msleep(50);
256
257         data->ctrl_reg1 = MPL3115_CTRL_OS_258MS;
258         ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
259                 data->ctrl_reg1);
260         if (ret < 0)
261                 return ret;
262
263         ret = iio_triggered_buffer_setup(indio_dev, NULL,
264                 mpl3115_trigger_handler, NULL);
265         if (ret < 0)
266                 return ret;
267
268         ret = iio_device_register(indio_dev);
269         if (ret < 0)
270                 goto buffer_cleanup;
271         return 0;
272
273 buffer_cleanup:
274         iio_triggered_buffer_cleanup(indio_dev);
275         return ret;
276 }
277
278 static int mpl3115_standby(struct mpl3115_data *data)
279 {
280         return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
281                 data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE);
282 }
283
284 static int mpl3115_remove(struct i2c_client *client)
285 {
286         struct iio_dev *indio_dev = i2c_get_clientdata(client);
287
288         iio_device_unregister(indio_dev);
289         iio_triggered_buffer_cleanup(indio_dev);
290         mpl3115_standby(iio_priv(indio_dev));
291
292         return 0;
293 }
294
295 #ifdef CONFIG_PM_SLEEP
296 static int mpl3115_suspend(struct device *dev)
297 {
298         return mpl3115_standby(iio_priv(i2c_get_clientdata(
299                 to_i2c_client(dev))));
300 }
301
302 static int mpl3115_resume(struct device *dev)
303 {
304         struct mpl3115_data *data = iio_priv(i2c_get_clientdata(
305                 to_i2c_client(dev)));
306
307         return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
308                 data->ctrl_reg1);
309 }
310
311 static SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume);
312 #define MPL3115_PM_OPS (&mpl3115_pm_ops)
313 #else
314 #define MPL3115_PM_OPS NULL
315 #endif
316
317 static const struct i2c_device_id mpl3115_id[] = {
318         { "mpl3115", 0 },
319         { }
320 };
321 MODULE_DEVICE_TABLE(i2c, mpl3115_id);
322
323 static const struct of_device_id mpl3115_of_match[] = {
324         { .compatible = "fsl,mpl3115" },
325         { }
326 };
327 MODULE_DEVICE_TABLE(of, mpl3115_of_match);
328
329 static struct i2c_driver mpl3115_driver = {
330         .driver = {
331                 .name   = "mpl3115",
332                 .of_match_table = mpl3115_of_match,
333                 .pm     = MPL3115_PM_OPS,
334         },
335         .probe = mpl3115_probe,
336         .remove = mpl3115_remove,
337         .id_table = mpl3115_id,
338 };
339 module_i2c_driver(mpl3115_driver);
340
341 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
342 MODULE_DESCRIPTION("Freescale MPL3115 pressure/temperature driver");
343 MODULE_LICENSE("GPL");