1 /* 2 * Copyright 2024 NXP 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <zephyr/drivers/sensor.h> 8 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 9 #include <zephyr/drivers/spi.h> 10 #endif 11 12 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 13 #include <zephyr/drivers/i2c.h> 14 #endif 15 #include <zephyr/drivers/gpio.h> 16 #include <zephyr/kernel.h> 17 18 #define FXLS8974_BUS_I2C (1<<0) 19 #define FXLS8974_BUS_SPI (1<<1) 20 #define FXLS8974_REG_OUTXLSB 0x04 21 #define FXLS8974_REG_OUTTEMP 0x01 22 #define FXLS8974_REG_WHOAMI 0x13 23 #define FXLS8974_REG_CTRLREG1 0x15 24 #define FXLS8974_REG_CTRLREG2 0x16 25 #define FXLS8974_REG_CTRLREG3 0x17 26 #define FXLS8974_REG_CTRLREG4 0x18 27 #define FXLS8974_REG_CTRLREG5 0x19 28 29 #define WHOAMI_ID_FXLS8964 0x84 30 #define WHOAMI_ID_FXLS8974 0x86 31 32 #define FXLS8974_CTRLREG1_ACTIVE_MASK 0x01 33 #define FXLS8974_CTRLREG1_RST_MASK 0x80 34 #define FXLS8974_CTRLREG1_FSR_MASK 0x06 35 #define FXLS8974_CTRLREG1_FSR_2G 0x00 36 #define FXLS8974_CTRLREG1_FSR_4G 0x02 37 #define FXLS8974_CTRLREG1_FSR_8G 0x04 38 #define FXLS8974_CTRLREG1_FSR_16G 0x06 39 40 #define FXLS8974_CTRLREG2_WAKE_PM_MASK 0xC0 41 #define FXLS8974_CTRLREG2_SLEEP_PM_MASK 0x30 42 43 #define FXLS8974_CTRLREG3_WAKE_ODR_MASK 0xF0 44 #define FXLS8974_CTRLREG3_SLEEP_ODR_MASK 0x0F 45 46 #define FXLS8974_CTRLREG3_ODR_RATE_3200 0x00 47 #define FXLS8974_CTRLREG3_ODR_RATE_1600 0x01 48 #define FXLS8974_CTRLREG3_ODR_RATE_800 0x02 49 #define FXLS8974_CTRLREG3_ODR_RATE_400 0x03 50 #define FXLS8974_CTRLREG3_ODR_RATE_200 0x04 51 #define FXLS8974_CTRLREG3_ODR_RATE_100 0x05 52 #define FXLS8974_CTRLREG3_ODR_RATE_50 0x06 53 #define FXLS8974_CTRLREG3_ODR_RATE_25 0x07 54 #define FXLS8974_CTRLREG3_ODR_RATE_12_5 0x08 55 #define FXLS8974_CTRLREG3_ODR_RATE_6_25 0x09 56 #define FXLS8974_CTRLREG3_ODR_RATE_3_125 0x0A 57 #define FXLS8974_CTRLREG3_ODR_RATE_1_563 0x0B 58 #define FXLS8974_CTRLREG3_ODR_RATE_0_781 0x0C 59 60 #define FXLS8974_CTRLREG4_INT_POL_HIGH 0x01 61 62 #define FXLS8974_INTREG_EN 0x20 63 #define FXLS8974_INT_PIN_SEL_REG 0x21 64 65 #define FXLS8974_DATA_ACCEL_X_OFFSET 0 66 #define FXLS8974_DATA_ACCEL_Y_OFFSET FXLS8974_BYTES_PER_CHANNEL_NORMAL 67 #define FXLS8974_DATA_ACCEL_Z_OFFSET 2*FXLS8974_BYTES_PER_CHANNEL_NORMAL 68 #define FXLS8974_DATA_TEMP_OFFSET 3*FXLS8974_BYTES_PER_CHANNEL_NORMAL 69 #define FXLS8974_ZERO_TEMP 25 70 71 #define FXLS8974_MAX_NUM_CHANNELS 4 72 #define FXLS8974_MAX_ACCEL_CHANNELS 3 73 #define FXLS8974_MAX_TEMP_CHANNELS 1 74 75 #define FXLS8974_BYTES_PER_CHANNEL_NORMAL 2 76 #define FXLS8974_BYTES_PER_CHANNEL_FAST 1 77 78 #define FXLS8974_MAX_ACCEL_BYTES (FXLS8974_MAX_ACCEL_CHANNELS*2) 79 #define FXLS8974_MAX_NUM_BYTES (FXLS8974_MAX_ACCEL_BYTES + FXLS8974_MAX_TEMP_CHANNELS) 80 81 #define FXLS8974_DRDY_MASK 0x80 82 83 enum fxls8974_active { 84 FXLS8974_ACTIVE_OFF = 0, 85 FXLS8974_ACTIVE_ON, 86 }; 87 88 enum fxls8974_wake { 89 FXLS8974_WAKE = 0, 90 FXLS8974_SLEEP, 91 }; 92 93 enum fxls8974_channel { 94 FXLS8974_CHANNEL_ACCEL_X = 0, 95 FXLS8974_CHANNEL_ACCEL_Y, 96 FXLS8974_CHANNEL_ACCEL_Z, 97 FXLS8974_CHANNEL_TEMP, 98 }; 99 100 struct fxls8974_io_ops { 101 int (*read)(const struct device *dev, 102 uint8_t reg, 103 void *data, 104 size_t length); 105 int (*byte_read)(const struct device *dev, 106 uint8_t reg, 107 uint8_t *byte); 108 int (*byte_write)(const struct device *dev, 109 uint8_t reg, 110 uint8_t byte); 111 int (*reg_field_update)(const struct device *dev, 112 uint8_t reg, 113 uint8_t mask, 114 uint8_t val); 115 }; 116 117 union fxls8974_bus_cfg { 118 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 119 struct spi_dt_spec spi; 120 #endif 121 122 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 123 struct i2c_dt_spec i2c; 124 #endif 125 }; 126 127 struct fxls8974_config { 128 const union fxls8974_bus_cfg bus_cfg; 129 const struct fxls8974_io_ops *ops; 130 struct gpio_dt_spec reset_gpio; 131 uint8_t range; 132 uint8_t inst_on_bus; 133 #ifdef CONFIG_FXLS8974_TRIGGER 134 struct gpio_dt_spec int_gpio; 135 #endif 136 137 }; 138 139 struct fxls8974_data { 140 struct k_sem sem; 141 int16_t raw[FXLS8974_MAX_NUM_CHANNELS]; 142 uint8_t whoami; 143 #ifdef CONFIG_FXLS8974_TRIGGER 144 const struct device *dev; 145 struct gpio_callback gpio_cb; 146 sensor_trigger_handler_t drdy_handler; 147 const struct sensor_trigger *drdy_trig; 148 #endif 149 #ifdef CONFIG_FXLS8974_TRIGGER_OWN_THREAD 150 K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_FXLS8974_THREAD_STACK_SIZE); 151 struct k_thread thread; 152 struct k_sem trig_sem; 153 #endif 154 #ifdef CONFIG_FXLS8974_TRIGGER_GLOBAL_THREAD 155 struct k_work work; 156 #endif 157 }; 158 159 int fxls8974_get_active(const struct device *dev, uint8_t *active); 160 int fxls8974_set_active(const struct device *dev, uint8_t active); 161 162 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 163 int fxls8974_byte_write_spi(const struct device *dev, 164 uint8_t reg, 165 uint8_t byte); 166 167 int fxls8974_byte_read_spi(const struct device *dev, 168 uint8_t reg, 169 uint8_t *byte); 170 171 int fxls8974_reg_field_update_spi(const struct device *dev, 172 uint8_t reg, 173 uint8_t mask, 174 uint8_t val); 175 176 int fxls8974_read_spi(const struct device *dev, 177 uint8_t reg, 178 void *data, 179 size_t length); 180 #endif 181 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 182 int fxls8974_byte_write_i2c(const struct device *dev, 183 uint8_t reg, 184 uint8_t byte); 185 186 int fxls8974_byte_read_i2c(const struct device *dev, 187 uint8_t reg, 188 uint8_t *byte); 189 190 int fxls8974_reg_field_update_i2c(const struct device *dev, 191 uint8_t reg, 192 uint8_t mask, 193 uint8_t val); 194 195 int fxls8974_read_i2c(const struct device *dev, 196 uint8_t reg, 197 void *data, 198 size_t length); 199 #endif 200 #if CONFIG_FXLS8974_TRIGGER 201 int fxls8974_trigger_init(const struct device *dev); 202 int fxls8974_trigger_set(const struct device *dev, 203 const struct sensor_trigger *trig, 204 sensor_trigger_handler_t handler); 205 #endif 206