sensors: add lps22hb sensor driver

Support for LPS22HB Pressure and temperature sensor provided
with bare minimum features.

For more info on this sensor:
http://www.st.com/en/mems-and-sensors/lps22hb.html

Change-Id: I14992b954053094beb054d0dba7581f6e29a3e68
Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
Erwan Gouriou 2017-05-02 15:21:36 +02:00 committed by Maureen Helm
commit 8ba04d595b
6 changed files with 388 additions and 0 deletions

View file

@ -76,6 +76,8 @@ source "drivers/sensor/lis3dh/Kconfig"
source "drivers/sensor/lis3mdl/Kconfig" source "drivers/sensor/lis3mdl/Kconfig"
source "drivers/sensor/lps22hb/Kconfig"
source "drivers/sensor/lps25hb/Kconfig" source "drivers/sensor/lps25hb/Kconfig"
source "drivers/sensor/lsm6ds0/Kconfig" source "drivers/sensor/lsm6ds0/Kconfig"

View file

@ -18,6 +18,7 @@ obj-$(CONFIG_ISL29035) += isl29035/
obj-$(CONFIG_LIS2DH) += lis2dh/ obj-$(CONFIG_LIS2DH) += lis2dh/
obj-$(CONFIG_LIS3DH) += lis3dh/ obj-$(CONFIG_LIS3DH) += lis3dh/
obj-$(CONFIG_LIS3MDL) += lis3mdl/ obj-$(CONFIG_LIS3MDL) += lis3mdl/
obj-$(CONFIG_LPS22HB) += lps22hb/
obj-$(CONFIG_LPS25HB) += lps25hb/ obj-$(CONFIG_LPS25HB) += lps25hb/
obj-$(CONFIG_LSM6DS0) += lsm6ds0/ obj-$(CONFIG_LSM6DS0) += lsm6ds0/
obj-$(CONFIG_LSM9DS0_GYRO) += lsm9ds0_gyro/ obj-$(CONFIG_LSM9DS0_GYRO) += lsm9ds0_gyro/

View file

@ -0,0 +1,56 @@
#
# Copyright (c) 2017 Linaro Limited
#
# SPDX-License-Identifier: Apache-2.0
#
menuconfig LPS22HB
bool
prompt "LPS22HB pressure and temperature"
depends on SENSOR && I2C
default n
help
Enable driver for LPS22HB I2C-based pressure and temperature
sensor.
config LPS22HB_DEV_NAME
string
prompt "Device name"
default "LPS22HB"
depends on LPS22HB
help
Device name used for LPS22HB sensor identification.
config LPS22HB_I2C_ADDR
hex
prompt "I2C address"
depends on LPS22HB
default 0x5D
range 0x5C 0x5D
help
I2C address of the LPS22HB sensor.
Use 0x5C if the SA0 pin is pulled to GND or 0x5D if the SA0
pin is pulled to VDD.
config LPS22HB_I2C_MASTER_DEV_NAME
string
prompt "I2C master where LPS22HB is connected"
depends on LPS22HB
default I2C_0_NAME
help
Specify the device name of the I2C master device to which
LPS22HB is connected.
menu "Attributes"
depends on LPS22HB
config LPS22HB_SAMPLING_RATE
int
prompt "Output data rate"
depends on LPS22HB
default 25
help
Sensor output data rate expressed in samples per second.
Data rates supported by the chip are 1, 10, 25, 50, 75.
endmenu

View file

@ -0,0 +1 @@
obj-$(CONFIG_LPS22HB) += lps22hb.o

View file

