Loading...
1/* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
2
3 This driver supports the bmp085 digital barometric pressure
4 and temperature sensor from Bosch Sensortec. The datasheet
5 is available from their website:
6 http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
7
8 A pressure measurement is issued by reading from pressure0_input.
9 The return value ranges from 30000 to 110000 pascal with a resulution
10 of 1 pascal (0.01 millibar) which enables measurements from 9000m above
11 to 500m below sea level.
12
13 The temperature can be read from temp0_input. Values range from
14 -400 to 850 representing the ambient temperature in degree celsius
15 multiplied by 10.The resolution is 0.1 celsius.
16
17 Because ambient pressure is temperature dependent, a temperature
18 measurement will be executed automatically even if the user is reading
19 from pressure0_input. This happens if the last temperature measurement
20 has been executed more then one second ago.
21
22 To decrease RMS noise from pressure measurements, the bmp085 can
23 autonomously calculate the average of up to eight samples. This is
24 set up by writing to the oversampling sysfs file. Accepted values
25 are 0, 1, 2 and 3. 2^x when x is the value written to this file
26 specifies the number of samples used to calculate the ambient pressure.
27 RMS noise is specified with six pascal (without averaging) and decreases
28 down to 3 pascal when using an oversampling setting of 3.
29
30 This program is free software; you can redistribute it and/or modify
31 it under the terms of the GNU General Public License as published by
32 the Free Software Foundation; either version 2 of the License, or
33 (at your option) any later version.
34
35 This program is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 GNU General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with this program; if not, write to the Free Software
42 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
43*/
44
45
46#include <linux/module.h>
47#include <linux/init.h>
48#include <linux/i2c.h>
49#include <linux/slab.h>
50#include <linux/delay.h>
51
52
53#define BMP085_I2C_ADDRESS 0x77
54#define BMP085_CHIP_ID 0x55
55
56#define BMP085_CALIBRATION_DATA_START 0xAA
57#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
58#define BMP085_CHIP_ID_REG 0xD0
59#define BMP085_VERSION_REG 0xD1
60#define BMP085_CTRL_REG 0xF4
61#define BMP085_TEMP_MEASUREMENT 0x2E
62#define BMP085_PRESSURE_MEASUREMENT 0x34
63#define BMP085_CONVERSION_REGISTER_MSB 0xF6
64#define BMP085_CONVERSION_REGISTER_LSB 0xF7
65#define BMP085_CONVERSION_REGISTER_XLSB 0xF8
66#define BMP085_TEMP_CONVERSION_TIME 5
67
68#define BMP085_CLIENT_NAME "bmp085"
69
70
71static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
72 I2C_CLIENT_END };
73
74struct bmp085_calibration_data {
75 s16 AC1, AC2, AC3;
76 u16 AC4, AC5, AC6;
77 s16 B1, B2;
78 s16 MB, MC, MD;
79};
80
81
82/* Each client has this additional data */
83struct bmp085_data {
84 struct i2c_client *client;
85 struct mutex lock;
86 struct bmp085_calibration_data calibration;
87 u32 raw_temperature;
88 u32 raw_pressure;
89 unsigned char oversampling_setting;
90 u32 last_temp_measurement;
91 s32 b6; /* calculated temperature correction coefficient */
92};
93
94
95static s32 bmp085_read_calibration_data(struct i2c_client *client)
96{
97 u16 tmp[BMP085_CALIBRATION_DATA_LENGTH];
98 struct bmp085_data *data = i2c_get_clientdata(client);
99 struct bmp085_calibration_data *cali = &(data->calibration);
100 s32 status = i2c_smbus_read_i2c_block_data(client,
101 BMP085_CALIBRATION_DATA_START,
102 BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16),
103 (u8 *)tmp);
104 if (status < 0)
105 return status;
106
107 if (status != BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16))
108 return -EIO;
109
110 cali->AC1 = be16_to_cpu(tmp[0]);
111 cali->AC2 = be16_to_cpu(tmp[1]);
112 cali->AC3 = be16_to_cpu(tmp[2]);
113 cali->AC4 = be16_to_cpu(tmp[3]);
114 cali->AC5 = be16_to_cpu(tmp[4]);
115 cali->AC6 = be16_to_cpu(tmp[5]);
116 cali->B1 = be16_to_cpu(tmp[6]);
117 cali->B2 = be16_to_cpu(tmp[7]);
118 cali->MB = be16_to_cpu(tmp[8]);
119 cali->MC = be16_to_cpu(tmp[9]);
120 cali->MD = be16_to_cpu(tmp[10]);
121 return 0;
122}
123
124
125static s32 bmp085_update_raw_temperature(struct bmp085_data *data)
126{
127 u16 tmp;
128 s32 status;
129
130 mutex_lock(&data->lock);
131 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
132 BMP085_TEMP_MEASUREMENT);
133 if (status != 0) {
134 dev_err(&data->client->dev,
135 "Error while requesting temperature measurement.\n");
136 goto exit;
137 }
138 msleep(BMP085_TEMP_CONVERSION_TIME);
139
140 status = i2c_smbus_read_i2c_block_data(data->client,
141 BMP085_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
142 if (status < 0)
143 goto exit;
144 if (status != sizeof(tmp)) {
145 dev_err(&data->client->dev,
146 "Error while reading temperature measurement result\n");
147 status = -EIO;
148 goto exit;
149 }
150 data->raw_temperature = be16_to_cpu(tmp);
151 data->last_temp_measurement = jiffies;
152 status = 0; /* everything ok, return 0 */
153
154exit:
155 mutex_unlock(&data->lock);
156 return status;
157}
158
159static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
160{
161 u32 tmp = 0;
162 s32 status;
163
164 mutex_lock(&data->lock);
165 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
166 BMP085_PRESSURE_MEASUREMENT + (data->oversampling_setting<<6));
167 if (status != 0) {
168 dev_err(&data->client->dev,
169 "Error while requesting pressure measurement.\n");
170 goto exit;
171 }
172
173 /* wait for the end of conversion */
174 msleep(2+(3 << data->oversampling_setting));
175
176 /* copy data into a u32 (4 bytes), but skip the first byte. */
177 status = i2c_smbus_read_i2c_block_data(data->client,
178 BMP085_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
179 if (status < 0)
180 goto exit;
181 if (status != 3) {
182 dev_err(&data->client->dev,
183 "Error while reading pressure measurement results\n");
184 status = -EIO;
185 goto exit;
186 }
187 data->raw_pressure = be32_to_cpu((tmp));
188 data->raw_pressure >>= (8-data->oversampling_setting);
189 status = 0; /* everything ok, return 0 */
190
191exit:
192 mutex_unlock(&data->lock);
193 return status;
194}
195
196
197/*
198 * This function starts the temperature measurement and returns the value
199 * in tenth of a degree celsius.
200 */
201static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature)
202{
203 struct bmp085_calibration_data *cali = &data->calibration;
204 long x1, x2;
205 int status;
206
207 status = bmp085_update_raw_temperature(data);
208 if (status != 0)
209 goto exit;
210
211 x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
212 x2 = (cali->MC << 11) / (x1 + cali->MD);
213 data->b6 = x1 + x2 - 4000;
214 /* if NULL just update b6. Used for pressure only measurements */
215 if (temperature != NULL)
216 *temperature = (x1+x2+8) >> 4;
217
218exit:
219 return status;;
220}
221
222/*
223 * This function starts the pressure measurement and returns the value
224 * in millibar. Since the pressure depends on the ambient temperature,
225 * a temperature measurement is executed if the last known value is older
226 * than one second.
227 */
228static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
229{
230 struct bmp085_calibration_data *cali = &data->calibration;
231 s32 x1, x2, x3, b3;
232 u32 b4, b7;
233 s32 p;
234 int status;
235
236 /* alt least every second force an update of the ambient temperature */
237 if (data->last_temp_measurement + 1*HZ < jiffies) {
238 status = bmp085_get_temperature(data, NULL);
239 if (status != 0)
240 goto exit;
241 }
242
243 status = bmp085_update_raw_pressure(data);
244 if (status != 0)
245 goto exit;
246
247 x1 = (data->b6 * data->b6) >> 12;
248 x1 *= cali->B2;
249 x1 >>= 11;
250
251 x2 = cali->AC2 * data->b6;
252 x2 >>= 11;
253
254 x3 = x1 + x2;
255
256 b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
257 b3 >>= 2;
258
259 x1 = (cali->AC3 * data->b6) >> 13;
260 x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
261 x3 = (x1 + x2 + 2) >> 2;
262 b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
263
264 b7 = ((u32)data->raw_pressure - b3) *
265 (50000 >> data->oversampling_setting);
266 p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
267
268 x1 = p >> 8;
269 x1 *= x1;
270 x1 = (x1 * 3038) >> 16;
271 x2 = (-7357 * p) >> 16;
272 p += (x1 + x2 + 3791) >> 4;
273
274 *pressure = p;
275
276exit:
277 return status;
278}
279
280/*
281 * This function sets the chip-internal oversampling. Valid values are 0..3.
282 * The chip will use 2^oversampling samples for internal averaging.
283 * This influences the measurement time and the accuracy; larger values
284 * increase both. The datasheet gives on overview on how measurement time,
285 * accuracy and noise correlate.
286 */
287static void bmp085_set_oversampling(struct bmp085_data *data,
288 unsigned char oversampling)
289{
290 if (oversampling > 3)
291 oversampling = 3;
292 data->oversampling_setting = oversampling;
293}
294
295/*
296 * Returns the currently selected oversampling. Range: 0..3
297 */
298static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
299{
300 return data->oversampling_setting;
301}
302
303/* sysfs callbacks */
304static ssize_t set_oversampling(struct device *dev,
305 struct device_attribute *attr,
306 const char *buf, size_t count)
307{
308 struct i2c_client *client = to_i2c_client(dev);
309 struct bmp085_data *data = i2c_get_clientdata(client);
310 unsigned long oversampling;
311 int success = strict_strtoul(buf, 10, &oversampling);
312 if (success == 0) {
313 bmp085_set_oversampling(data, oversampling);
314 return count;
315 }
316 return success;
317}
318
319static ssize_t show_oversampling(struct device *dev,
320 struct device_attribute *attr, char *buf)
321{
322 struct i2c_client *client = to_i2c_client(dev);
323 struct bmp085_data *data = i2c_get_clientdata(client);
324 return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
325}
326static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
327 show_oversampling, set_oversampling);
328
329
330static ssize_t show_temperature(struct device *dev,
331 struct device_attribute *attr, char *buf)
332{
333 int temperature;
334 int status;
335 struct i2c_client *client = to_i2c_client(dev);
336 struct bmp085_data *data = i2c_get_clientdata(client);
337
338 status = bmp085_get_temperature(data, &temperature);
339 if (status != 0)
340 return status;
341 else
342 return sprintf(buf, "%d\n", temperature);
343}
344static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
345
346
347static ssize_t show_pressure(struct device *dev,
348 struct device_attribute *attr, char *buf)
349{
350 int pressure;
351 int status;
352 struct i2c_client *client = to_i2c_client(dev);
353 struct bmp085_data *data = i2c_get_clientdata(client);
354
355 status = bmp085_get_pressure(data, &pressure);
356 if (status != 0)
357 return status;
358 else
359 return sprintf(buf, "%d\n", pressure);
360}
361static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
362
363
364static struct attribute *bmp085_attributes[] = {
365 &dev_attr_temp0_input.attr,
366 &dev_attr_pressure0_input.attr,
367 &dev_attr_oversampling.attr,
368 NULL
369};
370
371static const struct attribute_group bmp085_attr_group = {
372 .attrs = bmp085_attributes,
373};
374
375static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info)
376{
377 if (client->addr != BMP085_I2C_ADDRESS)
378 return -ENODEV;
379
380 if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID)
381 return -ENODEV;
382
383 return 0;
384}
385
386static int bmp085_init_client(struct i2c_client *client)
387{
388 unsigned char version;
389 int status;
390 struct bmp085_data *data = i2c_get_clientdata(client);
391 data->client = client;
392 status = bmp085_read_calibration_data(client);
393 if (status != 0)
394 goto exit;
395 version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG);
396 data->last_temp_measurement = 0;
397 data->oversampling_setting = 3;
398 mutex_init(&data->lock);
399 dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n",
400 (version & 0x0F), (version & 0xF0) >> 4);
401exit:
402 return status;
403}
404
405static int __devinit bmp085_probe(struct i2c_client *client,
406 const struct i2c_device_id *id)
407{
408 struct bmp085_data *data;
409 int err = 0;
410
411 data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL);
412 if (!data) {
413 err = -ENOMEM;
414 goto exit;
415 }
416
417 /* default settings after POR */
418 data->oversampling_setting = 0x00;
419
420 i2c_set_clientdata(client, data);
421
422 /* Initialize the BMP085 chip */
423 err = bmp085_init_client(client);
424 if (err != 0)
425 goto exit_free;
426
427 /* Register sysfs hooks */
428 err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group);
429 if (err)
430 goto exit_free;
431
432 dev_info(&data->client->dev, "Successfully initialized bmp085!\n");
433 goto exit;
434
435exit_free:
436 kfree(data);
437exit:
438 return err;
439}
440
441static int __devexit bmp085_remove(struct i2c_client *client)
442{
443 sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group);
444 kfree(i2c_get_clientdata(client));
445 return 0;
446}
447
448static const struct i2c_device_id bmp085_id[] = {
449 { "bmp085", 0 },
450 { }
451};
452MODULE_DEVICE_TABLE(i2c, bmp085_id);
453
454static struct i2c_driver bmp085_driver = {
455 .driver = {
456 .owner = THIS_MODULE,
457 .name = "bmp085"
458 },
459 .id_table = bmp085_id,
460 .probe = bmp085_probe,
461 .remove = __devexit_p(bmp085_remove),
462
463 .detect = bmp085_detect,
464 .address_list = normal_i2c
465};
466
467static int __init bmp085_init(void)
468{
469 return i2c_add_driver(&bmp085_driver);
470}
471
472static void __exit bmp085_exit(void)
473{
474 i2c_del_driver(&bmp085_driver);
475}
476
477
478MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
479MODULE_DESCRIPTION("BMP085 driver");
480MODULE_LICENSE("GPL");
481
482module_init(bmp085_init);
483module_exit(bmp085_exit);
1/* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
2 * Copyright (c) 2012 Bosch Sensortec GmbH
3 * Copyright (c) 2012 Unixphere AB
4 *
5 * This driver supports the bmp085 and bmp18x digital barometric pressure
6 * and temperature sensors from Bosch Sensortec. The datasheets
7 * are available from their website:
8 * http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
9 * http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP180-DS000-07.pdf
10 *
11 * A pressure measurement is issued by reading from pressure0_input.
12 * The return value ranges from 30000 to 110000 pascal with a resulution
13 * of 1 pascal (0.01 millibar) which enables measurements from 9000m above
14 * to 500m below sea level.
15 *
16 * The temperature can be read from temp0_input. Values range from
17 * -400 to 850 representing the ambient temperature in degree celsius
18 * multiplied by 10.The resolution is 0.1 celsius.
19 *
20 * Because ambient pressure is temperature dependent, a temperature
21 * measurement will be executed automatically even if the user is reading
22 * from pressure0_input. This happens if the last temperature measurement
23 * has been executed more then one second ago.
24 *
25 * To decrease RMS noise from pressure measurements, the bmp085 can
26 * autonomously calculate the average of up to eight samples. This is
27 * set up by writing to the oversampling sysfs file. Accepted values
28 * are 0, 1, 2 and 3. 2^x when x is the value written to this file
29 * specifies the number of samples used to calculate the ambient pressure.
30 * RMS noise is specified with six pascal (without averaging) and decreases
31 * down to 3 pascal when using an oversampling setting of 3.
32 *
33 * This program is free software; you can redistribute it and/or modify
34 * it under the terms of the GNU General Public License as published by
35 * the Free Software Foundation; either version 2 of the License, or
36 * (at your option) any later version.
37 *
38 * This program is distributed in the hope that it will be useful,
39 * but WITHOUT ANY WARRANTY; without even the implied warranty of
40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 * GNU General Public License for more details.
42 *
43 * You should have received a copy of the GNU General Public License
44 * along with this program; if not, write to the Free Software
45 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
46 */
47
48#include <linux/module.h>
49#include <linux/device.h>
50#include <linux/slab.h>
51#include <linux/of.h>
52#include "bmp085.h"
53#include <linux/interrupt.h>
54#include <linux/completion.h>
55#include <linux/gpio.h>
56
57#define BMP085_CHIP_ID 0x55
58#define BMP085_CALIBRATION_DATA_START 0xAA
59#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
60#define BMP085_CHIP_ID_REG 0xD0
61#define BMP085_CTRL_REG 0xF4
62#define BMP085_TEMP_MEASUREMENT 0x2E
63#define BMP085_PRESSURE_MEASUREMENT 0x34
64#define BMP085_CONVERSION_REGISTER_MSB 0xF6
65#define BMP085_CONVERSION_REGISTER_LSB 0xF7
66#define BMP085_CONVERSION_REGISTER_XLSB 0xF8
67#define BMP085_TEMP_CONVERSION_TIME 5
68
69struct bmp085_calibration_data {
70 s16 AC1, AC2, AC3;
71 u16 AC4, AC5, AC6;
72 s16 B1, B2;
73 s16 MB, MC, MD;
74};
75
76struct bmp085_data {
77 struct device *dev;
78 struct regmap *regmap;
79 struct mutex lock;
80 struct bmp085_calibration_data calibration;
81 u8 oversampling_setting;
82 u32 raw_temperature;
83 u32 raw_pressure;
84 u32 temp_measurement_period;
85 unsigned long last_temp_measurement;
86 u8 chip_id;
87 s32 b6; /* calculated temperature correction coefficient */
88 int irq;
89 struct completion done;
90};
91
92static irqreturn_t bmp085_eoc_isr(int irq, void *devid)
93{
94 struct bmp085_data *data = devid;
95
96 complete(&data->done);
97
98 return IRQ_HANDLED;
99}
100
101static s32 bmp085_read_calibration_data(struct bmp085_data *data)
102{
103 u16 tmp[BMP085_CALIBRATION_DATA_LENGTH];
104 struct bmp085_calibration_data *cali = &(data->calibration);
105 s32 status = regmap_bulk_read(data->regmap,
106 BMP085_CALIBRATION_DATA_START, (u8 *)tmp,
107 (BMP085_CALIBRATION_DATA_LENGTH << 1));
108 if (status < 0)
109 return status;
110
111 cali->AC1 = be16_to_cpu(tmp[0]);
112 cali->AC2 = be16_to_cpu(tmp[1]);
113 cali->AC3 = be16_to_cpu(tmp[2]);
114 cali->AC4 = be16_to_cpu(tmp[3]);
115 cali->AC5 = be16_to_cpu(tmp[4]);
116 cali->AC6 = be16_to_cpu(tmp[5]);
117 cali->B1 = be16_to_cpu(tmp[6]);
118 cali->B2 = be16_to_cpu(tmp[7]);
119 cali->MB = be16_to_cpu(tmp[8]);
120 cali->MC = be16_to_cpu(tmp[9]);
121 cali->MD = be16_to_cpu(tmp[10]);
122 return 0;
123}
124
125static s32 bmp085_update_raw_temperature(struct bmp085_data *data)
126{
127 u16 tmp;
128 s32 status;
129
130 mutex_lock(&data->lock);
131
132 init_completion(&data->done);
133
134 status = regmap_write(data->regmap, BMP085_CTRL_REG,
135 BMP085_TEMP_MEASUREMENT);
136 if (status < 0) {
137 dev_err(data->dev,
138 "Error while requesting temperature measurement.\n");
139 goto exit;
140 }
141 wait_for_completion_timeout(&data->done, 1 + msecs_to_jiffies(
142 BMP085_TEMP_CONVERSION_TIME));
143
144 status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB,
145 &tmp, sizeof(tmp));
146 if (status < 0) {
147 dev_err(data->dev,
148 "Error while reading temperature measurement result\n");
149 goto exit;
150 }
151 data->raw_temperature = be16_to_cpu(tmp);
152 data->last_temp_measurement = jiffies;
153 status = 0; /* everything ok, return 0 */
154
155exit:
156 mutex_unlock(&data->lock);
157 return status;
158}
159
160static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
161{
162 u32 tmp = 0;
163 s32 status;
164
165 mutex_lock(&data->lock);
166
167 init_completion(&data->done);
168
169 status = regmap_write(data->regmap, BMP085_CTRL_REG,
170 BMP085_PRESSURE_MEASUREMENT +
171 (data->oversampling_setting << 6));
172 if (status < 0) {
173 dev_err(data->dev,
174 "Error while requesting pressure measurement.\n");
175 goto exit;
176 }
177
178 /* wait for the end of conversion */
179 wait_for_completion_timeout(&data->done, 1 + msecs_to_jiffies(
180 2+(3 << data->oversampling_setting)));
181 /* copy data into a u32 (4 bytes), but skip the first byte. */
182 status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB,
183 ((u8 *)&tmp)+1, 3);
184 if (status < 0) {
185 dev_err(data->dev,
186 "Error while reading pressure measurement results\n");
187 goto exit;
188 }
189 data->raw_pressure = be32_to_cpu((tmp));
190 data->raw_pressure >>= (8-data->oversampling_setting);
191 status = 0; /* everything ok, return 0 */
192
193exit:
194 mutex_unlock(&data->lock);
195 return status;
196}
197
198/*
199 * This function starts the temperature measurement and returns the value
200 * in tenth of a degree celsius.
201 */
202static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature)
203{
204 struct bmp085_calibration_data *cali = &data->calibration;
205 long x1, x2;
206 int status;
207
208 status = bmp085_update_raw_temperature(data);
209 if (status < 0)
210 goto exit;
211
212 x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
213 x2 = (cali->MC << 11) / (x1 + cali->MD);
214 data->b6 = x1 + x2 - 4000;
215 /* if NULL just update b6. Used for pressure only measurements */
216 if (temperature != NULL)
217 *temperature = (x1+x2+8) >> 4;
218
219exit:
220 return status;
221}
222
223/*
224 * This function starts the pressure measurement and returns the value
225 * in millibar. Since the pressure depends on the ambient temperature,
226 * a temperature measurement is executed according to the given temperature
227 * measurement period (default is 1 sec boundary). This period could vary
228 * and needs to be adjusted according to the sensor environment, i.e. if big
229 * temperature variations then the temperature needs to be read out often.
230 */
231static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
232{
233 struct bmp085_calibration_data *cali = &data->calibration;
234 s32 x1, x2, x3, b3;
235 u32 b4, b7;
236 s32 p;
237 int status;
238
239 /* alt least every second force an update of the ambient temperature */
240 if ((data->last_temp_measurement == 0) ||
241 time_is_before_jiffies(data->last_temp_measurement + 1*HZ)) {
242 status = bmp085_get_temperature(data, NULL);
243 if (status < 0)
244 return status;
245 }
246
247 status = bmp085_update_raw_pressure(data);
248 if (status < 0)
249 return status;
250
251 x1 = (data->b6 * data->b6) >> 12;
252 x1 *= cali->B2;
253 x1 >>= 11;
254
255 x2 = cali->AC2 * data->b6;
256 x2 >>= 11;
257
258 x3 = x1 + x2;
259
260 b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
261 b3 >>= 2;
262
263 x1 = (cali->AC3 * data->b6) >> 13;
264 x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
265 x3 = (x1 + x2 + 2) >> 2;
266 b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
267
268 b7 = ((u32)data->raw_pressure - b3) *
269 (50000 >> data->oversampling_setting);
270 p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
271
272 x1 = p >> 8;
273 x1 *= x1;
274 x1 = (x1 * 3038) >> 16;
275 x2 = (-7357 * p) >> 16;
276 p += (x1 + x2 + 3791) >> 4;
277
278 *pressure = p;
279
280 return 0;
281}
282
283/*
284 * This function sets the chip-internal oversampling. Valid values are 0..3.
285 * The chip will use 2^oversampling samples for internal averaging.
286 * This influences the measurement time and the accuracy; larger values
287 * increase both. The datasheet gives an overview on how measurement time,
288 * accuracy and noise correlate.
289 */
290static void bmp085_set_oversampling(struct bmp085_data *data,
291 unsigned char oversampling)
292{
293 if (oversampling > 3)
294 oversampling = 3;
295 data->oversampling_setting = oversampling;
296}
297
298/*
299 * Returns the currently selected oversampling. Range: 0..3
300 */
301static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
302{
303 return data->oversampling_setting;
304}
305
306/* sysfs callbacks */
307static ssize_t set_oversampling(struct device *dev,
308 struct device_attribute *attr,
309 const char *buf, size_t count)
310{
311 struct bmp085_data *data = dev_get_drvdata(dev);
312 unsigned long oversampling;
313 int err = kstrtoul(buf, 10, &oversampling);
314
315 if (err == 0) {
316 mutex_lock(&data->lock);
317 bmp085_set_oversampling(data, oversampling);
318 mutex_unlock(&data->lock);
319 return count;
320 }
321
322 return err;
323}
324
325static ssize_t show_oversampling(struct device *dev,
326 struct device_attribute *attr, char *buf)
327{
328 struct bmp085_data *data = dev_get_drvdata(dev);
329
330 return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
331}
332static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
333 show_oversampling, set_oversampling);
334
335
336static ssize_t show_temperature(struct device *dev,
337 struct device_attribute *attr, char *buf)
338{
339 int temperature;
340 int status;
341 struct bmp085_data *data = dev_get_drvdata(dev);
342
343 status = bmp085_get_temperature(data, &temperature);
344 if (status < 0)
345 return status;
346 else
347 return sprintf(buf, "%d\n", temperature);
348}
349static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
350
351
352static ssize_t show_pressure(struct device *dev,
353 struct device_attribute *attr, char *buf)
354{
355 int pressure;
356 int status;
357 struct bmp085_data *data = dev_get_drvdata(dev);
358
359 status = bmp085_get_pressure(data, &pressure);
360 if (status < 0)
361 return status;
362 else
363 return sprintf(buf, "%d\n", pressure);
364}
365static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
366
367
368static struct attribute *bmp085_attributes[] = {
369 &dev_attr_temp0_input.attr,
370 &dev_attr_pressure0_input.attr,
371 &dev_attr_oversampling.attr,
372 NULL
373};
374
375static const struct attribute_group bmp085_attr_group = {
376 .attrs = bmp085_attributes,
377};
378
379int bmp085_detect(struct device *dev)
380{
381 struct bmp085_data *data = dev_get_drvdata(dev);
382 unsigned int id;
383 int ret;
384
385 ret = regmap_read(data->regmap, BMP085_CHIP_ID_REG, &id);
386 if (ret < 0)
387 return ret;
388
389 if (id != data->chip_id)
390 return -ENODEV;
391
392 return 0;
393}
394EXPORT_SYMBOL_GPL(bmp085_detect);
395
396static void bmp085_get_of_properties(struct bmp085_data *data)
397{
398#ifdef CONFIG_OF
399 struct device_node *np = data->dev->of_node;
400 u32 prop;
401
402 if (!np)
403 return;
404
405 if (!of_property_read_u32(np, "chip-id", &prop))
406 data->chip_id = prop & 0xff;
407
408 if (!of_property_read_u32(np, "temp-measurement-period", &prop))
409 data->temp_measurement_period = (prop/100)*HZ;
410
411 if (!of_property_read_u32(np, "default-oversampling", &prop))
412 data->oversampling_setting = prop & 0xff;
413#endif
414}
415
416static int bmp085_init_client(struct bmp085_data *data)
417{
418 int status = bmp085_read_calibration_data(data);
419
420 if (status < 0)
421 return status;
422
423 /* default settings */
424 data->chip_id = BMP085_CHIP_ID;
425 data->last_temp_measurement = 0;
426 data->temp_measurement_period = 1*HZ;
427 data->oversampling_setting = 3;
428
429 bmp085_get_of_properties(data);
430
431 mutex_init(&data->lock);
432
433 return 0;
434}
435
436struct regmap_config bmp085_regmap_config = {
437 .reg_bits = 8,
438 .val_bits = 8
439};
440EXPORT_SYMBOL_GPL(bmp085_regmap_config);
441
442int bmp085_probe(struct device *dev, struct regmap *regmap, int irq)
443{
444 struct bmp085_data *data;
445 int err = 0;
446
447 data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL);
448 if (!data) {
449 err = -ENOMEM;
450 goto exit;
451 }
452
453 dev_set_drvdata(dev, data);
454 data->dev = dev;
455 data->regmap = regmap;
456 data->irq = irq;
457
458 if (data->irq > 0) {
459 err = devm_request_irq(dev, data->irq, bmp085_eoc_isr,
460 IRQF_TRIGGER_RISING, "bmp085",
461 data);
462 if (err < 0)
463 goto exit_free;
464 }
465
466 /* Initialize the BMP085 chip */
467 err = bmp085_init_client(data);
468 if (err < 0)
469 goto exit_free;
470
471 err = bmp085_detect(dev);
472 if (err < 0) {
473 dev_err(dev, "%s: chip_id failed!\n", BMP085_NAME);
474 goto exit_free;
475 }
476
477 /* Register sysfs hooks */
478 err = sysfs_create_group(&dev->kobj, &bmp085_attr_group);
479 if (err)
480 goto exit_free;
481
482 dev_info(dev, "Successfully initialized %s!\n", BMP085_NAME);
483
484 return 0;
485
486exit_free:
487 kfree(data);
488exit:
489 return err;
490}
491EXPORT_SYMBOL_GPL(bmp085_probe);
492
493int bmp085_remove(struct device *dev)
494{
495 struct bmp085_data *data = dev_get_drvdata(dev);
496
497 sysfs_remove_group(&data->dev->kobj, &bmp085_attr_group);
498 kfree(data);
499
500 return 0;
501}
502EXPORT_SYMBOL_GPL(bmp085_remove);
503
504MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com>");
505MODULE_DESCRIPTION("BMP085 driver");
506MODULE_LICENSE("GPL");