| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2012 Invensense, Inc. |
|---|
| 3 | | -* |
|---|
| 4 | | -* This software is licensed under the terms of the GNU General Public |
|---|
| 5 | | -* License version 2, as published by the Free Software Foundation, and |
|---|
| 6 | | -* may be copied, distributed, and modified under those terms. |
|---|
| 7 | | -* |
|---|
| 8 | | -* This program is distributed in the hope that it will be useful, |
|---|
| 9 | | -* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | | -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | | -* GNU General Public License for more details. |
|---|
| 12 | 4 | */ |
|---|
| 5 | + |
|---|
| 6 | +#ifndef INV_MPU_IIO_H_ |
|---|
| 7 | +#define INV_MPU_IIO_H_ |
|---|
| 8 | + |
|---|
| 13 | 9 | #include <linux/i2c.h> |
|---|
| 14 | 10 | #include <linux/i2c-mux.h> |
|---|
| 15 | 11 | #include <linux/mutex.h> |
|---|
| .. | .. |
|---|
| 79 | 75 | INV_MPU9250, |
|---|
| 80 | 76 | INV_MPU9255, |
|---|
| 81 | 77 | INV_ICM20608, |
|---|
| 78 | + INV_ICM20609, |
|---|
| 79 | + INV_ICM20689, |
|---|
| 82 | 80 | INV_ICM20602, |
|---|
| 81 | + INV_ICM20690, |
|---|
| 82 | + INV_IAM20680, |
|---|
| 83 | 83 | INV_NUM_PARTS |
|---|
| 84 | 84 | }; |
|---|
| 85 | 85 | |
|---|
| 86 | +/* chip sensors mask: accelerometer, gyroscope, temperature, magnetometer */ |
|---|
| 87 | +#define INV_MPU6050_SENSOR_ACCL BIT(0) |
|---|
| 88 | +#define INV_MPU6050_SENSOR_GYRO BIT(1) |
|---|
| 89 | +#define INV_MPU6050_SENSOR_TEMP BIT(2) |
|---|
| 90 | +#define INV_MPU6050_SENSOR_MAGN BIT(3) |
|---|
| 91 | + |
|---|
| 86 | 92 | /** |
|---|
| 87 | 93 | * struct inv_mpu6050_chip_config - Cached chip configuration data. |
|---|
| 94 | + * @clk: selected chip clock |
|---|
| 88 | 95 | * @fsr: Full scale range. |
|---|
| 89 | 96 | * @lpf: Digital low pass filter frequency. |
|---|
| 90 | 97 | * @accl_fs: accel full scale range. |
|---|
| 98 | + * @accl_en: accel engine enabled |
|---|
| 99 | + * @gyro_en: gyro engine enabled |
|---|
| 100 | + * @temp_en: temperature sensor enabled |
|---|
| 101 | + * @magn_en: magn engine (i2c master) enabled |
|---|
| 91 | 102 | * @accl_fifo_enable: enable accel data output |
|---|
| 92 | 103 | * @gyro_fifo_enable: enable gyro data output |
|---|
| 104 | + * @temp_fifo_enable: enable temp data output |
|---|
| 105 | + * @magn_fifo_enable: enable magn data output |
|---|
| 93 | 106 | * @divider: chip sample rate divider (sample rate divider - 1) |
|---|
| 94 | 107 | */ |
|---|
| 95 | 108 | struct inv_mpu6050_chip_config { |
|---|
| 109 | + unsigned int clk:3; |
|---|
| 96 | 110 | unsigned int fsr:2; |
|---|
| 97 | 111 | unsigned int lpf:3; |
|---|
| 98 | 112 | unsigned int accl_fs:2; |
|---|
| 113 | + unsigned int accl_en:1; |
|---|
| 114 | + unsigned int gyro_en:1; |
|---|
| 115 | + unsigned int temp_en:1; |
|---|
| 116 | + unsigned int magn_en:1; |
|---|
| 99 | 117 | unsigned int accl_fifo_enable:1; |
|---|
| 100 | 118 | unsigned int gyro_fifo_enable:1; |
|---|
| 119 | + unsigned int temp_fifo_enable:1; |
|---|
| 120 | + unsigned int magn_fifo_enable:1; |
|---|
| 101 | 121 | u8 divider; |
|---|
| 102 | 122 | u8 user_ctrl; |
|---|
| 103 | 123 | }; |
|---|
| 124 | + |
|---|
| 125 | +/* |
|---|
| 126 | + * Maximum of 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8. |
|---|
| 127 | + * May be less if fewer channels are enabled, as long as the timestamp |
|---|
| 128 | + * remains 8 byte aligned |
|---|
| 129 | + */ |
|---|
| 130 | +#define INV_MPU6050_OUTPUT_DATA_SIZE 32 |
|---|
| 104 | 131 | |
|---|
| 105 | 132 | /** |
|---|
| 106 | 133 | * struct inv_mpu6050_hw - Other important hardware information. |
|---|
| .. | .. |
|---|
| 139 | 166 | * @chip_period: chip internal period estimation (~1kHz). |
|---|
| 140 | 167 | * @it_timestamp: timestamp from previous interrupt. |
|---|
| 141 | 168 | * @data_timestamp: timestamp for next data sample. |
|---|
| 169 | + * @vdd_supply: VDD voltage regulator for the chip. |
|---|
| 170 | + * @vddio_supply I/O voltage regulator for the chip. |
|---|
| 171 | + * @magn_disabled: magnetometer disabled for backward compatibility reason. |
|---|
| 172 | + * @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss. |
|---|
| 173 | + * @magn_orient: magnetometer sensor chip orientation if available. |
|---|
| 174 | + * @suspended_sensors: sensors mask of sensors turned off for suspend |
|---|
| 175 | + * @data: dma safe buffer used for bulk reads. |
|---|
| 142 | 176 | */ |
|---|
| 143 | 177 | struct inv_mpu6050_state { |
|---|
| 144 | 178 | struct mutex lock; |
|---|
| .. | .. |
|---|
| 149 | 183 | enum inv_devices chip_type; |
|---|
| 150 | 184 | struct i2c_mux_core *muxc; |
|---|
| 151 | 185 | struct i2c_client *mux_client; |
|---|
| 152 | | - unsigned int powerup_count; |
|---|
| 153 | 186 | struct inv_mpu6050_platform_data plat_data; |
|---|
| 154 | 187 | struct iio_mount_matrix orientation; |
|---|
| 155 | 188 | struct regmap *map; |
|---|
| .. | .. |
|---|
| 159 | 192 | s64 chip_period; |
|---|
| 160 | 193 | s64 it_timestamp; |
|---|
| 161 | 194 | s64 data_timestamp; |
|---|
| 195 | + struct regulator *vdd_supply; |
|---|
| 196 | + struct regulator *vddio_supply; |
|---|
| 197 | + bool magn_disabled; |
|---|
| 198 | + s32 magn_raw_to_gauss[3]; |
|---|
| 199 | + struct iio_mount_matrix magn_orient; |
|---|
| 200 | + unsigned int suspended_sensors; |
|---|
| 201 | + u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned; |
|---|
| 162 | 202 | }; |
|---|
| 163 | 203 | |
|---|
| 164 | 204 | /*register and associated bit definition*/ |
|---|
| .. | .. |
|---|
| 171 | 211 | #define INV_MPU6050_REG_ACCEL_CONFIG 0x1C |
|---|
| 172 | 212 | |
|---|
| 173 | 213 | #define INV_MPU6050_REG_FIFO_EN 0x23 |
|---|
| 214 | +#define INV_MPU6050_BIT_SLAVE_0 0x01 |
|---|
| 215 | +#define INV_MPU6050_BIT_SLAVE_1 0x02 |
|---|
| 216 | +#define INV_MPU6050_BIT_SLAVE_2 0x04 |
|---|
| 174 | 217 | #define INV_MPU6050_BIT_ACCEL_OUT 0x08 |
|---|
| 175 | 218 | #define INV_MPU6050_BITS_GYRO_OUT 0x70 |
|---|
| 219 | +#define INV_MPU6050_BIT_TEMP_OUT 0x80 |
|---|
| 220 | + |
|---|
| 221 | +#define INV_MPU6050_REG_I2C_MST_CTRL 0x24 |
|---|
| 222 | +#define INV_MPU6050_BITS_I2C_MST_CLK_400KHZ 0x0D |
|---|
| 223 | +#define INV_MPU6050_BIT_I2C_MST_P_NSR 0x10 |
|---|
| 224 | +#define INV_MPU6050_BIT_SLV3_FIFO_EN 0x20 |
|---|
| 225 | +#define INV_MPU6050_BIT_WAIT_FOR_ES 0x40 |
|---|
| 226 | +#define INV_MPU6050_BIT_MULT_MST_EN 0x80 |
|---|
| 227 | + |
|---|
| 228 | +/* control I2C slaves from 0 to 3 */ |
|---|
| 229 | +#define INV_MPU6050_REG_I2C_SLV_ADDR(_x) (0x25 + 3 * (_x)) |
|---|
| 230 | +#define INV_MPU6050_BIT_I2C_SLV_RNW 0x80 |
|---|
| 231 | + |
|---|
| 232 | +#define INV_MPU6050_REG_I2C_SLV_REG(_x) (0x26 + 3 * (_x)) |
|---|
| 233 | + |
|---|
| 234 | +#define INV_MPU6050_REG_I2C_SLV_CTRL(_x) (0x27 + 3 * (_x)) |
|---|
| 235 | +#define INV_MPU6050_BIT_SLV_GRP 0x10 |
|---|
| 236 | +#define INV_MPU6050_BIT_SLV_REG_DIS 0x20 |
|---|
| 237 | +#define INV_MPU6050_BIT_SLV_BYTE_SW 0x40 |
|---|
| 238 | +#define INV_MPU6050_BIT_SLV_EN 0x80 |
|---|
| 239 | + |
|---|
| 240 | +/* I2C master delay register */ |
|---|
| 241 | +#define INV_MPU6050_REG_I2C_SLV4_CTRL 0x34 |
|---|
| 242 | +#define INV_MPU6050_BITS_I2C_MST_DLY(_x) ((_x) & 0x1F) |
|---|
| 243 | + |
|---|
| 244 | +#define INV_MPU6050_REG_I2C_MST_STATUS 0x36 |
|---|
| 245 | +#define INV_MPU6050_BIT_I2C_SLV0_NACK 0x01 |
|---|
| 246 | +#define INV_MPU6050_BIT_I2C_SLV1_NACK 0x02 |
|---|
| 247 | +#define INV_MPU6050_BIT_I2C_SLV2_NACK 0x04 |
|---|
| 248 | +#define INV_MPU6050_BIT_I2C_SLV3_NACK 0x08 |
|---|
| 176 | 249 | |
|---|
| 177 | 250 | #define INV_MPU6050_REG_INT_ENABLE 0x38 |
|---|
| 178 | 251 | #define INV_MPU6050_BIT_DATA_RDY_EN 0x01 |
|---|
| .. | .. |
|---|
| 186 | 259 | #define INV_MPU6050_BIT_FIFO_OVERFLOW_INT 0x10 |
|---|
| 187 | 260 | #define INV_MPU6050_BIT_RAW_DATA_RDY_INT 0x01 |
|---|
| 188 | 261 | |
|---|
| 262 | +#define INV_MPU6050_REG_EXT_SENS_DATA 0x49 |
|---|
| 263 | + |
|---|
| 264 | +/* I2C slaves data output from 0 to 3 */ |
|---|
| 265 | +#define INV_MPU6050_REG_I2C_SLV_DO(_x) (0x63 + (_x)) |
|---|
| 266 | + |
|---|
| 267 | +#define INV_MPU6050_REG_I2C_MST_DELAY_CTRL 0x67 |
|---|
| 268 | +#define INV_MPU6050_BIT_I2C_SLV0_DLY_EN 0x01 |
|---|
| 269 | +#define INV_MPU6050_BIT_I2C_SLV1_DLY_EN 0x02 |
|---|
| 270 | +#define INV_MPU6050_BIT_I2C_SLV2_DLY_EN 0x04 |
|---|
| 271 | +#define INV_MPU6050_BIT_I2C_SLV3_DLY_EN 0x08 |
|---|
| 272 | +#define INV_MPU6050_BIT_DELAY_ES_SHADOW 0x80 |
|---|
| 273 | + |
|---|
| 274 | +#define INV_MPU6050_REG_SIGNAL_PATH_RESET 0x68 |
|---|
| 275 | +#define INV_MPU6050_BIT_TEMP_RST BIT(0) |
|---|
| 276 | +#define INV_MPU6050_BIT_ACCEL_RST BIT(1) |
|---|
| 277 | +#define INV_MPU6050_BIT_GYRO_RST BIT(2) |
|---|
| 278 | + |
|---|
| 189 | 279 | #define INV_MPU6050_REG_USER_CTRL 0x6A |
|---|
| 280 | +#define INV_MPU6050_BIT_SIG_COND_RST 0x01 |
|---|
| 190 | 281 | #define INV_MPU6050_BIT_FIFO_RST 0x04 |
|---|
| 191 | 282 | #define INV_MPU6050_BIT_DMP_RST 0x08 |
|---|
| 192 | 283 | #define INV_MPU6050_BIT_I2C_MST_EN 0x20 |
|---|
| .. | .. |
|---|
| 197 | 288 | #define INV_MPU6050_REG_PWR_MGMT_1 0x6B |
|---|
| 198 | 289 | #define INV_MPU6050_BIT_H_RESET 0x80 |
|---|
| 199 | 290 | #define INV_MPU6050_BIT_SLEEP 0x40 |
|---|
| 291 | +#define INV_MPU6050_BIT_TEMP_DIS 0x08 |
|---|
| 200 | 292 | #define INV_MPU6050_BIT_CLK_MASK 0x7 |
|---|
| 201 | 293 | |
|---|
| 202 | 294 | #define INV_MPU6050_REG_PWR_MGMT_2 0x6C |
|---|
| .. | .. |
|---|
| 213 | 305 | #define INV_MPU6050_BYTES_PER_3AXIS_SENSOR 6 |
|---|
| 214 | 306 | #define INV_MPU6050_FIFO_COUNT_BYTE 2 |
|---|
| 215 | 307 | |
|---|
| 216 | | -/* ICM20602 FIFO samples include temperature readings */ |
|---|
| 217 | | -#define INV_ICM20602_BYTES_PER_TEMP_SENSOR 2 |
|---|
| 308 | +/* MPU9X50 9-axis magnetometer */ |
|---|
| 309 | +#define INV_MPU9X50_BYTES_MAGN 7 |
|---|
| 310 | + |
|---|
| 311 | +/* FIFO temperature sample size */ |
|---|
| 312 | +#define INV_MPU6050_BYTES_PER_TEMP_SENSOR 2 |
|---|
| 218 | 313 | |
|---|
| 219 | 314 | /* mpu6500 registers */ |
|---|
| 220 | 315 | #define INV_MPU6500_REG_ACCEL_CONFIG_2 0x1D |
|---|
| 316 | +#define INV_ICM20689_BITS_FIFO_SIZE_MAX 0xC0 |
|---|
| 221 | 317 | #define INV_MPU6500_REG_ACCEL_OFFSET 0x77 |
|---|
| 222 | 318 | |
|---|
| 223 | 319 | /* delay time in milliseconds */ |
|---|
| 224 | 320 | #define INV_MPU6050_POWER_UP_TIME 100 |
|---|
| 225 | 321 | #define INV_MPU6050_TEMP_UP_TIME 100 |
|---|
| 226 | | -#define INV_MPU6050_SENSOR_UP_TIME 30 |
|---|
| 322 | +#define INV_MPU6050_ACCEL_UP_TIME 20 |
|---|
| 323 | +#define INV_MPU6050_GYRO_UP_TIME 35 |
|---|
| 324 | +#define INV_MPU6050_GYRO_DOWN_TIME 150 |
|---|
| 325 | +#define INV_MPU6050_SUSPEND_DELAY_MS 2000 |
|---|
| 227 | 326 | |
|---|
| 228 | 327 | /* delay time in microseconds */ |
|---|
| 229 | 328 | #define INV_MPU6050_REG_UP_TIME_MIN 5000 |
|---|
| .. | .. |
|---|
| 235 | 334 | #define INV_MPU6050_MAX_ACCL_FS_PARAM 3 |
|---|
| 236 | 335 | #define INV_MPU6050_THREE_AXIS 3 |
|---|
| 237 | 336 | #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3 |
|---|
| 337 | +#define INV_ICM20690_GYRO_CONFIG_FSR_SHIFT 2 |
|---|
| 238 | 338 | #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3 |
|---|
| 239 | 339 | |
|---|
| 240 | 340 | #define INV_MPU6500_TEMP_OFFSET 7011 |
|---|
| .. | .. |
|---|
| 242 | 342 | |
|---|
| 243 | 343 | #define INV_ICM20608_TEMP_OFFSET 8170 |
|---|
| 244 | 344 | #define INV_ICM20608_TEMP_SCALE 3059976 |
|---|
| 245 | | - |
|---|
| 246 | | -/* 6 + 6 round up and plus 8 */ |
|---|
| 247 | | -#define INV_MPU6050_OUTPUT_DATA_SIZE 24 |
|---|
| 248 | 345 | |
|---|
| 249 | 346 | #define INV_MPU6050_REG_INT_PIN_CFG 0x37 |
|---|
| 250 | 347 | #define INV_MPU6050_ACTIVE_HIGH 0x00 |
|---|
| .. | .. |
|---|
| 257 | 354 | #define INV_MPU6050_TS_PERIOD_JITTER 4 |
|---|
| 258 | 355 | |
|---|
| 259 | 356 | /* init parameters */ |
|---|
| 260 | | -#define INV_MPU6050_INIT_FIFO_RATE 50 |
|---|
| 261 | 357 | #define INV_MPU6050_MAX_FIFO_RATE 1000 |
|---|
| 262 | 358 | #define INV_MPU6050_MIN_FIFO_RATE 4 |
|---|
| 263 | 359 | |
|---|
| .. | .. |
|---|
| 282 | 378 | #define INV_MPU9255_WHOAMI_VALUE 0x73 |
|---|
| 283 | 379 | #define INV_MPU6515_WHOAMI_VALUE 0x74 |
|---|
| 284 | 380 | #define INV_ICM20608_WHOAMI_VALUE 0xAF |
|---|
| 381 | +#define INV_ICM20609_WHOAMI_VALUE 0xA6 |
|---|
| 382 | +#define INV_ICM20689_WHOAMI_VALUE 0x98 |
|---|
| 285 | 383 | #define INV_ICM20602_WHOAMI_VALUE 0x12 |
|---|
| 384 | +#define INV_ICM20690_WHOAMI_VALUE 0x20 |
|---|
| 385 | +#define INV_IAM20680_WHOAMI_VALUE 0xA9 |
|---|
| 286 | 386 | |
|---|
| 287 | 387 | /* scan element definition for generic MPU6xxx devices */ |
|---|
| 288 | 388 | enum inv_mpu6050_scan { |
|---|
| 289 | 389 | INV_MPU6050_SCAN_ACCL_X, |
|---|
| 290 | 390 | INV_MPU6050_SCAN_ACCL_Y, |
|---|
| 291 | 391 | INV_MPU6050_SCAN_ACCL_Z, |
|---|
| 392 | + INV_MPU6050_SCAN_TEMP, |
|---|
| 292 | 393 | INV_MPU6050_SCAN_GYRO_X, |
|---|
| 293 | 394 | INV_MPU6050_SCAN_GYRO_Y, |
|---|
| 294 | 395 | INV_MPU6050_SCAN_GYRO_Z, |
|---|
| 295 | 396 | INV_MPU6050_SCAN_TIMESTAMP, |
|---|
| 296 | | -}; |
|---|
| 297 | 397 | |
|---|
| 298 | | -/* scan element definition for ICM20602, which includes temperature */ |
|---|
| 299 | | -enum inv_icm20602_scan { |
|---|
| 300 | | - INV_ICM20602_SCAN_ACCL_X, |
|---|
| 301 | | - INV_ICM20602_SCAN_ACCL_Y, |
|---|
| 302 | | - INV_ICM20602_SCAN_ACCL_Z, |
|---|
| 303 | | - INV_ICM20602_SCAN_TEMP, |
|---|
| 304 | | - INV_ICM20602_SCAN_GYRO_X, |
|---|
| 305 | | - INV_ICM20602_SCAN_GYRO_Y, |
|---|
| 306 | | - INV_ICM20602_SCAN_GYRO_Z, |
|---|
| 307 | | - INV_ICM20602_SCAN_TIMESTAMP, |
|---|
| 398 | + INV_MPU9X50_SCAN_MAGN_X = INV_MPU6050_SCAN_GYRO_Z + 1, |
|---|
| 399 | + INV_MPU9X50_SCAN_MAGN_Y, |
|---|
| 400 | + INV_MPU9X50_SCAN_MAGN_Z, |
|---|
| 401 | + INV_MPU9X50_SCAN_TIMESTAMP, |
|---|
| 308 | 402 | }; |
|---|
| 309 | 403 | |
|---|
| 310 | 404 | enum inv_mpu6050_filter_e { |
|---|
| 311 | | - INV_MPU6050_FILTER_256HZ_NOLPF2 = 0, |
|---|
| 312 | | - INV_MPU6050_FILTER_188HZ, |
|---|
| 313 | | - INV_MPU6050_FILTER_98HZ, |
|---|
| 314 | | - INV_MPU6050_FILTER_42HZ, |
|---|
| 405 | + INV_MPU6050_FILTER_NOLPF2 = 0, |
|---|
| 406 | + INV_MPU6050_FILTER_200HZ, |
|---|
| 407 | + INV_MPU6050_FILTER_100HZ, |
|---|
| 408 | + INV_MPU6050_FILTER_45HZ, |
|---|
| 315 | 409 | INV_MPU6050_FILTER_20HZ, |
|---|
| 316 | 410 | INV_MPU6050_FILTER_10HZ, |
|---|
| 317 | 411 | INV_MPU6050_FILTER_5HZ, |
|---|
| 318 | | - INV_MPU6050_FILTER_2100HZ_NOLPF, |
|---|
| 412 | + INV_MPU6050_FILTER_NOLPF, |
|---|
| 319 | 413 | NUM_MPU6050_FILTER |
|---|
| 320 | 414 | }; |
|---|
| 321 | 415 | |
|---|
| .. | .. |
|---|
| 349 | 443 | |
|---|
| 350 | 444 | irqreturn_t inv_mpu6050_read_fifo(int irq, void *p); |
|---|
| 351 | 445 | int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev, int irq_type); |
|---|
| 352 | | -int inv_reset_fifo(struct iio_dev *indio_dev); |
|---|
| 353 | | -int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask); |
|---|
| 446 | +int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable); |
|---|
| 447 | +int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, |
|---|
| 448 | + unsigned int mask); |
|---|
| 354 | 449 | int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val); |
|---|
| 355 | | -int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on); |
|---|
| 356 | 450 | int inv_mpu_acpi_create_mux_client(struct i2c_client *client); |
|---|
| 357 | 451 | void inv_mpu_acpi_delete_mux_client(struct i2c_client *client); |
|---|
| 358 | 452 | int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, |
|---|
| 359 | 453 | int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type); |
|---|
| 360 | 454 | extern const struct dev_pm_ops inv_mpu_pmops; |
|---|
| 455 | + |
|---|
| 456 | +#endif |
|---|