1 /*  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
5     is available from their website:
6     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 
71 static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
72 							I2C_CLIENT_END };
73 
74 struct 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 */
83 struct 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;
90 	u32 last_temp_measurement;
91 	s32 b6; /* calculated temperature correction coefficient */
92 };
93 
94 
bmp085_read_calibration_data(struct i2c_client * client)95 static 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 
bmp085_update_raw_temperature(struct bmp085_data * data)125 static 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 
154 exit:
155 	mutex_unlock(&data->lock);
156 	return status;
157 }
158 
bmp085_update_raw_pressure(struct bmp085_data * data)159 static 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 
191 exit:
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  */
bmp085_get_temperature(struct bmp085_data * data,int * temperature)201 static 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 
218 exit:
219 	return status;;
220 }
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  */
bmp085_get_pressure(struct bmp085_data * data,int * pressure)228 static 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 */
237 	if (data->last_temp_measurement + 1*HZ < jiffies) {
238 		status = bmp085_get_temperature(data, NULL);
239 		if (status != 0)
240 			goto exit;
241 	}
242 
243 	status = bmp085_update_raw_pressure(data);
244 	if (status != 0)
245 		goto exit;
246 
247 	x1 = (data->b6 * data->b6) >> 12;
248 	x1 *= cali->B2;
249 	x1 >>= 11;
250 
251 	x2 = cali->AC2 * data->b6;
252 	x2 >>= 11;
253 
254 	x3 = x1 + x2;
255 
256 	b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
257 	b3 >>= 2;
258 
259 	x1 = (cali->AC3 * data->b6) >> 13;
260 	x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
261 	x3 = (x1 + x2 + 2) >> 2;
262 	b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
263 
264 	b7 = ((u32)data->raw_pressure - b3) *
265 					(50000 >> data->oversampling_setting);
266 	p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
267 
268 	x1 = p >> 8;
269 	x1 *= x1;
270 	x1 = (x1 * 3038) >> 16;
271 	x2 = (-7357 * p) >> 16;
272 	p += (x1 + x2 + 3791) >> 4;
273 
274 	*pressure = p;
275 
276 exit:
277 	return status;
278 }
279 
280 /*
281  * This function sets the chip-internal oversampling. Valid values are 0..3.
282  * The chip will use 2^oversampling samples for internal averaging.
283  * This influences the measurement time and the accuracy; larger values
284  * increase both. The datasheet gives on overview on how measurement time,
285  * accuracy and noise correlate.
286  */
bmp085_set_oversampling(struct bmp085_data * data,unsigned char oversampling)287 static void bmp085_set_oversampling(struct bmp085_data *data,
288 						unsigned char oversampling)
289 {
290 	if (oversampling > 3)
291 		oversampling = 3;
292 	data->oversampling_setting = oversampling;
293 }
294 
295 /*
296  * Returns the currently selected oversampling. Range: 0..3
297  */
bmp085_get_oversampling(struct bmp085_data * data)298 static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
299 {
300 	return data->oversampling_setting;
301 }
302 
303 /* sysfs callbacks */
set_oversampling(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)304 static ssize_t set_oversampling(struct device *dev,
305 				struct device_attribute *attr,
306 				const char *buf, size_t count)
307 {
308 	struct i2c_client *client = to_i2c_client(dev);
309 	struct bmp085_data *data = i2c_get_clientdata(client);
310 	unsigned long oversampling;
311 	int success = strict_strtoul(buf, 10, &oversampling);
312 	if (success == 0) {
313 		bmp085_set_oversampling(data, oversampling);
314 		return count;
315 	}
316 	return success;
317 }
318 
show_oversampling(struct device * dev,struct device_attribute * attr,char * buf)319 static ssize_t show_oversampling(struct device *dev,
320 				 struct device_attribute *attr, char *buf)
321 {
322 	struct i2c_client *client = to_i2c_client(dev);
323 	struct bmp085_data *data = i2c_get_clientdata(client);
324 	return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
325 }
326 static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
327 					show_oversampling, set_oversampling);
328 
329 
show_temperature(struct device * dev,struct device_attribute * attr,char * buf)330 static ssize_t show_temperature(struct device *dev,
331 				struct device_attribute *attr, char *buf)
332 {
333 	int temperature;
334 	int status;
335 	struct i2c_client *client = to_i2c_client(dev);
336 	struct bmp085_data *data = i2c_get_clientdata(client);
337 
338 	status = bmp085_get_temperature(data, &temperature);
339 	if (status != 0)
340 		return status;
341 	else
342 		return sprintf(buf, "%d\n", temperature);
343 }
344 static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
345 
346 
show_pressure(struct device * dev,struct device_attribute * attr,char * buf)347 static ssize_t show_pressure(struct device *dev,
348 			     struct device_attribute *attr, char *buf)
349 {
350 	int pressure;
351 	int status;
352 	struct i2c_client *client = to_i2c_client(dev);
353 	struct bmp085_data *data = i2c_get_clientdata(client);
354 
355 	status = bmp085_get_pressure(data, &pressure);
356 	if (status != 0)
357 		return status;
358 	else
359 		return sprintf(buf, "%d\n", pressure);
360 }
361 static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
362 
363 
364 static struct attribute *bmp085_attributes[] = {
365 	&dev_attr_temp0_input.attr,
366 	&dev_attr_pressure0_input.attr,
367 	&dev_attr_oversampling.attr,
368 	NULL
369 };
370 
371 static const struct attribute_group bmp085_attr_group = {
372 	.attrs = bmp085_attributes,
373 };
374 
bmp085_detect(struct i2c_client * client,struct i2c_board_info * info)375 static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info)
376 {
377 	if (client->addr != BMP085_I2C_ADDRESS)
378 		return -ENODEV;
379 
380 	if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID)
381 		return -ENODEV;
382 
383 	return 0;
384 }
385 
bmp085_init_client(struct i2c_client * client)386 static int bmp085_init_client(struct i2c_client *client)
387 {
388 	unsigned char version;
389 	int status;
390 	struct bmp085_data *data = i2c_get_clientdata(client);
391 	data->client = client;
392 	status = bmp085_read_calibration_data(client);
393 	if (status != 0)
394 		goto exit;
395 	version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG);
396 	data->last_temp_measurement = 0;
397 	data->oversampling_setting = 3;
398 	mutex_init(&data->lock);
399 	dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n",
400 			(version & 0x0F), (version & 0xF0) >> 4);
401 exit:
402 	return status;
403 }
404 
bmp085_probe(struct i2c_client * client,const struct i2c_device_id * id)405 static int __devinit bmp085_probe(struct i2c_client *client,
406 			 const struct i2c_device_id *id)
407 {
408 	struct bmp085_data *data;
409 	int err = 0;
410 
411 	data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL);
412 	if (!data) {
413 		err = -ENOMEM;
414 		goto exit;
415 	}
416 
417 	/* default settings after POR */
418 	data->oversampling_setting = 0x00;
419 
420 	i2c_set_clientdata(client, data);
421 
422 	/* Initialize the BMP085 chip */
423 	err = bmp085_init_client(client);
424 	if (err != 0)
425 		goto exit_free;
426 
427 	/* Register sysfs hooks */
428 	err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group);
429 	if (err)
430 		goto exit_free;
431 
432 	dev_info(&data->client->dev, "Successfully initialized bmp085!\n");
433 	goto exit;
434 
435 exit_free:
436 	kfree(data);
437 exit:
438 	return err;
439 }
440 
bmp085_remove(struct i2c_client * client)441 static int __devexit bmp085_remove(struct i2c_client *client)
442 {
443 	sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group);
444 	kfree(i2c_get_clientdata(client));
445 	return 0;
446 }
447 
448 static const struct i2c_device_id bmp085_id[] = {
449 	{ "bmp085", 0 },
450 	{ }
451 };
452 MODULE_DEVICE_TABLE(i2c, bmp085_id);
453 
454 static struct i2c_driver bmp085_driver = {
455 	.driver = {
456 		.owner = THIS_MODULE,
457 		.name	= "bmp085"
458 	},
459 	.id_table	= bmp085_id,
460 	.probe		= bmp085_probe,
461 	.remove		= __devexit_p(bmp085_remove),
462 
463 	.detect		= bmp085_detect,
464 	.address_list	= normal_i2c
465 };
466 
bmp085_init(void)467 static int __init bmp085_init(void)
468 {
469 	return i2c_add_driver(&bmp085_driver);
470 }
471 
bmp085_exit(void)472 static void __exit bmp085_exit(void)
473 {
474 	i2c_del_driver(&bmp085_driver);
475 }
476 
477 
478 MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
479 MODULE_DESCRIPTION("BMP085 driver");
480 MODULE_LICENSE("GPL");
481 
482 module_init(bmp085_init);
483 module_exit(bmp085_exit);
484