blob: 36f8e9c130f0500bc748953747bf20c5005d4939 [file] [log] [blame]
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Copyright (C) 2012 Invensense, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _INV_ICM20602_IIO_H_
#define _INV_ICM20602_IIO_H_
#include <linux/i2c.h>
#include <linux/kfifo.h>
#include <linux/spinlock.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/platform_data/invensense_mpu6050.h>
/*
* it uses sensor irq to trigger
* if set INV20602_DEVICE_IRQ_TRIGGER as 1,
* otherwise use SMD IRQ to trigger
*/
#define INV20602_DEVICE_IRQ_TRIGGER 0
#if INV20602_DEVICE_IRQ_TRIGGER
#define INV20602_SMD_IRQ_TRIGGER 0
#else
#define INV20602_SMD_IRQ_TRIGGER 1
#endif
#define ICM20602_LDO_VTG_MIN_UV 1800000
#define ICM20602_LDO_VTG_MAX_UV 1800000
#define INV_ICM20602_TIME_STAMP_TOR 5
#define ICM20602_PACKAGE_SIZE 14
/* device enum */
enum inv_devices {
INV_ICM20602,
INV_NUM_PARTS,
};
enum _mpu_err {
MPU_SUCCESS = 0,
MPU_FAIL = 1,
MPU_READ_FAIL = 2,
MPU_WRITE_FAIL = 3,
};
/* Gyro Full Scale Range Enum */
enum inv_icm20602_gyro_fsr_e {
ICM20602_GYRO_FSR_250DPS = 0,
ICM20602_GYRO_FSR_500DPS,
ICM20602_GYRO_FSR_1000DPS,
ICM20602_GYRO_FSR_2000DPS,
ICM20602_GYRO_FSR_NUM,
};
/* Accelerometor Full Scale Range Enum */
enum inv_icm20602_acc_fsr_e {
ICM20602_ACC_FSR_2G = 0,
ICM20602_ACC_FSR_4G,
ICM20602_ACC_FSR_8G,
ICM20602_ACC_FSR_16G,
ICM20602_ACC_FSR_NUM,
};
/* scan element definition */
enum inv_icm20602_scan {
INV_ICM20602_SCAN_ACCL_X,
INV_ICM20602_SCAN_ACCL_Y,
INV_ICM20602_SCAN_ACCL_Z,
INV_ICM20602_SCAN_GYRO_X,
INV_ICM20602_SCAN_GYRO_Y,
INV_ICM20602_SCAN_GYRO_Z,
INV_ICM20602_SCAN_TEMP,
INV_ICM20602_SCAN_TIMESTAMP,
};
/* this is for CONFIGURATION reg bit[2:0] DLFP_CFG */
enum inv_icm20602_gyro_temp_lpf_e {
INV_ICM20602_GLFP_250HZ = 0, /* 8KHz */
INV_ICM20602_GYRO_LFP_176HZ, /* 1KHz */
INV_ICM20602_GYRO_LFP_92HZ,
INV_ICM20602_GYRO_LFP_41HZ,
INV_ICM20602_GYRO_LFP_20HZ,
INV_ICM20602_GYRO_LFP_10HZ,
INV_ICM20602_GYRO_LFP_5HZ,
INV_ICM20602_GYRO_LFP_NUM,
};
enum inv_icm20602_gyro_sample_rate_e {
ICM20602_SAMPLE_RATE_100HZ = 100,
ICM20602_SAMPLE_RATE_200HZ = 200,
ICM20602_SAMPLE_RATE_500HZ = 500,
ICM20602_SAMPLE_RATE_1000HZ = 1000,
};
/* this is for ACCEL CONFIGURATION 2 reg */
enum inv_icm20602_acc_lpf_e {
ICM20602_ACCLFP_218 = 1,
ICM20602_ACCLFP_99,
ICM20602_ACCLFP_44,
ICM20602_ACCLFP_21,
ICM20602_ACCLFP_10,
ICM20602_ACCLFP_5,
ICM20602_ACCLFP_420_NOLPF,
ICM20602_ACCLPF_NUM = 7,
};
/* IIO attribute address */
enum INV_ICM20602_IIO_ATTR_ADDR {
ATTR_ICM20602_GYRO_MATRIX,
ATTR_ICM20602_ACCL_MATRIX,
};
/* this is for GYRO CONFIGURATION reg */
enum inv_icm20602_fs_e {
INV_ICM20602_FS_250DPS = 0,
INV_ICM20602_FS_500DPS,
INV_ICM20602_FS_1000DPS,
INV_ICM20602_FS_2000DPS,
NUM_ICM20602_FS,
};
enum inv_icm20602_clock_sel_e {
INV_ICM20602_CLK_INTERNAL = 0,
INV_ICM20602_CLK_PLL,
INV_NUM_CLK,
};
enum inv_icm20602_spi_freq {
MPU_SPI_FREQUENCY_1MHZ = 960000UL,
MPU_SPI_FREQUENCY_5MHZ = 4800000UL,
MPU_SPI_FREQUENCY_8MHZ = 8000000UL,
MPU_SPI_FREQUENCY_10MHZ = 10000000UL,
MPU_SPI_FREQUENCY_15MHZ = 15000000UL,
MPU_SPI_FREQUENCY_20MHZ = 20000000UL,
};
#define MPU_SPI_BUF_LEN 512
#define ICM20602_DEV_NAME "icm20602_iio"
struct inv_icm20602_platform_data {
__s8 orientation[9];
};
struct X_Y_Z {
u8 X;
u8 Y;
u8 Z;
};
enum RAW_TYPE {
ACCEL = 1,
GYRO = 2,
TEMP = 4,
};
struct icm20602_user_config {
enum inv_icm20602_gyro_temp_lpf_e gyro_lpf;
enum inv_icm20602_gyro_fsr_e gyro_fsr;
struct X_Y_Z gyro_self_test;
enum inv_icm20602_acc_lpf_e acc_lpf;
enum inv_icm20602_acc_fsr_e acc_fsr;
struct X_Y_Z acc_self_test;
uint32_t gyro_accel_sample_rate;
uint32_t user_fps_in_ms;
bool fifo_enabled;
uint16_t fifo_waterlevel;
struct X_Y_Z wake_on_motion;
};
enum inv_icm20602_interface {
ICM20602_I2C = 0,
ICM20602_SPI
};
/*
* struct inv_icm20602_state - Driver state variables.
* @TIMESTAMP_FIFO_SIZE: fifo size for timestamp.
* @trig: IIO trigger.
* @chip_config: Cached attribute information.
* @reg: Map of important registers.
* @hw: Other hardware-specific information.
* @chip_type: chip type.
* @time_stamp_lock: spin lock to time stamp.
* @spi: spi devices
* @plat_data: platform data.
* @timestamps: kfifo queue to store time stamp.
*/
struct inv_icm20602_state {
#define TIMESTAMP_FIFO_SIZE 32
enum inv_icm20602_interface interface;
struct iio_trigger *trig;
const struct inv_icm20602_reg_map *reg;
struct icm20602_user_config *config;
spinlock_t time_stamp_lock;
struct spi_device *spi;
struct i2c_client *client;
u8 fifo_packet_size;
int fifo_cnt_threshold;
char *buf;
struct struct_icm20602_data *data_push;
enum inv_devices chip_type;
int gpio;
DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
};
struct struct_icm20602_raw_data {
u8 ACCEL_XOUT_H;
u8 ACCEL_XOUT_L;
u8 ACCEL_YOUT_H;
u8 ACCEL_YOUT_L;
u8 ACCEL_ZOUT_H;
u8 ACCEL_ZOUT_L;
u8 TEMP_OUT_H;
u8 TEMP_OUT_L;
u8 GYRO_XOUT_H;
u8 GYRO_XOUT_L;
u8 GYRO_YOUT_H;
u8 GYRO_YOUT_L;
u8 GYRO_ZOUT_H;
u8 GYRO_ZOUT_L;
};
struct struct_icm20602_real_data {
u16 ACCEL_XOUT;
u16 ACCEL_YOUT;
u16 ACCEL_ZOUT;
u16 GYRO_XOUT;
u16 GYRO_YOUT;
u16 GYRO_ZOUT;
u16 TEMP_OUT;
};
struct struct_icm20602_data {
s64 timestamps;
u8 *raw_data;
};
extern struct iio_trigger *inv_trig;
irqreturn_t inv_icm20602_irq_handler(int irq, void *p);
irqreturn_t inv_icm20602_read_fifo_fn(int irq, void *p);
int inv_icm20602_probe_trigger(struct iio_dev *indio_dev);
void inv_icm20602_remove_trigger(struct inv_icm20602_state *st);
int inv_icm20602_validate_trigger(struct iio_dev *indio_dev,
struct iio_trigger *trig);
int icm20602_int_status(struct inv_icm20602_state *st, u8 *int_status);
int icm20602_int_wm_status(struct inv_icm20602_state *st, u8 *int_status);
int icm20602_reset_fifo(struct inv_icm20602_state *st);
int icm20602_fifo_count(struct inv_icm20602_state *st, u16 *fifo_count);
int icm20602_read_raw(struct inv_icm20602_state *st,
struct struct_icm20602_real_data *real_data, uint32_t type);
int icm20602_init_reg_map(void);
int icm20602_init_device(struct inv_icm20602_state *st);
int icm20602_detect(struct inv_icm20602_state *st);
int icm20602_read_fifo(struct inv_icm20602_state *st,
void *buf, const int size);
int icm20602_start_fifo(struct inv_icm20602_state *st);
int icm20602_stop_fifo(struct inv_icm20602_state *st);
bool icm20602_self_test(struct inv_icm20602_state *st);
#endif