^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ADXL372 3-Axis Digital Accelerometer core driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2018 Analog Devices Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/trigger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "adxl372.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* ADXL372 registers definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ADXL372_DEVID 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ADXL372_DEVID_MST 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ADXL372_PARTID 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define ADXL372_STATUS_1 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define ADXL372_STATUS_2 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ADXL372_FIFO_ENTRIES_2 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ADXL372_FIFO_ENTRIES_1 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ADXL372_X_DATA_H 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ADXL372_X_DATA_L 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ADXL372_Y_DATA_H 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ADXL372_Y_DATA_L 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ADXL372_Z_DATA_H 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define ADXL372_Z_DATA_L 0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ADXL372_X_MAXPEAK_H 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ADXL372_X_MAXPEAK_L 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ADXL372_Y_MAXPEAK_H 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ADXL372_Y_MAXPEAK_L 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ADXL372_Z_MAXPEAK_H 0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ADXL372_Z_MAXPEAK_L 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ADXL372_OFFSET_X 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ADXL372_OFFSET_Y 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define ADXL372_OFFSET_Z 0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ADXL372_X_THRESH_ACT_H 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ADXL372_X_THRESH_ACT_L 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define ADXL372_Y_THRESH_ACT_H 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ADXL372_Y_THRESH_ACT_L 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define ADXL372_Z_THRESH_ACT_H 0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define ADXL372_Z_THRESH_ACT_L 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define ADXL372_TIME_ACT 0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define ADXL372_X_THRESH_INACT_H 0x2A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define ADXL372_X_THRESH_INACT_L 0x2B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define ADXL372_Y_THRESH_INACT_H 0x2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define ADXL372_Y_THRESH_INACT_L 0x2D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define ADXL372_Z_THRESH_INACT_H 0x2E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define ADXL372_Z_THRESH_INACT_L 0x2F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define ADXL372_TIME_INACT_H 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define ADXL372_TIME_INACT_L 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define ADXL372_X_THRESH_ACT2_H 0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define ADXL372_X_THRESH_ACT2_L 0x33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define ADXL372_Y_THRESH_ACT2_H 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define ADXL372_Y_THRESH_ACT2_L 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define ADXL372_Z_THRESH_ACT2_H 0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define ADXL372_Z_THRESH_ACT2_L 0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define ADXL372_HPF 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define ADXL372_FIFO_SAMPLES 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define ADXL372_FIFO_CTL 0x3A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define ADXL372_INT1_MAP 0x3B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define ADXL372_INT2_MAP 0x3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define ADXL372_TIMING 0x3D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define ADXL372_MEASURE 0x3E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define ADXL372_POWER_CTL 0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define ADXL372_SELF_TEST 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define ADXL372_RESET 0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define ADXL372_FIFO_DATA 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define ADXL372_DEVID_VAL 0xAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define ADXL372_PARTID_VAL 0xFA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define ADXL372_RESET_CODE 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* ADXL372_POWER_CTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ADXL372_POWER_CTL_MODE_MSK GENMASK_ULL(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define ADXL372_POWER_CTL_MODE(x) (((x) & 0x3) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* ADXL372_MEASURE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define ADXL372_MEASURE_LINKLOOP_MSK GENMASK_ULL(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define ADXL372_MEASURE_LINKLOOP_MODE(x) (((x) & 0x3) << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define ADXL372_MEASURE_BANDWIDTH_MSK GENMASK_ULL(2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define ADXL372_MEASURE_BANDWIDTH_MODE(x) (((x) & 0x7) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* ADXL372_TIMING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define ADXL372_TIMING_ODR_MSK GENMASK_ULL(7, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define ADXL372_TIMING_ODR_MODE(x) (((x) & 0x7) << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* ADXL372_FIFO_CTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define ADXL372_FIFO_CTL_FORMAT_MSK GENMASK(5, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define ADXL372_FIFO_CTL_FORMAT_MODE(x) (((x) & 0x7) << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ADXL372_FIFO_CTL_MODE_MSK GENMASK(2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ADXL372_FIFO_CTL_MODE_MODE(x) (((x) & 0x3) << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define ADXL372_FIFO_CTL_SAMPLES_MSK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define ADXL372_FIFO_CTL_SAMPLES_MODE(x) (((x) > 0xFF) ? 1 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* ADXL372_STATUS_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define ADXL372_STATUS_1_DATA_RDY(x) (((x) >> 0) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define ADXL372_STATUS_1_FIFO_RDY(x) (((x) >> 1) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define ADXL372_STATUS_1_FIFO_FULL(x) (((x) >> 2) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define ADXL372_STATUS_1_FIFO_OVR(x) (((x) >> 3) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define ADXL372_STATUS_1_USR_NVM_BUSY(x) (((x) >> 5) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define ADXL372_STATUS_1_AWAKE(x) (((x) >> 6) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define ADXL372_STATUS_1_ERR_USR_REGS(x) (((x) >> 7) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* ADXL372_STATUS_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define ADXL372_STATUS_2_INACT(x) (((x) >> 4) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define ADXL372_STATUS_2_ACT(x) (((x) >> 5) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ADXL372_STATUS_2_AC2(x) (((x) >> 6) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* ADXL372_INT1_MAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define ADXL372_INT1_MAP_DATA_RDY_MSK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define ADXL372_INT1_MAP_DATA_RDY_MODE(x) (((x) & 0x1) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define ADXL372_INT1_MAP_FIFO_RDY_MSK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define ADXL372_INT1_MAP_FIFO_RDY_MODE(x) (((x) & 0x1) << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define ADXL372_INT1_MAP_FIFO_FULL_MSK BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define ADXL372_INT1_MAP_FIFO_FULL_MODE(x) (((x) & 0x1) << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define ADXL372_INT1_MAP_FIFO_OVR_MSK BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define ADXL372_INT1_MAP_FIFO_OVR_MODE(x) (((x) & 0x1) << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define ADXL372_INT1_MAP_INACT_MSK BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define ADXL372_INT1_MAP_INACT_MODE(x) (((x) & 0x1) << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define ADXL372_INT1_MAP_ACT_MSK BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define ADXL372_INT1_MAP_ACT_MODE(x) (((x) & 0x1) << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define ADXL372_INT1_MAP_AWAKE_MSK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define ADXL372_INT1_MAP_AWAKE_MODE(x) (((x) & 0x1) << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define ADXL372_INT1_MAP_LOW_MSK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define ADXL372_INT1_MAP_LOW_MODE(x) (((x) & 0x1) << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* ADX372_THRESH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define ADXL372_THRESH_VAL_H_MSK GENMASK(10, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define ADXL372_THRESH_VAL_H_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_H_MSK, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define ADXL372_THRESH_VAL_L_MSK GENMASK(2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define ADXL372_THRESH_VAL_L_SEL(x) FIELD_GET(ADXL372_THRESH_VAL_L_MSK, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* The ADXL372 includes a deep, 512 sample FIFO buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define ADXL372_FIFO_SIZE 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define ADXL372_X_AXIS_EN(x) ((x) & BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define ADXL372_Y_AXIS_EN(x) ((x) & BIT(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define ADXL372_Z_AXIS_EN(x) ((x) & BIT(2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * At +/- 200g with 12-bit resolution, scale is computed as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * (200 + 200) * 9.81 / (2^12 - 1) = 0.958241
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define ADXL372_USCALE 958241
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) enum adxl372_op_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ADXL372_STANDBY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ADXL372_WAKE_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ADXL372_INSTANT_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ADXL372_FULL_BW_MEASUREMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) enum adxl372_act_proc_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ADXL372_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ADXL372_LINKED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ADXL372_LOOPED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) enum adxl372_th_activity {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ADXL372_ACTIVITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ADXL372_ACTIVITY2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ADXL372_INACTIVITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) enum adxl372_odr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ADXL372_ODR_400HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ADXL372_ODR_800HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ADXL372_ODR_1600HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ADXL372_ODR_3200HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ADXL372_ODR_6400HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) enum adxl372_bandwidth {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ADXL372_BW_200HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ADXL372_BW_400HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ADXL372_BW_800HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ADXL372_BW_1600HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ADXL372_BW_3200HZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static const unsigned int adxl372_th_reg_high_addr[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) [ADXL372_ACTIVITY] = ADXL372_X_THRESH_ACT_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) [ADXL372_ACTIVITY2] = ADXL372_X_THRESH_ACT2_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) [ADXL372_INACTIVITY] = ADXL372_X_THRESH_INACT_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) enum adxl372_fifo_format {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ADXL372_XYZ_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ADXL372_X_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ADXL372_Y_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ADXL372_XY_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ADXL372_Z_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ADXL372_XZ_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ADXL372_YZ_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ADXL372_XYZ_PEAK_FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) enum adxl372_fifo_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ADXL372_FIFO_BYPASSED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ADXL372_FIFO_STREAMED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ADXL372_FIFO_TRIGGERED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ADXL372_FIFO_OLD_SAVED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static const int adxl372_samp_freq_tbl[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 400, 800, 1600, 3200, 6400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static const int adxl372_bw_freq_tbl[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 200, 400, 800, 1600, 3200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct adxl372_axis_lookup {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) unsigned int bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) enum adxl372_fifo_format fifo_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { BIT(0), ADXL372_X_FIFO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { BIT(1), ADXL372_Y_FIFO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { BIT(2), ADXL372_Z_FIFO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { BIT(0) | BIT(1), ADXL372_XY_FIFO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) { BIT(0) | BIT(2), ADXL372_XZ_FIFO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { BIT(1) | BIT(2), ADXL372_YZ_FIFO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) { BIT(0) | BIT(1) | BIT(2), ADXL372_XYZ_FIFO },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static const struct iio_event_spec adxl372_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .dir = IIO_EV_DIR_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .mask_separate = BIT(IIO_EV_INFO_VALUE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .dir = IIO_EV_DIR_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .mask_separate = BIT(IIO_EV_INFO_VALUE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD) | BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define ADXL372_ACCEL_CHANNEL(index, reg, axis) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .type = IIO_ACCEL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .address = reg, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .channel2 = IIO_MOD_##axis, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .scan_index = index, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .sign = 's', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .realbits = 12, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .shift = 4, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .endianness = IIO_BE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .event_spec = adxl372_events, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .num_event_specs = ARRAY_SIZE(adxl372_events) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static const struct iio_chan_spec adxl372_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ADXL372_ACCEL_CHANNEL(0, ADXL372_X_DATA_H, X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ADXL372_ACCEL_CHANNEL(1, ADXL372_Y_DATA_H, Y),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ADXL372_ACCEL_CHANNEL(2, ADXL372_Z_DATA_H, Z),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct adxl372_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct iio_trigger *dready_trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct iio_trigger *peak_datardy_trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) enum adxl372_fifo_mode fifo_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) enum adxl372_fifo_format fifo_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) unsigned int fifo_axis_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) enum adxl372_op_mode op_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) enum adxl372_act_proc_mode act_proc_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) enum adxl372_odr odr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) enum adxl372_bandwidth bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u32 act_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u32 inact_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u8 fifo_set_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned long int1_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned long int2_bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u16 watermark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) __be16 fifo_buf[ADXL372_FIFO_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) bool peak_fifo_mode_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct mutex threshold_m; /* lock for threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static const unsigned long adxl372_channel_masks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) BIT(0), BIT(1), BIT(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) BIT(0) | BIT(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) BIT(1) | BIT(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) BIT(0) | BIT(1) | BIT(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static ssize_t adxl372_read_threshold_value(struct iio_dev *indio_dev, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) u16 *threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) __be16 raw_regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u16 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = regmap_bulk_read(st->regmap, addr, &raw_regval, sizeof(raw_regval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) regval = be16_to_cpu(raw_regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) regval >>= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) *threshold = regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static ssize_t adxl372_write_threshold_value(struct iio_dev *indio_dev, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) u16 threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) mutex_lock(&st->threshold_m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ret = regmap_write(st->regmap, addr, ADXL372_THRESH_VAL_H_SEL(threshold));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = regmap_update_bits(st->regmap, addr + 1, GENMASK(7, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ADXL372_THRESH_VAL_L_SEL(threshold) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) mutex_unlock(&st->threshold_m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int adxl372_read_axis(struct adxl372_state *st, u8 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) __be16 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = regmap_bulk_read(st->regmap, addr, ®val, sizeof(regval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return be16_to_cpu(regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static int adxl372_set_op_mode(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) enum adxl372_op_mode op_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ret = regmap_update_bits(st->regmap, ADXL372_POWER_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ADXL372_POWER_CTL_MODE_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ADXL372_POWER_CTL_MODE(op_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) st->op_mode = op_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int adxl372_set_odr(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) enum adxl372_odr odr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ret = regmap_update_bits(st->regmap, ADXL372_TIMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ADXL372_TIMING_ODR_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ADXL372_TIMING_ODR_MODE(odr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) st->odr = odr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int adxl372_find_closest_match(const int *array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned int size, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (val <= array[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int adxl372_set_bandwidth(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) enum adxl372_bandwidth bw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = regmap_update_bits(st->regmap, ADXL372_MEASURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ADXL372_MEASURE_BANDWIDTH_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ADXL372_MEASURE_BANDWIDTH_MODE(bw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) st->bw = bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int adxl372_set_act_proc_mode(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) enum adxl372_act_proc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = regmap_update_bits(st->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ADXL372_MEASURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ADXL372_MEASURE_LINKLOOP_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ADXL372_MEASURE_LINKLOOP_MODE(mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) st->act_proc_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int adxl372_set_activity_threshold(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) enum adxl372_th_activity act,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) bool ref_en, bool enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unsigned int threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) unsigned char buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) unsigned char th_reg_high_val, th_reg_low_val, th_reg_high_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* scale factor is 100 mg/code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) th_reg_high_val = (threshold / 100) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) th_reg_low_val = ((threshold / 100) << 5) | (ref_en << 1) | enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) th_reg_high_addr = adxl372_th_reg_high_addr[act];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) buf[0] = th_reg_high_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) buf[1] = th_reg_low_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) buf[2] = th_reg_high_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) buf[3] = th_reg_low_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) buf[4] = th_reg_high_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) buf[5] = th_reg_low_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return regmap_bulk_write(st->regmap, th_reg_high_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) buf, ARRAY_SIZE(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int adxl372_set_activity_time_ms(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) unsigned int act_time_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) unsigned int reg_val, scale_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * 3.3 ms per code is the scale factor of the TIME_ACT register for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * ODR = 6400 Hz. It is 6.6 ms per code for ODR = 3200 Hz and below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (st->odr == ADXL372_ODR_6400HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) scale_factor = 3300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) scale_factor = 6600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) reg_val = DIV_ROUND_CLOSEST(act_time_ms * 1000, scale_factor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* TIME_ACT register is 8 bits wide */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (reg_val > 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) reg_val = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = regmap_write(st->regmap, ADXL372_TIME_ACT, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) st->act_time_ms = act_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static int adxl372_set_inactivity_time_ms(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) unsigned int inact_time_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) unsigned int reg_val_h, reg_val_l, res, scale_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * 13 ms per code is the scale factor of the TIME_INACT register for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * ODR = 6400 Hz. It is 26 ms per code for ODR = 3200 Hz and below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (st->odr == ADXL372_ODR_6400HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) scale_factor = 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) scale_factor = 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) res = DIV_ROUND_CLOSEST(inact_time_ms, scale_factor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) reg_val_h = (res >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) reg_val_l = res & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret = regmap_write(st->regmap, ADXL372_TIME_INACT_H, reg_val_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ret = regmap_write(st->regmap, ADXL372_TIME_INACT_L, reg_val_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) st->inact_time_ms = inact_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static int adxl372_set_interrupts(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) unsigned long int1_bitmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) unsigned long int2_bitmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ret = regmap_write(st->regmap, ADXL372_INT1_MAP, int1_bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return regmap_write(st->regmap, ADXL372_INT2_MAP, int2_bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static int adxl372_configure_fifo(struct adxl372_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) unsigned int fifo_samples, fifo_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* FIFO must be configured while in standby mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = adxl372_set_op_mode(st, ADXL372_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * watermark stores the number of sets; we need to write the FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * registers with the number of samples
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) fifo_samples = (st->watermark * st->fifo_set_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) fifo_ctl = ADXL372_FIFO_CTL_FORMAT_MODE(st->fifo_format) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ADXL372_FIFO_CTL_MODE_MODE(st->fifo_mode) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ADXL372_FIFO_CTL_SAMPLES_MODE(fifo_samples);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ret = regmap_write(st->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ADXL372_FIFO_SAMPLES, fifo_samples & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ret = regmap_write(st->regmap, ADXL372_FIFO_CTL, fifo_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return adxl372_set_op_mode(st, ADXL372_FULL_BW_MEASUREMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static int adxl372_get_status(struct adxl372_state *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u8 *status1, u8 *status2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u16 *fifo_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) __be32 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* STATUS1, STATUS2, FIFO_ENTRIES2 and FIFO_ENTRIES are adjacent regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ret = regmap_bulk_read(st->regmap, ADXL372_STATUS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) &buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) val = be32_to_cpu(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) *status1 = (val >> 24) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) *status2 = (val >> 16) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * FIFO_ENTRIES contains the least significant byte, and FIFO_ENTRIES2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * contains the two most significant bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) *fifo_entries = val & 0x3FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static void adxl372_arrange_axis_data(struct adxl372_state *st, __be16 *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) __be16 axis_sample[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) memset(axis_sample, 0, 3 * sizeof(__be16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (ADXL372_X_AXIS_EN(st->fifo_axis_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) axis_sample[i++] = sample[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ADXL372_Y_AXIS_EN(st->fifo_axis_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) axis_sample[i++] = sample[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (ADXL372_Z_AXIS_EN(st->fifo_axis_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) axis_sample[i++] = sample[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) memcpy(sample, axis_sample, 3 * sizeof(__be16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static void adxl372_push_event(struct iio_dev *indio_dev, s64 timestamp, u8 status2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) unsigned int ev_dir = IIO_EV_DIR_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (ADXL372_STATUS_2_ACT(status2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) ev_dir = IIO_EV_DIR_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (ADXL372_STATUS_2_INACT(status2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ev_dir = IIO_EV_DIR_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (ev_dir != IIO_EV_DIR_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) IIO_EV_TYPE_THRESH, ev_dir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static irqreturn_t adxl372_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) u8 status1, status2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) u16 fifo_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ret = adxl372_get_status(st, &status1, &status2, &fifo_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) adxl372_push_event(indio_dev, iio_get_time_ns(indio_dev), status2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (st->fifo_mode != ADXL372_FIFO_BYPASSED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ADXL372_STATUS_1_FIFO_FULL(status1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * When reading data from multiple axes from the FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * to ensure that data is not overwritten and stored out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * of order at least one sample set must be left in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * FIFO after every read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) fifo_entries -= st->fifo_set_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /* Read data from the FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = regmap_noinc_read(st->regmap, ADXL372_FIFO_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) st->fifo_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) fifo_entries * sizeof(u16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Each sample is 2 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) for (i = 0; i < fifo_entries; i += st->fifo_set_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* filter peak detection data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (st->peak_fifo_mode_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) adxl372_arrange_axis_data(st, &st->fifo_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) iio_push_to_buffers(indio_dev, &st->fifo_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static int adxl372_setup(struct adxl372_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = regmap_read(st->regmap, ADXL372_DEVID, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (regval != ADXL372_DEVID_VAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) dev_err(st->dev, "Invalid chip id %x\n", regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Perform a software reset to make sure the device is in a consistent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * state after start up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ret = regmap_write(st->regmap, ADXL372_RESET, ADXL372_RESET_CODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = adxl372_set_op_mode(st, ADXL372_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* Set threshold for activity detection to 1g */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ret = adxl372_set_activity_threshold(st, ADXL372_ACTIVITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) true, true, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* Set threshold for inactivity detection to 100mg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ret = adxl372_set_activity_threshold(st, ADXL372_INACTIVITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) true, true, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* Set activity processing in Looped mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ret = adxl372_set_act_proc_mode(st, ADXL372_LOOPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ret = adxl372_set_odr(st, ADXL372_ODR_6400HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ret = adxl372_set_bandwidth(st, ADXL372_BW_3200HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* Set activity timer to 1ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ret = adxl372_set_activity_time_ms(st, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* Set inactivity timer to 10s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ret = adxl372_set_inactivity_time_ms(st, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Set the mode of operation to full bandwidth measurement mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return adxl372_set_op_mode(st, ADXL372_FULL_BW_MEASUREMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int adxl372_reg_access(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) unsigned int writeval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) unsigned int *readval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (readval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return regmap_read(st->regmap, reg, readval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return regmap_write(st->regmap, reg, writeval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static int adxl372_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) int *val, int *val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ret = adxl372_read_axis(st, chan->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) *val = sign_extend32(ret >> chan->scan_type.shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) chan->scan_type.realbits - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) *val2 = ADXL372_USCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) *val = adxl372_samp_freq_tbl[st->odr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) *val = adxl372_bw_freq_tbl[st->bw];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static int adxl372_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) int val, int val2, long info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int odr_index, bw_index, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) odr_index = adxl372_find_closest_match(adxl372_samp_freq_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ARRAY_SIZE(adxl372_samp_freq_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ret = adxl372_set_odr(st, odr_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * The timer period depends on the ODR selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * At 3200 Hz and below, it is 6.6 ms; at 6400 Hz, it is 3.3 ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ret = adxl372_set_activity_time_ms(st, st->act_time_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * The timer period depends on the ODR selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * At 3200 Hz and below, it is 26 ms; at 6400 Hz, it is 13 ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ret = adxl372_set_inactivity_time_ms(st, st->inact_time_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * The maximum bandwidth is constrained to at most half of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * the ODR to ensure that the Nyquist criteria is not violated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (st->bw > odr_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ret = adxl372_set_bandwidth(st, odr_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) bw_index = adxl372_find_closest_match(adxl372_bw_freq_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ARRAY_SIZE(adxl372_bw_freq_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return adxl372_set_bandwidth(st, bw_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static int adxl372_read_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) enum iio_event_type type, enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) enum iio_event_info info, int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) unsigned int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) u16 raw_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) case IIO_EV_INFO_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) *val = raw_value * ADXL372_USCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) *val2 = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = adxl372_read_threshold_value(indio_dev, addr, &raw_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) *val = raw_value * ADXL372_USCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) *val2 = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case IIO_EV_INFO_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) *val = st->act_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) *val2 = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) *val = st->inact_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) *val2 = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static int adxl372_write_event_value(struct iio_dev *indio_dev, const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) enum iio_event_type type, enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) enum iio_event_info info, int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) unsigned int val_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) unsigned int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) u16 raw_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) case IIO_EV_INFO_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) raw_val = DIV_ROUND_UP(val * 1000000, ADXL372_USCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) addr = ADXL372_X_THRESH_ACT_H + 2 * chan->scan_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return adxl372_write_threshold_value(indio_dev, addr, raw_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) addr = ADXL372_X_THRESH_INACT_H + 2 * chan->scan_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return adxl372_write_threshold_value(indio_dev, addr, raw_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) case IIO_EV_INFO_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) val_ms = val * 1000 + DIV_ROUND_UP(val2, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return adxl372_set_activity_time_ms(st, val_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return adxl372_set_inactivity_time_ms(st, val_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) static int adxl372_read_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) enum iio_event_type type, enum iio_event_direction dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return FIELD_GET(ADXL372_INT1_MAP_ACT_MSK, st->int1_bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return FIELD_GET(ADXL372_INT1_MAP_INACT_MSK, st->int1_bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) static int adxl372_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) enum iio_event_type type, enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_ACT_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ADXL372_INT1_MAP_ACT_MODE(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) set_mask_bits(&st->int1_bitmask, ADXL372_INT1_MAP_INACT_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ADXL372_INT1_MAP_INACT_MODE(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return adxl372_set_interrupts(st, st->int1_bitmask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static ssize_t adxl372_show_filter_freq_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) size_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) for (i = 0; i <= st->odr; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) "%d ", adxl372_bw_freq_tbl[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) buf[len - 1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static ssize_t adxl372_get_fifo_enabled(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return sprintf(buf, "%d\n", st->fifo_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static ssize_t adxl372_get_fifo_watermark(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return sprintf(buf, "%d\n", st->watermark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static IIO_CONST_ATTR(hwfifo_watermark_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) __stringify(ADXL372_FIFO_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) adxl372_get_fifo_watermark, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) adxl372_get_fifo_enabled, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) static const struct attribute *adxl372_fifo_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static int adxl372_set_watermark(struct iio_dev *indio_dev, unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (val > ADXL372_FIFO_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) val = ADXL372_FIFO_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) st->watermark = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static int adxl372_buffer_postenable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ret = adxl372_set_interrupts(st, st->int1_bitmask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) mask = *indio_dev->active_scan_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (mask == adxl372_axis_lookup_table[i].bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (i == ARRAY_SIZE(adxl372_axis_lookup_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) st->fifo_format = adxl372_axis_lookup_table[i].fifo_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) st->fifo_axis_mask = adxl372_axis_lookup_table[i].bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) indio_dev->masklength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Configure the FIFO to store sets of impact event peak. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (st->peak_fifo_mode_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) st->fifo_set_size = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) st->fifo_format = ADXL372_XYZ_PEAK_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * The 512 FIFO samples can be allotted in several ways, such as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * 170 sample sets of concurrent 3-axis data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * 256 sample sets of concurrent 2-axis data (user selectable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * 512 sample sets of single-axis data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * 170 sets of impact event peak (x, y, z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if ((st->watermark * st->fifo_set_size) > ADXL372_FIFO_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) st->watermark = (ADXL372_FIFO_SIZE / st->fifo_set_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) st->fifo_mode = ADXL372_FIFO_STREAMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) ret = adxl372_configure_fifo(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) st->fifo_mode = ADXL372_FIFO_BYPASSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) adxl372_set_interrupts(st, st->int1_bitmask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static int adxl372_buffer_predisable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) st->int1_bitmask &= ~ADXL372_INT1_MAP_FIFO_FULL_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) adxl372_set_interrupts(st, st->int1_bitmask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) st->fifo_mode = ADXL372_FIFO_BYPASSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) adxl372_configure_fifo(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static const struct iio_buffer_setup_ops adxl372_buffer_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .postenable = adxl372_buffer_postenable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .predisable = adxl372_buffer_predisable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static int adxl372_dready_trig_set_state(struct iio_trigger *trig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return adxl372_set_interrupts(st, st->int1_bitmask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) static int adxl372_validate_trigger(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) struct iio_trigger *trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (st->dready_trig != trig && st->peak_datardy_trig != trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static const struct iio_trigger_ops adxl372_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .validate_device = &iio_trigger_validate_own_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) .set_trigger_state = adxl372_dready_trig_set_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static int adxl372_peak_dready_trig_set_state(struct iio_trigger *trig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) struct adxl372_state *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) st->int1_bitmask |= ADXL372_INT1_MAP_FIFO_FULL_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) st->peak_fifo_mode_en = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return adxl372_set_interrupts(st, st->int1_bitmask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static const struct iio_trigger_ops adxl372_peak_data_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .validate_device = &iio_trigger_validate_own_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .set_trigger_state = adxl372_peak_dready_trig_set_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 0444, adxl372_show_filter_freq_avail, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static struct attribute *adxl372_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) &iio_const_attr_sampling_frequency_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static const struct attribute_group adxl372_attrs_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) .attrs = adxl372_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static const struct iio_info adxl372_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .validate_trigger = &adxl372_validate_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) .attrs = &adxl372_attrs_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) .read_raw = adxl372_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) .write_raw = adxl372_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) .read_event_config = adxl372_read_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) .write_event_config = adxl372_write_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) .read_event_value = adxl372_read_event_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) .write_event_value = adxl372_write_event_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) .debugfs_reg_access = &adxl372_reg_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) .hwfifo_set_watermark = adxl372_set_watermark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return (reg == ADXL372_FIFO_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) EXPORT_SYMBOL_GPL(adxl372_readable_noinc_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) int adxl372_probe(struct device *dev, struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) int irq, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) struct adxl372_state *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) dev_set_drvdata(dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) st->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) st->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) st->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) mutex_init(&st->threshold_m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) indio_dev->channels = adxl372_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) indio_dev->num_channels = ARRAY_SIZE(adxl372_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) indio_dev->available_scan_masks = adxl372_channel_masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) indio_dev->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) indio_dev->info = &adxl372_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ret = adxl372_setup(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) dev_err(dev, "ADXL372 setup failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) ret = devm_iio_triggered_buffer_setup(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) indio_dev, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) adxl372_trigger_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) &adxl372_buffer_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) iio_buffer_set_attrs(indio_dev->buffer, adxl372_fifo_attributes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (st->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) st->dready_trig = devm_iio_trigger_alloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) "%s-dev%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) indio_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (st->dready_trig == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) st->peak_datardy_trig = devm_iio_trigger_alloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) "%s-dev%d-peak",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) indio_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (!st->peak_datardy_trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) st->dready_trig->ops = &adxl372_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) st->peak_datardy_trig->ops = &adxl372_peak_data_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) st->dready_trig->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) st->peak_datardy_trig->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) iio_trigger_set_drvdata(st->dready_trig, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) iio_trigger_set_drvdata(st->peak_datardy_trig, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ret = devm_iio_trigger_register(dev, st->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ret = devm_iio_trigger_register(dev, st->peak_datardy_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) indio_dev->trig = iio_trigger_get(st->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ret = devm_request_threaded_irq(dev, st->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) iio_trigger_generic_data_rdy_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) IRQF_TRIGGER_RISING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) indio_dev->name, st->dready_trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return devm_iio_device_register(dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) EXPORT_SYMBOL_GPL(adxl372_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) MODULE_LICENSE("GPL");