aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/bmp085.c
diff options
context:
space:
mode:
authorEric Andersson <eric.andersson@unixphere.com>2012-04-09 16:16:17 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-18 17:57:14 -0400
commit985087dbcb0265f46e8651fdc7e974f8a7184423 (patch)
treeaad96003f89022623f4c8bf940267300530a9eb2 /drivers/misc/bmp085.c
parentc5a86ab6dd6e424c56826421a80b855e24f7caa1 (diff)
misc: add support for bmp18x chips to the bmp085 driver
The bmp18x chip family comes in an I2C respectively SPI variant. Hence, the bmp085 driver was split to support both buses. Tested-by: Zhengguang Guo <zhengguang.guo@bosch-sensortec.com> Reviewed-by: Stefan Nilsson <stefan.nilsson@unixphere.com> Signed-off-by: Eric Andersson <eric.andersson@unixphere.com> Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/bmp085.c')
-rw-r--r--drivers/misc/bmp085.c163
1 files changed, 67 insertions, 96 deletions
diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c
index 6adde9e1a0d1..62e418293b7e 100644
--- a/drivers/misc/bmp085.c
+++ b/drivers/misc/bmp085.c
@@ -2,10 +2,11 @@
2 * Copyright (c) 2012 Bosch Sensortec GmbH 2 * Copyright (c) 2012 Bosch Sensortec GmbH
3 * Copyright (c) 2012 Unixphere AB 3 * Copyright (c) 2012 Unixphere AB
4 * 4 *
5 * This driver supports the bmp085 digital barometric pressure 5 * This driver supports the bmp085 and bmp18x digital barometric pressure
6 * and temperature sensor from Bosch Sensortec. The datasheet 6 * and temperature sensors from Bosch Sensortec. The datasheets
7 * is available from their website: 7 * are available from their website:
8 * http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf 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
9 * 10 *
10 * A pressure measurement is issued by reading from pressure0_input. 11 * A pressure measurement is issued by reading from pressure0_input.
11 * The return value ranges from 30000 to 110000 pascal with a resulution 12 * The return value ranges from 30000 to 110000 pascal with a resulution
@@ -47,15 +48,12 @@
47#include <linux/module.h> 48#include <linux/module.h>
48#include <linux/device.h> 49#include <linux/device.h>
49#include <linux/init.h> 50#include <linux/init.h>
50#include <linux/i2c.h>
51#include <linux/slab.h> 51#include <linux/slab.h>
52#include <linux/delay.h> 52#include <linux/delay.h>
53#include <linux/of.h> 53#include <linux/of.h>
54#include "bmp085.h"
54 55
55#define BMP085_NAME "bmp085"
56#define BMP085_I2C_ADDRESS 0x77
57#define BMP085_CHIP_ID 0x55 56#define BMP085_CHIP_ID 0x55
58
59#define BMP085_CALIBRATION_DATA_START 0xAA 57#define BMP085_CALIBRATION_DATA_START 0xAA
60#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */ 58#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
61#define BMP085_CHIP_ID_REG 0xD0 59#define BMP085_CHIP_ID_REG 0xD0
@@ -67,9 +65,6 @@
67#define BMP085_CONVERSION_REGISTER_XLSB 0xF8 65#define BMP085_CONVERSION_REGISTER_XLSB 0xF8
68#define BMP085_TEMP_CONVERSION_TIME 5 66#define BMP085_TEMP_CONVERSION_TIME 5
69 67
70static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
71 I2C_CLIENT_END };
72
73struct bmp085_calibration_data { 68struct bmp085_calibration_data {
74 s16 AC1, AC2, AC3; 69 s16 AC1, AC2, AC3;
75 u16 AC4, AC5, AC6; 70 u16 AC4, AC5, AC6;
@@ -78,7 +73,8 @@ struct bmp085_calibration_data {
78}; 73};
79 74
80struct bmp085_data { 75struct bmp085_data {
81 struct i2c_client *client; 76 struct device *dev;
77 struct regmap *regmap;
82 struct mutex lock; 78 struct mutex lock;
83 struct bmp085_calibration_data calibration; 79 struct bmp085_calibration_data calibration;
84 u8 oversampling_setting; 80 u8 oversampling_setting;
@@ -90,21 +86,16 @@ struct bmp085_data {
90 s32 b6; /* calculated temperature correction coefficient */ 86 s32 b6; /* calculated temperature correction coefficient */
91}; 87};
92 88
93static s32 bmp085_read_calibration_data(struct i2c_client *client) 89static s32 bmp085_read_calibration_data(struct bmp085_data *data)
94{ 90{
95 u16 tmp[BMP085_CALIBRATION_DATA_LENGTH]; 91 u16 tmp[BMP085_CALIBRATION_DATA_LENGTH];
96 struct bmp085_data *data = i2c_get_clientdata(client);
97 struct bmp085_calibration_data *cali = &(data->calibration); 92 struct bmp085_calibration_data *cali = &(data->calibration);
98 s32 status = i2c_smbus_read_i2c_block_data(client, 93 s32 status = regmap_bulk_read(data->regmap,
99 BMP085_CALIBRATION_DATA_START, 94 BMP085_CALIBRATION_DATA_START, (u8 *)tmp,
100 (BMP085_CALIBRATION_DATA_LENGTH << 1), 95 (BMP085_CALIBRATION_DATA_LENGTH << 1));
101 (u8 *)tmp);
102 if (status < 0) 96 if (status < 0)
103 return status; 97 return status;
104 98
105 if (status != (BMP085_CALIBRATION_DATA_LENGTH << 1))
106 return -EIO;
107
108 cali->AC1 = be16_to_cpu(tmp[0]); 99 cali->AC1 = be16_to_cpu(tmp[0]);
109 cali->AC2 = be16_to_cpu(tmp[1]); 100 cali->AC2 = be16_to_cpu(tmp[1]);
110 cali->AC3 = be16_to_cpu(tmp[2]); 101 cali->AC3 = be16_to_cpu(tmp[2]);
@@ -125,23 +116,20 @@ static s32 bmp085_update_raw_temperature(struct bmp085_data *data)
125 s32 status; 116 s32 status;
126 117
127 mutex_lock(&data->lock); 118 mutex_lock(&data->lock);
128 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG, 119 status = regmap_write(data->regmap, BMP085_CTRL_REG,
129 BMP085_TEMP_MEASUREMENT); 120 BMP085_TEMP_MEASUREMENT);
130 if (status < 0) { 121 if (status < 0) {
131 dev_err(&data->client->dev, 122 dev_err(data->dev,
132 "Error while requesting temperature measurement.\n"); 123 "Error while requesting temperature measurement.\n");
133 goto exit; 124 goto exit;
134 } 125 }
135 msleep(BMP085_TEMP_CONVERSION_TIME); 126 msleep(BMP085_TEMP_CONVERSION_TIME);
136 127
137 status = i2c_smbus_read_i2c_block_data(data->client, 128 status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB,
138 BMP085_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp); 129 &tmp, sizeof(tmp));
139 if (status < 0) 130 if (status < 0) {
140 goto exit; 131 dev_err(data->dev,
141 if (status != sizeof(tmp)) {
142 dev_err(&data->client->dev,
143 "Error while reading temperature measurement result\n"); 132 "Error while reading temperature measurement result\n");
144 status = -EIO;
145 goto exit; 133 goto exit;
146 } 134 }
147 data->raw_temperature = be16_to_cpu(tmp); 135 data->raw_temperature = be16_to_cpu(tmp);
@@ -159,11 +147,11 @@ static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
159 s32 status; 147 s32 status;
160 148
161 mutex_lock(&data->lock); 149 mutex_lock(&data->lock);
162 status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG, 150 status = regmap_write(data->regmap, BMP085_CTRL_REG,
163 BMP085_PRESSURE_MEASUREMENT + 151 BMP085_PRESSURE_MEASUREMENT +
164 (data->oversampling_setting << 6)); 152 (data->oversampling_setting << 6));
165 if (status < 0) { 153 if (status < 0) {
166 dev_err(&data->client->dev, 154 dev_err(data->dev,
167 "Error while requesting pressure measurement.\n"); 155 "Error while requesting pressure measurement.\n");
168 goto exit; 156 goto exit;
169 } 157 }
@@ -172,14 +160,11 @@ static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
172 msleep(2+(3 << data->oversampling_setting)); 160 msleep(2+(3 << data->oversampling_setting));
173 161
174 /* copy data into a u32 (4 bytes), but skip the first byte. */ 162 /* copy data into a u32 (4 bytes), but skip the first byte. */
175 status = i2c_smbus_read_i2c_block_data(data->client, 163 status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB,
176 BMP085_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1); 164 ((u8 *)&tmp)+1, 3);
177 if (status < 0) 165 if (status < 0) {
178 goto exit; 166 dev_err(data->dev,
179 if (status != 3) {
180 dev_err(&data->client->dev,
181 "Error while reading pressure measurement results\n"); 167 "Error while reading pressure measurement results\n");
182 status = -EIO;
183 goto exit; 168 goto exit;
184 } 169 }
185 data->raw_pressure = be32_to_cpu((tmp)); 170 data->raw_pressure = be32_to_cpu((tmp));
@@ -304,8 +289,7 @@ static ssize_t set_oversampling(struct device *dev,
304 struct device_attribute *attr, 289 struct device_attribute *attr,
305 const char *buf, size_t count) 290 const char *buf, size_t count)
306{ 291{
307 struct i2c_client *client = to_i2c_client(dev); 292 struct bmp085_data *data = dev_get_drvdata(dev);
308 struct bmp085_data *data = i2c_get_clientdata(client);
309 unsigned long oversampling; 293 unsigned long oversampling;
310 int err = kstrtoul(buf, 10, &oversampling); 294 int err = kstrtoul(buf, 10, &oversampling);
311 295
@@ -322,8 +306,7 @@ static ssize_t set_oversampling(struct device *dev,
322static ssize_t show_oversampling(struct device *dev, 306static ssize_t show_oversampling(struct device *dev,
323 struct device_attribute *attr, char *buf) 307 struct device_attribute *attr, char *buf)
324{ 308{
325 struct i2c_client *client = to_i2c_client(dev); 309 struct bmp085_data *data = dev_get_drvdata(dev);
326 struct bmp085_data *data = i2c_get_clientdata(client);
327 310
328 return sprintf(buf, "%u\n", bmp085_get_oversampling(data)); 311 return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
329} 312}
@@ -336,8 +319,7 @@ static ssize_t show_temperature(struct device *dev,
336{ 319{
337 int temperature; 320 int temperature;
338 int status; 321 int status;
339 struct i2c_client *client = to_i2c_client(dev); 322 struct bmp085_data *data = dev_get_drvdata(dev);
340 struct bmp085_data *data = i2c_get_clientdata(client);
341 323
342 status = bmp085_get_temperature(data, &temperature); 324 status = bmp085_get_temperature(data, &temperature);
343 if (status < 0) 325 if (status < 0)
@@ -353,8 +335,7 @@ static ssize_t show_pressure(struct device *dev,
353{ 335{
354 int pressure; 336 int pressure;
355 int status; 337 int status;
356 struct i2c_client *client = to_i2c_client(dev); 338 struct bmp085_data *data = dev_get_drvdata(dev);
357 struct bmp085_data *data = i2c_get_clientdata(client);
358 339
359 status = bmp085_get_pressure(data, &pressure); 340 status = bmp085_get_pressure(data, &pressure);
360 if (status < 0) 341 if (status < 0)
@@ -376,22 +357,27 @@ static const struct attribute_group bmp085_attr_group = {
376 .attrs = bmp085_attributes, 357 .attrs = bmp085_attributes,
377}; 358};
378 359
379static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info) 360int bmp085_detect(struct device *dev)
380{ 361{
381 if (client->addr != BMP085_I2C_ADDRESS) 362 struct bmp085_data *data = dev_get_drvdata(dev);
382 return -ENODEV; 363 unsigned int id;
364 int ret;
365
366 ret = regmap_read(data->regmap, BMP085_CHIP_ID_REG, &id);
367 if (ret < 0)
368 return ret;
383 369
384 if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID) 370 if (id != data->chip_id)
385 return -ENODEV; 371 return -ENODEV;
386 372
387 return 0; 373 return 0;
388} 374}
375EXPORT_SYMBOL_GPL(bmp085_detect);
389 376
390static void __init bmp085_get_of_properties(struct i2c_client *client, 377static void __init bmp085_get_of_properties(struct bmp085_data *data)
391 struct bmp085_data *data)
392{ 378{
393#ifdef CONFIG_OF 379#ifdef CONFIG_OF
394 struct device_node *np = client->dev.of_node; 380 struct device_node *np = data->dev->of_node;
395 u32 prop; 381 u32 prop;
396 382
397 if (!np) 383 if (!np)
@@ -408,30 +394,33 @@ static void __init bmp085_get_of_properties(struct i2c_client *client,
408#endif 394#endif
409} 395}
410 396
411static int bmp085_init_client(struct i2c_client *client) 397static int bmp085_init_client(struct bmp085_data *data)
412{ 398{
413 struct bmp085_data *data = i2c_get_clientdata(client); 399 int status = bmp085_read_calibration_data(data);
414 int status = bmp085_read_calibration_data(client);
415 400
416 if (status < 0) 401 if (status < 0)
417 return status; 402 return status;
418 403
419 /* default settings */ 404 /* default settings */
420 data->client = client;
421 data->chip_id = BMP085_CHIP_ID; 405 data->chip_id = BMP085_CHIP_ID;
422 data->last_temp_measurement = 0; 406 data->last_temp_measurement = 0;
423 data->temp_measurement_period = 1*HZ; 407 data->temp_measurement_period = 1*HZ;
424 data->oversampling_setting = 3; 408 data->oversampling_setting = 3;
425 409
426 bmp085_get_of_properties(client, data); 410 bmp085_get_of_properties(data);
427 411
428 mutex_init(&data->lock); 412 mutex_init(&data->lock);
429 413
430 return 0; 414 return 0;
431} 415}
432 416
433static int __devinit bmp085_probe(struct i2c_client *client, 417struct regmap_config bmp085_regmap_config = {
434 const struct i2c_device_id *id) 418 .reg_bits = 8,
419 .val_bits = 8
420};
421EXPORT_SYMBOL_GPL(bmp085_regmap_config);
422
423__devinit int bmp085_probe(struct device *dev, struct regmap *regmap)
435{ 424{
436 struct bmp085_data *data; 425 struct bmp085_data *data;
437 int err = 0; 426 int err = 0;
@@ -442,19 +431,27 @@ static int __devinit bmp085_probe(struct i2c_client *client,
442 goto exit; 431 goto exit;
443 } 432 }
444 433
445 i2c_set_clientdata(client, data); 434 dev_set_drvdata(dev, data);
435 data->dev = dev;
436 data->regmap = regmap;
446 437
447 /* Initialize the BMP085 chip */ 438 /* Initialize the BMP085 chip */
448 err = bmp085_init_client(client); 439 err = bmp085_init_client(data);
449 if (err < 0) 440 if (err < 0)
450 goto exit_free; 441 goto exit_free;
451 442
443 err = bmp085_detect(dev);
444 if (err < 0) {
445 dev_err(dev, "%s: chip_id failed!\n", BMP085_NAME);
446 goto exit_free;
447 }
448
452 /* Register sysfs hooks */ 449 /* Register sysfs hooks */
453 err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group); 450 err = sysfs_create_group(&dev->kobj, &bmp085_attr_group);
454 if (err) 451 if (err)
455 goto exit_free; 452 goto exit_free;
456 453
457 dev_info(&client->dev, "Successfully initialized %s!\n", BMP085_NAME); 454 dev_info(dev, "Successfully initialized %s!\n", BMP085_NAME);
458 455
459 return 0; 456 return 0;
460 457
@@ -463,44 +460,18 @@ exit_free:
463exit: 460exit:
464 return err; 461 return err;
465} 462}
463EXPORT_SYMBOL_GPL(bmp085_probe);
466 464
467static int __devexit bmp085_remove(struct i2c_client *client) 465int bmp085_remove(struct device *dev)
468{ 466{
469 struct bmp085_data *data = i2c_get_clientdata(client); 467 struct bmp085_data *data = dev_get_drvdata(dev);
470 468
471 sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group); 469 sysfs_remove_group(&data->dev->kobj, &bmp085_attr_group);
472 kfree(data); 470 kfree(data);
473 471
474 return 0; 472 return 0;
475} 473}
476 474EXPORT_SYMBOL_GPL(bmp085_remove);
477static const struct of_device_id bmp085_of_match[] = {
478 { .compatible = "bosch,bmp085", },
479 { },
480};
481MODULE_DEVICE_TABLE(of, bmp085_of_match);
482
483static const struct i2c_device_id bmp085_id[] = {
484 { BMP085_NAME, 0 },
485 { }
486};
487MODULE_DEVICE_TABLE(i2c, bmp085_id);
488
489static struct i2c_driver bmp085_driver = {
490 .driver = {
491 .owner = THIS_MODULE,
492 .name = BMP085_NAME,
493 .of_match_table = bmp085_of_match
494 },
495 .id_table = bmp085_id,
496 .probe = bmp085_probe,
497 .remove = __devexit_p(bmp085_remove),
498
499 .detect = bmp085_detect,
500 .address_list = normal_i2c
501};
502
503module_i2c_driver(bmp085_driver);
504 475
505MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com>"); 476MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com>");
506MODULE_DESCRIPTION("BMP085 driver"); 477MODULE_DESCRIPTION("BMP085 driver");