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"); 507