/*
* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
* Copyright (c) 2012 Bosch Sensortec GmbH
* Copyright (c) 2012 Unixphere AB
* Copyright (c) 2014 Intel Corporation
* Copyright (c) 2016 Linus Walleij <linus.walleij@linaro.org>
*
* Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Datasheet:
* https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-DS000-121.pdf
* https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-DS001-12.pdf
* https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
*/
#define pr_fmt(fmt) "bmp280: " fmt
#include <linux/device.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
#include <linux/irq.h> /* For irq_get_irq_data() */
#include <linux/completion.h>
#include <linux/pm_runtime.h>
#include <linux/random.h>
#include "bmp280.h"
/*
* These enums are used for indexing into the array of calibration
* coefficients for BMP180.
*/
enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD };
struct bmp180_calib {
s16 AC1;
s16 AC2;
s16 AC3;
u16 AC4;
u16 AC5;
u16 AC6;
s16 B1;
s16 B2;
s16 MB;
s16 MC;
s16 MD;
};
struct bmp280_data {
struct device *dev;
struct mutex lock;
struct regmap *regmap;
struct completion done;
bool use_eoc;
const struct bmp280_chip_info *chip_info;
struct bmp180_calib calib;
struct regulator *vddd;
struct regulator *vdda;
unsigned int start_up_time; /* in milliseconds */
/* log of base 2 of oversampling rate */
u8 oversampling_press;
u8 oversampling_temp;
u8 oversampling_humid;
/*
* Carryover value from temperature conversion, used in pressure
* calculation.
*/
s32 t_fine;
};
struct bmp280_chip_info {
const int *oversampling_temp_avail;
int num_oversampling_temp_avail;
const int *oversampling_press_avail;
int num_oversampling_press_avail;
const int *oversampling_humid_avail;
int num_oversampling_humid_avail;
int (*chip_config)(struct bmp280_data *);
int (*read_temp)(struct bmp280_data *, int *);
int (*read_press)(struct bmp280_data *, int *, int *);
int (*read_humid)(struct bmp280_data *, int *, int *);
};
/*
* These enums are used for indexing into the array of compensation
* parameters for BMP280.
*/
enum { T1, T2, T3 };
enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
static const struct iio_chan_spec bmp280_channels[] = {
{
.type = IIO_PRESSURE,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
{
.type = IIO_HUMIDITYRELATIVE,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
};
/*
* Returns humidity in percent, resolution is 0.01 percent. Output value of
* "47445" represents 47445/1024 = 46.333 %RH.
*
* Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
*/
static u32 bmp280_compensate_humidity(struct bmp280_data *data,
s32 adc_humidity)
{
struct device *dev = data->dev;
unsigned int H1, H3, tmp;
int H2, H4, H5, H6, ret, var;
ret = regmap_read(data->regmap, BMP280_REG_COMP_H1, &H1);