@ -0,0 +1,158 @@
/* lps22hb.c - Driver for LPS22HB pressure and temperature sensor */
/*
* Copyright (c) 2017 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sensor.h>
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <misc/byteorder.h>
#include <misc/__assert.h>
#include "lps22hb.h"
static inline int lps22hb_set_odr_raw(struct device *dev, u8_t odr)
{
struct lps22hb_data *data = dev->driver_data;
const struct lps22hb_config *config = dev->config->config_info;
return i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
LPS22HB_REG_CTRL_REG1,
LPS22HB_MASK_CTRL_REG1_ODR,
odr << LPS22HB_SHIFT_CTRL_REG1_ODR);
}
static int lps22hb_sample_fetch(struct device *dev,
enum sensor_channel chan)
{
struct lps22hb_data *data = dev->driver_data;
const struct lps22hb_config *config = dev->config->config_info;
u8_t out[5];
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
if (i2c_burst_read(data->i2c_master, config->i2c_slave_addr,
LPS22HB_REG_PRESS_OUT_XL, out, 5) < 0) {
SYS_LOG_DBG("Failed to read sample");
return -EIO;
}
data->sample_press = (s32_t)((u32_t)(out[0]) |
((u32_t)(out[1]) << 8) |
((u32_t)(out[2]) << 16));
data->sample_temp = (s16_t)((u16_t)(out[3]) |
((u16_t)(out[4]) << 8));
return 0;
}
static inline void lps22hb_press_convert(struct sensor_value *val,
s32_t raw_val)
{
/* Pressure sensitivity is 4096 LSB/hPa */
/* Convert raw_val to val in kPa */
val->val1 = (raw_val >> 12) / 10;
val->val2 = ((s32_t)((raw_val) & 0x0FFF) * 1000L) >> 12;
}
static inline void lps22hb_temp_convert(struct sensor_value *val,
s16_t raw_val)
{
/* Temperature sensitivity is 100 LSB/deg C */
val->val1 = raw_val / 100;
val->val2 = (s32_t)raw_val % 100;
}
static int lps22hb_channel_get(struct device *dev,
enum sensor_channel chan,
struct sensor_value *val)
{
struct lps22hb_data *data = dev->driver_data;
if (chan == SENSOR_CHAN_PRESS) {
lps22hb_press_convert(val, data->sample_press);
} else if (chan == SENSOR_CHAN_TEMP) {
lps22hb_temp_convert(val, data->sample_temp);
} else {
return -ENOTSUP;
}
return 0;
}
static const struct sensor_driver_api lps22hb_api_funcs = {
.sample_fetch = lps22hb_sample_fetch,
.channel_get = lps22hb_channel_get,
};
static int lps22hb_init_chip(struct device *dev)
{
struct lps22hb_data *data = dev->driver_data;
const struct lps22hb_config *config = dev->config->config_info;
u8_t chip_id;
if (i2c_reg_read_byte(data->i2c_master, config->i2c_slave_addr,
LPS22HB_REG_WHO_AM_I, &chip_id) < 0) {
SYS_LOG_DBG("Failed reading chip id");
goto err_poweroff;
}
if (chip_id != LPS22HB_VAL_WHO_AM_I) {
SYS_LOG_DBG("Invalid chip id 0x%x", chip_id);
goto err_poweroff;
}
if (lps22hb_set_odr_raw(dev, LPS22HB_DEFAULT_SAMPLING_RATE) < 0) {
SYS_LOG_DBG("Failed to set sampling rate");
goto err_poweroff;
}
if (i2c_reg_update_byte(data->i2c_master, config->i2c_slave_addr,
LPS22HB_REG_CTRL_REG1,
LPS22HB_MASK_CTRL_REG1_BDU,
(1 << LPS22HB_SHIFT_CTRL_REG1_BDU)) < 0) {
SYS_LOG_DBG("Failed to set BDU");
goto err_poweroff;
}
return 0;
err_poweroff:
return -EIO;
}
static int lps22hb_init(struct device *dev)
{
const struct lps22hb_config * const config = dev->config->config_info;
struct lps22hb_data *data = dev->driver_data;
data->i2c_master = device_get_binding(config->i2c_master_dev_name);
if (!data->i2c_master) {
SYS_LOG_DBG("I2c master not found: %s",
config->i2c_master_dev_name);
return -EINVAL;
}
if (lps22hb_init_chip(dev) < 0) {
SYS_LOG_DBG("Failed to initialize chip");
return -EIO;
}
return 0;
}
static const struct lps22hb_config lps22hb_config = {
.i2c_master_dev_name = CONFIG_LPS22HB_I2C_MASTER_DEV_NAME,
.i2c_slave_addr = CONFIG_LPS22HB_I2C_ADDR,
};
static struct lps22hb_data lps22hb_data;
DEVICE_AND_API_INIT(lps22hb, CONFIG_LPS22HB_DEV_NAME, lps22hb_init,
&lps22hb_data, &lps22hb_config, POST_KERNEL,
CONFIG_SENSOR_INIT_PRIORITY, &lps22hb_api_funcs);

View file

