1 /* 2 * Copyright (c) 2016 Freescale Semiconductor, Inc. 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 FXOS8700_BUS_I2C (1<<0) 19 #define FXOS8700_BUS_SPI (1<<1) 20 #define FXOS8700_REG_STATUS 0x00 21 #define FXOS8700_REG_OUTXMSB 0x01 22 #define FXOS8700_REG_INT_SOURCE 0x0c 23 #define FXOS8700_REG_WHOAMI 0x0d 24 #define FXOS8700_REG_XYZ_DATA_CFG 0x0e 25 #define FXOS8700_REG_FF_MT_CFG 0x15 26 #define FXOS8700_REG_FF_MT_SRC 0x16 27 #define FXOS8700_REG_FF_MT_THS 0x17 28 #define FXOS8700_REG_FF_MT_COUNT 0x18 29 #define FXOS8700_REG_PULSE_CFG 0x21 30 #define FXOS8700_REG_PULSE_SRC 0x22 31 #define FXOS8700_REG_PULSE_THSX 0x23 32 #define FXOS8700_REG_PULSE_THSY 0x24 33 #define FXOS8700_REG_PULSE_THSZ 0x25 34 #define FXOS8700_REG_PULSE_TMLT 0x26 35 #define FXOS8700_REG_PULSE_LTCY 0x27 36 #define FXOS8700_REG_PULSE_WIND 0x28 37 #define FXOS8700_REG_CTRLREG1 0x2a 38 #define FXOS8700_REG_CTRLREG2 0x2b 39 #define FXOS8700_REG_CTRLREG3 0x2c 40 #define FXOS8700_REG_CTRLREG4 0x2d 41 #define FXOS8700_REG_CTRLREG5 0x2e 42 #define FXOS8700_REG_M_OUTXMSB 0x33 43 #define FXOS8700_REG_TEMP 0x51 44 #define FXOS8700_REG_M_CTRLREG1 0x5b 45 #define FXOS8700_REG_M_CTRLREG2 0x5c 46 #define FXOS8700_REG_M_INT_SRC 0x5e 47 #define FXOS8700_REG_M_VECM_CFG 0x69 48 #define FXOS8700_REG_M_VECM_THS_MSB 0x6a 49 #define FXOS8700_REG_M_VECM_THS_LSB 0x6b 50 51 /* Devices that are compatible with this driver: */ 52 #define WHOAMI_ID_MMA8451 0x1A 53 #define WHOAMI_ID_MMA8652 0x4A 54 #define WHOAMI_ID_MMA8653 0x5A 55 #define WHOAMI_ID_FXOS8700 0xC7 56 57 #define FXOS8700_DRDY_MASK (1 << 0) 58 #define FXOS8700_MAG_VECM_INT1_MASK (1 << 0) 59 #define FXOS8700_VECM_MASK (1 << 1) 60 #define FXOS8700_MOTION_MASK (1 << 2) 61 #define FXOS8700_PULSE_MASK (1 << 3) 62 63 #define FXOS8700_XYZ_DATA_CFG_FS_MASK 0x03 64 65 #define FXOS8700_PULSE_SRC_DPE (1 << 3) 66 67 #define FXOS8700_CTRLREG1_ACTIVE_MASK 0x01 68 #define FXOS8700_CTRLREG1_DR_MASK (7 << 3) 69 #define FXOS8700_CTRLREG1_DR_RATE_800 0 70 #define FXOS8700_CTRLREG1_DR_RATE_400 (1 << 3) 71 #define FXOS8700_CTRLREG1_DR_RATE_200 (2 << 3) 72 #define FXOS8700_CTRLREG1_DR_RATE_100 (3 << 3) 73 #define FXOS8700_CTRLREG1_DR_RATE_50 (4 << 3) 74 #define FXOS8700_CTRLREG1_DR_RATE_12_5 (5 << 3) 75 #define FXOS8700_CTRLREG1_DR_RATE_6_25 (6 << 3) 76 #define FXOS8700_CTRLREG1_DR_RATE_1_56 (7 << 3) 77 78 #define FXOS8700_CTRLREG2_RST_MASK 0x40 79 #define FXOS8700_CTRLREG2_MODS_MASK 0x03 80 81 #define FXOS8700_FF_MT_CFG_ELE BIT(7) 82 #define FXOS8700_FF_MT_CFG_OAE BIT(6) 83 #define FXOS8700_FF_MT_CFG_ZEFE BIT(5) 84 #define FXOS8700_FF_MT_CFG_YEFE BIT(4) 85 #define FXOS8700_FF_MT_CFG_XEFE BIT(3) 86 #define FXOS8700_FF_MT_THS_MASK 0x7f 87 #define FXOS8700_FF_MT_THS_SCALE (SENSOR_G * 63000LL / 1000000LL) 88 89 #define FXOS8700_M_CTRLREG1_MODE_MASK 0x03 90 91 #define FXOS8700_M_CTRLREG2_AUTOINC_MASK (1 << 5) 92 93 #define FXOS8700_NUM_ACCEL_CHANNELS 3 94 #define FXOS8700_NUM_MAG_CHANNELS 3 95 #define FXOS8700_NUM_HYBRID_CHANNELS 6 96 #define FXOS8700_MAX_NUM_CHANNELS 6 97 98 #define FXOS8700_BYTES_PER_CHANNEL_NORMAL 2 99 #define FXOS8700_BYTES_PER_CHANNEL_FAST 1 100 101 #define FXOS8700_MAX_NUM_BYTES (FXOS8700_BYTES_PER_CHANNEL_NORMAL * \ 102 FXOS8700_MAX_NUM_CHANNELS) 103 104 enum fxos8700_power { 105 FXOS8700_POWER_STANDBY = 0, 106 FXOS8700_POWER_ACTIVE, 107 }; 108 109 enum fxos8700_mode { 110 FXOS8700_MODE_ACCEL = 0, 111 FXOS8700_MODE_MAGN = 1, 112 FXOS8700_MODE_HYBRID = 3, 113 }; 114 115 enum fxos8700_power_mode { 116 FXOS8700_PM_NORMAL = 0, 117 FXOS8700_PM_LOW_NOISE_LOW_POWER, 118 FXOS8700_PM_HIGH_RESOLUTION, 119 FXOS8700_PM_LOW_POWER, 120 }; 121 122 enum fxos8700_channel { 123 FXOS8700_CHANNEL_ACCEL_X = 0, 124 FXOS8700_CHANNEL_ACCEL_Y, 125 FXOS8700_CHANNEL_ACCEL_Z, 126 FXOS8700_CHANNEL_MAGN_X, 127 FXOS8700_CHANNEL_MAGN_Y, 128 FXOS8700_CHANNEL_MAGN_Z, 129 }; 130 131 /* FXOS8700 specific triggers */ 132 enum fxos_trigger_type { 133 FXOS8700_TRIG_M_VECM, 134 }; 135 136 struct fxos8700_io_ops { 137 int (*read)(const struct device *dev, 138 uint8_t reg, 139 void *data, 140 size_t length); 141 int (*byte_read)(const struct device *dev, 142 uint8_t reg, 143 uint8_t *byte); 144 int (*byte_write)(const struct device *dev, 145 uint8_t reg, 146 uint8_t byte); 147 int (*reg_field_update)(const struct device *dev, 148 uint8_t reg, 149 uint8_t mask, 150 uint8_t val); 151 }; 152 153 union fxos8700_bus_cfg { 154 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 155 struct spi_dt_spec spi; 156 #endif 157 158 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 159 struct i2c_dt_spec i2c; 160 #endif 161 }; 162 163 struct fxos8700_config { 164 const union fxos8700_bus_cfg bus_cfg; 165 const struct fxos8700_io_ops *ops; 166 #ifdef CONFIG_FXOS8700_TRIGGER 167 struct gpio_dt_spec int_gpio; 168 #endif 169 struct gpio_dt_spec reset_gpio; 170 enum fxos8700_mode mode; 171 enum fxos8700_power_mode power_mode; 172 uint8_t range; 173 uint8_t start_addr; 174 uint8_t start_channel; 175 uint8_t num_channels; 176 #ifdef CONFIG_FXOS8700_PULSE 177 uint8_t pulse_cfg; 178 uint8_t pulse_ths[3]; 179 uint8_t pulse_tmlt; 180 uint8_t pulse_ltcy; 181 uint8_t pulse_wind; 182 #endif 183 #ifdef CONFIG_FXOS8700_MAG_VECM 184 uint8_t mag_vecm_cfg; 185 uint8_t mag_vecm_ths[2]; 186 #endif 187 uint8_t inst_on_bus; 188 }; 189 190 struct fxos8700_data { 191 struct k_sem sem; 192 #ifdef CONFIG_FXOS8700_TRIGGER 193 const struct device *dev; 194 struct gpio_callback gpio_cb; 195 sensor_trigger_handler_t drdy_handler; 196 const struct sensor_trigger *drdy_trig; 197 #endif 198 #ifdef CONFIG_FXOS8700_PULSE 199 sensor_trigger_handler_t tap_handler; 200 const struct sensor_trigger *tap_trig; 201 sensor_trigger_handler_t double_tap_handler; 202 const struct sensor_trigger *double_tap_trig; 203 #endif 204 #ifdef CONFIG_FXOS8700_MOTION 205 sensor_trigger_handler_t motion_handler; 206 const struct sensor_trigger *motion_trig; 207 #endif 208 #ifdef CONFIG_FXOS8700_MAG_VECM 209 sensor_trigger_handler_t m_vecm_handler; 210 const struct sensor_trigger *m_vecm_trig; 211 #endif 212 #ifdef CONFIG_FXOS8700_TRIGGER_OWN_THREAD 213 K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_FXOS8700_THREAD_STACK_SIZE); 214 struct k_thread thread; 215 struct k_sem trig_sem; 216 #endif 217 #ifdef CONFIG_FXOS8700_TRIGGER_GLOBAL_THREAD 218 struct k_work work; 219 #endif 220 int16_t raw[FXOS8700_MAX_NUM_CHANNELS]; 221 #ifdef CONFIG_FXOS8700_TEMP 222 int8_t temp; 223 #endif 224 uint8_t whoami; 225 }; 226 227 int fxos8700_get_power(const struct device *dev, enum fxos8700_power *power); 228 int fxos8700_set_power(const struct device *dev, enum fxos8700_power power); 229 230 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) 231 int fxos8700_byte_write_spi(const struct device *dev, 232 uint8_t reg, 233 uint8_t byte); 234 235 int fxos8700_byte_read_spi(const struct device *dev, 236 uint8_t reg, 237 uint8_t *byte); 238 239 int fxos8700_reg_field_update_spi(const struct device *dev, 240 uint8_t reg, 241 uint8_t mask, 242 uint8_t val); 243 244 int fxos8700_read_spi(const struct device *dev, 245 uint8_t reg, 246 void *data, 247 size_t length); 248 #endif 249 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) 250 int fxos8700_byte_write_i2c(const struct device *dev, 251 uint8_t reg, 252 uint8_t byte); 253 254 int fxos8700_byte_read_i2c(const struct device *dev, 255 uint8_t reg, 256 uint8_t *byte); 257 258 int fxos8700_reg_field_update_i2c(const struct device *dev, 259 uint8_t reg, 260 uint8_t mask, 261 uint8_t val); 262 263 int fxos8700_read_i2c(const struct device *dev, 264 uint8_t reg, 265 void *data, 266 size_t length); 267 #endif 268 #if CONFIG_FXOS8700_TRIGGER 269 int fxos8700_trigger_init(const struct device *dev); 270 int fxos8700_trigger_set(const struct device *dev, 271 const struct sensor_trigger *trig, 272 sensor_trigger_handler_t handler); 273 #endif 274