blob: 4b5b710da4e2fcb4da55ecf3b1a180710dcab3dd [file] [log] [blame]
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +08001/* Copyright (c) 2011 Bosch Sensortec GmbH
2 Copyright (c) 2011 Unixphere
3
4 Based on:
5 BMP085 driver, bmp085.c
6 Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
7
8 This driver supports the bmp18x digital barometric pressure
9 and temperature sensors from Bosch Sensortec.
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 bmp18x 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/device.h>
49#include <linux/init.h>
50#include <linux/slab.h>
51#include <linux/delay.h>
52#include <linux/input.h>
53#include <linux/workqueue.h>
54#include <linux/module.h>
55#ifdef CONFIG_HAS_EARLYSUSPEND
56#include <linux/earlysuspend.h>
57#endif
58#include "bmp18x.h"
59
60#define BMP18X_CHIP_ID 0x55
61
62#define BMP18X_CALIBRATION_DATA_START 0xAA
63#define BMP18X_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
64#define BMP18X_CHIP_ID_REG 0xD0
65#define BMP18X_CTRL_REG 0xF4
66#define BMP18X_TEMP_MEASUREMENT 0x2E
67#define BMP18X_PRESSURE_MEASUREMENT 0x34
68#define BMP18X_CONVERSION_REGISTER_MSB 0xF6
69#define BMP18X_CONVERSION_REGISTER_LSB 0xF7
70#define BMP18X_CONVERSION_REGISTER_XLSB 0xF8
71#define BMP18X_TEMP_CONVERSION_TIME 5
72
73#define ABS_MIN_PRESSURE 30000
74#define ABS_MAX_PRESSURE 120000
75#define BMP_DELAY_DEFAULT 200
76
77struct bmp18x_calibration_data {
78 s16 AC1, AC2, AC3;
79 u16 AC4, AC5, AC6;
80 s16 B1, B2;
81 s16 MB, MC, MD;
82};
83
84/* Each client has this additional data */
85struct bmp18x_data {
86 struct bmp18x_data_bus data_bus;
87 struct device *dev;
88 struct mutex lock;
89 struct bmp18x_calibration_data calibration;
90 u8 oversampling_setting;
91 u8 sw_oversampling_setting;
92 u32 raw_temperature;
93 u32 raw_pressure;
94 u32 temp_measurement_period;
95 u32 last_temp_measurement;
96 s32 b6; /* calculated temperature correction coefficient */
97#ifdef CONFIG_HAS_EARLYSUSPEND
98 struct early_suspend early_suspend;
99#endif
100 struct input_dev *input;
101 struct delayed_work work;
102 u32 delay;
103 u32 enable;
104};
105
106#ifdef CONFIG_HAS_EARLYSUSPEND
107static void bmp18x_early_suspend(struct early_suspend *h);
108static void bmp18x_late_resume(struct early_suspend *h);
109#endif
110
111static s32 bmp18x_read_calibration_data(struct bmp18x_data *data)
112{
113 u16 tmp[BMP18X_CALIBRATION_DATA_LENGTH];
114 struct bmp18x_calibration_data *cali = &(data->calibration);
115 s32 status = data->data_bus.bops->read_block(data->data_bus.client,
116 BMP18X_CALIBRATION_DATA_START,
117 BMP18X_CALIBRATION_DATA_LENGTH*sizeof(u16),
118 (u8 *)tmp);
119 if (status < 0)
120 return status;
121
122 if (status != BMP18X_CALIBRATION_DATA_LENGTH*sizeof(u16))
123 return -EIO;
124
125 cali->AC1 = be16_to_cpu(tmp[0]);
126 cali->AC2 = be16_to_cpu(tmp[1]);
127 cali->AC3 = be16_to_cpu(tmp[2]);
128 cali->AC4 = be16_to_cpu(tmp[3]);
129 cali->AC5 = be16_to_cpu(tmp[4]);
130 cali->AC6 = be16_to_cpu(tmp[5]);
131 cali->B1 = be16_to_cpu(tmp[6]);
132 cali->B2 = be16_to_cpu(tmp[7]);
133 cali->MB = be16_to_cpu(tmp[8]);
134 cali->MC = be16_to_cpu(tmp[9]);
135 cali->MD = be16_to_cpu(tmp[10]);
136 return 0;
137}
138
139
140static s32 bmp18x_update_raw_temperature(struct bmp18x_data *data)
141{
142 u16 tmp;
143 s32 status;
144
145 mutex_lock(&data->lock);
146 status = data->data_bus.bops->write_byte(data->data_bus.client,
147 BMP18X_CTRL_REG, BMP18X_TEMP_MEASUREMENT);
148 if (status != 0) {
149 dev_err(data->dev,
150 "Error while requesting temperature measurement.\n");
151 goto exit;
152 }
153 msleep(BMP18X_TEMP_CONVERSION_TIME);
154
155 status = data->data_bus.bops->read_block(data->data_bus.client,
156 BMP18X_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
157 if (status < 0)
158 goto exit;
159 if (status != sizeof(tmp)) {
160 dev_err(data->dev,
161 "Error while reading temperature measurement result\n");
162 status = -EIO;
163 goto exit;
164 }
165 data->raw_temperature = be16_to_cpu(tmp);
166 data->last_temp_measurement = jiffies;
167 status = 0; /* everything ok, return 0 */
168
169exit:
170 mutex_unlock(&data->lock);
171 return status;
172}
173
174static s32 bmp18x_update_raw_pressure(struct bmp18x_data *data)
175{
176 u32 tmp = 0;
177 s32 status;
178
179 mutex_lock(&data->lock);
180 status = data->data_bus.bops->write_byte(data->data_bus.client,
181 BMP18X_CTRL_REG, BMP18X_PRESSURE_MEASUREMENT +
182 (data->oversampling_setting<<6));
183 if (status != 0) {
184 dev_err(data->dev,
185 "Error while requesting pressure measurement.\n");
186 goto exit;
187 }
188
189 /* wait for the end of conversion */
190 msleep(2+(3 << data->oversampling_setting));
191
192 /* copy data into a u32 (4 bytes), but skip the first byte. */
193 status = data->data_bus.bops->read_block(data->data_bus.client,
194 BMP18X_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
195 if (status < 0)
196 goto exit;
197 if (status != 3) {
198 dev_err(data->dev,
199 "Error while reading pressure measurement results\n");
200 status = -EIO;
201 goto exit;
202 }
203 data->raw_pressure = be32_to_cpu((tmp));
204 data->raw_pressure >>= (8-data->oversampling_setting);
205 status = 0; /* everything ok, return 0 */
206
207exit:
208 mutex_unlock(&data->lock);
209 return status;
210}
211
212
213/*
214 * This function starts the temperature measurement and returns the value
215 * in tenth of a degree celsius.
216 */
217static s32 bmp18x_get_temperature(struct bmp18x_data *data, int *temperature)
218{
219 struct bmp18x_calibration_data *cali = &data->calibration;
220 long x1, x2;
221 int status;
222
223 status = bmp18x_update_raw_temperature(data);
224 if (status != 0)
225 goto exit;
226
227 x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
228 x2 = (cali->MC << 11) / (x1 + cali->MD);
229 data->b6 = x1 + x2 - 4000;
230 /* if NULL just update b6. Used for pressure only measurements */
231 if (temperature != NULL)
232 *temperature = (x1+x2+8) >> 4;
233
234exit:
235 return status;
236}
237
238/*
239 * This function starts the pressure measurement and returns the value
240 * in millibar. Since the pressure depends on the ambient temperature,
241 * a temperature measurement is executed according to the given temperature
242 * measurememt period (default is 1 sec boundary). This period could vary
243 * and needs to be adjusted accoring to the sensor environment, i.e. if big
244 * temperature variations then the temperature needs to be read out often.
245 */
246static s32 bmp18x_get_pressure(struct bmp18x_data *data, int *pressure)
247{
248 struct bmp18x_calibration_data *cali = &data->calibration;
249 s32 x1, x2, x3, b3;
250 u32 b4, b7;
251 s32 p;
252 int status;
253 int i_loop, i;
254 u32 p_tmp;
255
256 /* update the ambient temperature according to the given meas. period */
257 if (data->last_temp_measurement +
258 data->temp_measurement_period < jiffies) {
259 status = bmp18x_get_temperature(data, NULL);
260 if (status != 0)
261 goto exit;
262 }
263
264 if ((data->oversampling_setting == 3)
265 && (data->sw_oversampling_setting == 1)) {
266 i_loop = 3;
267 } else {
268 i_loop = 1;
269 }
270
271 p_tmp = 0;
272 for (i = 0; i < i_loop; i++) {
273 status = bmp18x_update_raw_pressure(data);
274 if (status != 0)
275 goto exit;
276 p_tmp += data->raw_pressure;
277 }
278
279 data->raw_pressure = (p_tmp + (i_loop >> 1)) / i_loop;
280
281 x1 = (data->b6 * data->b6) >> 12;
282 x1 *= cali->B2;
283 x1 >>= 11;
284
285 x2 = cali->AC2 * data->b6;
286 x2 >>= 11;
287
288 x3 = x1 + x2;
289
290 b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
291 b3 >>= 2;
292
293 x1 = (cali->AC3 * data->b6) >> 13;
294 x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
295 x3 = (x1 + x2 + 2) >> 2;
296 b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
297
298 b7 = ((u32)data->raw_pressure - b3) *
299 (50000 >> data->oversampling_setting);
300 p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
301
302 x1 = p >> 8;
303 x1 *= x1;
304 x1 = (x1 * 3038) >> 16;
305 x2 = (-7357 * p) >> 16;
306 p += (x1 + x2 + 3791) >> 4;
307
308 *pressure = p;
309
310exit:
311 return status;
312}
313
314/*
315 * This function sets the chip-internal oversampling. Valid values are 0..3.
316 * The chip will use 2^oversampling samples for internal averaging.
317 * This influences the measurement time and the accuracy; larger values
318 * increase both. The datasheet gives on overview on how measurement time,
319 * accuracy and noise correlate.
320 */
321static void bmp18x_set_oversampling(struct bmp18x_data *data,
322 unsigned char oversampling)
323{
324 if (oversampling > 3)
325 oversampling = 3;
326 data->oversampling_setting = oversampling;
327}
328
329/*
330 * Returns the currently selected oversampling. Range: 0..3
331 */
332static unsigned char bmp18x_get_oversampling(struct bmp18x_data *data)
333{
334 return data->oversampling_setting;
335}
336
337/* sysfs callbacks */
338static ssize_t set_oversampling(struct device *dev,
339 struct device_attribute *attr,
340 const char *buf, size_t count)
341{
342 struct bmp18x_data *data = dev_get_drvdata(dev);
343 unsigned long oversampling;
344 int success = kstrtoul(buf, 10, &oversampling);
345 if (success == 0) {
346 mutex_lock(&data->lock);
347 bmp18x_set_oversampling(data, oversampling);
348 if (oversampling != 3)
349 data->sw_oversampling_setting = 0;
350 mutex_unlock(&data->lock);
351 return count;
352 }
353 return success;
354}
355
356static ssize_t show_oversampling(struct device *dev,
357 struct device_attribute *attr, char *buf)
358{
359 struct bmp18x_data *data = dev_get_drvdata(dev);
360 return snprintf(buf, PAGE_SIZE,
361 "%u\n", bmp18x_get_oversampling(data));
362}
363static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
364 show_oversampling, set_oversampling);
365
366static ssize_t set_sw_oversampling(struct device *dev,
367 struct device_attribute *attr,
368 const char *buf, size_t count)
369{
370 struct bmp18x_data *data = dev_get_drvdata(dev);
371 unsigned long sw_oversampling;
372 int success = kstrtoul(buf, 10, &sw_oversampling);
373 if (success == 0) {
374 mutex_lock(&data->lock);
375 data->sw_oversampling_setting = sw_oversampling ? 1 : 0;
376 mutex_unlock(&data->lock);
377 }
378 return success;
379}
380
381static ssize_t show_sw_oversampling(struct device *dev,
382 struct device_attribute *attr, char *buf)
383{
384 struct bmp18x_data *data = dev_get_drvdata(dev);
385 return snprintf(buf, PAGE_SIZE,
386 "%u\n", data->sw_oversampling_setting);
387}
388static DEVICE_ATTR(sw_oversampling, S_IWUSR | S_IRUGO,
389 show_sw_oversampling, set_sw_oversampling);
390
391static ssize_t show_delay(struct device *dev,
392 struct device_attribute *attr, char *buf)
393{
394 struct bmp18x_data *data = dev_get_drvdata(dev);
395 return snprintf(buf, PAGE_SIZE, "%u\n", data->delay);
396}
397
398static ssize_t set_delay(struct device *dev,
399 struct device_attribute *attr,
400 const char *buf, size_t count)
401{
402 struct bmp18x_data *data = dev_get_drvdata(dev);
403 unsigned long delay;
404 int success = kstrtoul(buf, 10, &delay);
405 if (success == 0) {
406 mutex_lock(&data->lock);
407 data->delay = delay;
408 mutex_unlock(&data->lock);
409 }
410 return success;
411}
412static DEVICE_ATTR(delay, S_IWUSR | S_IRUGO,
413 show_delay, set_delay);
414
415static ssize_t show_enable(struct device *dev,
416 struct device_attribute *attr, char *buf)
417{
418 struct bmp18x_data *data = dev_get_drvdata(dev);
419 return snprintf(buf, PAGE_SIZE, "%u\n", data->enable);
420}
421
422static ssize_t set_enable(struct device *dev,
423 struct device_attribute *attr,
424 const char *buf, size_t count)
425{
426 struct bmp18x_data *data = dev_get_drvdata(dev);
427 unsigned long enable;
428 int success = kstrtoul(buf, 10, &enable);
429 if (success == 0) {
430 mutex_lock(&data->lock);
431 data->enable = enable ? 1 : 0;
432
433 if (data->enable) {
434 bmp18x_enable(dev);
435 schedule_delayed_work(&data->work,
436 msecs_to_jiffies(data->delay));
437 } else {
438 cancel_delayed_work_sync(&data->work);
439 bmp18x_disable(dev);
440 }
441 mutex_unlock(&data->lock);
442
443 }
Richard Liu47d071d2013-04-14 14:08:16 -0700444 return count;
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +0800445}
446static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
447 show_enable, set_enable);
448
449static ssize_t show_temperature(struct device *dev,
450 struct device_attribute *attr, char *buf)
451{
452 int temperature;
453 int status;
454 struct bmp18x_data *data = dev_get_drvdata(dev);
455
456 status = bmp18x_get_temperature(data, &temperature);
457 if (status != 0)
458 return status;
459 else
460 return snprintf(buf, PAGE_SIZE,
461 "%d\n", temperature);
462}
463static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
464
465
466static ssize_t show_pressure(struct device *dev,
467 struct device_attribute *attr, char *buf)
468{
469 int pressure;
470 int status;
471 struct bmp18x_data *data = dev_get_drvdata(dev);
472
473 status = bmp18x_get_pressure(data, &pressure);
474 if (status != 0)
475 return status;
476 else
477 return snprintf(buf, PAGE_SIZE, "%d\n", pressure);
478}
479static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
480
481
482static struct attribute *bmp18x_attributes[] = {
483 &dev_attr_temp0_input.attr,
484 &dev_attr_pressure0_input.attr,
485 &dev_attr_oversampling.attr,
486 &dev_attr_sw_oversampling.attr,
487 &dev_attr_delay.attr,
488 &dev_attr_enable.attr,
489 NULL
490};
491
492static const struct attribute_group bmp18x_attr_group = {
493 .attrs = bmp18x_attributes,
494};
495
496static void bmp18x_work_func(struct work_struct *work)
497{
498 struct bmp18x_data *client_data =
499 container_of((struct delayed_work *)work,
500 struct bmp18x_data, work);
501 unsigned long delay = msecs_to_jiffies(client_data->delay);
502 unsigned long j1 = jiffies;
503 int pressure;
504 int status;
505
506 status = bmp18x_get_pressure(client_data, &pressure);
507
508 if (status == 0) {
509 input_report_abs(client_data->input, ABS_PRESSURE, pressure);
510 input_sync(client_data->input);
511 }
512
513 schedule_delayed_work(&client_data->work, delay-(jiffies-j1));
514}
515
516static int bmp18x_input_init(struct bmp18x_data *data)
517{
518 struct input_dev *dev;
519 int err;
520
521 dev = input_allocate_device();
522 if (!dev)
523 return -ENOMEM;
524 dev->name = BMP18X_NAME;
525 dev->id.bustype = BUS_I2C;
526
527 input_set_capability(dev, EV_ABS, ABS_MISC);
528 input_set_abs_params(dev, ABS_PRESSURE,
529 ABS_MIN_PRESSURE, ABS_MAX_PRESSURE, 0, 0);
530 input_set_drvdata(dev, data);
531
532 err = input_register_device(dev);
533 if (err < 0) {
534 input_free_device(dev);
535 return err;
536 }
537 data->input = dev;
538
539 return 0;
540}
541
542static void bmp18x_input_delete(struct bmp18x_data *data)
543{
544 struct input_dev *dev = data->input;
545
546 input_unregister_device(dev);
547 input_free_device(dev);
548}
549
550static int bmp18x_init_client(struct bmp18x_data *data,
551 struct bmp18x_platform_data *pdata)
552{
553 int status = bmp18x_read_calibration_data(data);
554 if (status != 0)
555 goto exit;
556 data->last_temp_measurement = 0;
557 data->temp_measurement_period =
558 pdata ? (pdata->temp_measurement_period/1000)*HZ : 1*HZ;
559 data->oversampling_setting = pdata ? pdata->default_oversampling : 3;
560 if (data->oversampling_setting == 3)
561 data->sw_oversampling_setting
562 = pdata ? pdata->default_sw_oversampling : 0;
563 mutex_init(&data->lock);
564exit:
565 return status;
566}
567
568__devinit int bmp18x_probe(struct device *dev, struct bmp18x_data_bus *data_bus)
569{
570 struct bmp18x_data *data;
571 struct bmp18x_platform_data *pdata = dev->platform_data;
572 u8 chip_id = pdata && pdata->chip_id ? pdata->chip_id : BMP18X_CHIP_ID;
573 int err = 0;
574
575 if (pdata && pdata->init_hw) {
Richard Liu47d071d2013-04-14 14:08:16 -0700576 err = pdata->init_hw(data_bus);
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +0800577 if (err) {
578 printk(KERN_ERR "%s: init_hw failed!\n",
579 BMP18X_NAME);
580 goto exit;
581 }
582 }
583
584 if (data_bus->bops->read_byte(data_bus->client,
585 BMP18X_CHIP_ID_REG) != chip_id) {
586 printk(KERN_ERR "%s: chip_id failed!\n", BMP18X_NAME);
587 err = -ENODEV;
588 goto exit;
589 }
590
591 data = kzalloc(sizeof(struct bmp18x_data), GFP_KERNEL);
592 if (!data) {
593 err = -ENOMEM;
594 goto exit;
595 }
596
597 dev_set_drvdata(dev, data);
598 data->data_bus = *data_bus;
599 data->dev = dev;
600
601 /* Initialize the BMP18X chip */
602 err = bmp18x_init_client(data, pdata);
603 if (err != 0)
604 goto exit_free;
605
606 /* Initialize the BMP18X input device */
607 err = bmp18x_input_init(data);
608 if (err != 0)
609 goto exit_free;
610
611 /* Register sysfs hooks */
612 err = sysfs_create_group(&data->input->dev.kobj, &bmp18x_attr_group);
613 if (err)
614 goto error_sysfs;
615 /* workqueue init */
616 INIT_DELAYED_WORK(&data->work, bmp18x_work_func);
617 data->delay = BMP_DELAY_DEFAULT;
618 data->enable = 0;
619
620#ifdef CONFIG_HAS_EARLYSUSPEND
621 data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
622 data->early_suspend.suspend = bmp18x_early_suspend;
623 data->early_suspend.resume = bmp18x_late_resume;
624 register_early_suspend(&data->early_suspend);
625#endif
626
627 dev_info(dev, "Succesfully initialized bmp18x!\n");
628 return 0;
629
630error_sysfs:
631 bmp18x_input_delete(data);
632exit_free:
633 kfree(data);
634exit:
635 if (pdata && pdata->deinit_hw)
Richard Liu47d071d2013-04-14 14:08:16 -0700636 pdata->deinit_hw(data_bus);
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +0800637 return err;
638}
639EXPORT_SYMBOL(bmp18x_probe);
640
641int bmp18x_remove(struct device *dev)
642{
643 struct bmp18x_data *data = dev_get_drvdata(dev);
644#ifdef CONFIG_HAS_EARLYSUSPEND
645 unregister_early_suspend(&data->early_suspend);
646#endif
647 sysfs_remove_group(&data->input->dev.kobj, &bmp18x_attr_group);
648 kfree(data);
649
650 return 0;
651}
652EXPORT_SYMBOL(bmp18x_remove);
653
654#ifdef CONFIG_PM
655int bmp18x_disable(struct device *dev)
656{
657 struct bmp18x_platform_data *pdata = dev->platform_data;
Richard Liu47d071d2013-04-14 14:08:16 -0700658 struct bmp18x_data *data = dev_get_drvdata(dev);
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +0800659 if (pdata && pdata->deinit_hw)
Richard Liu47d071d2013-04-14 14:08:16 -0700660 pdata->deinit_hw(&data->data_bus);
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +0800661
662 return 0;
663}
664EXPORT_SYMBOL(bmp18x_disable);
665
666int bmp18x_enable(struct device *dev)
667{
668 struct bmp18x_platform_data *pdata = dev->platform_data;
Richard Liu47d071d2013-04-14 14:08:16 -0700669 struct bmp18x_data *data = dev_get_drvdata(dev);
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +0800670 if (pdata && pdata->init_hw)
Richard Liu47d071d2013-04-14 14:08:16 -0700671 return pdata->init_hw(&data->data_bus);
hongji.zhou@cn.bosch.comf1204ad2013-02-05 14:45:04 +0800672
673 return 0;
674}
675EXPORT_SYMBOL(bmp18x_enable);
676#endif
677
678#ifdef CONFIG_HAS_EARLYSUSPEND
679static void bmp18x_early_suspend(struct early_suspend *h)
680{
681 struct bmp18x_data *data =
682 container_of(h, struct bmp18x_data, early_suspend);
683 if (data->enable) {
684 cancel_delayed_work_sync(&data->work);
685 (void) bmp18x_disable(data->dev);
686 }
687}
688
689static void bmp18x_late_resume(struct early_suspend *h)
690{
691 struct bmp18x_data *data =
692 container_of(h, struct bmp18x_data, early_suspend);
693
694 if (data->enable) {
695 (void) bmp18x_enable(data->dev);
696 schedule_delayed_work(&data->work,
697 msecs_to_jiffies(data->delay));
698 }
699
700}
701#endif
702
703MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
704MODULE_DESCRIPTION("BMP18X driver");
705MODULE_LICENSE("GPL");