1 /* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/i2c.h>
22 #include <linux/slab.h>
23 #include <linux/delay.h>
26 #define BMP085_I2C_ADDRESS 0x77
27 #define BMP085_CHIP_ID 0x55
29 #define BMP085_CALIBRATION_DATA_START 0xAA
30 #define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
31 #define BMP085_CHIP_ID_REG 0xD0
32 #define BMP085_VERSION_REG 0xD1
33 #define BMP085_CTRL_REG 0xF4
34 #define BMP085_TEMP_MEASUREMENT 0x2E
35 #define BMP085_PRESSURE_MEASUREMENT 0x34
36 #define BMP085_CONVERSION_REGISTER_MSB 0xF6
37 #define BMP085_CONVERSION_REGISTER_LSB 0xF7
38 #define BMP085_CONVERSION_REGISTER_XLSB 0xF8
39 #define BMP085_TEMP_CONVERSION_TIME 5
41 #define BMP085_CLIENT_NAME "bmp085"
44 static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
47 struct bmp085_calibration_data {
55 /* Each client has this additional data */
57 struct i2c_client *client;
59 struct bmp085_calibration_data calibration;
62 unsigned char oversampling_setting;
63 unsigned long last_temp_measurement;
64 s32 b6; /* calculated temperature correction coefficient */
68 static s32 bmp085_read_calibration_data(struct i2c_client *client)
70 u16 tmp[BMP085_CALIBRATION_DATA_LENGTH];
71 struct bmp085_data *data = i2c_get_clientdata(client);
72 struct bmp085_calibration_data *cali = &(data->calibration);
73 s32 status = i2c_smbus_read_i2c_block_data(client,
74 BMP085_CALIBRATION_DATA_START,
75 BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16),
80 if (status != BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16))
83 cali->AC1 = be16_to_cpu(tmp[0]);
84 cali->AC2 = be16_to_cpu(tmp[1]);
85 cali->AC3 = be16_to_cpu(tmp[2]);
86 cali->AC4 = be16_to_cpu(tmp[3]);
87 cali->AC5 = be16_to_cpu(tmp[4]);
88 cali->AC6 = be16_to_cpu(tmp[5]);
89 cali->B1 = be16_to_cpu(tmp[6]);
90 cali->B2 = be16_to_cpu(tmp[7]);
91 cali->MB = be16_to_cpu(tmp[8]);
92 cali->MC = be16_to_cpu(tmp[9]);
93 cali->MD = be16_to_cpu(tmp[10]);
98 static s32 bmp085_update_raw_temperature(struct bmp085_data *data)
103 mutex_lock(&data->lock);
104 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
105 BMP085_TEMP_MEASUREMENT);
107 dev_err(&data->client->dev,
108 "Error while requesting temperature measurement.\n");
111 msleep(BMP085_TEMP_CONVERSION_TIME);
113 status = i2c_smbus_read_i2c_block_data(data->client,
114 BMP085_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
117 if (status != sizeof(tmp)) {
118 dev_err(&data->client->dev,
119 "Error while reading temperature measurement result\n");
123 data->raw_temperature = be16_to_cpu(tmp);
124 data->last_temp_measurement = jiffies;
125 status = 0; /* everything ok, return 0 */
128 mutex_unlock(&data->lock);
132 static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
137 mutex_lock(&data->lock);
138 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
139 BMP085_PRESSURE_MEASUREMENT + (data->oversampling_setting<<6));
141 dev_err(&data->client->dev,
142 "Error while requesting pressure measurement.\n");
146 /* wait for the end of conversion */
147 msleep(2+(3 << data->oversampling_setting<<1));
149 /* copy data into a u32 (4 bytes), but skip the first byte. */
150 status = i2c_smbus_read_i2c_block_data(data->client,
151 BMP085_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
155 dev_err(&data->client->dev,
156 "Error while reading pressure measurement results\n");
160 data->raw_pressure = be32_to_cpu((tmp));
161 data->raw_pressure >>= (8-data->oversampling_setting);
162 status = 0; /* everything ok, return 0 */
165 mutex_unlock(&data->lock);
171 * This function starts the temperature measurement and returns the value
172 * in tenth of a degree celsius.
174 static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature)
176 struct bmp085_calibration_data *cali = &data->calibration;
180 status = bmp085_update_raw_temperature(data);
184 x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
185 x2 = (cali->MC << 11) / (x1 + cali->MD);
186 data->b6 = x1 + x2 - 4000;
187 /* if NULL just update b6. Used for pressure only measurements */
188 if (temperature != NULL)
189 *temperature = (x1+x2+8) >> 4;
196 * This function starts the pressure measurement and returns the value
197 * in millibar. Since the pressure depends on the ambient temperature,
198 * a temperature measurement is executed if the last known value is older
201 static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
203 struct bmp085_calibration_data *cali = &data->calibration;
209 /* alt least every second force an update of the ambient temperature */
210 if (data->last_temp_measurement + 1*HZ < jiffies) {
211 status = bmp085_get_temperature(data, NULL);
216 status = bmp085_update_raw_pressure(data);
220 x1 = (data->b6 * data->b6) >> 12;
224 x2 = cali->AC2 * data->b6;
229 b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
232 x1 = (cali->AC3 * data->b6) >> 13;
233 x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
234 x3 = (x1 + x2 + 2) >> 2;
235 b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
237 b7 = ((u32)data->raw_pressure - b3) *
238 (50000 >> data->oversampling_setting);
239 p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
243 x1 = (x1 * 3038) >> 16;
244 x2 = (-7357 * p) >> 16;
245 p += (x1 + x2 + 3791) >> 4;
254 * This function sets the chip-internal oversampling. Valid values are 0..3.
255 * The chip will use 2^oversampling samples for interlan averaging.
256 * This influences the measurement time and the accuracy; larger values
257 * increase both. The datasheet gives on overview on how measurement time,
258 * accuracy and noise correlate.
260 static void bmp085_set_oversampling(struct bmp085_data *data,
261 unsigned char oversampling)
263 if (oversampling > 3)
265 data->oversampling_setting = oversampling;
269 * Returns the currently selected oversampling. Range: 0..3
271 static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
273 return data->oversampling_setting;
276 /* sysfs callbacks */
277 static ssize_t set_oversampling(struct device *dev,
278 struct device_attribute *attr,
279 const char *buf, size_t count)
281 struct i2c_client *client = to_i2c_client(dev);
282 struct bmp085_data *data = i2c_get_clientdata(client);
283 unsigned long oversampling;
284 int success = strict_strtoul(buf, 10, &oversampling);
286 bmp085_set_oversampling(data, oversampling);
292 static ssize_t show_oversampling(struct device *dev,
293 struct device_attribute *attr, char *buf)
295 struct i2c_client *client = to_i2c_client(dev);
296 struct bmp085_data *data = i2c_get_clientdata(client);
297 return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
299 static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
300 show_oversampling, set_oversampling);
303 static ssize_t show_temperature(struct device *dev,
304 struct device_attribute *attr, char *buf)
308 struct i2c_client *client = to_i2c_client(dev);
309 struct bmp085_data *data = i2c_get_clientdata(client);
311 status = bmp085_get_temperature(data, &temperature);
315 return sprintf(buf, "%d\n", temperature);
317 static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
320 static ssize_t show_pressure(struct device *dev,
321 struct device_attribute *attr, char *buf)
325 struct i2c_client *client = to_i2c_client(dev);
326 struct bmp085_data *data = i2c_get_clientdata(client);
328 status = bmp085_get_pressure(data, &pressure);
332 return sprintf(buf, "%d\n", pressure);
334 static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
337 static struct attribute *bmp085_attributes[] = {
338 &dev_attr_temp0_input.attr,
339 &dev_attr_pressure0_input.attr,
340 &dev_attr_oversampling.attr,
344 static const struct attribute_group bmp085_attr_group = {
345 .attrs = bmp085_attributes,
348 static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info)
350 if (client->addr != BMP085_I2C_ADDRESS)
353 if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID)
359 static int bmp085_init_client(struct i2c_client *client)
361 unsigned char version;
363 struct bmp085_data *data = i2c_get_clientdata(client);
364 data->client = client;
365 status = bmp085_read_calibration_data(client);
368 version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG);
369 data->last_temp_measurement = 0;
370 data->oversampling_setting = 3;
371 mutex_init(&data->lock);
372 dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n",
373 (version & 0x0F), (version & 0xF0) >> 4);
378 static int bmp085_probe(struct i2c_client *client,
379 const struct i2c_device_id *id)
381 struct bmp085_data *data;
384 data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL);
390 /* default settings after POR */
391 data->oversampling_setting = 0x00;
393 i2c_set_clientdata(client, data);
395 /* Initialize the BMP085 chip */
396 err = bmp085_init_client(client);
400 /* Register sysfs hooks */
401 err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group);
405 dev_info(&data->client->dev, "Succesfully initialized bmp085!\n");
414 static int bmp085_remove(struct i2c_client *client)
416 sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group);
417 kfree(i2c_get_clientdata(client));
421 static const struct i2c_device_id bmp085_id[] = {
426 static struct i2c_driver bmp085_driver = {
428 .owner = THIS_MODULE,
431 .id_table = bmp085_id,
432 .probe = bmp085_probe,
433 .remove = bmp085_remove,
435 .detect = bmp085_detect,
436 .address_list = normal_i2c
439 static int __init bmp085_init(void)
441 return i2c_add_driver(&bmp085_driver);
444 static void __exit bmp085_exit(void)
446 i2c_del_driver(&bmp085_driver);
450 MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
451 MODULE_DESCRIPTION("BMP085 driver");
452 MODULE_LICENSE("GPL");
454 module_init(bmp085_init);
455 module_exit(bmp085_exit);