1 /* 2 * Copyright (c) 2017 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DH_LIS2DH_H_ 8 #define ZEPHYR_DRIVERS_SENSOR_LIS2DH_LIS2DH_H_ 9 10 #include <zephyr/kernel.h> 11 #include <zephyr/device.h> 12 #include <zephyr/sys/util.h> 13 #include <stdint.h> 14 #include <zephyr/drivers/gpio.h> 15 #include <zephyr/drivers/sensor.h> 16 #include <string.h> 17 18 #define LIS2DH_REG_WAI 0x0f 19 #define LIS2DH_CHIP_ID 0x33 20 21 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 22 #include <zephyr/drivers/spi.h> 23 #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ 24 25 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 26 #include <zephyr/drivers/i2c.h> 27 #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ 28 29 #define LIS2DH_AUTOINCREMENT_ADDR BIT(7) 30 31 #define LIS2DH_REG_CTRL0 0x1e 32 #define LIS2DH_SDO_PU_DISC_SHIFT 7 33 #define LIS2DH_SDO_PU_DISC_MASK BIT(LIS2DH_SDO_PU_DISC_SHIFT) 34 35 #define LIS2DH_REG_CTRL1 0x20 36 #define LIS2DH_ACCEL_XYZ_SHIFT 0 37 #define LIS2DH_ACCEL_X_EN_BIT BIT(0) 38 #define LIS2DH_ACCEL_Y_EN_BIT BIT(1) 39 #define LIS2DH_ACCEL_Z_EN_BIT BIT(2) 40 #define LIS2DH_ACCEL_EN_BITS (LIS2DH_ACCEL_X_EN_BIT | \ 41 LIS2DH_ACCEL_Y_EN_BIT | \ 42 LIS2DH_ACCEL_Z_EN_BIT) 43 #define LIS2DH_ACCEL_XYZ_MASK BIT_MASK(3) 44 45 #define LIS2DH_LP_EN_BIT_MASK BIT(3) 46 #if defined(CONFIG_LIS2DH_OPER_MODE_LOW_POWER) 47 #define LIS2DH_LP_EN_BIT BIT(3) 48 #else 49 #define LIS2DH_LP_EN_BIT 0 50 #endif 51 52 #define LIS2DH_SUSPEND 0 53 54 #define LIS2DH_ODR_1 1 55 #define LIS2DH_ODR_2 2 56 #define LIS2DH_ODR_3 3 57 #define LIS2DH_ODR_4 4 58 #define LIS2DH_ODR_5 5 59 #define LIS2DH_ODR_6 6 60 #define LIS2DH_ODR_7 7 61 #define LIS2DH_ODR_8 8 62 #define LIS2DH_ODR_9 9 63 64 #if defined(CONFIG_LIS2DH_ODR_1) 65 #define LIS2DH_ODR_IDX LIS2DH_ODR_1 66 #elif defined(CONFIG_LIS2DH_ODR_2) 67 #define LIS2DH_ODR_IDX LIS2DH_ODR_2 68 #elif defined(CONFIG_LIS2DH_ODR_3) 69 #define LIS2DH_ODR_IDX LIS2DH_ODR_3 70 #elif defined(CONFIG_LIS2DH_ODR_4) || defined(CONFIG_LIS2DH_ODR_RUNTIME) 71 #define LIS2DH_ODR_IDX LIS2DH_ODR_4 72 #elif defined(CONFIG_LIS2DH_ODR_5) 73 #define LIS2DH_ODR_IDX LIS2DH_ODR_5 74 #elif defined(CONFIG_LIS2DH_ODR_6) 75 #define LIS2DH_ODR_IDX LIS2DH_ODR_6 76 #elif defined(CONFIG_LIS2DH_ODR_7) 77 #define LIS2DH_ODR_IDX LIS2DH_ODR_7 78 #elif defined(CONFIG_LIS2DH_ODR_8) 79 #define LIS2DH_ODR_IDX LIS2DH_ODR_8 80 #elif defined(CONFIG_LIS2DH_ODR_9_NORMAL) || defined(CONFIG_LIS2DH_ODR_9_LOW) 81 #define LIS2DH_ODR_IDX LIS2DH_ODR_9 82 #endif 83 84 #define LIS2DH_ODR_SHIFT 4 85 #define LIS2DH_ODR_RATE(r) ((r) << LIS2DH_ODR_SHIFT) 86 #define LIS2DH_ODR_BITS (LIS2DH_ODR_RATE(LIS2DH_ODR_IDX)) 87 #define LIS2DH_ODR_MASK (BIT_MASK(4) << LIS2DH_ODR_SHIFT) 88 89 #define LIS2DH_REG_CTRL2 0x21 90 #define LIS2DH_HPIS1_EN_BIT BIT(0) 91 #define LIS2DH_HPIS2_EN_BIT BIT(1) 92 #define LIS2DH_FDS_EN_BIT BIT(3) 93 94 #define LIS2DH_HPIS_EN_SHIFT 0 95 #define LIS2DH_HPIS_EN_MASK BIT_MASK(2) << LIS2DH_HPIS_EN_SHIFT 96 97 #define LIS2DH_REG_CTRL3 0x22 98 #define LIS2DH_EN_DRDY1_INT1_SHIFT 4 99 #define LIS2DH_EN_DRDY1_INT1 BIT(LIS2DH_EN_DRDY1_INT1_SHIFT) 100 101 #define LIS2DH_REG_CTRL4 0x23 102 #define LIS2DH_FS_SHIFT 4 103 #define LIS2DH_FS_MASK (BIT_MASK(2) << LIS2DH_FS_SHIFT) 104 105 #if defined(CONFIG_LIS2DH_ACCEL_RANGE_2G) ||\ 106 defined(CONFIG_LIS2DH_ACCEL_RANGE_RUNTIME) 107 #define LIS2DH_FS_IDX 0 108 #elif defined(CONFIG_LIS2DH_ACCEL_RANGE_4G) 109 #define LIS2DH_FS_IDX 1 110 #elif defined(CONFIG_LIS2DH_ACCEL_RANGE_8G) 111 #define LIS2DH_FS_IDX 2 112 #elif defined(CONFIG_LIS2DH_ACCEL_RANGE_16G) 113 #define LIS2DH_FS_IDX 3 114 #endif 115 116 #define LIS2DH_FS_SELECT(fs) ((fs) << LIS2DH_FS_SHIFT) 117 #define LIS2DH_FS_BITS (LIS2DH_FS_SELECT(LIS2DH_FS_IDX)) 118 #if defined(CONFIG_LIS2DH_OPER_MODE_HIGH_RES) 119 #define LIS2DH_HR_BIT BIT(3) 120 #else 121 #define LIS2DH_HR_BIT 0 122 #endif 123 124 #define LIS2DH_REG_CTRL5 0x24 125 #define LIS2DH_LIR_INT2_SHIFT 1 126 #define LIS2DH_LIR_INT1_SHIFT 3 127 #define LIS2DH_EN_LIR_INT2 BIT(LIS2DH_LIR_INT2_SHIFT) 128 #define LIS2DH_EN_LIR_INT1 BIT(LIS2DH_LIR_INT1_SHIFT) 129 130 #define LIS2DH_REG_CTRL6 0x25 131 #define LIS2DH_EN_INT2_INT2_SHIFT 5 132 #define LIS2DH_EN_INT2_INT2 BIT(LIS2DH_EN_INT2_INT2_SHIFT) 133 #define LIS2DH_EN_INT1_INT1_SHIFT 6 134 #define LIS2DH_EN_INT1_INT1 BIT(LIS2DH_EN_INT1_INT1_SHIFT) 135 136 #define LIS2DH_REG_REFERENCE 0x26 137 138 #define LIS2DH_REG_STATUS 0x27 139 #define LIS2DH_STATUS_ZYZ_OVR BIT(7) 140 #define LIS2DH_STATUS_Z_OVR BIT(6) 141 #define LIS2DH_STATUS_Y_OVR BIT(5) 142 #define LIS2DH_STATUS_X_OVR BIT(4) 143 #define LIS2DH_STATUS_OVR_MASK (BIT_MASK(4) << 4) 144 #define LIS2DH_STATUS_ZYX_DRDY BIT(3) 145 #define LIS2DH_STATUS_Z_DRDY BIT(2) 146 #define LIS2DH_STATUS_Y_DRDY BIT(1) 147 #define LIS2DH_STATUS_X_DRDY BIT(0) 148 #define LIS2DH_STATUS_DRDY_MASK BIT_MASK(4) 149 150 #define LIS2DH_REG_ACCEL_X_LSB 0x28 151 #define LIS2DH_REG_ACCEL_Y_LSB 0x2A 152 #define LIS2DH_REG_ACCEL_Z_LSB 0x2C 153 #define LIS2DH_REG_ACCEL_X_MSB 0x29 154 #define LIS2DH_REG_ACCEL_Y_MSB 0x2B 155 #define LIS2DH_REG_ACCEL_Z_MSB 0x2D 156 157 #define LIS2DH_REG_INT1_CFG 0x30 158 #define LIS2DH_REG_INT1_SRC 0x31 159 #define LIS2DH_REG_INT1_THS 0x32 160 #define LIS2DH_REG_INT1_DUR 0x33 161 #define LIS2DH_REG_INT2_CFG 0x34 162 #define LIS2DH_REG_INT2_SRC 0x35 163 #define LIS2DH_REG_INT2_THS 0x36 164 #define LIS2DH_REG_INT2_DUR 0x37 165 166 #define LIS2DH_INT_CFG_MODE_SHIFT 6 167 #define LIS2DH_INT_CFG_AOI_CFG BIT(LIS2DH_INT_CFG_MODE_SHIFT + 1) 168 #define LIS2DH_INT_CFG_6D_CFG BIT(LIS2DH_INT_CFG_MODE_SHIFT) 169 #define LIS2DH_INT_CFG_ZHIE_ZUPE BIT(5) 170 #define LIS2DH_INT_CFG_ZLIE_ZDOWNE BIT(4) 171 #define LIS2DH_INT_CFG_YHIE_YUPE BIT(3) 172 #define LIS2DH_INT_CFG_YLIE_YDOWNE BIT(2) 173 #define LIS2DH_INT_CFG_XHIE_XUPE BIT(1) 174 #define LIS2DH_INT_CFG_XLIE_XDOWNE BIT(0) 175 176 /* sample buffer size includes status register */ 177 #define LIS2DH_BUF_SZ 7 178 179 #define LIS2DH_CTRL4_BDU_BIT BIT(7) 180 181 union lis2dh_sample { 182 uint8_t raw[LIS2DH_BUF_SZ]; 183 struct { 184 uint8_t status; 185 int16_t xyz[3]; 186 } __packed; 187 }; 188 189 union lis2dh_bus_cfg { 190 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 191 struct i2c_dt_spec i2c; 192 #endif 193 194 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 195 struct spi_dt_spec spi; 196 #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ 197 }; 198 199 struct temperature { 200 uint8_t cfg_addr; 201 uint8_t enable_mask; 202 uint8_t dout_addr; 203 uint8_t fractional_bits; 204 }; 205 206 struct lis2dh_config { 207 int (*bus_init)(const struct device *dev); 208 const union lis2dh_bus_cfg bus_cfg; 209 #ifdef CONFIG_LIS2DH_TRIGGER 210 const struct gpio_dt_spec gpio_drdy; 211 const struct gpio_dt_spec gpio_int; 212 #endif /* CONFIG_LIS2DH_TRIGGER */ 213 struct { 214 bool is_lsm303agr_dev : 1; 215 bool disc_pull_up : 1; 216 bool anym_on_int1 : 1; 217 bool anym_latch : 1; 218 uint8_t anym_mode : 2; 219 } hw; 220 #ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE 221 const struct temperature temperature; 222 #endif 223 }; 224 225 struct lis2dh_transfer_function { 226 int (*read_data)(const struct device *dev, uint8_t reg_addr, 227 uint8_t *value, uint8_t len); 228 int (*write_data)(const struct device *dev, uint8_t reg_addr, 229 uint8_t *value, uint8_t len); 230 int (*read_reg)(const struct device *dev, uint8_t reg_addr, 231 uint8_t *value); 232 int (*write_reg)(const struct device *dev, uint8_t reg_addr, 233 uint8_t value); 234 int (*update_reg)(const struct device *dev, uint8_t reg_addr, 235 uint8_t mask, uint8_t value); 236 }; 237 238 struct lis2dh_data { 239 const struct device *bus; 240 const struct lis2dh_transfer_function *hw_tf; 241 242 union lis2dh_sample sample; 243 /* current scaling factor, in micro m/s^2 / lsb */ 244 uint32_t scale; 245 246 #ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE 247 struct sensor_value temperature; 248 #endif 249 250 #ifdef CONFIG_PM_DEVICE 251 uint8_t reg_ctrl1_active_val; 252 #endif 253 254 #ifdef CONFIG_LIS2DH_TRIGGER 255 const struct device *dev; 256 struct gpio_callback gpio_int1_cb; 257 struct gpio_callback gpio_int2_cb; 258 259 sensor_trigger_handler_t handler_drdy; 260 const struct sensor_trigger *trig_drdy; 261 sensor_trigger_handler_t handler_anymotion; 262 const struct sensor_trigger *trig_anymotion; 263 atomic_t trig_flags; 264 enum sensor_channel chan_drdy; 265 266 #if defined(CONFIG_LIS2DH_TRIGGER_OWN_THREAD) 267 K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_LIS2DH_THREAD_STACK_SIZE); 268 struct k_thread thread; 269 struct k_sem gpio_sem; 270 #elif defined(CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD) 271 struct k_work work; 272 #endif 273 274 #endif /* CONFIG_LIS2DH_TRIGGER */ 275 }; 276 277 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 278 int lis2dh_spi_access(struct lis2dh_data *ctx, uint8_t cmd, 279 void *data, size_t length); 280 #endif 281 282 #ifdef CONFIG_LIS2DH_TRIGGER 283 int lis2dh_trigger_set(const struct device *dev, 284 const struct sensor_trigger *trig, 285 sensor_trigger_handler_t handler); 286 287 int lis2dh_init_interrupt(const struct device *dev); 288 289 int lis2dh_acc_slope_config(const struct device *dev, 290 enum sensor_attribute attr, 291 const struct sensor_value *val); 292 #endif 293 294 #ifdef CONFIG_LIS2DH_ACCEL_HP_FILTERS 295 int lis2dh_acc_hp_filter_set(const struct device *dev, 296 int32_t val); 297 #endif 298 299 int lis2dh_spi_init(const struct device *dev); 300 int lis2dh_i2c_init(const struct device *dev); 301 302 303 #endif /* __SENSOR_LIS2DH__ */ 304