Linux Audio

Check our new training course

Loading...
v3.1
  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
 71static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
 72							I2C_CLIENT_END };
 73
 74struct 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 */
 83struct 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
 95static 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
125static 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
154exit:
155	mutex_unlock(&data->lock);
156	return status;
157}
158
159static 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
191exit:
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 */
201static 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
218exit:
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 */
228static 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
276exit:
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 */
287static 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 */
298static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
299{
300	return data->oversampling_setting;
301}
302
303/* sysfs callbacks */
304static 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
319static 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}
326static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
327					show_oversampling, set_oversampling);
328
329
330static 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}
344static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
345
346
347static 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}
361static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
362
363
364static 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
371static const struct attribute_group bmp085_attr_group = {
372	.attrs = bmp085_attributes,
373};
374
375static 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
386static 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);
401exit:
402	return status;
403}
404
405static 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
435exit_free:
436	kfree(data);
437exit:
438	return err;
439}
 
440
441static 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
448static const struct i2c_device_id bmp085_id[] = {
449	{ "bmp085", 0 },
450	{ }
451};
452MODULE_DEVICE_TABLE(i2c, bmp085_id);
453
454static 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
467static int __init bmp085_init(void)
468{
469	return i2c_add_driver(&bmp085_driver);
470}
471
472static void __exit bmp085_exit(void)
473{
474	i2c_del_driver(&bmp085_driver);
475}
 
476
477
478MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
479MODULE_DESCRIPTION("BMP085 driver");
480MODULE_LICENSE("GPL");
481
482module_init(bmp085_init);
483module_exit(bmp085_exit);
v4.6
  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");