mpl115.c (0b767b31889539fbc31383469317264ebee3cf08) | mpl115.c (c984b9cbbd17d3eb602de3802e25d975182474fa) |
---|---|
1/* | 1/* |
2 * mpl115.c - Support for Freescale MPL115A2 pressure/temperature sensor | 2 * mpl115.c - Support for Freescale MPL115A pressure/temperature sensor |
3 * 4 * Copyright (c) 2014 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 * | 3 * 4 * Copyright (c) 2014 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: shutdown pin 13 * 14 */ 15 16#include <linux/module.h> | 10 * TODO: shutdown pin 11 * 12 */ 13 14#include <linux/module.h> |
17#include <linux/i2c.h> | |
18#include <linux/iio/iio.h> 19#include <linux/delay.h> 20 | 15#include <linux/iio/iio.h> 16#include <linux/delay.h> 17 |
18#include "mpl115.h" 19 |
|
21#define MPL115_PADC 0x00 /* pressure ADC output value, MSB first, 10 bit */ 22#define MPL115_TADC 0x02 /* temperature ADC output value, MSB first, 10 bit */ 23#define MPL115_A0 0x04 /* 12 bit integer, 3 bit fraction */ 24#define MPL115_B1 0x06 /* 2 bit integer, 13 bit fraction */ 25#define MPL115_B2 0x08 /* 1 bit integer, 14 bit fraction */ 26#define MPL115_C12 0x0a /* 0 bit integer, 13 bit fraction */ 27#define MPL115_CONVERT 0x12 /* convert temperature and pressure */ 28 29struct mpl115_data { | 20#define MPL115_PADC 0x00 /* pressure ADC output value, MSB first, 10 bit */ 21#define MPL115_TADC 0x02 /* temperature ADC output value, MSB first, 10 bit */ 22#define MPL115_A0 0x04 /* 12 bit integer, 3 bit fraction */ 23#define MPL115_B1 0x06 /* 2 bit integer, 13 bit fraction */ 24#define MPL115_B2 0x08 /* 1 bit integer, 14 bit fraction */ 25#define MPL115_C12 0x0a /* 0 bit integer, 13 bit fraction */ 26#define MPL115_CONVERT 0x12 /* convert temperature and pressure */ 27 28struct mpl115_data { |
30 struct i2c_client *client; | 29 struct device *dev; |
31 struct mutex lock; 32 s16 a0; 33 s16 b1, b2; 34 s16 c12; | 30 struct mutex lock; 31 s16 a0; 32 s16 b1, b2; 33 s16 c12; |
34 const struct mpl115_ops *ops; |
|
35}; 36 37static int mpl115_request(struct mpl115_data *data) 38{ | 35}; 36 37static int mpl115_request(struct mpl115_data *data) 38{ |
39 int ret = i2c_smbus_write_byte_data(data->client, MPL115_CONVERT, 0); | 39 int ret = data->ops->write(data->dev, MPL115_CONVERT, 0); 40 |
40 if (ret < 0) 41 return ret; 42 43 usleep_range(3000, 4000); 44 45 return 0; 46} 47 --- 4 unchanged lines hidden (view full) --- 52 int a1, y1, pcomp; 53 unsigned kpa; 54 55 mutex_lock(&data->lock); 56 ret = mpl115_request(data); 57 if (ret < 0) 58 goto done; 59 | 41 if (ret < 0) 42 return ret; 43 44 usleep_range(3000, 4000); 45 46 return 0; 47} 48 --- 4 unchanged lines hidden (view full) --- 53 int a1, y1, pcomp; 54 unsigned kpa; 55 56 mutex_lock(&data->lock); 57 ret = mpl115_request(data); 58 if (ret < 0) 59 goto done; 60 |
60 ret = i2c_smbus_read_word_swapped(data->client, MPL115_PADC); | 61 ret = data->ops->read(data->dev, MPL115_PADC); |
61 if (ret < 0) 62 goto done; 63 padc = ret >> 6; 64 | 62 if (ret < 0) 63 goto done; 64 padc = ret >> 6; 65 |
65 ret = i2c_smbus_read_word_swapped(data->client, MPL115_TADC); | 66 ret = data->ops->read(data->dev, MPL115_TADC); |
66 if (ret < 0) 67 goto done; 68 tadc = ret >> 6; 69 70 /* see Freescale AN3785 */ 71 a1 = data->b1 + ((data->c12 * tadc) >> 11); 72 y1 = (data->a0 << 10) + a1 * padc; 73 --- 11 unchanged lines hidden (view full) --- 85static int mpl115_read_temp(struct mpl115_data *data) 86{ 87 int ret; 88 89 mutex_lock(&data->lock); 90 ret = mpl115_request(data); 91 if (ret < 0) 92 goto done; | 67 if (ret < 0) 68 goto done; 69 tadc = ret >> 6; 70 71 /* see Freescale AN3785 */ 72 a1 = data->b1 + ((data->c12 * tadc) >> 11); 73 y1 = (data->a0 << 10) + a1 * padc; 74 --- 11 unchanged lines hidden (view full) --- 86static int mpl115_read_temp(struct mpl115_data *data) 87{ 88 int ret; 89 90 mutex_lock(&data->lock); 91 ret = mpl115_request(data); 92 if (ret < 0) 93 goto done; |
93 ret = i2c_smbus_read_word_swapped(data->client, MPL115_TADC); | 94 ret = data->ops->read(data->dev, MPL115_TADC); |
94done: 95 mutex_unlock(&data->lock); 96 return ret; 97} 98 99static int mpl115_read_raw(struct iio_dev *indio_dev, 100 struct iio_chan_spec const *chan, 101 int *val, int *val2, long mask) --- 38 unchanged lines hidden (view full) --- 140 }, 141}; 142 143static const struct iio_info mpl115_info = { 144 .read_raw = &mpl115_read_raw, 145 .driver_module = THIS_MODULE, 146}; 147 | 95done: 96 mutex_unlock(&data->lock); 97 return ret; 98} 99 100static int mpl115_read_raw(struct iio_dev *indio_dev, 101 struct iio_chan_spec const *chan, 102 int *val, int *val2, long mask) --- 38 unchanged lines hidden (view full) --- 141 }, 142}; 143 144static const struct iio_info mpl115_info = { 145 .read_raw = &mpl115_read_raw, 146 .driver_module = THIS_MODULE, 147}; 148 |
148static int mpl115_probe(struct i2c_client *client, 149 const struct i2c_device_id *id) | 149int mpl115_probe(struct device *dev, const char *name, 150 const struct mpl115_ops *ops) |
150{ 151 struct mpl115_data *data; 152 struct iio_dev *indio_dev; 153 int ret; 154 | 151{ 152 struct mpl115_data *data; 153 struct iio_dev *indio_dev; 154 int ret; 155 |
155 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) 156 return -ENODEV; 157 158 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | 156 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); |
159 if (!indio_dev) 160 return -ENOMEM; 161 162 data = iio_priv(indio_dev); | 157 if (!indio_dev) 158 return -ENOMEM; 159 160 data = iio_priv(indio_dev); |
163 data->client = client; | 161 data->dev = dev; 162 data->ops = ops; |
164 mutex_init(&data->lock); 165 166 indio_dev->info = &mpl115_info; | 163 mutex_init(&data->lock); 164 165 indio_dev->info = &mpl115_info; |
167 indio_dev->name = id->name; 168 indio_dev->dev.parent = &client->dev; | 166 indio_dev->name = name; 167 indio_dev->dev.parent = dev; |
169 indio_dev->modes = INDIO_DIRECT_MODE; 170 indio_dev->channels = mpl115_channels; 171 indio_dev->num_channels = ARRAY_SIZE(mpl115_channels); 172 | 168 indio_dev->modes = INDIO_DIRECT_MODE; 169 indio_dev->channels = mpl115_channels; 170 indio_dev->num_channels = ARRAY_SIZE(mpl115_channels); 171 |
173 ret = i2c_smbus_read_word_swapped(data->client, MPL115_A0); | 172 ret = data->ops->init(data->dev); 173 if (ret) 174 return ret; 175 176 ret = data->ops->read(data->dev, MPL115_A0); |
174 if (ret < 0) 175 return ret; 176 data->a0 = ret; | 177 if (ret < 0) 178 return ret; 179 data->a0 = ret; |
177 ret = i2c_smbus_read_word_swapped(data->client, MPL115_B1); | 180 ret = data->ops->read(data->dev, MPL115_B1); |
178 if (ret < 0) 179 return ret; 180 data->b1 = ret; | 181 if (ret < 0) 182 return ret; 183 data->b1 = ret; |
181 ret = i2c_smbus_read_word_swapped(data->client, MPL115_B2); | 184 ret = data->ops->read(data->dev, MPL115_B2); |
182 if (ret < 0) 183 return ret; 184 data->b2 = ret; | 185 if (ret < 0) 186 return ret; 187 data->b2 = ret; |
185 ret = i2c_smbus_read_word_swapped(data->client, MPL115_C12); | 188 ret = data->ops->read(data->dev, MPL115_C12); |
186 if (ret < 0) 187 return ret; 188 data->c12 = ret; 189 | 189 if (ret < 0) 190 return ret; 191 data->c12 = ret; 192 |
190 return devm_iio_device_register(&client->dev, indio_dev); | 193 return devm_iio_device_register(dev, indio_dev); |
191} | 194} |
195EXPORT_SYMBOL_GPL(mpl115_probe); |
|
192 | 196 |
193static const struct i2c_device_id mpl115_id[] = { 194 { "mpl115", 0 }, 195 { } 196}; 197MODULE_DEVICE_TABLE(i2c, mpl115_id); 198 199static struct i2c_driver mpl115_driver = { 200 .driver = { 201 .name = "mpl115", 202 }, 203 .probe = mpl115_probe, 204 .id_table = mpl115_id, 205}; 206module_i2c_driver(mpl115_driver); 207 | |
208MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 209MODULE_DESCRIPTION("Freescale MPL115 pressure/temperature driver"); 210MODULE_LICENSE("GPL"); | 197MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 198MODULE_DESCRIPTION("Freescale MPL115 pressure/temperature driver"); 199MODULE_LICENSE("GPL"); |