blob: 76c3064629f1c802ef38c0f3ad4ae15f5a1142cb [file] [log] [blame]
Christoph Mair5bf1d292010-08-09 17:20:28 -07001/* 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
Lucas De Marchi25985ed2011-03-30 22:57:33 -03005 is available from their website:
Christoph Mair5bf1d292010-08-09 17:20:28 -07006 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;
Bernhard Walleb2222582012-02-25 10:28:12 +010090 unsigned long last_temp_measurement;
Christoph Mair5bf1d292010-08-09 17:20:28 -070091 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:
Jesper Juhlf80ea662011-12-17 23:52:27 +0100219 return status;
Christoph Mair5bf1d292010-08-09 17:20:28 -0700220}
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 */
Bernhard Walle3734f782012-02-19 18:28:01 +0100237 if (data->last_temp_measurement == 0 ||
238 time_is_before_jiffies(data->last_temp_measurement + 1*HZ)) {
Christoph Mair5bf1d292010-08-09 17:20:28 -0700239 status = bmp085_get_temperature(data, NULL);
240 if (status != 0)
241 goto exit;
242 }
243
244 status = bmp085_update_raw_pressure(data);
245 if (status != 0)
246 goto exit;
247
248 x1 = (data->b6 * data->b6) >> 12;
249 x1 *= cali->B2;
250 x1 >>= 11;
251
252 x2 = cali->AC2 * data->b6;
253 x2 >>= 11;
254
255 x3 = x1 + x2;
256
257 b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
258 b3 >>= 2;
259
260 x1 = (cali->AC3 * data->b6) >> 13;
261 x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
262 x3 = (x1 + x2 + 2) >> 2;
263 b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
264
265 b7 = ((u32)data->raw_pressure - b3) *
266 (50000 >> data->oversampling_setting);
267 p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
268
269 x1 = p >> 8;
270 x1 *= x1;
271 x1 = (x1 * 3038) >> 16;
272 x2 = (-7357 * p) >> 16;
273 p += (x1 + x2 + 3791) >> 4;
274
275 *pressure = p;
276
277exit:
278 return status;
279}
280
281/*
282 * This function sets the chip-internal oversampling. Valid values are 0..3.
283 * The chip will use 2^oversampling samples for internal averaging.
284 * This influences the measurement time and the accuracy; larger values
285 * increase both. The datasheet gives on overview on how measurement time,
286 * accuracy and noise correlate.
287 */
288static void bmp085_set_oversampling(struct bmp085_data *data,
289 unsigned char oversampling)
290{
291 if (oversampling > 3)
292 oversampling = 3;
293 data->oversampling_setting = oversampling;
294}
295
296/*
297 * Returns the currently selected oversampling. Range: 0..3
298 */
299static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
300{
301 return data->oversampling_setting;
302}
303
304/* sysfs callbacks */
305static ssize_t set_oversampling(struct device *dev,
306 struct device_attribute *attr,
307 const char *buf, size_t count)
308{
309 struct i2c_client *client = to_i2c_client(dev);
310 struct bmp085_data *data = i2c_get_clientdata(client);
311 unsigned long oversampling;
312 int success = strict_strtoul(buf, 10, &oversampling);
313 if (success == 0) {
314 bmp085_set_oversampling(data, oversampling);
315 return count;
316 }
317 return success;
318}
319
320static ssize_t show_oversampling(struct device *dev,
321 struct device_attribute *attr, char *buf)
322{
323 struct i2c_client *client = to_i2c_client(dev);
324 struct bmp085_data *data = i2c_get_clientdata(client);
325 return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
326}
327static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
328 show_oversampling, set_oversampling);
329
330
331static ssize_t show_temperature(struct device *dev,
332 struct device_attribute *attr, char *buf)
333{
334 int temperature;
335 int status;
336 struct i2c_client *client = to_i2c_client(dev);
337 struct bmp085_data *data = i2c_get_clientdata(client);
338
339 status = bmp085_get_temperature(data, &temperature);
340 if (status != 0)
341 return status;
342 else
343 return sprintf(buf, "%d\n", temperature);
344}
345static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
346
347
348static ssize_t show_pressure(struct device *dev,
349 struct device_attribute *attr, char *buf)
350{
351 int pressure;
352 int status;
353 struct i2c_client *client = to_i2c_client(dev);
354 struct bmp085_data *data = i2c_get_clientdata(client);
355
356 status = bmp085_get_pressure(data, &pressure);
357 if (status != 0)
358 return status;
359 else
360 return sprintf(buf, "%d\n", pressure);
361}
362static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
363
364
365static struct attribute *bmp085_attributes[] = {
366 &dev_attr_temp0_input.attr,
367 &dev_attr_pressure0_input.attr,
368 &dev_attr_oversampling.attr,
369 NULL
370};
371
372static const struct attribute_group bmp085_attr_group = {
373 .attrs = bmp085_attributes,
374};
375
376static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info)
377{
378 if (client->addr != BMP085_I2C_ADDRESS)
379 return -ENODEV;
380
381 if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID)
382 return -ENODEV;
383
384 return 0;
385}
386
387static int bmp085_init_client(struct i2c_client *client)
388{
389 unsigned char version;
390 int status;
391 struct bmp085_data *data = i2c_get_clientdata(client);
392 data->client = client;
393 status = bmp085_read_calibration_data(client);
394 if (status != 0)
395 goto exit;
396 version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG);
397 data->last_temp_measurement = 0;
398 data->oversampling_setting = 3;
399 mutex_init(&data->lock);
400 dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n",
401 (version & 0x0F), (version & 0xF0) >> 4);
402exit:
403 return status;
404}
405
Shubhrajyoti Datta45bff2e2011-03-22 16:33:57 -0700406static int __devinit bmp085_probe(struct i2c_client *client,
Christoph Mair5bf1d292010-08-09 17:20:28 -0700407 const struct i2c_device_id *id)
408{
409 struct bmp085_data *data;
410 int err = 0;
411
412 data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL);
413 if (!data) {
414 err = -ENOMEM;
415 goto exit;
416 }
417
418 /* default settings after POR */
419 data->oversampling_setting = 0x00;
420
421 i2c_set_clientdata(client, data);
422
423 /* Initialize the BMP085 chip */
424 err = bmp085_init_client(client);
425 if (err != 0)
426 goto exit_free;
427
428 /* Register sysfs hooks */
429 err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group);
430 if (err)
431 goto exit_free;
432
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300433 dev_info(&data->client->dev, "Successfully initialized bmp085!\n");
Christoph Mair5bf1d292010-08-09 17:20:28 -0700434 goto exit;
435
436exit_free:
437 kfree(data);
438exit:
439 return err;
440}
441
Shubhrajyoti Datta45bff2e2011-03-22 16:33:57 -0700442static int __devexit bmp085_remove(struct i2c_client *client)
Christoph Mair5bf1d292010-08-09 17:20:28 -0700443{
444 sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group);
445 kfree(i2c_get_clientdata(client));
446 return 0;
447}
448
449static const struct i2c_device_id bmp085_id[] = {
450 { "bmp085", 0 },
451 { }
452};
Axel Lin97e419a2011-03-04 17:36:22 -0800453MODULE_DEVICE_TABLE(i2c, bmp085_id);
Christoph Mair5bf1d292010-08-09 17:20:28 -0700454
455static struct i2c_driver bmp085_driver = {
456 .driver = {
457 .owner = THIS_MODULE,
458 .name = "bmp085"
459 },
460 .id_table = bmp085_id,
461 .probe = bmp085_probe,
Shubhrajyoti Datta45bff2e2011-03-22 16:33:57 -0700462 .remove = __devexit_p(bmp085_remove),
Christoph Mair5bf1d292010-08-09 17:20:28 -0700463
464 .detect = bmp085_detect,
465 .address_list = normal_i2c
466};
467
Axel Lina64fe2e2012-01-22 15:36:45 +0800468module_i2c_driver(bmp085_driver);
Christoph Mair5bf1d292010-08-09 17:20:28 -0700469
470MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
471MODULE_DESCRIPTION("BMP085 driver");
472MODULE_LICENSE("GPL");