@ -0,0 +1,170 @@
/* sensor_lps25hb.h - header file for LPS22HB pressure and temperature
* sensor driver
*/
/*
* Copyright (c) 2017 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SENSOR_LPS22HB_H__
#define __SENSOR_LPS22HB_H__
#include <stdint.h>
#include <i2c.h>
#include <misc/util.h>
#define LPS22HB_REG_WHO_AM_I 0x0F
#define LPS22HB_VAL_WHO_AM_I 0xB1
#define LPS22HB_REG_INTERRUPT_CFG 0x0B
#define LPS22HB_MASK_INTERRUPT_CFG_AUTORIFP BIT(7)
#define LPS22HB_SHIFT_INTERRUPT_CFG_AUTORIFP 7
#define LPS22HB_MASK_INTERRUPT_CFG_RESET_ARP BIT(6)
#define LPS22HB_SHIFT_INTERRUPT_CFG_RESET_ARP 6
#define LPS22HB_MASK_INTERRUPT_CFG_AUTOZERO BIT(5)
#define LPS22HB_SHIFT_INTERRUPT_CFG_AUTOZERO 5
#define LPS22HB_MASK_INTERRUPT_CFG_RESET_AZ BIT(4)
#define LPS22HB_SHIFT_INTERRUPT_CFG_RESET_AZ 4
#define LPS22HB_MASK_INTERRUPT_CFG_DIFF_EN BIT(3)
#define LPS22HB_SHIFT_INTERRUPT_CFG_DIFF_EN 3
#define LPS22HB_MASK_INTERRUPT_CFG_LIR BIT(2)
#define LPS22HB_SHIFT_INTERRUPT_CFG_LIR 2
#define LPS22HB_MASK_INTERRUPT_CFG_PL_E BIT(1)
#define LPS22HB_SHIFT_INTERRUPT_CFG_PL_E 1
#define LPS22HB_MASK_INTERRUPT_CFG_PH_E BIT(0)
#define LPS22HB_SHIFT_INTERRUPT_CFG_PH_E 0
#define LPS22HB_REG_THS_P_L 0x0C
#define LPS22HB_REG_THS_P_H 0x0D
#define LPS22HB_REG_CTRL_REG1 0x10
#define LPS22HB_MASK_CTRL_REG1_ODR (BIT(6) | BIT(5) | BIT(4))
#define LPS22HB_SHIFT_CTRL_REG1_ODR 4
#define LPS22HB_MASK_CTRL_REG1_EN_LPFP BIT(3)
#define LPS22HB_SHIFT_CTRL_REG1_EN_LPFP 3
#define LPS22HB_MASK_CTRL_REG1_LPFP_CFG BIT(2)
#define LPS22HB_SHIFT_CTRL_REG1_LPFP_CFG 2
#define LPS22HB_MASK_CTRL_REG1_BDU BIT(1)
#define LPS22HB_SHIFT_CTRL_REG1_BDU 1
#define LPS22HB_MASK_CTRL_REG1_SIM BIT(0)
#define LPS22HB_SHIFT_CTRL_REG1_SIM 0
#define LPS22HB_REG_CTRL_REG2 0x11
#define LPS22HB_MASK_CTRL_REG2_BOOT BIT(7)
#define LPS22HB_SHIFT_CTRL_REG2_BOOT 7
#define LPS22HB_MASK_CTRL_REG2_FIFO_EN BIT(6)
#define LPS22HB_SHIFT_CTRL_REG2_FIFO_EN 6
#define LPS22HB_MASK_CTRL_REG2_STOP_ON_FTH BIT(5)
#define LPS22HB_SHIFT_CTRL_REG2_STOP_ON_FTH 5
#define LPS22HB_MASK_CTRL_REG2_IF_ADD_INC BIT(4)
#define LPS22HB_SHIFT_CTRL_REG2_IF_ADD_INC 4
#define LPS22HB_MASK_CTRL_REG2_I2C_DIS BIT(3)
#define LPS22HB_SHIFT_CTRL_REG2_I2C_DIS 3
#define LPS22HB_MASK_CTRL_REG2_SWRESET BIT(2)
#define LPS22HB_SHIFT_CTRL_REG2_SWRESET 2
#define LPS22HB_MASK_CTRL_REG2_ONE_SHOT BIT(0)
#define LPS22HB_SHIFT_CTRL_REG2_ONE_SHOT 0
#define LPS22HB_REG_CTRL_REG3 0x12
#define LPS22HB_MASK_CTRL_REG3_INT_H_L BIT(7)
#define LPS22HB_SHIFT_CTRL_REG3_INT_H_L 7
#define LPS22HB_MASK_CTRL_REG3_PP_OD BIT(6)
#define LPS22HB_SHIFT_CTRL_REG3_PP_OD 6
#define LPS22HB_MASK_CTRL_REG3_F_FSS5 BIT(5)
#define LPS22HB_SHIFT_CTRL_REG3_F_FFS5 5
#define LPS22HB_MASK_CTRL_REG3_F_FTH BIT(4)
#define LPS22HB_SHIFT_CTRL_REG3_F_FTH 4
#define LPS22HB_MASK_CTRL_REG3_F_OVR BIT(3)
#define LPS22HB_SHIFT_CTRL_REG3_F_OVR 3
#define LPS22HB_MASK_CTRL_REG3_DRDY BIT(2)
#define LPS22HB_SHIFT_CTRL_REG3_DRDY 2
#define LPS22HB_MASK_CTRL_REG3_INT_S (BIT(1) | BIT(0))
#define LPS22HB_SHIFT_CTRL_REG_INT_S 0
#define LPS22HB_REG_FIFO_CTRL 0x14
#define LPS22HB_MASK_FIFO_CTRL_F_MODE (BIT(7) | BIT(6) | BIT(5))
#define LPS22HB_SHIFT_FIFO_CTRL_F_MODE 5
#define LPS22HB_MASK_FIFO_CTRL_WTM (BIT(4) | BIT(3) | BIT(2) | \
BIT(2) | BIT(1) | BIT(0))
#define LPS22HB_SHIFT_FIFO_CTRL_WTM 0
#define LPS22HB_REG_REF_P_XL 0x15
#define LPS22HB_REG_REF_P_L 0x16
#define LPS22HB_REG_REF_P_H 0x17
#define LPS22HB_REG_RPDS_L 0x18
#define LPS22HB_REG_RPDS_H 0x19
#define LPS22HB_REG_RES_CONF 0x1A
#define LPS22HB_MASK_RES_CONF_LC_EN BIT(0)
#define LPS22HB_SHIFT_RES_CONF_LC_EN 0
#define LPS22HB_REG_INT_SOURCE 0x25
#define LPS22HB_MASK_INT_SOURCE_IA BIT(2)
#define LPS22HB_SHIFT_INT_SOURCE_IA 2
#define LPS22HB_MASK_INT_SOURCE_PL BIT(1)
#define LPS22HB_SHIFT_INT_SOURCE_PL 1
#define LPS22HB_MASK_INT_SOURCE_PH BIT(0)
#define LPS22HB_SHIFT_INT_SOURCE_PH 0
#define LPS22HB_REG_FIFO_STATUS 0x26
#define LPS22HB_MASK_FIFO_STATUS_FTH_FIFO BIT(7)
#define LPS22HB_SHIFT_FIFO_STATUS_FTH_FIFO 7
#define LPS22HB_MASK_FIFO_STATUS_OVR BIT(6)
#define LPS22HB_SHIFT_FIFO_STATUS_OVR 6
#define LPS22HB_MASK_FIFO_STATUS_EMPTY_FIFO BIT(5)
#define LPS22HB_SHIFT_FIFO_STATUS_EMPTY_FIFO 5
#define LPS22HB_MASK_FIFO_STATUS_FSS (BIT(4) | BIT(3) | BIT(2) | \
BIT(1) | BIT(0))
#define LPS22HB_SHIFT_FIFO_STATUS_FSS 0
#define LPS22HB_REG_STATUS 0x27
#define LPS22HB_MASK_STATUS_P_OR BIT(5)
#define LPS22HB_SHIFT_STATUS_P_OR 5
#define LPS22HB_MASK_STATUS_T_OR BIT(4)
#define LPS22HB_SHIFT_STATUS_T_OR 4
#define LPS22HB_MASK_STATUS_P_DA BIT(1)
#define LPS22HB_SHIFT_STATUS_P_DA 1
#define LPS22HB_MASK_STATUS_T_DA BIT(0)
#define LPS22HB_SHIFT_STATUS_T_DA 0
#define LPS22HB_REG_PRESS_OUT_XL 0x28
#define LPS22HB_REG_PRESS_OUT_L 0x29
#define LPS22HB_REG_PRESS_OUT_H 0x2A
#define LPS22HB_REG_TEMP_OUT_L 0x2B
#define LPS22HB_REG_TEMP_OUT_H 0x2C
#define LPS22HB_REG_LPFP_RES 0x33
#if CONFIG_LPS22HB_SAMPLING_RATE == 1
#define LPS22HB_DEFAULT_SAMPLING_RATE 1
#elif CONFIG_LPS22HB_SAMPLING_RATE == 10
#define LPS22HB_DEFAULT_SAMPLING_RATE 2
#elif CONFIG_LPS22HB_SAMPLING_RATE == 25
#define LPS22HB_DEFAULT_SAMPLING_RATE 3
#elif CONFIG_LPS22HB_SAMPLING_RATE == 50
#define LPS22HB_DEFAULT_SAMPLING_RATE 4
#elif CONFIG_LPS22HB_SAMPLING_RATE == 75
#define LPS22HB_DEFAULT_SAMPLING_RATE 5
#endif
struct lps22hb_config {
char *i2c_master_dev_name;
u16_t i2c_slave_addr;
};
struct lps22hb_data {
struct device *i2c_master;
s32_t sample_press;
s16_t sample_temp;
};
#define SYS_LOG_DOMAIN "LPS22HB"
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_SENSOR_LEVEL
#include <logging/sys_log.h>
#endif /* __SENSOR_LPS22HB_H__ */