123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * STMicroelectronics st_h3lis331dl sensor driver
- *
- * MEMS Software Solutions Team
- *
- * Copyright 2023 STMicroelectronics Inc.
- */
- #ifndef ST_H3LIS331DL_H
- #define ST_H3LIS331DL_H
- #include <linux/bitfield.h>
- #include <linux/device.h>
- #include <linux/iio/iio.h>
- #include <linux/delay.h>
- #include <linux/regmap.h>
- #define ST_H3LIS331DL_DEV_NAME "h3lis331dl"
- #define ST_LIS331DLH_DEV_NAME "lis331dlh"
- #define ST_H3LIS331DL_REG_WHO_AM_I_ADDR 0x0f
- #define ST_H3LIS331DL_WHO_AM_I_VAL 0x32
- #define ST_H3LIS331DL_CTRL_REG1_ADDR 0x20
- #define ST_H3LIS331DL_EN_MASK GENMASK(2, 0)
- #define ST_H3LIS331DL_DR_MASK GENMASK(4, 3)
- #define ST_H3LIS331DL_PM_MASK GENMASK(7, 5)
- #define ST_H3LIS331DL_CTRL_REG2_ADDR 0x21
- #define ST_H3LIS331DL_BOOT_MASK BIT(7)
- #define ST_H3LIS331DL_CTRL_REG3_ADDR 0x22
- #define ST_H3LIS331DL_I1CFG_MASK GENMASK(1, 0)
- #define ST_H3LIS331DL_LIR1_MASK BIT(2)
- #define ST_H3LIS331DL_I2CFG_MASK GENMASK(4, 3)
- #define ST_H3LIS331DL_LIR2_MASK BIT(5)
- #define ST_H3LIS331DL_PP_OD_MASK BIT(6)
- #define ST_H3LIS331DL_IHL_MASK BIT(7)
- #define ST_H3LIS331DL_CFG_DRDY_VAL 0x02
- #define ST_H3LIS331DL_CTRL_REG4_ADDR 0x23
- #define ST_H3LIS331DL_FS_MASK GENMASK(5, 4)
- #define ST_H3LIS331DL_BLE_MASK BIT(6)
- #define ST_H3LIS331DL_BDU_MASK BIT(7)
- #define ST_H3LIS331DL_STATUS_REG_ADDR 0x27
- #define ST_H3LIS331DL_ZYXDA_MASK BIT(3)
- #define ST_H3LIS331DL_REG_OUTX_L_ADDR 0x28
- #define ST_H3LIS331DL_REG_OUTY_L_ADDR 0x2a
- #define ST_H3LIS331DL_REG_OUTZ_L_ADDR 0x2c
- #define ST_H3LIS331DL_SAMPLE_SIZE 6
- /* enable reading address with auto increment */
- #define ST_H3LIS331DL_AUTO_INCREMENT(_addr) (0x80 | _addr)
- #define ST_H3LIS331DL_DATA_CHANNEL(chan_type, addr, mod, ch2, scan_idx, \
- rb, sb, sg, ex_info) \
- { \
- .type = chan_type, \
- .address = addr, \
- .modified = mod, \
- .channel2 = ch2, \
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
- BIT(IIO_CHAN_INFO_SCALE), \
- .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
- .scan_index = scan_idx, \
- .scan_type = { \
- .sign = sg, \
- .realbits = rb, \
- .storagebits = sb, \
- .endianness = IIO_LE, \
- }, \
- .ext_info = ex_info, \
- }
- #define ST_H3LIS331DL_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask))
- #define ST_H3LIS331DL_ACC_SENSOR_ID 0
- #define ST_H3LIS331DL_ODR_LIST_SIZE 8
- #define ST_H3LIS331DL_FS_LIST_SIZE 3
- /**
- * struct st_h3lis331dl_reg - Generic sensor register description (addr + mask)
- * @addr: Address of register.
- * @mask: Bitmask register for proper usage.
- */
- struct st_h3lis331dl_reg {
- u8 addr;
- u8 mask;
- };
- /**
- * struct st_h3lis331dl_odr - Single ODR entry
- * @hz: Most significant part of the sensor ODR (Hz).
- * @val: ODR register value.
- */
- struct st_h3lis331dl_odr {
- int hz;
- u8 val;
- };
- /**
- * struct st_h3lis331dl_odr_table_entry - Sensor ODR table
- * @size: Size of ODR table.
- * @reg: ODR register.
- * @odr_avl: Array of supported ODR value.
- */
- struct st_h3lis331dl_odr_table_entry {
- u8 size;
- struct st_h3lis331dl_reg reg;
- struct st_h3lis331dl_odr odr_avl[ST_H3LIS331DL_ODR_LIST_SIZE];
- };
- /**
- * struct st_h3lis331dl_fs - Full Scale sensor table entry
- * @gain: Sensor sensitivity.
- * @val: FS register value.
- */
- struct st_h3lis331dl_fs {
- u32 gain;
- u8 val;
- };
- /**
- * struct st_h3lis331dl_fs_table_entry - Full Scale sensor table
- * @size: Full Scale sensor table size.
- * @reg: Register description for FS settings.
- * @fs_avl: Full Scale list entries.
- */
- struct st_h3lis331dl_fs_table_entry {
- u8 size;
- struct st_h3lis331dl_reg reg;
- struct st_h3lis331dl_fs fs_avl[ST_H3LIS331DL_FS_LIST_SIZE];
- };
- #define ST_H3LIS331DL_ACC_FS_100G_GAIN IIO_G_TO_M_S_2(784000)
- #define ST_H3LIS331DL_ACC_FS_200G_GAIN IIO_G_TO_M_S_2(1568000)
- #define ST_H3LIS331DL_ACC_FS_400G_GAIN IIO_G_TO_M_S_2(3136000)
- /**
- * struct st_h3lis331dl_sensor - ST IMU sensor instance
- * @is: Sensor id.
- * @name: Sensor name.
- * @hw: Pointer to instance of struct st_h3lis331dl_hw.
- * @trig: Trigger used by IIO event sensors.
- * @odr: Sensor odr.
- * @gain: Configured sensor sensitivity.
- * @offset: Sensor data offset.
- * @decimator: Sensor decimator
- * @dec_counter: Sensor decimator counter
- */
- struct st_h3lis331dl_sensor {
- int id;
- char name[32];
- struct st_h3lis331dl_hw *hw;
- struct iio_trigger *trig;
- int odr;
- u32 gain;
- u32 offset;
- u8 decimator;
- u8 dec_counter;
- };
- /**
- * struct st_h3lis331dl_hw - ST IMU MEMS hw instance
- * @dev: Pointer to instance of struct device (I2C or SPI).
- * @irq: Device interrupt line (I2C or SPI).
- * @regmap: Register map of the device.
- * @int_pin: Save interrupt pin used by sensor.
- * @lock: Mutex to protect read and write operations.
- * @enable_mask: Enabled sensor bitmask.
- * @ts: hw timestamp value always monotonic where the most
- * significant 8byte are incremented at every disable/enable.
- * @iio_devs: Pointers to acc/gyro iio_dev instances.
- * @vdd_supply: Voltage regulator for VDD.
- * @vddio_supply: Voltage regulator for VDDIIO.
- * @orientation: Sensor chip orientation relative to main hardware.
- * @self_test: Self test start and read result.
- * @selftest_available: Reports self test available for this sensor.
- */
- struct st_h3lis331dl_hw {
- struct device *dev;
- int irq;
- struct regmap *regmap;
- int int_pin;
- struct mutex lock;
- u64 enable_mask;
- u64 requested_mask;
- s64 ts;
- struct iio_dev *iio_devs;
- struct regulator *vdd_supply;
- struct regulator *vddio_supply;
- struct iio_mount_matrix orientation;
- };
- extern const struct dev_pm_ops st_h3lis331dl_pm_ops;
- static inline int __st_h3lis331dl_write_with_mask(struct st_h3lis331dl_hw *hw,
- unsigned int addr,
- unsigned int mask,
- unsigned int data)
- {
- int err;
- unsigned int val = ST_H3LIS331DL_SHIFT_VAL(data, mask);
- err = regmap_update_bits(hw->regmap, addr, mask, val);
- return err;
- }
- static inline int
- st_h3lis331dl_update_bits_locked(struct st_h3lis331dl_hw *hw, unsigned int addr,
- unsigned int mask, unsigned int val)
- {
- int err;
- mutex_lock(&hw->lock);
- err = __st_h3lis331dl_write_with_mask(hw, addr, mask, val);
- mutex_unlock(&hw->lock);
- return err;
- }
- /* use when mask is constant */
- static inline int
- st_h3lis331dl_write_with_mask_locked(struct st_h3lis331dl_hw *hw,
- unsigned int addr,
- unsigned int mask,
- unsigned int data)
- {
- int err;
- unsigned int val = ST_H3LIS331DL_SHIFT_VAL(mask, data);
- mutex_lock(&hw->lock);
- err = regmap_update_bits(hw->regmap, addr, mask, val);
- mutex_unlock(&hw->lock);
- return err;
- }
- static inline s64 st_h3lis331dl_get_time_ns(struct iio_dev *iio_dev)
- {
- return iio_get_time_ns(iio_dev);
- }
- int st_h3lis331dl_probe(struct device *dev, int irq, int hw_id,
- struct regmap *regmap);
- int st_h3lis331dl_sensor_set_enable(struct st_h3lis331dl_sensor *sensor,
- bool enable);
- int st_h3lis331dl_trigger_setup(struct st_h3lis331dl_hw *hw);
- int st_h3lis331dl_allocate_triggered_buffer(struct st_h3lis331dl_hw *hw);
- #endif /* ST_H3LIS331DL_H */
|