2018-09-01 22:52:14 +03:00
// SPDX-License-Identifier: GPL-2.0
2015-03-14 23:29:31 +03:00
/*
* MS5611 pressure and temperature sensor driver ( I2C bus )
*
* Copyright ( c ) Tomasz Duszynski < tduszyns @ gmail . com >
*
* 7 - bit I2C slave addresses :
*
* 0x77 ( CSB pin low )
* 0x76 ( CSB pin high )
*
*/
# include <linux/delay.h>
# include <linux/i2c.h>
# include <linux/module.h>
2016-03-01 13:31:37 +03:00
# include <linux/of_device.h>
2015-03-14 23:29:31 +03:00
# include "ms5611.h"
static int ms5611_i2c_reset ( struct device * dev )
{
struct ms5611_state * st = iio_priv ( dev_to_iio_dev ( dev ) ) ;
return i2c_smbus_write_byte ( st - > client , MS5611_RESET ) ;
}
static int ms5611_i2c_read_prom_word ( struct device * dev , int index , u16 * word )
{
int ret ;
struct ms5611_state * st = iio_priv ( dev_to_iio_dev ( dev ) ) ;
ret = i2c_smbus_read_word_swapped ( st - > client ,
MS5611_READ_PROM_WORD + ( index < < 1 ) ) ;
if ( ret < 0 )
return ret ;
* word = ret ;
return 0 ;
}
static int ms5611_i2c_read_adc ( struct ms5611_state * st , s32 * val )
{
int ret ;
u8 buf [ 3 ] ;
ret = i2c_smbus_read_i2c_block_data ( st - > client , MS5611_READ_ADC ,
3 , buf ) ;
if ( ret < 0 )
return ret ;
* val = ( buf [ 0 ] < < 16 ) | ( buf [ 1 ] < < 8 ) | buf [ 2 ] ;
return 0 ;
}
static int ms5611_i2c_read_adc_temp_and_pressure ( struct device * dev ,
s32 * temp , s32 * pressure )
{
int ret ;
struct ms5611_state * st = iio_priv ( dev_to_iio_dev ( dev ) ) ;
2016-03-01 13:31:38 +03:00
const struct ms5611_osr * osr = st - > temp_osr ;
2015-03-14 23:29:31 +03:00
2016-03-01 13:31:38 +03:00
ret = i2c_smbus_write_byte ( st - > client , osr - > cmd ) ;
2015-03-14 23:29:31 +03:00
if ( ret < 0 )
return ret ;
2016-03-01 13:31:38 +03:00
usleep_range ( osr - > conv_usec , osr - > conv_usec + ( osr - > conv_usec / 10UL ) ) ;
2015-03-14 23:29:31 +03:00
ret = ms5611_i2c_read_adc ( st , temp ) ;
if ( ret < 0 )
return ret ;
2016-03-01 13:31:38 +03:00
osr = st - > pressure_osr ;
ret = i2c_smbus_write_byte ( st - > client , osr - > cmd ) ;
2015-03-14 23:29:31 +03:00
if ( ret < 0 )
return ret ;
2016-03-01 13:31:38 +03:00
usleep_range ( osr - > conv_usec , osr - > conv_usec + ( osr - > conv_usec / 10UL ) ) ;
2015-03-14 23:29:31 +03:00
return ms5611_i2c_read_adc ( st , pressure ) ;
}
static int ms5611_i2c_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
{
struct ms5611_state * st ;
struct iio_dev * indio_dev ;
if ( ! i2c_check_functionality ( client - > adapter ,
I2C_FUNC_SMBUS_WRITE_BYTE |
I2C_FUNC_SMBUS_READ_WORD_DATA |
I2C_FUNC_SMBUS_READ_I2C_BLOCK ) )
2016-02-27 09:13:49 +03:00
return - EOPNOTSUPP ;
2015-03-14 23:29:31 +03:00
indio_dev = devm_iio_device_alloc ( & client - > dev , sizeof ( * st ) ) ;
if ( ! indio_dev )
return - ENOMEM ;
st = iio_priv ( indio_dev ) ;
2016-02-03 19:50:38 +03:00
i2c_set_clientdata ( client , indio_dev ) ;
2015-03-14 23:29:31 +03:00
st - > reset = ms5611_i2c_reset ;
st - > read_prom_word = ms5611_i2c_read_prom_word ;
st - > read_adc_temp_and_pressure = ms5611_i2c_read_adc_temp_and_pressure ;
st - > client = client ;
2016-02-17 20:52:50 +03:00
return ms5611_probe ( indio_dev , & client - > dev , id - > name , id - > driver_data ) ;
2015-03-14 23:29:31 +03:00
}
2016-02-03 19:50:38 +03:00
static int ms5611_i2c_remove ( struct i2c_client * client )
{
return ms5611_remove ( i2c_get_clientdata ( client ) ) ;
}
2016-03-01 13:31:37 +03:00
# if defined(CONFIG_OF)
static const struct of_device_id ms5611_i2c_matches [ ] = {
{ . compatible = " meas,ms5611 " } ,
{ . compatible = " meas,ms5607 " } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , ms5611_i2c_matches ) ;
# endif
2015-03-14 23:29:31 +03:00
static const struct i2c_device_id ms5611_id [ ] = {
2015-06-23 21:45:48 +03:00
{ " ms5611 " , MS5611 } ,
{ " ms5607 " , MS5607 } ,
2015-03-14 23:29:31 +03:00
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , ms5611_id ) ;
static struct i2c_driver ms5611_driver = {
. driver = {
. name = " ms5611 " ,
2016-03-01 13:31:37 +03:00
. of_match_table = of_match_ptr ( ms5611_i2c_matches )
2015-03-14 23:29:31 +03:00
} ,
. id_table = ms5611_id ,
. probe = ms5611_i2c_probe ,
2016-02-03 19:50:38 +03:00
. remove = ms5611_i2c_remove ,
2015-03-14 23:29:31 +03:00
} ;
module_i2c_driver ( ms5611_driver ) ;
MODULE_AUTHOR ( " Tomasz Duszynski <tduszyns@gmail.com> " ) ;
MODULE_DESCRIPTION ( " MS5611 i2c driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;