123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * STMicroelectronics lis2dw12 driver
- *
- * MEMS Software Solutions Team
- *
- * Copyright 2016 STMicroelectronics Inc.
- */
- #ifndef ST_LIS2DW12_H
- #define ST_LIS2DW12_H
- #include <linux/bitfield.h>
- #include <linux/device.h>
- #include <linux/iio/events.h>
- #include <linux/iio/iio.h>
- #include <linux/of_device.h>
- #include <linux/regmap.h>
- #include "../common/stm_iio_types.h"
- #define ST_LIS2DW12_DEV_NAME "lis2dw12"
- #define ST_IIS2DLPC_DEV_NAME "iis2dlpc"
- #define ST_AIS2IH_DEV_NAME "ais2ih"
- #define ST_LIS2DW12_REGMAP "lis2dw12_regmap"
- #define ST_LIS2DW12_MAX_WATERMARK 31
- #define ST_LIS2DW12_DATA_SIZE 6
- #define ST_LIS2DW12_WHOAMI_ADDR 0x0f
- #define ST_LIS2DW12_WHOAMI_VAL 0x44
- #define ST_LIS2DW12_CTRL1_ADDR 0x20
- #define ST_LIS2DW12_ODR_MASK GENMASK(7, 4)
- #define ST_LIS2DW12_MODE_MASK GENMASK(3, 2)
- #define ST_LIS2DW12_LP_MODE_MASK GENMASK(1, 0)
- #define ST_LIS2DW12_CTRL2_ADDR 0x21
- #define ST_LIS2DW12_BDU_MASK BIT(3)
- #define ST_LIS2DW12_RESET_MASK BIT(6)
- #define ST_LIS2DW12_CTRL3_ADDR 0x22
- #define ST_LIS2DW12_LIR_MASK BIT(4)
- #define ST_LIS2DW12_ST_MASK GENMASK(7, 6)
- #define ST_LIS2DW12_CTRL4_INT1_CTRL_ADDR 0x23
- #define ST_LIS2DW12_DRDY_MASK BIT(0)
- #define ST_LIS2DW12_FTH_INT_MASK BIT(1)
- #define ST_LIS2DW12_TAP_INT1_MASK BIT(6)
- #define ST_LIS2DW12_TAP_TAP_INT1_MASK BIT(3)
- #define ST_LIS2DW12_FF_INT1_MASK BIT(4)
- #define ST_LIS2DW12_WU_INT1_MASK BIT(5)
- #define ST_LIS2DW12_CTRL5_INT2_CTRL_ADDR 0x24
- #define ST_LIS2DW12_CTRL6_ADDR 0x25
- #define ST_LIS2DW12_LN_MASK BIT(2)
- #define ST_LIS2DW12_FS_MASK GENMASK(5, 4)
- #define ST_LIS2DW12_BW_MASK GENMASK(7, 6)
- #define ST_LIS2DW12_STATUS_ADDR 0x27
- #define ST_LIS2DW12_STATUS_FF_MASK BIT(0)
- #define ST_LIS2DW12_STATUS_TAP_TAP_MASK BIT(4)
- #define ST_LIS2DW12_STATUS_TAP_MASK BIT(3)
- #define ST_LIS2DW12_STATUS_WU_MASK BIT(6)
- #define ST_LIS2DW12_STATUS_FTH_MASK BIT(7)
- #define ST_LIS2DW12_OUT_X_L_ADDR 0x28
- #define ST_LIS2DW12_OUT_Y_L_ADDR 0x2a
- #define ST_LIS2DW12_OUT_Z_L_ADDR 0x2c
- #define ST_LIS2DW12_FIFO_CTRL_ADDR 0x2e
- #define ST_LIS2DW12_FIFOMODE_MASK GENMASK(7, 5)
- #define ST_LIS2DW12_FTH_MASK GENMASK(4, 0)
- #define ST_LIS2DW12_FIFO_SAMPLES_ADDR 0x2f
- #define ST_LIS2DW12_FIFO_SAMPLES_FTH_MASK BIT(7)
- #define ST_LIS2DW12_FIFO_SAMPLES_OVR_MASK BIT(6)
- #define ST_LIS2DW12_TAP_THS_X_ADDR 0x30
- #define ST_LIS2DW12_TAP_THS_Y_ADDR 0x31
- #define ST_LIS2DW12_TAP_THS_Z_ADDR 0x32
- #define ST_LIS2DW12_TAP_AXIS_MASK GENMASK(7, 5)
- #define ST_LIS2DW12_TAP_THS_MAK GENMASK(4, 0)
- #define ST_LIS2DW12_INT_DUR_ADDR 0x33
- #define ST_LIS2DW12_WAKE_UP_THS_ADDR 0x34
- #define ST_LIS2DW12_WAKE_UP_THS_MAK GENMASK(5, 0)
- #define ST_LIS2DW12_SINGLE_DOUBLE_TAP_MAK BIT(7)
- #define ST_LIS2DW12_FREE_FALL_ADDR 0x36
- #define ST_LIS2DW12_FREE_FALL_THS_MASK GENMASK(2, 0)
- #define ST_LIS2DW12_FREE_FALL_DUR_MASK GENMASK(7, 3)
- #define ST_LIS2DW12_WU_SRC_ADDR 0x38
- #define ST_LIS2DW12_TAP_SRC_ADDR 0x39
- #define ST_LIS2DW12_STAP_SRC_MASK BIT(5)
- #define ST_LIS2DW12_DTAP_SRC_MASK BIT(4)
- #define ST_LIS2DW12_TAP_EVT_MASK GENMASK(2, 0)
- #define ST_LIS2DW12_FIFO_SAMPLES_DIFF_MASK GENMASK(5, 0)
- #define ST_LIS2DW12_ALL_INT_SRC_ADDR 0x3b
- #define ST_LIS2DW12_ALL_INT_SRC_FF_MASK BIT(0)
- #define ST_LIS2DW12_ALL_INT_SRC_WU_MASK BIT(1)
- #define ST_LIS2DW12_ALL_INT_SRC_TAP_MASK BIT(2)
- #define ST_LIS2DW12_ALL_INT_SRC_TAP_TAP_MASK BIT(3)
- #define ST_LIS2DW12_ABS_INT_CFG_ADDR 0x3f
- #define ST_LIS2DW12_ALL_INT_MASK BIT(5)
- #define ST_LIS2DW12_INT2_ON_INT1_MASK BIT(6)
- #define ST_LIS2DW12_DRDY_PULSED_MASK BIT(7)
- #define ST_LIS2DW12_FS_2G_GAIN IIO_G_TO_M_S_2(244)
- #define ST_LIS2DW12_FS_4G_GAIN IIO_G_TO_M_S_2(488)
- #define ST_LIS2DW12_FS_8G_GAIN IIO_G_TO_M_S_2(976)
- #define ST_LIS2DW12_FS_16G_GAIN IIO_G_TO_M_S_2(1952)
- #define ST_LIS2DW12_SELFTEST_MIN 285
- #define ST_LIS2DW12_SELFTEST_MAX 6150
- #define ST_LIS2DW12_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & \
- (mask))
- enum st_lis2dw12_fifo_mode {
- ST_LIS2DW12_FIFO_BYPASS = 0x0,
- ST_LIS2DW12_FIFO_CONTINUOUS = 0x6,
- };
- enum st_lis2dw12_selftest_status {
- ST_LIS2DW12_ST_RESET,
- ST_LIS2DW12_ST_PASS,
- ST_LIS2DW12_ST_FAIL,
- };
- enum st_lis2dw12_sensor_id {
- ST_LIS2DW12_ID_ACC,
- ST_LIS2DW12_ID_TAP_TAP,
- ST_LIS2DW12_ID_TAP,
- ST_LIS2DW12_ID_WU,
- ST_LIS2DW12_ID_MAX,
- };
- struct st_lis2dw12_sensor {
- enum st_lis2dw12_sensor_id id;
- struct st_lis2dw12_hw *hw;
- char name[32];
- u16 gain;
- u16 odr;
- };
- struct st_lis2dw12_hw {
- struct regmap *regmap;
- struct device *dev;
- int irq;
- int irq_emb;
- int irq_pin;
- u8 irq_reg;
- char name[32];
- struct mutex fifo_lock;
- struct mutex lock;
- struct iio_dev *iio_devs[ST_LIS2DW12_ID_MAX];
- enum st_lis2dw12_selftest_status st_status;
- u16 enable_mask;
- u8 watermark;
- u8 std_level;
- u64 samples;
- s64 delta_ts;
- s64 ts_irq;
- s64 ts;
- };
- /* HW devices that can wakeup the target */
- #define ST_LIS2DW12_WAKE_UP_SENSORS (BIT(ST_LIS2DW12_ID_ACC) | \
- BIT(ST_LIS2DW12_ID_TAP_TAP) | \
- BIT(ST_LIS2DW12_ID_TAP) | \
- BIT(ST_LIS2DW12_ID_WU))
- /* this is the minimal ODR for wake-up sensors and dependencies */
- #define ST_LIS2DW12_MIN_ODR_IN_WAKEUP 25
- static inline int
- __st_lis2dw12_write_with_mask(struct st_lis2dw12_hw *hw,
- unsigned int addr, int mask,
- unsigned int data)
- {
- int err;
- unsigned int val = ST_LIS2DW12_SHIFT_VAL(data, mask);
- err = regmap_update_bits(hw->regmap, addr, mask, val);
- return err;
- }
- static inline int
- st_lis2dw12_update_bits_locked(struct st_lis2dw12_hw *hw,
- unsigned int addr, unsigned int mask,
- unsigned int val)
- {
- int err;
- mutex_lock(&hw->lock);
- err = __st_lis2dw12_write_with_mask(hw, addr, mask, val);
- mutex_unlock(&hw->lock);
- return err;
- }
- static inline int
- st_lis2dw12_write_with_mask_locked(struct st_lis2dw12_hw *hw,
- unsigned int addr, unsigned int mask,
- unsigned int data)
- {
- int err;
- mutex_lock(&hw->lock);
- err = __st_lis2dw12_write_with_mask(hw, addr, mask, data);
- mutex_unlock(&hw->lock);
- return err;
- }
- static inline int st_lis2dw12_write_locked(struct st_lis2dw12_hw *hw,
- unsigned int addr, u8 *val,
- unsigned int len)
- {
- int err;
- mutex_lock(&hw->lock);
- err = regmap_bulk_write(hw->regmap, addr, val, len);
- mutex_unlock(&hw->lock);
- return err;
- }
- static inline int st_lis2dw12_read(struct st_lis2dw12_hw *hw, unsigned int addr,
- void *val, unsigned int len)
- {
- return regmap_bulk_read(hw->regmap, addr, val, len);
- }
- static inline bool st_lis2dw12_is_volatile_reg(struct device *dev,
- unsigned int reg)
- {
- switch (reg) {
- case ST_LIS2DW12_WHOAMI_ADDR:
- case ST_LIS2DW12_STATUS_ADDR:
- case ST_LIS2DW12_OUT_X_L_ADDR:
- case ST_LIS2DW12_OUT_X_L_ADDR + 1:
- case ST_LIS2DW12_OUT_Y_L_ADDR:
- case ST_LIS2DW12_OUT_Y_L_ADDR + 1:
- case ST_LIS2DW12_OUT_Z_L_ADDR:
- case ST_LIS2DW12_OUT_Z_L_ADDR + 1:
- case ST_LIS2DW12_FIFO_SAMPLES_ADDR:
- case ST_LIS2DW12_TAP_SRC_ADDR:
- case ST_LIS2DW12_ALL_INT_SRC_ADDR:
- return true;
- default:
- return false;
- }
- }
- static inline int
- st_lis2dw12_set_fifo_mode(struct st_lis2dw12_hw *hw,
- enum st_lis2dw12_fifo_mode mode)
- {
- return st_lis2dw12_write_with_mask_locked(hw,
- ST_LIS2DW12_FIFO_CTRL_ADDR,
- ST_LIS2DW12_FIFOMODE_MASK,
- mode);
- }
- static inline int st_lis2dw12_is_fifo_enabled(struct st_lis2dw12_hw *hw)
- {
- return hw->enable_mask & (BIT(ST_LIS2DW12_ID_ACC));
- }
- extern const struct dev_pm_ops st_lis2dw12_pm_ops;
- int st_lis2dw12_probe(struct device *dev, int irq, const char *name,
- struct regmap *regmap);
- int st_lis2dw12_fifo_setup(struct st_lis2dw12_hw *hw);
- int st_lis2dw12_update_fifo_watermark(struct st_lis2dw12_hw *hw, u8 watermark);
- ssize_t st_lis2dw12_flush_fifo(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size);
- ssize_t st_lis2dw12_set_hwfifo_watermark(struct device *device,
- struct device_attribute *attr,
- const char *buf, size_t size);
- int st_lis2dw12_sensor_set_enable(struct st_lis2dw12_sensor *sensor,
- bool enable);
- int st_lis2dw12_suspend_fifo(struct st_lis2dw12_hw *hw);
- #endif /* ST_LIS2DW12_H */
|