1 /* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
2 * Copyright (c) 2012 Bosch Sensortec GmbH
3 * Copyright (c) 2012 Unixphere AB
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
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.
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.
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.
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.
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.
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.
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.
48 #include <linux/module.h>
49 #include <linux/device.h>
50 #include <linux/init.h>
51 #include <linux/slab.h>
52 #include <linux/delay.h>
56 #define BMP085_CHIP_ID 0x55
57 #define BMP085_CALIBRATION_DATA_START 0xAA
58 #define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
59 #define BMP085_CHIP_ID_REG 0xD0
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
68 struct bmp085_calibration_data
{
77 struct regmap
*regmap
;
79 struct bmp085_calibration_data calibration
;
80 u8 oversampling_setting
;
83 u32 temp_measurement_period
;
84 unsigned long last_temp_measurement
;
86 s32 b6
; /* calculated temperature correction coefficient */
89 static s32
bmp085_read_calibration_data(struct bmp085_data
*data
)
91 u16 tmp
[BMP085_CALIBRATION_DATA_LENGTH
];
92 struct bmp085_calibration_data
*cali
= &(data
->calibration
);
93 s32 status
= regmap_bulk_read(data
->regmap
,
94 BMP085_CALIBRATION_DATA_START
, (u8
*)tmp
,
95 (BMP085_CALIBRATION_DATA_LENGTH
<< 1));
99 cali
->AC1
= be16_to_cpu(tmp
[0]);
100 cali
->AC2
= be16_to_cpu(tmp
[1]);
101 cali
->AC3
= be16_to_cpu(tmp
[2]);
102 cali
->AC4
= be16_to_cpu(tmp
[3]);
103 cali
->AC5
= be16_to_cpu(tmp
[4]);
104 cali
->AC6
= be16_to_cpu(tmp
[5]);
105 cali
->B1
= be16_to_cpu(tmp
[6]);
106 cali
->B2
= be16_to_cpu(tmp
[7]);
107 cali
->MB
= be16_to_cpu(tmp
[8]);
108 cali
->MC
= be16_to_cpu(tmp
[9]);
109 cali
->MD
= be16_to_cpu(tmp
[10]);
113 static s32
bmp085_update_raw_temperature(struct bmp085_data
*data
)
118 mutex_lock(&data
->lock
);
119 status
= regmap_write(data
->regmap
, BMP085_CTRL_REG
,
120 BMP085_TEMP_MEASUREMENT
);
123 "Error while requesting temperature measurement.\n");
126 msleep(BMP085_TEMP_CONVERSION_TIME
);
128 status
= regmap_bulk_read(data
->regmap
, BMP085_CONVERSION_REGISTER_MSB
,
132 "Error while reading temperature measurement result\n");
135 data
->raw_temperature
= be16_to_cpu(tmp
);
136 data
->last_temp_measurement
= jiffies
;
137 status
= 0; /* everything ok, return 0 */
140 mutex_unlock(&data
->lock
);
144 static s32
bmp085_update_raw_pressure(struct bmp085_data
*data
)
149 mutex_lock(&data
->lock
);
150 status
= regmap_write(data
->regmap
, BMP085_CTRL_REG
,
151 BMP085_PRESSURE_MEASUREMENT
+
152 (data
->oversampling_setting
<< 6));
155 "Error while requesting pressure measurement.\n");
159 /* wait for the end of conversion */
160 msleep(2+(3 << data
->oversampling_setting
));
162 /* copy data into a u32 (4 bytes), but skip the first byte. */
163 status
= regmap_bulk_read(data
->regmap
, BMP085_CONVERSION_REGISTER_MSB
,
167 "Error while reading pressure measurement results\n");
170 data
->raw_pressure
= be32_to_cpu((tmp
));
171 data
->raw_pressure
>>= (8-data
->oversampling_setting
);
172 status
= 0; /* everything ok, return 0 */
175 mutex_unlock(&data
->lock
);
180 * This function starts the temperature measurement and returns the value
181 * in tenth of a degree celsius.
183 static s32
bmp085_get_temperature(struct bmp085_data
*data
, int *temperature
)
185 struct bmp085_calibration_data
*cali
= &data
->calibration
;
189 status
= bmp085_update_raw_temperature(data
);
193 x1
= ((data
->raw_temperature
- cali
->AC6
) * cali
->AC5
) >> 15;
194 x2
= (cali
->MC
<< 11) / (x1
+ cali
->MD
);
195 data
->b6
= x1
+ x2
- 4000;
196 /* if NULL just update b6. Used for pressure only measurements */
197 if (temperature
!= NULL
)
198 *temperature
= (x1
+x2
+8) >> 4;
205 * This function starts the pressure measurement and returns the value
206 * in millibar. Since the pressure depends on the ambient temperature,
207 * a temperature measurement is executed according to the given temperature
208 * measurement period (default is 1 sec boundary). This period could vary
209 * and needs to be adjusted according to the sensor environment, i.e. if big
210 * temperature variations then the temperature needs to be read out often.
212 static s32
bmp085_get_pressure(struct bmp085_data
*data
, int *pressure
)
214 struct bmp085_calibration_data
*cali
= &data
->calibration
;
220 /* alt least every second force an update of the ambient temperature */
221 if ((data
->last_temp_measurement
== 0) ||
222 time_is_before_jiffies(data
->last_temp_measurement
+ 1*HZ
)) {
223 status
= bmp085_get_temperature(data
, NULL
);
228 status
= bmp085_update_raw_pressure(data
);
232 x1
= (data
->b6
* data
->b6
) >> 12;
236 x2
= cali
->AC2
* data
->b6
;
241 b3
= (((((s32
)cali
->AC1
) * 4 + x3
) << data
->oversampling_setting
) + 2);
244 x1
= (cali
->AC3
* data
->b6
) >> 13;
245 x2
= (cali
->B1
* ((data
->b6
* data
->b6
) >> 12)) >> 16;
246 x3
= (x1
+ x2
+ 2) >> 2;
247 b4
= (cali
->AC4
* (u32
)(x3
+ 32768)) >> 15;
249 b7
= ((u32
)data
->raw_pressure
- b3
) *
250 (50000 >> data
->oversampling_setting
);
251 p
= ((b7
< 0x80000000) ? ((b7
<< 1) / b4
) : ((b7
/ b4
) * 2));
255 x1
= (x1
* 3038) >> 16;
256 x2
= (-7357 * p
) >> 16;
257 p
+= (x1
+ x2
+ 3791) >> 4;
265 * This function sets the chip-internal oversampling. Valid values are 0..3.
266 * The chip will use 2^oversampling samples for internal averaging.
267 * This influences the measurement time and the accuracy; larger values
268 * increase both. The datasheet gives an overview on how measurement time,
269 * accuracy and noise correlate.
271 static void bmp085_set_oversampling(struct bmp085_data
*data
,
272 unsigned char oversampling
)
274 if (oversampling
> 3)
276 data
->oversampling_setting
= oversampling
;
280 * Returns the currently selected oversampling. Range: 0..3
282 static unsigned char bmp085_get_oversampling(struct bmp085_data
*data
)
284 return data
->oversampling_setting
;
287 /* sysfs callbacks */
288 static ssize_t
set_oversampling(struct device
*dev
,
289 struct device_attribute
*attr
,
290 const char *buf
, size_t count
)
292 struct bmp085_data
*data
= dev_get_drvdata(dev
);
293 unsigned long oversampling
;
294 int err
= kstrtoul(buf
, 10, &oversampling
);
297 mutex_lock(&data
->lock
);
298 bmp085_set_oversampling(data
, oversampling
);
299 mutex_unlock(&data
->lock
);
306 static ssize_t
show_oversampling(struct device
*dev
,
307 struct device_attribute
*attr
, char *buf
)
309 struct bmp085_data
*data
= dev_get_drvdata(dev
);
311 return sprintf(buf
, "%u\n", bmp085_get_oversampling(data
));
313 static DEVICE_ATTR(oversampling
, S_IWUSR
| S_IRUGO
,
314 show_oversampling
, set_oversampling
);
317 static ssize_t
show_temperature(struct device
*dev
,
318 struct device_attribute
*attr
, char *buf
)
322 struct bmp085_data
*data
= dev_get_drvdata(dev
);
324 status
= bmp085_get_temperature(data
, &temperature
);
328 return sprintf(buf
, "%d\n", temperature
);
330 static DEVICE_ATTR(temp0_input
, S_IRUGO
, show_temperature
, NULL
);
333 static ssize_t
show_pressure(struct device
*dev
,
334 struct device_attribute
*attr
, char *buf
)
338 struct bmp085_data
*data
= dev_get_drvdata(dev
);
340 status
= bmp085_get_pressure(data
, &pressure
);
344 return sprintf(buf
, "%d\n", pressure
);
346 static DEVICE_ATTR(pressure0_input
, S_IRUGO
, show_pressure
, NULL
);
349 static struct attribute
*bmp085_attributes
[] = {
350 &dev_attr_temp0_input
.attr
,
351 &dev_attr_pressure0_input
.attr
,
352 &dev_attr_oversampling
.attr
,
356 static const struct attribute_group bmp085_attr_group
= {
357 .attrs
= bmp085_attributes
,
360 int bmp085_detect(struct device
*dev
)
362 struct bmp085_data
*data
= dev_get_drvdata(dev
);
366 ret
= regmap_read(data
->regmap
, BMP085_CHIP_ID_REG
, &id
);
370 if (id
!= data
->chip_id
)
375 EXPORT_SYMBOL_GPL(bmp085_detect
);
377 static void __init
bmp085_get_of_properties(struct bmp085_data
*data
)
380 struct device_node
*np
= data
->dev
->of_node
;
386 if (!of_property_read_u32(np
, "chip-id", &prop
))
387 data
->chip_id
= prop
& 0xff;
389 if (!of_property_read_u32(np
, "temp-measurement-period", &prop
))
390 data
->temp_measurement_period
= (prop
/100)*HZ
;
392 if (!of_property_read_u32(np
, "default-oversampling", &prop
))
393 data
->oversampling_setting
= prop
& 0xff;
397 static int bmp085_init_client(struct bmp085_data
*data
)
399 int status
= bmp085_read_calibration_data(data
);
404 /* default settings */
405 data
->chip_id
= BMP085_CHIP_ID
;
406 data
->last_temp_measurement
= 0;
407 data
->temp_measurement_period
= 1*HZ
;
408 data
->oversampling_setting
= 3;
410 bmp085_get_of_properties(data
);
412 mutex_init(&data
->lock
);
417 struct regmap_config bmp085_regmap_config
= {
421 EXPORT_SYMBOL_GPL(bmp085_regmap_config
);
423 int bmp085_probe(struct device
*dev
, struct regmap
*regmap
)
425 struct bmp085_data
*data
;
428 data
= kzalloc(sizeof(struct bmp085_data
), GFP_KERNEL
);
434 dev_set_drvdata(dev
, data
);
436 data
->regmap
= regmap
;
438 /* Initialize the BMP085 chip */
439 err
= bmp085_init_client(data
);
443 err
= bmp085_detect(dev
);
445 dev_err(dev
, "%s: chip_id failed!\n", BMP085_NAME
);
449 /* Register sysfs hooks */
450 err
= sysfs_create_group(&dev
->kobj
, &bmp085_attr_group
);
454 dev_info(dev
, "Successfully initialized %s!\n", BMP085_NAME
);
463 EXPORT_SYMBOL_GPL(bmp085_probe
);
465 int bmp085_remove(struct device
*dev
)
467 struct bmp085_data
*data
= dev_get_drvdata(dev
);
469 sysfs_remove_group(&data
->dev
->kobj
, &bmp085_attr_group
);
474 EXPORT_SYMBOL_GPL(bmp085_remove
);
476 MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com>");
477 MODULE_DESCRIPTION("BMP085 driver");
478 MODULE_LICENSE("GPL");