2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2014-10-21 11:09:58 +03:00
/*
2016-06-30 03:48:51 +02:00
* Copyright ( c ) 2010 Christoph Mair < christoph . mair @ gmail . com >
* Copyright ( c ) 2012 Bosch Sensortec GmbH
* Copyright ( c ) 2012 Unixphere AB
2014-10-21 11:09:58 +03:00
* Copyright ( c ) 2014 Intel Corporation
2016-06-30 03:48:51 +02:00
* Copyright ( c ) 2016 Linus Walleij < linus . walleij @ linaro . org >
2014-10-21 11:09:58 +03:00
*
2016-04-24 22:52:10 +09:00
* Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor .
2014-10-21 11:09:58 +03:00
*
2016-04-24 22:52:10 +09:00
* 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
2016-05-04 22:57:30 -07:00
* https : //ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
2014-10-21 11:09:58 +03:00
*/
# define pr_fmt(fmt) "bmp280: " fmt
2016-06-30 03:48:49 +02:00
# include <linux/device.h>
2016-06-30 03:48:50 +02:00
# include <linux/module.h>
2014-10-21 11:09:58 +03:00
# include <linux/regmap.h>
2016-04-24 22:52:10 +09:00
# include <linux/delay.h>
2014-10-21 11:09:58 +03:00
# include <linux/iio/iio.h>
# include <linux/iio/sysfs.h>
2016-06-30 03:48:47 +02:00
# include <linux/gpio/consumer.h>
2016-06-30 03:48:48 +02:00
# include <linux/regulator/consumer.h>
2016-06-30 03:48:52 +02:00
# include <linux/interrupt.h>
# include <linux/irq.h> /* For irq_get_irq_data() */
# include <linux/completion.h>
2016-06-30 03:48:53 +02:00
# include <linux/pm_runtime.h>
2016-06-30 03:48:54 +02:00
# include <linux/random.h>
2014-10-21 11:09:58 +03:00
2016-06-30 03:48:49 +02:00
# include "bmp280.h"
2014-10-21 11:09:58 +03:00
2016-06-30 03:48:54 +02:00
/*
* 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 ;
} ;
2017-12-12 21:35:37 +01:00
/* See datasheet Section 4.2.2. */
struct bmp280_calib {
u16 T1 ;
s16 T2 ;
s16 T3 ;
u16 P1 ;
s16 P2 ;
s16 P3 ;
s16 P4 ;
s16 P5 ;
s16 P6 ;
s16 P7 ;
s16 P8 ;
s16 P9 ;
u8 H1 ;
s16 H2 ;
u8 H3 ;
s16 H4 ;
s16 H5 ;
s8 H6 ;
} ;
2019-10-02 10:57:56 +02:00
static const char * const bmp280_supply_names [ ] = {
" vddd " , " vdda "
} ;
# define BMP280_NUM_SUPPLIES ARRAY_SIZE(bmp280_supply_names)
2014-10-21 11:09:58 +03:00
struct bmp280_data {
2016-06-30 03:48:49 +02:00
struct device * dev ;
2014-10-21 11:09:58 +03:00
struct mutex lock ;
struct regmap * regmap ;
2016-06-30 03:48:52 +02:00
struct completion done ;
bool use_eoc ;
2016-04-24 22:52:10 +09:00
const struct bmp280_chip_info * chip_info ;
2017-12-12 21:35:37 +01:00
union {
struct bmp180_calib bmp180 ;
struct bmp280_calib bmp280 ;
} calib ;
2019-10-02 10:57:56 +02:00
struct regulator_bulk_data supplies [ BMP280_NUM_SUPPLIES ] ;
2016-11-26 09:17:26 +05:30
unsigned int start_up_time ; /* in microseconds */
2014-10-21 11:09:58 +03:00
2016-04-24 22:52:11 +09:00
/* log of base 2 of oversampling rate */
u8 oversampling_press ;
u8 oversampling_temp ;
2016-05-04 22:57:30 -07:00
u8 oversampling_humid ;
2016-04-24 22:52:11 +09:00
2014-10-21 11:09:58 +03:00
/*
* Carryover value from temperature conversion , used in pressure
* calculation .
*/
s32 t_fine ;
} ;
2016-04-24 22:52:10 +09:00
struct bmp280_chip_info {
2016-04-24 22:52:11 +09:00
const int * oversampling_temp_avail ;
int num_oversampling_temp_avail ;
const int * oversampling_press_avail ;
int num_oversampling_press_avail ;
2016-05-04 22:57:30 -07:00
const int * oversampling_humid_avail ;
int num_oversampling_humid_avail ;
2016-04-24 22:52:10 +09:00
int ( * chip_config ) ( struct bmp280_data * ) ;
int ( * read_temp ) ( struct bmp280_data * , int * ) ;
int ( * read_press ) ( struct bmp280_data * , int * , int * ) ;
2016-05-04 22:57:30 -07:00
int ( * read_humid ) ( struct bmp280_data * , int * , int * ) ;
2016-04-24 22:52:10 +09:00
} ;
2014-11-20 14:00:48 +02:00
/*
* These enums are used for indexing into the array of compensation
2016-04-24 22:52:10 +09:00
* parameters for BMP280 .
2014-11-20 14:00:48 +02:00
*/
enum { T1 , T2 , T3 } ;
enum { P1 , P2 , P3 , P4 , P5 , P6 , P7 , P8 , P9 } ;
2014-10-21 11:09:58 +03:00
static const struct iio_chan_spec bmp280_channels [ ] = {
{
. type = IIO_PRESSURE ,
2016-04-24 22:52:11 +09:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_PROCESSED ) |
BIT ( IIO_CHAN_INFO_OVERSAMPLING_RATIO ) ,
2014-10-21 11:09:58 +03:00
} ,
{
. type = IIO_TEMP ,
2016-04-24 22:52:11 +09:00
. info_mask_separate = BIT ( IIO_CHAN_INFO_PROCESSED ) |
BIT ( IIO_CHAN_INFO_OVERSAMPLING_RATIO ) ,
2014-10-21 11:09:58 +03:00
} ,
2016-05-04 22:57:30 -07:00
{
. type = IIO_HUMIDITYRELATIVE ,
. info_mask_separate = BIT ( IIO_CHAN_INFO_PROCESSED ) |
BIT ( IIO_CHAN_INFO_OVERSAMPLING_RATIO ) ,
} ,
2014-10-21 11:09:58 +03:00
} ;
2017-12-12 21:35:37 +01:00
static int bmp280_read_calib ( struct bmp280_data * data ,
struct bmp280_calib * calib ,
unsigned int chip )
2016-05-04 22:57:30 -07:00
{
2017-12-12 21:35:37 +01:00
int ret ;
unsigned int tmp ;
2019-10-13 11:17:42 +01:00
__le16 l16 ;
__be16 b16 ;
2016-06-30 03:48:49 +02:00
struct device * dev = data - > dev ;
2017-12-12 21:35:37 +01:00
__le16 t_buf [ BMP280_COMP_TEMP_REG_COUNT / 2 ] ;
__le16 p_buf [ BMP280_COMP_PRESS_REG_COUNT / 2 ] ;
/* Read temperature calibration values. */
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_COMP_TEMP_START ,
t_buf , BMP280_COMP_TEMP_REG_COUNT ) ;
if ( ret < 0 ) {
dev_err ( data - > dev ,
" failed to read temperature calibration parameters \n " ) ;
return ret ;
}
2019-03-12 09:40:18 +01:00
/* Toss the temperature calibration data into the entropy pool */
add_device_randomness ( t_buf , sizeof ( t_buf ) ) ;
2017-12-12 21:35:37 +01:00
calib - > T1 = le16_to_cpu ( t_buf [ T1 ] ) ;
calib - > T2 = le16_to_cpu ( t_buf [ T2 ] ) ;
calib - > T3 = le16_to_cpu ( t_buf [ T3 ] ) ;
2016-05-04 22:57:30 -07:00
2017-12-12 21:35:37 +01:00
/* Read pressure calibration values. */
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_COMP_PRESS_START ,
p_buf , BMP280_COMP_PRESS_REG_COUNT ) ;
if ( ret < 0 ) {
dev_err ( data - > dev ,
" failed to read pressure calibration parameters \n " ) ;
return ret ;
}
2019-03-12 09:40:18 +01:00
/* Toss the pressure calibration data into the entropy pool */
add_device_randomness ( p_buf , sizeof ( p_buf ) ) ;
2017-12-12 21:35:37 +01:00
calib - > P1 = le16_to_cpu ( p_buf [ P1 ] ) ;
calib - > P2 = le16_to_cpu ( p_buf [ P2 ] ) ;
calib - > P3 = le16_to_cpu ( p_buf [ P3 ] ) ;
calib - > P4 = le16_to_cpu ( p_buf [ P4 ] ) ;
calib - > P5 = le16_to_cpu ( p_buf [ P5 ] ) ;
calib - > P6 = le16_to_cpu ( p_buf [ P6 ] ) ;
calib - > P7 = le16_to_cpu ( p_buf [ P7 ] ) ;
calib - > P8 = le16_to_cpu ( p_buf [ P8 ] ) ;
calib - > P9 = le16_to_cpu ( p_buf [ P9 ] ) ;
/*
* Read humidity calibration values .
* Due to some odd register addressing we cannot just
* do a big bulk read . Instead , we have to read each Hx
* value separately and sometimes do some bit shifting . . .
* Humidity data is only available on BME280 .
*/
if ( chip ! = BME280_CHIP_ID )
return 0 ;
ret = regmap_read ( data - > regmap , BMP280_REG_COMP_H1 , & tmp ) ;
2016-05-04 22:57:30 -07:00
if ( ret < 0 ) {
dev_err ( dev , " failed to read H1 comp value \n " ) ;
return ret ;
}
2017-12-12 21:35:37 +01:00
calib - > H1 = tmp ;
2016-05-04 22:57:30 -07:00
2019-10-13 11:17:42 +01:00
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_COMP_H2 , & l16 , 2 ) ;
2016-05-04 22:57:30 -07:00
if ( ret < 0 ) {
dev_err ( dev , " failed to read H2 comp value \n " ) ;
return ret ;
}
2019-10-13 11:17:42 +01:00
calib - > H2 = sign_extend32 ( le16_to_cpu ( l16 ) , 15 ) ;
2016-05-04 22:57:30 -07:00
2017-12-12 21:35:37 +01:00
ret = regmap_read ( data - > regmap , BMP280_REG_COMP_H3 , & tmp ) ;
2016-05-04 22:57:30 -07:00
if ( ret < 0 ) {
dev_err ( dev , " failed to read H3 comp value \n " ) ;
return ret ;
}
2017-12-12 21:35:37 +01:00
calib - > H3 = tmp ;
2016-05-04 22:57:30 -07:00
2019-10-13 11:17:42 +01:00
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_COMP_H4 , & b16 , 2 ) ;
2016-05-04 22:57:30 -07:00
if ( ret < 0 ) {
dev_err ( dev , " failed to read H4 comp value \n " ) ;
return ret ;
}
2019-10-13 11:17:42 +01:00
calib - > H4 = sign_extend32 ( ( ( be16_to_cpu ( b16 ) > > 4 ) & 0xff0 ) |
( be16_to_cpu ( b16 ) & 0xf ) , 11 ) ;
2016-05-04 22:57:30 -07:00
2019-10-13 11:17:42 +01:00
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_COMP_H5 , & l16 , 2 ) ;
2016-05-04 22:57:30 -07:00
if ( ret < 0 ) {
dev_err ( dev , " failed to read H5 comp value \n " ) ;
return ret ;
}
2019-10-13 11:17:42 +01:00
calib - > H5 = sign_extend32 ( ( ( le16_to_cpu ( l16 ) > > 4 ) & 0xfff ) , 11 ) ;
2016-05-04 22:57:30 -07:00
ret = regmap_read ( data - > regmap , BMP280_REG_COMP_H6 , & tmp ) ;
if ( ret < 0 ) {
dev_err ( dev , " failed to read H6 comp value \n " ) ;
return ret ;
}
2017-12-12 21:35:37 +01:00
calib - > H6 = sign_extend32 ( tmp , 7 ) ;
return 0 ;
}
/*
* 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 )
{
s32 var ;
struct bmp280_calib * calib = & data - > calib . bmp280 ;
2016-05-04 22:57:30 -07:00
2017-04-10 19:00:01 +02:00
var = ( ( s32 ) data - > t_fine ) - ( s32 ) 76800 ;
2017-12-12 21:35:37 +01:00
var = ( ( ( ( adc_humidity < < 14 ) - ( calib - > H4 < < 20 ) - ( calib - > H5 * var ) )
+ ( s32 ) 16384 ) > > 15 ) * ( ( ( ( ( ( ( var * calib - > H6 ) > > 10 )
* ( ( ( var * ( s32 ) calib - > H3 ) > > 11 ) + ( s32 ) 32768 ) ) > > 10 )
+ ( s32 ) 2097152 ) * calib - > H2 + 8192 ) > > 14 ) ;
var - = ( ( ( ( var > > 15 ) * ( var > > 15 ) ) > > 7 ) * ( s32 ) calib - > H1 ) > > 4 ;
2016-05-04 22:57:30 -07:00
2020-05-04 20:10:34 +02:00
var = clamp_val ( var , 0 , 419430400 ) ;
2016-05-04 22:57:30 -07:00
return var > > 12 ;
} ;
2014-10-21 11:09:58 +03:00
/*
* Returns temperature in DegC , resolution is 0.01 DegC . Output value of
* " 5123 " equals 51.23 DegC . t_fine carries fine temperature as global
* value .
*
* Taken from datasheet , Section 3.11 .3 , " Compensation formula " .
*/
static s32 bmp280_compensate_temp ( struct bmp280_data * data ,
s32 adc_temp )
{
2014-12-19 23:59:25 +01:00
s32 var1 , var2 ;
2017-12-12 21:35:37 +01:00
struct bmp280_calib * calib = & data - > calib . bmp280 ;
2014-11-20 14:00:48 +02:00
2017-12-12 21:35:37 +01:00
var1 = ( ( ( adc_temp > > 3 ) - ( ( s32 ) calib - > T1 < < 1 ) ) *
( ( s32 ) calib - > T2 ) ) > > 11 ;
var2 = ( ( ( ( ( adc_temp > > 4 ) - ( ( s32 ) calib - > T1 ) ) *
( ( adc_temp > > 4 ) - ( ( s32 ) calib - > T1 ) ) ) > > 12 ) *
( ( s32 ) calib - > T3 ) ) > > 14 ;
2015-04-08 18:26:12 +03:00
data - > t_fine = var1 + var2 ;
2014-10-21 11:09:58 +03:00
2014-12-19 23:59:25 +01:00
return ( data - > t_fine * 5 + 128 ) > > 8 ;
2014-10-21 11:09:58 +03:00
}
/*
* Returns pressure in Pa as unsigned 32 bit integer in Q24 .8 format ( 24
* integer bits and 8 fractional bits ) . Output value of " 24674867 "
* represents 24674867 / 256 = 96386.2 Pa = 963.862 hPa
*
* Taken from datasheet , Section 3.11 .3 , " Compensation formula " .
*/
static u32 bmp280_compensate_press ( struct bmp280_data * data ,
s32 adc_press )
{
s64 var1 , var2 , p ;
2017-12-12 21:35:37 +01:00
struct bmp280_calib * calib = & data - > calib . bmp280 ;
2014-10-21 11:09:58 +03:00
2014-11-20 14:00:48 +02:00
var1 = ( ( s64 ) data - > t_fine ) - 128000 ;
2017-12-12 21:35:37 +01:00
var2 = var1 * var1 * ( s64 ) calib - > P6 ;
var2 + = ( var1 * ( s64 ) calib - > P5 ) < < 17 ;
var2 + = ( ( s64 ) calib - > P4 ) < < 35 ;
var1 = ( ( var1 * var1 * ( s64 ) calib - > P3 ) > > 8 ) +
( ( var1 * ( s64 ) calib - > P2 ) < < 12 ) ;
var1 = ( ( ( ( s64 ) 1 ) < < 47 ) + var1 ) * ( ( s64 ) calib - > P1 ) > > 33 ;
2014-10-21 11:09:58 +03:00
if ( var1 = = 0 )
return 0 ;
2014-11-20 14:00:48 +02:00
p = ( ( ( ( s64 ) 1048576 - adc_press ) < < 31 ) - var2 ) * 3125 ;
2014-10-23 15:52:00 +01:00
p = div64_s64 ( p , var1 ) ;
2017-12-12 21:35:37 +01:00
var1 = ( ( ( s64 ) calib - > P9 ) * ( p > > 13 ) * ( p > > 13 ) ) > > 25 ;
var2 = ( ( s64 ) ( calib - > P8 ) * p ) > > 19 ;
p = ( ( p + var1 + var2 ) > > 8 ) + ( ( ( s64 ) calib - > P7 ) < < 4 ) ;
2014-10-21 11:09:58 +03:00
2014-12-19 23:59:25 +01:00
return ( u32 ) p ;
2014-10-21 11:09:58 +03:00
}
static int bmp280_read_temp ( struct bmp280_data * data ,
int * val )
{
int ret ;
__be32 tmp = 0 ;
s32 adc_temp , comp_temp ;
2020-03-23 12:41:28 +02:00
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_TEMP_MSB , & tmp , 3 ) ;
2014-10-21 11:09:58 +03:00
if ( ret < 0 ) {
2016-06-30 03:48:49 +02:00
dev_err ( data - > dev , " failed to read temperature \n " ) ;
2014-10-21 11:09:58 +03:00
return ret ;
}
adc_temp = be32_to_cpu ( tmp ) > > 12 ;
2017-07-25 11:11:14 +02:00
if ( adc_temp = = BMP280_TEMP_SKIPPED ) {
/* reading was skipped */
dev_err ( data - > dev , " reading temperature skipped \n " ) ;
return - EIO ;
}
2014-11-20 14:00:48 +02:00
comp_temp = bmp280_compensate_temp ( data , adc_temp ) ;
2014-10-21 11:09:58 +03:00
/*
* val might be NULL if we ' re called by the read_press routine ,
* who only cares about the carry over t_fine value .
*/
if ( val ) {
* val = comp_temp * 10 ;
return IIO_VAL_INT ;
}
return 0 ;
}
static int bmp280_read_press ( struct bmp280_data * data ,
int * val , int * val2 )
{
int ret ;
__be32 tmp = 0 ;
s32 adc_press ;
u32 comp_press ;
/* Read and compensate temperature so we get a reading of t_fine. */
ret = bmp280_read_temp ( data , NULL ) ;
if ( ret < 0 )
return ret ;
2020-03-23 12:41:28 +02:00
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_PRESS_MSB , & tmp , 3 ) ;
2014-10-21 11:09:58 +03:00
if ( ret < 0 ) {
2016-06-30 03:48:49 +02:00
dev_err ( data - > dev , " failed to read pressure \n " ) ;
2014-10-21 11:09:58 +03:00
return ret ;
}
adc_press = be32_to_cpu ( tmp ) > > 12 ;
2017-07-25 11:11:14 +02:00
if ( adc_press = = BMP280_PRESS_SKIPPED ) {
/* reading was skipped */
dev_err ( data - > dev , " reading pressure skipped \n " ) ;
return - EIO ;
}
2014-11-20 14:00:48 +02:00
comp_press = bmp280_compensate_press ( data , adc_press ) ;
2014-10-21 11:09:58 +03:00
2014-10-31 01:22:00 +00:00
* val = comp_press ;
* val2 = 256000 ;
2014-10-21 11:09:58 +03:00
2014-10-31 01:22:00 +00:00
return IIO_VAL_FRACTIONAL ;
2014-10-21 11:09:58 +03:00
}
2016-05-04 22:57:30 -07:00
static int bmp280_read_humid ( struct bmp280_data * data , int * val , int * val2 )
{
2020-03-23 12:41:28 +02:00
__be16 tmp ;
2016-05-04 22:57:30 -07:00
int ret ;
s32 adc_humidity ;
u32 comp_humidity ;
/* Read and compensate temperature so we get a reading of t_fine. */
ret = bmp280_read_temp ( data , NULL ) ;
if ( ret < 0 )
return ret ;
2020-03-23 12:41:28 +02:00
ret = regmap_bulk_read ( data - > regmap , BMP280_REG_HUMIDITY_MSB , & tmp , 2 ) ;
2016-05-04 22:57:30 -07:00
if ( ret < 0 ) {
2016-06-30 03:48:49 +02:00
dev_err ( data - > dev , " failed to read humidity \n " ) ;
2016-05-04 22:57:30 -07:00
return ret ;
}
adc_humidity = be16_to_cpu ( tmp ) ;
2017-07-25 11:11:14 +02:00
if ( adc_humidity = = BMP280_HUMIDITY_SKIPPED ) {
/* reading was skipped */
dev_err ( data - > dev , " reading humidity skipped \n " ) ;
return - EIO ;
}
2016-05-04 22:57:30 -07:00
comp_humidity = bmp280_compensate_humidity ( data , adc_humidity ) ;
2018-05-28 17:38:59 +02:00
* val = comp_humidity * 1000 / 1024 ;
2016-05-04 22:57:30 -07:00
2018-05-28 17:38:59 +02:00
return IIO_VAL_INT ;
2016-05-04 22:57:30 -07:00
}
2014-10-21 11:09:58 +03:00
static int bmp280_read_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int * val , int * val2 , long mask )
{
int ret ;
struct bmp280_data * data = iio_priv ( indio_dev ) ;
2016-06-30 03:48:53 +02:00
pm_runtime_get_sync ( data - > dev ) ;
2014-10-21 11:09:58 +03:00
mutex_lock ( & data - > lock ) ;
switch ( mask ) {
case IIO_CHAN_INFO_PROCESSED :
switch ( chan - > type ) {
2016-05-04 22:57:30 -07:00
case IIO_HUMIDITYRELATIVE :
ret = data - > chip_info - > read_humid ( data , val , val2 ) ;
break ;
2014-10-21 11:09:58 +03:00
case IIO_PRESSURE :
2016-04-24 22:52:10 +09:00
ret = data - > chip_info - > read_press ( data , val , val2 ) ;
2014-10-21 11:09:58 +03:00
break ;
case IIO_TEMP :
2016-04-24 22:52:10 +09:00
ret = data - > chip_info - > read_temp ( data , val ) ;
2014-10-21 11:09:58 +03:00
break ;
default :
ret = - EINVAL ;
break ;
}
break ;
2016-04-24 22:52:11 +09:00
case IIO_CHAN_INFO_OVERSAMPLING_RATIO :
switch ( chan - > type ) {
2016-05-04 22:57:30 -07:00
case IIO_HUMIDITYRELATIVE :
* val = 1 < < data - > oversampling_humid ;
ret = IIO_VAL_INT ;
break ;
2016-04-24 22:52:11 +09:00
case IIO_PRESSURE :
* val = 1 < < data - > oversampling_press ;
ret = IIO_VAL_INT ;
break ;
case IIO_TEMP :
* val = 1 < < data - > oversampling_temp ;
ret = IIO_VAL_INT ;
break ;
default :
ret = - EINVAL ;
break ;
}
break ;
2014-10-21 11:09:58 +03:00
default :
ret = - EINVAL ;
break ;
}
mutex_unlock ( & data - > lock ) ;
2016-06-30 03:48:53 +02:00
pm_runtime_mark_last_busy ( data - > dev ) ;
pm_runtime_put_autosuspend ( data - > dev ) ;
2014-10-21 11:09:58 +03:00
return ret ;
}
2016-05-04 22:57:30 -07:00
static int bmp280_write_oversampling_ratio_humid ( struct bmp280_data * data ,
int val )
{
int i ;
const int * avail = data - > chip_info - > oversampling_humid_avail ;
const int n = data - > chip_info - > num_oversampling_humid_avail ;
for ( i = 0 ; i < n ; i + + ) {
if ( avail [ i ] = = val ) {
data - > oversampling_humid = ilog2 ( val ) ;
return data - > chip_info - > chip_config ( data ) ;
}
}
return - EINVAL ;
}
2016-04-24 22:52:11 +09:00
static int bmp280_write_oversampling_ratio_temp ( struct bmp280_data * data ,
int val )
{
int i ;
const int * avail = data - > chip_info - > oversampling_temp_avail ;
const int n = data - > chip_info - > num_oversampling_temp_avail ;
for ( i = 0 ; i < n ; i + + ) {
if ( avail [ i ] = = val ) {
data - > oversampling_temp = ilog2 ( val ) ;
return data - > chip_info - > chip_config ( data ) ;
}
}
return - EINVAL ;
}
static int bmp280_write_oversampling_ratio_press ( struct bmp280_data * data ,
int val )
{
int i ;
const int * avail = data - > chip_info - > oversampling_press_avail ;
const int n = data - > chip_info - > num_oversampling_press_avail ;
for ( i = 0 ; i < n ; i + + ) {
if ( avail [ i ] = = val ) {
data - > oversampling_press = ilog2 ( val ) ;
return data - > chip_info - > chip_config ( data ) ;
}
}
return - EINVAL ;
}
static int bmp280_write_raw ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
int val , int val2 , long mask )
{
int ret = 0 ;
struct bmp280_data * data = iio_priv ( indio_dev ) ;
switch ( mask ) {
case IIO_CHAN_INFO_OVERSAMPLING_RATIO :
2016-06-30 03:48:53 +02:00
pm_runtime_get_sync ( data - > dev ) ;
2016-04-24 22:52:11 +09:00
mutex_lock ( & data - > lock ) ;
switch ( chan - > type ) {
2016-05-04 22:57:30 -07:00
case IIO_HUMIDITYRELATIVE :
ret = bmp280_write_oversampling_ratio_humid ( data , val ) ;
break ;
2016-04-24 22:52:11 +09:00
case IIO_PRESSURE :
ret = bmp280_write_oversampling_ratio_press ( data , val ) ;
break ;
case IIO_TEMP :
ret = bmp280_write_oversampling_ratio_temp ( data , val ) ;
break ;
default :
ret = - EINVAL ;
break ;
}
mutex_unlock ( & data - > lock ) ;
2016-06-30 03:48:53 +02:00
pm_runtime_mark_last_busy ( data - > dev ) ;
pm_runtime_put_autosuspend ( data - > dev ) ;
2016-04-24 22:52:11 +09:00
break ;
default :
return - EINVAL ;
}
return ret ;
}
2020-03-23 12:41:26 +02:00
static int bmp280_read_avail ( struct iio_dev * indio_dev ,
struct iio_chan_spec const * chan ,
const int * * vals , int * type , int * length ,
long mask )
2016-04-24 22:52:11 +09:00
{
2020-03-23 12:41:26 +02:00
struct bmp280_data * data = iio_priv ( indio_dev ) ;
2016-04-24 22:52:11 +09:00
2020-03-23 12:41:26 +02:00
switch ( mask ) {
case IIO_CHAN_INFO_OVERSAMPLING_RATIO :
switch ( chan - > type ) {
case IIO_PRESSURE :
* vals = data - > chip_info - > oversampling_press_avail ;
* length = data - > chip_info - > num_oversampling_press_avail ;
break ;
case IIO_TEMP :
* vals = data - > chip_info - > oversampling_temp_avail ;
* length = data - > chip_info - > num_oversampling_temp_avail ;
break ;
default :
return - EINVAL ;
}
* type = IIO_VAL_INT ;
return IIO_AVAIL_LIST ;
default :
return - EINVAL ;
}
2016-04-24 22:52:11 +09:00
}
2014-10-21 11:09:58 +03:00
static const struct iio_info bmp280_info = {
. read_raw = & bmp280_read_raw ,
2020-03-23 12:41:26 +02:00
. read_avail = & bmp280_read_avail ,
2016-04-24 22:52:11 +09:00
. write_raw = & bmp280_write_raw ,
2014-10-21 11:09:58 +03:00
} ;
2016-04-24 22:52:10 +09:00
static int bmp280_chip_config ( struct bmp280_data * data )
2014-10-21 11:09:58 +03:00
{
int ret ;
2016-04-24 22:52:11 +09:00
u8 osrs = BMP280_OSRS_TEMP_X ( data - > oversampling_temp + 1 ) |
BMP280_OSRS_PRESS_X ( data - > oversampling_press + 1 ) ;
2014-10-21 11:09:58 +03:00
2017-08-28 16:21:39 -07:00
ret = regmap_write_bits ( data - > regmap , BMP280_REG_CTRL_MEAS ,
2014-10-21 11:09:58 +03:00
BMP280_OSRS_TEMP_MASK |
BMP280_OSRS_PRESS_MASK |
BMP280_MODE_MASK ,
2016-04-24 22:52:11 +09:00
osrs | BMP280_MODE_NORMAL ) ;
2014-10-21 11:09:58 +03:00
if ( ret < 0 ) {
2016-06-30 03:48:49 +02:00
dev_err ( data - > dev ,
2014-12-19 23:59:25 +01:00
" failed to write ctrl_meas register \n " ) ;
2014-10-21 11:09:58 +03:00
return ret ;
}
ret = regmap_update_bits ( data - > regmap , BMP280_REG_CONFIG ,
BMP280_FILTER_MASK ,
BMP280_FILTER_4X ) ;
if ( ret < 0 ) {
2016-06-30 03:48:49 +02:00
dev_err ( data - > dev ,
2014-10-21 11:09:58 +03:00
" failed to write config register \n " ) ;
return ret ;
}
return ret ;
}
2016-04-24 22:52:11 +09:00
static const int bmp280_oversampling_avail [ ] = { 1 , 2 , 4 , 8 , 16 } ;
2016-04-24 22:52:10 +09:00
static const struct bmp280_chip_info bmp280_chip_info = {
2016-04-24 22:52:11 +09:00
. oversampling_temp_avail = bmp280_oversampling_avail ,
. num_oversampling_temp_avail = ARRAY_SIZE ( bmp280_oversampling_avail ) ,
. oversampling_press_avail = bmp280_oversampling_avail ,
. num_oversampling_press_avail = ARRAY_SIZE ( bmp280_oversampling_avail ) ,
2016-04-24 22:52:10 +09:00
. chip_config = bmp280_chip_config ,
. read_temp = bmp280_read_temp ,
. read_press = bmp280_read_press ,
} ;
2016-05-04 22:57:30 -07:00
static int bme280_chip_config ( struct bmp280_data * data )
{
2017-07-25 11:11:14 +02:00
int ret ;
2016-05-04 22:57:30 -07:00
u8 osrs = BMP280_OSRS_HUMIDITIY_X ( data - > oversampling_humid + 1 ) ;
2017-07-25 11:11:14 +02:00
/*
* Oversampling of humidity must be set before oversampling of
* temperature / pressure is set to become effective .
*/
ret = regmap_update_bits ( data - > regmap , BMP280_REG_CTRL_HUMIDITY ,
BMP280_OSRS_HUMIDITY_MASK , osrs ) ;
2016-05-04 22:57:30 -07:00
if ( ret < 0 )
return ret ;
2017-07-25 11:11:14 +02:00
return bmp280_chip_config ( data ) ;
2016-05-04 22:57:30 -07:00
}
static const struct bmp280_chip_info bme280_chip_info = {
. oversampling_temp_avail = bmp280_oversampling_avail ,
. num_oversampling_temp_avail = ARRAY_SIZE ( bmp280_oversampling_avail ) ,
. oversampling_press_avail = bmp280_oversampling_avail ,
. num_oversampling_press_avail = ARRAY_SIZE ( bmp280_oversampling_avail ) ,
. oversampling_humid_avail = bmp280_oversampling_avail ,
. num_oversampling_humid_avail = ARRAY_SIZE ( bmp280_oversampling_avail ) ,
. chip_config = bme280_chip_config ,
. read_temp = bmp280_read_temp ,
. read_press = bmp280_read_press ,
. read_humid = bmp280_read_humid ,
} ;
2016-04-24 22:52:10 +09:00
static int bmp180_measure ( struct bmp280_data * data , u8 ctrl_meas )
{
int ret ;
const int conversion_time_max [ ] = { 4500 , 7500 , 13500 , 25500 } ;
unsigned int delay_us ;
unsigned int ctrl ;
2016-06-30 03:48:52 +02:00
if ( data - > use_eoc )
2020-03-23 12:41:25 +02:00
reinit_completion ( & data - > done ) ;
2016-06-30 03:48:52 +02:00
2016-04-24 22:52:10 +09:00
ret = regmap_write ( data - > regmap , BMP280_REG_CTRL_MEAS , ctrl_meas ) ;
if ( ret )
return ret ;
2016-06-30 03:48:52 +02:00
if ( data - > use_eoc ) {
/*
* If we have a completion interrupt , use it , wait up to
* 100 ms . The longest conversion time listed is 76.5 ms for
* advanced resolution mode .
*/
ret = wait_for_completion_timeout ( & data - > done ,
1 + msecs_to_jiffies ( 100 ) ) ;
if ( ! ret )
dev_err ( data - > dev , " timeout waiting for completion \n " ) ;
} else {
if ( ctrl_meas = = BMP180_MEAS_TEMP )
delay_us = 4500 ;
else
delay_us =
conversion_time_max [ data - > oversampling_press ] ;
usleep_range ( delay_us , delay_us + 1000 ) ;
}
2016-04-24 22:52:10 +09:00
ret = regmap_read ( data - > regmap , BMP280_REG_CTRL_MEAS , & ctrl ) ;
if ( ret )
return ret ;
/* The value of this bit reset to "0" after conversion is complete */
if ( ctrl & BMP180_MEAS_SCO )
return - EIO ;
return 0 ;
}
static int bmp180_read_adc_temp ( struct bmp280_data * data , int * val )
{
2020-03-23 12:41:28 +02:00
__be16 tmp ;
2016-04-24 22:52:10 +09:00
int ret ;
ret = bmp180_measure ( data , BMP180_MEAS_TEMP ) ;
if ( ret )
return ret ;
2020-03-23 12:41:28 +02:00
ret = regmap_bulk_read ( data - > regmap , BMP180_REG_OUT_MSB , & tmp , 2 ) ;
2016-04-24 22:52:10 +09:00
if ( ret )
return ret ;
* val = be16_to_cpu ( tmp ) ;
return 0 ;
}
static int bmp180_read_calib ( struct bmp280_data * data ,
struct bmp180_calib * calib )
{
int ret ;
int i ;
__be16 buf [ BMP180_REG_CALIB_COUNT / 2 ] ;
ret = regmap_bulk_read ( data - > regmap , BMP180_REG_CALIB_START , buf ,
sizeof ( buf ) ) ;
if ( ret < 0 )
return ret ;
/* None of the words has the value 0 or 0xFFFF */
for ( i = 0 ; i < ARRAY_SIZE ( buf ) ; i + + ) {
if ( buf [ i ] = = cpu_to_be16 ( 0 ) | | buf [ i ] = = cpu_to_be16 ( 0xffff ) )
return - EIO ;
}
2016-06-30 03:48:54 +02:00
/* Toss the calibration data into the entropy pool */
add_device_randomness ( buf , sizeof ( buf ) ) ;
2016-04-24 22:52:10 +09:00
calib - > AC1 = be16_to_cpu ( buf [ AC1 ] ) ;
calib - > AC2 = be16_to_cpu ( buf [ AC2 ] ) ;
calib - > AC3 = be16_to_cpu ( buf [ AC3 ] ) ;
calib - > AC4 = be16_to_cpu ( buf [ AC4 ] ) ;
calib - > AC5 = be16_to_cpu ( buf [ AC5 ] ) ;
calib - > AC6 = be16_to_cpu ( buf [ AC6 ] ) ;
calib - > B1 = be16_to_cpu ( buf [ B1 ] ) ;
calib - > B2 = be16_to_cpu ( buf [ B2 ] ) ;
calib - > MB = be16_to_cpu ( buf [ MB ] ) ;
calib - > MC = be16_to_cpu ( buf [ MC ] ) ;
calib - > MD = be16_to_cpu ( buf [ MD ] ) ;
return 0 ;
}
/*
* Returns temperature in DegC , resolution is 0.1 DegC .
* t_fine carries fine temperature as global value .
*
* Taken from datasheet , Section 3.5 , " Calculating pressure and temperature " .
*/
static s32 bmp180_compensate_temp ( struct bmp280_data * data , s32 adc_temp )
{
s32 x1 , x2 ;
2017-12-12 21:35:37 +01:00
struct bmp180_calib * calib = & data - > calib . bmp180 ;
2016-04-24 22:52:10 +09:00
2016-06-30 03:48:54 +02:00
x1 = ( ( adc_temp - calib - > AC6 ) * calib - > AC5 ) > > 15 ;
x2 = ( calib - > MC < < 11 ) / ( x1 + calib - > MD ) ;
2016-04-24 22:52:10 +09:00
data - > t_fine = x1 + x2 ;
return ( data - > t_fine + 8 ) > > 4 ;
}
static int bmp180_read_temp ( struct bmp280_data * data , int * val )
{
int ret ;
s32 adc_temp , comp_temp ;
ret = bmp180_read_adc_temp ( data , & adc_temp ) ;
if ( ret )
return ret ;
comp_temp = bmp180_compensate_temp ( data , adc_temp ) ;
/*
* val might be NULL if we ' re called by the read_press routine ,
* who only cares about the carry over t_fine value .
*/
if ( val ) {
* val = comp_temp * 100 ;
return IIO_VAL_INT ;
}
return 0 ;
}
static int bmp180_read_adc_press ( struct bmp280_data * data , int * val )
{
int ret ;
__be32 tmp = 0 ;
2016-04-24 22:52:11 +09:00
u8 oss = data - > oversampling_press ;
2016-04-24 22:52:10 +09:00
ret = bmp180_measure ( data , BMP180_MEAS_PRESS_X ( oss ) ) ;
if ( ret )
return ret ;
2020-03-23 12:41:28 +02:00
ret = regmap_bulk_read ( data - > regmap , BMP180_REG_OUT_MSB , & tmp , 3 ) ;
2016-04-24 22:52:10 +09:00
if ( ret )
return ret ;
* val = ( be32_to_cpu ( tmp ) > > 8 ) > > ( 8 - oss ) ;
return 0 ;
}
/*
* Returns pressure in Pa , resolution is 1 Pa .
*
* Taken from datasheet , Section 3.5 , " Calculating pressure and temperature " .
*/
static u32 bmp180_compensate_press ( struct bmp280_data * data , s32 adc_press )
{
s32 x1 , x2 , x3 , p ;
s32 b3 , b6 ;
u32 b4 , b7 ;
2016-04-24 22:52:11 +09:00
s32 oss = data - > oversampling_press ;
2017-12-12 21:35:37 +01:00
struct bmp180_calib * calib = & data - > calib . bmp180 ;
2016-04-24 22:52:10 +09:00
b6 = data - > t_fine - 4000 ;
2016-06-30 03:48:54 +02:00
x1 = ( calib - > B2 * ( b6 * b6 > > 12 ) ) > > 11 ;
x2 = calib - > AC2 * b6 > > 11 ;
2016-04-24 22:52:10 +09:00
x3 = x1 + x2 ;
2016-06-30 03:48:54 +02:00
b3 = ( ( ( ( s32 ) calib - > AC1 * 4 + x3 ) < < oss ) + 2 ) / 4 ;
x1 = calib - > AC3 * b6 > > 13 ;
x2 = ( calib - > B1 * ( ( b6 * b6 ) > > 12 ) ) > > 16 ;
2016-04-24 22:52:10 +09:00
x3 = ( x1 + x2 + 2 ) > > 2 ;
2016-06-30 03:48:54 +02:00
b4 = calib - > AC4 * ( u32 ) ( x3 + 32768 ) > > 15 ;
2016-04-24 22:52:10 +09:00
b7 = ( ( u32 ) adc_press - b3 ) * ( 50000 > > oss ) ;
if ( b7 < 0x80000000 )
p = ( b7 * 2 ) / b4 ;
else
p = ( b7 / b4 ) * 2 ;
x1 = ( p > > 8 ) * ( p > > 8 ) ;
x1 = ( x1 * 3038 ) > > 16 ;
x2 = ( - 7357 * p ) > > 16 ;
return p + ( ( x1 + x2 + 3791 ) > > 4 ) ;
}
static int bmp180_read_press ( struct bmp280_data * data ,
int * val , int * val2 )
{
int ret ;
s32 adc_press ;
u32 comp_press ;
/* Read and compensate temperature so we get a reading of t_fine. */
ret = bmp180_read_temp ( data , NULL ) ;
if ( ret )
return ret ;
ret = bmp180_read_adc_press ( data , & adc_press ) ;
if ( ret )
return ret ;
comp_press = bmp180_compensate_press ( data , adc_press ) ;
* val = comp_press ;
* val2 = 1000 ;
return IIO_VAL_FRACTIONAL ;
}
static int bmp180_chip_config ( struct bmp280_data * data )
{
return 0 ;
}
2016-04-24 22:52:11 +09:00
static const int bmp180_oversampling_temp_avail [ ] = { 1 } ;
static const int bmp180_oversampling_press_avail [ ] = { 1 , 2 , 4 , 8 } ;
2016-04-24 22:52:10 +09:00
static const struct bmp280_chip_info bmp180_chip_info = {
2016-04-24 22:52:11 +09:00
. oversampling_temp_avail = bmp180_oversampling_temp_avail ,
. num_oversampling_temp_avail =
ARRAY_SIZE ( bmp180_oversampling_temp_avail ) ,
. oversampling_press_avail = bmp180_oversampling_press_avail ,
. num_oversampling_press_avail =
ARRAY_SIZE ( bmp180_oversampling_press_avail ) ,
2016-04-24 22:52:10 +09:00
. chip_config = bmp180_chip_config ,
. read_temp = bmp180_read_temp ,
. read_press = bmp180_read_press ,
} ;
2016-06-30 03:48:52 +02:00
static irqreturn_t bmp085_eoc_irq ( int irq , void * d )
{
struct bmp280_data * data = d ;
complete ( & data - > done ) ;
return IRQ_HANDLED ;
}
static int bmp085_fetch_eoc_irq ( struct device * dev ,
const char * name ,
int irq ,
struct bmp280_data * data )
{
unsigned long irq_trig ;
int ret ;
irq_trig = irqd_get_trigger_type ( irq_get_irq_data ( irq ) ) ;
if ( irq_trig ! = IRQF_TRIGGER_RISING ) {
2020-03-23 12:41:29 +02:00
dev_err ( dev , " non-rising trigger given for EOC interrupt, trying to enforce it \n " ) ;
2016-06-30 03:48:52 +02:00
irq_trig = IRQF_TRIGGER_RISING ;
}
2020-03-23 12:41:25 +02:00
init_completion ( & data - > done ) ;
2016-06-30 03:48:52 +02:00
ret = devm_request_threaded_irq ( dev ,
irq ,
bmp085_eoc_irq ,
NULL ,
irq_trig ,
name ,
data ) ;
if ( ret ) {
/* Bail out without IRQ but keep the driver in place */
dev_err ( dev , " unable to request DRDY IRQ \n " ) ;
return 0 ;
}
data - > use_eoc = true ;
return 0 ;
}
2019-10-07 04:41:31 +02:00
static void bmp280_pm_disable ( void * data )
{
struct device * dev = data ;
pm_runtime_get_sync ( dev ) ;
pm_runtime_put_noidle ( dev ) ;
pm_runtime_disable ( dev ) ;
}
static void bmp280_regulators_disable ( void * data )
{
struct regulator_bulk_data * supplies = data ;
regulator_bulk_disable ( BMP280_NUM_SUPPLIES , supplies ) ;
}
2016-06-30 03:48:49 +02:00
int bmp280_common_probe ( struct device * dev ,
struct regmap * regmap ,
unsigned int chip ,
2016-06-30 03:48:52 +02:00
const char * name ,
int irq )
2014-10-21 11:09:58 +03:00
{
int ret ;
struct iio_dev * indio_dev ;
struct bmp280_data * data ;
unsigned int chip_id ;
2016-06-30 03:48:47 +02:00
struct gpio_desc * gpiod ;
2014-10-21 11:09:58 +03:00
2016-06-30 03:48:49 +02:00
indio_dev = devm_iio_device_alloc ( dev , sizeof ( * data ) ) ;
2014-10-21 11:09:58 +03:00
if ( ! indio_dev )
return - ENOMEM ;
data = iio_priv ( indio_dev ) ;
mutex_init ( & data - > lock ) ;
2016-06-30 03:48:49 +02:00
data - > dev = dev ;
2014-10-21 11:09:58 +03:00
2016-06-30 03:48:49 +02:00
indio_dev - > name = name ;
2014-10-21 11:09:58 +03:00
indio_dev - > channels = bmp280_channels ;
indio_dev - > info = & bmp280_info ;
indio_dev - > modes = INDIO_DIRECT_MODE ;
2016-06-30 03:48:49 +02:00
switch ( chip ) {
2016-04-24 22:52:10 +09:00
case BMP180_CHIP_ID :
2016-05-04 22:57:30 -07:00
indio_dev - > num_channels = 2 ;
2016-04-24 22:52:10 +09:00
data - > chip_info = & bmp180_chip_info ;
2016-04-24 22:52:11 +09:00
data - > oversampling_press = ilog2 ( 8 ) ;
data - > oversampling_temp = ilog2 ( 1 ) ;
2016-11-26 09:17:26 +05:30
data - > start_up_time = 10000 ;
2016-04-24 22:52:10 +09:00
break ;
case BMP280_CHIP_ID :
2016-05-04 22:57:30 -07:00
indio_dev - > num_channels = 2 ;
2016-04-24 22:52:10 +09:00
data - > chip_info = & bmp280_chip_info ;
2016-04-24 22:52:11 +09:00
data - > oversampling_press = ilog2 ( 16 ) ;
data - > oversampling_temp = ilog2 ( 2 ) ;
2016-11-26 09:17:26 +05:30
data - > start_up_time = 2000 ;
2016-04-24 22:52:10 +09:00
break ;
2016-05-04 22:57:30 -07:00
case BME280_CHIP_ID :
indio_dev - > num_channels = 3 ;
data - > chip_info = & bme280_chip_info ;
data - > oversampling_press = ilog2 ( 16 ) ;
data - > oversampling_humid = ilog2 ( 16 ) ;
data - > oversampling_temp = ilog2 ( 2 ) ;
2016-11-26 09:17:26 +05:30
data - > start_up_time = 2000 ;
2016-05-04 22:57:30 -07:00
break ;
2016-04-24 22:52:10 +09:00
default :
return - EINVAL ;
}
2016-06-30 03:48:48 +02:00
/* Bring up regulators */
2019-10-02 10:57:56 +02:00
regulator_bulk_set_supply_names ( data - > supplies ,
bmp280_supply_names ,
BMP280_NUM_SUPPLIES ) ;
ret = devm_regulator_bulk_get ( dev ,
BMP280_NUM_SUPPLIES , data - > supplies ) ;
2016-06-30 03:48:48 +02:00
if ( ret ) {
2019-10-02 10:57:56 +02:00
dev_err ( dev , " failed to get regulators \n " ) ;
2016-06-30 03:48:48 +02:00
return ret ;
}
2019-10-02 10:57:56 +02:00
ret = regulator_bulk_enable ( BMP280_NUM_SUPPLIES , data - > supplies ) ;
2016-06-30 03:48:48 +02:00
if ( ret ) {
2019-10-02 10:57:56 +02:00
dev_err ( dev , " failed to enable regulators \n " ) ;
return ret ;
2016-06-30 03:48:48 +02:00
}
2019-10-02 10:57:56 +02:00
2019-10-07 04:41:31 +02:00
ret = devm_add_action_or_reset ( dev , bmp280_regulators_disable ,
data - > supplies ) ;
if ( ret )
return ret ;
2016-06-30 03:48:48 +02:00
/* Wait to make sure we started up properly */
2016-11-26 09:17:26 +05:30
usleep_range ( data - > start_up_time , data - > start_up_time + 100 ) ;
2016-06-30 03:48:48 +02:00
2016-06-30 03:48:47 +02:00
/* Bring chip out of reset if there is an assigned GPIO line */
2020-03-23 12:41:27 +02:00
gpiod = devm_gpiod_get_optional ( dev , " reset " , GPIOD_OUT_HIGH ) ;
2016-06-30 03:48:47 +02:00
/* Deassert the signal */
2020-03-23 12:41:27 +02:00
if ( gpiod ) {
2016-06-30 03:48:49 +02:00
dev_info ( dev , " release reset \n " ) ;
2016-06-30 03:48:47 +02:00
gpiod_set_value ( gpiod , 0 ) ;
}
2016-06-30 03:48:49 +02:00
data - > regmap = regmap ;
ret = regmap_read ( regmap , BMP280_REG_ID , & chip_id ) ;
2014-10-21 11:09:58 +03:00
if ( ret < 0 )
2019-10-07 04:41:31 +02:00
return ret ;
2016-06-30 03:48:49 +02:00
if ( chip_id ! = chip ) {
dev_err ( dev , " bad chip id: expected %x got %x \n " ,
chip , chip_id ) ;
2019-10-07 04:41:31 +02:00
return - EINVAL ;
2014-10-21 11:09:58 +03:00
}
2016-04-24 22:52:10 +09:00
ret = data - > chip_info - > chip_config ( data ) ;
2014-10-21 11:09:58 +03:00
if ( ret < 0 )
2019-10-07 04:41:31 +02:00
return ret ;
2014-10-21 11:09:58 +03:00
2016-06-30 03:48:49 +02:00
dev_set_drvdata ( dev , indio_dev ) ;
2016-06-30 03:48:48 +02:00
2016-06-30 03:48:54 +02:00
/*
2017-12-12 21:35:37 +01:00
* Some chips have calibration parameters " programmed into the devices'
* non - volatile memory during production " . Let's read them out at probe
* time once . They will not change .
2016-06-30 03:48:54 +02:00
*/
if ( chip_id = = BMP180_CHIP_ID ) {
2017-12-12 21:35:37 +01:00
ret = bmp180_read_calib ( data , & data - > calib . bmp180 ) ;
if ( ret < 0 ) {
dev_err ( data - > dev ,
" failed to read calibration coefficients \n " ) ;
2019-10-07 04:41:31 +02:00
return ret ;
2017-12-12 21:35:37 +01:00
}
} else if ( chip_id = = BMP280_CHIP_ID | | chip_id = = BME280_CHIP_ID ) {
ret = bmp280_read_calib ( data , & data - > calib . bmp280 , chip_id ) ;
2016-06-30 03:48:54 +02:00
if ( ret < 0 ) {
dev_err ( data - > dev ,
" failed to read calibration coefficients \n " ) ;
2019-10-07 04:41:31 +02:00
return ret ;
2016-06-30 03:48:54 +02:00
}
}
2016-06-30 03:48:52 +02:00
/*
* Attempt to grab an optional EOC IRQ - only the BMP085 has this
* however as it happens , the BMP085 shares the chip ID of BMP180
* so we look for an IRQ if we have that .
*/
if ( irq > 0 | | ( chip_id = = BMP180_CHIP_ID ) ) {
ret = bmp085_fetch_eoc_irq ( dev , name , irq , data ) ;
if ( ret )
2019-10-07 04:41:31 +02:00
return ret ;
2016-06-30 03:48:52 +02:00
}
2016-06-30 03:48:53 +02:00
/* Enable runtime PM */
pm_runtime_get_noresume ( dev ) ;
pm_runtime_set_active ( dev ) ;
pm_runtime_enable ( dev ) ;
/*
* Set autosuspend to two orders of magnitude larger than the
* start - up time .
*/
2016-11-26 09:17:26 +05:30
pm_runtime_set_autosuspend_delay ( dev , data - > start_up_time / 10 ) ;
2016-06-30 03:48:53 +02:00
pm_runtime_use_autosuspend ( dev ) ;
pm_runtime_put ( dev ) ;
2019-10-07 04:41:31 +02:00
ret = devm_add_action_or_reset ( dev , bmp280_pm_disable , dev ) ;
2016-06-30 03:48:48 +02:00
if ( ret )
2019-10-07 04:41:31 +02:00
return ret ;
2016-06-30 03:48:48 +02:00
2019-10-07 04:41:31 +02:00
return devm_iio_device_register ( dev , indio_dev ) ;
2016-06-30 03:48:48 +02:00
}
2016-06-30 03:48:50 +02:00
EXPORT_SYMBOL ( bmp280_common_probe ) ;
2016-06-30 03:48:48 +02:00
2016-06-30 03:48:53 +02:00
# ifdef CONFIG_PM
static int bmp280_runtime_suspend ( struct device * dev )
{
2016-07-27 22:32:58 +02:00
struct iio_dev * indio_dev = dev_get_drvdata ( dev ) ;
struct bmp280_data * data = iio_priv ( indio_dev ) ;
2016-06-30 03:48:53 +02:00
2019-10-02 10:57:56 +02:00
return regulator_bulk_disable ( BMP280_NUM_SUPPLIES , data - > supplies ) ;
2016-06-30 03:48:53 +02:00
}
static int bmp280_runtime_resume ( struct device * dev )
{
2016-07-27 22:32:58 +02:00
struct iio_dev * indio_dev = dev_get_drvdata ( dev ) ;
struct bmp280_data * data = iio_priv ( indio_dev ) ;
2016-06-30 03:48:53 +02:00
int ret ;
2019-10-02 10:57:56 +02:00
ret = regulator_bulk_enable ( BMP280_NUM_SUPPLIES , data - > supplies ) ;
2016-06-30 03:48:53 +02:00
if ( ret )
return ret ;
2016-11-26 09:17:26 +05:30
usleep_range ( data - > start_up_time , data - > start_up_time + 100 ) ;
2016-06-30 03:48:53 +02:00
return data - > chip_info - > chip_config ( data ) ;
}
# endif /* CONFIG_PM */
const struct dev_pm_ops bmp280_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS ( pm_runtime_force_suspend ,
pm_runtime_force_resume )
SET_RUNTIME_PM_OPS ( bmp280_runtime_suspend ,
bmp280_runtime_resume , NULL )
} ;
EXPORT_SYMBOL ( bmp280_dev_pm_ops ) ;
2016-06-30 03:48:50 +02:00
MODULE_AUTHOR ( " Vlad Dogaru <vlad.dogaru@intel.com> " ) ;
MODULE_DESCRIPTION ( " Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;