blob: 2b49b7777b2940f0eaa79dbfaecd946555d2c2f8 [file] [log] [blame]
/* CWMCU.h - header file for CyWee digital 3-axis gyroscope
*
* Copyright (C) 2010 CyWee Group Ltd.
* Author: Joe Wei <joewei@cywee.com>
*
* 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 __CWMCUSENSOR_H__
#define __CWMCUSENSOR_H__
#include <linux/ioctl.h>
#include "SensorSupport.h"
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/irq_work.h>
#include <linux/ioctl.h>
#include <sensors_io.h>
#include <linux/i2c.h>
#define CWMCU_I2C_NAME "CwMcuSensor"
#define CWMCU_SPI_NAME "CwMcuSensor"
#define LOG_TAG_HAL "CwHal"
#define LOG_TAG_KERNEL "CwKernel"
#define LOG_TAG_MCU "CwMcu"
/* turn on gpio interrupt if defined */
#define CWM_USE_IRQ_WORK
//#define CWM_USE_DELAY_WORK
#define CWM_USE_ERROR_HANDLE_WORK
#define CWMCU_MUTEX
#define CWM_USE_TIME_SYNC_WORK
#define CMD_BUFFER_SIZE 16
#define SYNC_TIME_DELAY_MS (60000)
enum SCAN_status {
CW_SCAN_ID = 0,
CW_SCAN_X,
CW_SCAN_Y,
CW_SCAN_Z,
CW_SCAN_XX,
CW_SCAN_YY,
CW_SCAN_ZZ,
CW_SCAN_TIMESTAMP,
};
enum MCU_mode {
CW_NORMAL = 0x00,
CW_SLEEP,
CW_NO_SLEEP,
CW_BOOT
};
/* power manager status */
typedef enum {
SWITCH_POWER_ENABLE = 0,
SWITCH_POWER_DELAY,
SWITCH_POWER_BATCH,
SWITCH_POWER_FLUSH,
SWITCH_POWER_NORMAL,
SWITCH_POWER_CALIB,
SWITCH_POWER_INTERRUPT,
SWITCH_POWER_POLLING,
SWITCH_POWER_PROBE,
SWITCH_POWER_SHUTDOWN,
SWITCH_POWER_LOG,
SWITCH_POWER_FIRMWARE_COMMAND,
SWITCH_POWER_VERSION,
SWITCH_POWER_TIME,
SWITCH_POWER_SYS,
SWITCH_POWER_MCU_GPIO
} SWITCH_POWER_ID;
typedef enum {
ERR_TASK_BLOCK = -10,
SEND_QUEUE_FULL = -9,
DRIVER_CHECK_CHIP_ID_FAIL = -8,
DRIVER_ENABLE_FAIL = -7,
DRIVER_DISABLE_FAIL = -6,
DRIVER_GETDATA_FAIL = -5,
I2C_FAIL = -4,
DRIVER_NO_USE = -3,
SENSORS_NO_INITIAL = -2,
FAIL = -1,
NO_ERROR = 0,
NO_DATA = 1
} ERR_MSG;
/* interrupt status */
typedef enum {
IRQ_INIT = 0,
IRQ_DATA_READY = 1,
IRQ_GESTURE = 2,
IRQ_BATCH_TIMEOUT = 3,
IRQ_BATCH_FULL = 4,
IRQ_INFO = 5,
IRQ_CALIB = 6,
IRQ_ERROR = 7,
IRQ_INPUT = 8,
IRQ_HALL = 9,
IRQ_HRLOG = 10,
IRQ_MAX_SIZE
} IRQ_STATUS_LIST;
typedef enum {
KERNEL_NON =
0, KERNEL_PROBE, KERNEL_SUSPEND, KERNEL_RESUME, KERNEL_SHUTDOWN
} KERNEL_STATUS;
typedef enum {
CALIB_TYPE_NON = 0,
CALIB_TYPE_DEFAULT = 1,
CALIB_TYPE_SELFTEST = 2,
CALIB_TYPE_SENSORS_ENABLE = 3,
CALIB_TYPE_SENSORS_DISABLE = 4,
CALIB_TYPE_CHIP_ID = 5,
} CALIBRATOR_TYPE;
typedef enum {
CALIB_STATUS_OUT_OF_RANGE = -2,
CALIB_STATUS_FAIL = -1,
CALIB_STATUS_NON = 0,
CALIB_STATUS_INPROCESS = 1,
CALIB_STATUS_PASS = 2,
} CALIBRATOR_STATUS;
typedef enum {
D_IRQ = 0,
D_IIO_DATA = 1,
D_EN = 2,
D_CALIB = 3,
D_DELAY_WQ = 4,
} DEBUG_E;
enum LOGCAT_STATUS {
EVENT_COUNT = 1,
EVENT_DATA
};
typedef enum {
SYSCMD = 0,
SYSINFO = 1,
ACCESSORYINFO,
GPSINFO,
WIFIINFO,
HEALTHINFO,
TIMEINFO,
} INFO_Type;
/* calibrator command format */
/*
CALIB_EN:
cmd/id/type/
CALIB_CHECK_STATUS:
CALIB_DATA_WRITE:
CALIB_DATA_READ:
CALIB_FLASH_WRITE:
CALIB_FLASH_READ:
cmd/id/
Acc/Gyro flow:
echo CALIB_EN/(ACCELERATION or GYRO)/CALIB_TYPE_DEFAULT > calibrator_cmd
echo CALIB_CHECK_STATUS/(ACCELERATION or GYRO)/CALIB_TYPE_DEFAULT > calibrator_cmd
do{
cat calibrator_data
data format:
[0] i2c error code
[1] calibrator status
}while(calibrator status != CALIB_STATUS_INPROCESS);
if(status == CALIB_STATUS_PASS)
echo CALIB_DATA_READ/(ACCELERATION or GYRO) > calibrator_cmd
cat calibrator_data
data format:
[0] i2c error code
[1:4] (int)X bias
[5:8] (int)Y bias
[9:12] (int)Z bias
If Mcu reset or system reboot: need reload calibrator data to MCU
echo CALIB_DATA_WRITE/(ACCELERATION or GYRO) > calibrator_cmd
echo [0:29] > calibrator_data
data format:
[0:3] (int)X bias
[4:7] (int)Y bias
[8:11] (int)Z bias
Mag flow:
When system boot up or MCU reset, reload data to MCU
echo CALIB_DATA_WRITE/MAGNETIC > calibrator_cmd
echo [0:29] > calibrator_data
data format:
[0:29] mag private data
When sensors disable need save MCU mag calibrator data to system
echo CALIB_DATA_READ/MAGNETIC > calibrator_cmd
cat calibrator_data
data format:
[0] i2c error code
[1:30] mag private data
Proximity flow:
echo CALIB_EN/PROXIMITY/CALIB_TYPE_SENSORS_ENABLE > calibrator_cmd
echo CALIB_DATA_READ/PROXIMITY > calibrator_cmd
while(1)
cat calibrator_data
data format:
[0] i2c error code
[1:4]light bias(not use)
[5:8](int) is Hight threshold to check sensors is near
[9:12](int) is low threshold to check sensors is far
[13:16](int) Sensors current raw data
if calibrator successful:
echo CALIB_DATA_WRITE/PROXIMITY > calibrator_cmd
echo [0:29] > calibrator_data
data format:
[0:3]light bias(not use)
[4:7](int) is Hight threshold to check sensors is near
[8:11](int) is low threshold to check sensors is far
disable sensors
echo CALIB_EN/PROXIMITY/CALIB_TYPE_SENSORS_DISABLE > calibrator_cmd
*/
typedef enum {
CALIB_EN = 0,
CALIB_CHECK_STATUS,
CALIB_DATA_WRITE,
CALIB_DATA_READ,
CALIB_FLASH_WRITE,
CALIB_FLASH_READ,
CALIB_GET_SEN_DATA, //X:[0:3];Z:[4:7];Z:[8:11]; data format: android format * 10000
CALIB_GET_ALL_CALIB_STATUS,
CALIB_GET_ALL_SELFTEST_STATUS,
CALIB_EN_SPECIAL_SENSOR,
CALIB_CHECK_SPECIAL_SENSOR_STATUS,
CALIB_FLASH_ERASE,
} CALIBRATOR_CMD;
/* firmware update command */
typedef enum {
CHANGE_TO_BOOTLOADER_MODE = 1,
CHANGE_TO_NORMAL_MODE = 5,
CHECK_FIRMWAVE_VERSION,
SET_DEBUG_LOG,
SET_SYSTEM_COMMAND,
SET_SENSORS_POSITION,
SHOW_LOG_INFO,
GET_FWPROJECT_ID,
MCU_RESET,
MCU_SET_GPIO_INPUT = 20,
MCU_SET_GPIO_OUTPUT = 21,
MCU_SET_GPIO_CONTROL = 22,
MCU_SET_GPIO_CLEAN = 23,
CMD_CALIBRATOR = 30,
CMD_SELF_TEST = 31,
} FIRMWARE_CMD;
typedef enum {
NonSystemComand = 0, WatchDogReset = 1, SystemNoSleep =
2, SystemCommandIndexEnd
} SYSTEM_COMMAND_INDEX;
typedef enum {
//5Byte: 0:handle;1:id;2:Rate;[3:4]:timeout ms;
RegMapW_SetEnable = 0x01,
//5Byte: 0:handle;1:id;2:Rate;[3:4]:timeout ms;
RegMapW_SetDisable = 0x02,
//2Byte: 0:handle;1:id;
RegMapW_SetFlush = 0x04,
//16Byte: enable list;
RegMapR_GetHostEnableList = 0x05,
/*-- For Internal user used --*/
//8Byte: enable list;
RegMapR_GetInternalEnableList = 0x06,
// The register of report the sensor/gesture data
RegMapR_GetSensorData = 0x07,
// Report the gesture data to Host(Android)
RegMapW_ReportSensorToHost = 0x08,
// Set and Get HW sensor setting
RegMapW_SetHWSensorSetting = 0x09,
// Send the enable request for customer algorithm
RegMapR_GetCustomAlgoEnable = 0x0B,
// Send the disable request for customer algorithm
RegMapR_GetCustomAlgoDisable = 0x0C,
/*----------------------------*/
//4Byte
RegMapR_ErrorCode = 0x0E,
//2Byte(uint16_t)
RegMapR_InterruptStatus = 0x0F,
/**
* 2byte
* byte 0: sensors id
* byte 1: position
*/
RegMapW_SetSensorAxisReference = 0x1F,
/**
* 2byte
* count
* byte 0: count L
* byte 1: count H
*
* 9byte
* event
* byte 0: sensors id
* byte 1: sensors X L
* byte 2: sensors X H
* byte 3: sensors Y L
* byte 4: sensors Y H
* byte 5: sensors Z L
* byte 6: sensors Z H
* byte 7: timestamp L
* byte 8: timestamp H
*/
RegMapR_StreamCount = 0x20,
RegMapR_StreamEvent = 0x21,
RegMapR_BatchCount = 0x22,
RegMapR_BatchEvent = 0x23,
/**
* 4byte
* byte [0]:Hall0 Sensor Near[0] Far[1]
* byte [1]:Hall0 Sensor Status
* byte [2]:Hall1 Sensor Near[0] Far[1]
* byte [3]:Hall1 Sensor Status
*/
RegMapR_HallStatus = 0x2C,
/**
* 1byte
* count
*
* 9byte
* byte 0: sensors id
* byte 1: Handle
* [byte 2:byte 8] data
*/
RegMapR_GestureCount = 0x24,
RegMapR_GestureEvent = 0x25,
/**
* 2byte
* count
*
* 30byte
* Log
*/
RegMapR_SystemInfoMsgCount = 0x26,
RegMapR_SystemInfoMsgEvent = 0x27,
/**
* Warming message
* 2byte
* count
*
* 30byte
* Log
*/
RegMapR_WarningMsgCount = 0x28,
RegMapR_WarningMsgEvent = 0x29,
/**
* Log message
* 2byte
* count
*
* 128
* Log messagebyte
* Log
*/
RegMapR_LogMsgCount = 0x2A,
RegMapR_LogMsgEvent = 0x2B,
/**
* 2byte
* byte 0: Sensors Id
* byte 1: Sensors Type
*
* wbyte
* Calibrator Status
* byte 0: Sensors Id
* byte 1: Sensors Status
*/
RegMapW_CalibratorCmd = 0x40,
RegMapW_CalibratorData = 0x41,
RegMapR_CalibratorData = 0x43,
/**
* 64byte
*/
RegMapR_MagSpecialData = 0x44,
/**
* 1byte
*/
RegMapW_SetSystemCommand = 0x5A,
RegMapW_SetHostStatus = 0x5B,
/**
* 30byte
*/
RegMapW_SetSystemMsg = 0x5C,
RegMapR_GetSystemMsg = 0x5D,
RegMapR_GetAccelerationRawData = 0x60,
RegMapR_GetMagneticRawData = 0x61,
RegMapR_GetGyroRawData = 0x62,
RegMapR_GetLightRawData = 0x63,
RegMapR_GetProximityRawData = 0x64,
RegMapR_GetRawData5 = 0x65,
RegMapR_GetRawData6 = 0x66,
RegMapR_GetRawData7 = 0x67,
RegMapR_GetRawData8 = 0x68,
RegMapR_GetRawData9 = 0x69,
/**
* 4byte
* data[0] = BuildSubVersion;
* data[1] = BuildVersion;
* data[2] = BuildDay;
* data[3] = BuildMonth;
*/
RegMapR_GetFWVersion = 0x80,
RegMapR_GetSystemTimestamp = 0x81,
/**
* 64byte
* data
*/
RegMapR_GetProjectID = 0x82,
/*Project ID for function available check */
RegMapR_GetCountOfRegID = 0x83,
RegMapR_GetReadRegTableSetting = 0x84,
RegMapR_GetWriteRegTableSetting = 0x85,
RegMapW_SetUARTDebugList = 0x86,
RegMapR_GetLibVersion = 0x87,
/**
* 2byte
* data
* 0:0x43 1:0x57
*/
RegMapR_ChipId = 0x88,
/*
Adding by Jack Tsai 2016/2/2
*/
RegMapR_hrLog_Count = 0x8B,
RegMapR_hrLog_Event = 0x8C,
/*
request time sync event from sensor hub 2017/10/17
*/
RegMapR_ReqTimeSyncEvt = 0x92,
/*Pass the regist table information to the
* host to detemine the read and write behavior
*/
CW_MAX_REG
} CwRegisterMapIndex;
typedef struct {
uint8_t cIndex;
uint8_t cObjLen;
} RegInformation;
struct CWMCU_SENSORS_INFO {
uint8_t en;
uint8_t mode;
uint8_t rate;
uint16_t timeout;
};
typedef struct {
uint8_t hw_id;
uint8_t deviceaddr;
uint8_t rate;
uint8_t mode; //default: MODE_BYPASS
uint8_t position;
uint8_t private_setting[4]; //private_setting[2] = INTERRUPT_SETTING
} SensorsInit_T;
#define CWMCU_NODATA 0xff
#define DPS_MAX (1 << (16 - 1))
/* GPIO for MCU control */
#define QueueSystemInfoMsgSize 30
#define QueueSystemInfoMsgBuffSize QueueSystemInfoMsgSize*5
struct CWMCU_T {
struct i2c_client *client;
struct spi_device *spi;
struct regulator *vdd;
struct regulator *vcc_i2c;
struct workqueue_struct *driver_wq;
#ifdef CWM_USE_IRQ_WORK
struct work_struct work;
#endif
#ifdef CWM_USE_DELAY_WORK
struct delayed_work delay_work;
#endif
#ifdef CWM_USE_ERROR_HANDLE_WORK
struct delayed_work error_handle_work;
#endif
#ifdef CWM_USE_TIME_SYNC_WORK
struct delayed_work time_sync_work;
#endif
struct work_struct resume_work;
struct input_dev *input;
struct CWMCU_SENSORS_INFO
sensors_info[HANDLE_ID_END][SENSORS_ID_END];
SensorsInit_T hw_info[DRIVER_ID_END];
RegInformation *pReadRegInfo;
RegInformation *pWriteRegInfo;
u8 m_cReadRegCount;
u8 m_cWriteRegCount;
int mcu_mode;
uint8_t kernel_status;
uint8_t meg_status[31];
/* enable & batch list */
uint32_t enabled_list[HANDLE_ID_END];
uint32_t interrupt_status;
uint8_t calibratordata[DRIVER_ID_END][30];
uint8_t calibratorUpdate[DRIVER_ID_END];
uint8_t CalibratorStatus[DRIVER_ID_END];
uint8_t SelfTestStatus[DRIVER_ID_END];
/* Mcu site enable list */
/* power status */
volatile uint32_t power_on_list;
/* Calibrator status */
int cal_cmd;
int cal_type;
int cal_id;
/* gpio */
int irq_gpio;
int wakeup_gpio;
int reset_gpio;
int boot_gpio;
uint32_t debug_log;
int cmd;
uint32_t addr;
int len;
int adjust_len;
int mcu_slave_addr;
int firmware_update_status;
int cw_i2c_rw; /* r = 0 , w = 1 */
int cw_i2c_len;
uint8_t cw_i2c_data[300];
#ifdef CWM_USE_ERROR_HANDLE_WORK
int i2c_error_count;
int i2c_error_state;
#endif
s32 iio_data[6];
struct iio_dev *indio_dev;
struct irq_work iio_irq_work;
struct iio_trigger *trig;
atomic_t pseudo_irq_enable;
struct class *sensor_class;
struct device *sensor_dev;
struct notifier_block cw_pm_notifier;
atomic_t delay;
int wq_polling_time;
struct mutex mutex_lock;
unsigned char loge_buff[QueueSystemInfoMsgSize * 2];
unsigned char loge_buff_count;
uint8_t logcat_cmd;
/*Data for GPS and Health Info*/
uint8_t GPSData[40];
uint8_t HEALTHData[30];
uint8_t POSITIONData[3];
int mcu_status;
int mcu_init_count;
int mcu_suspend_flag;
int watch_orientation;
};
#define CW_INFO(fmt,arg...) pr_info("-CWMCU_INF- "fmt"\n",##arg)
#define CW_ERROR(fmt,arg...) pr_err("-CWMCU_ERR- "fmt"\n",##arg)
#define CW_DEBUG(fmt,arg...) pr_debug("-CWMCU_DBG- "fmt"\n",##arg)
extern int CWMCU_bus_register(void);
extern void CWMCU_bus_unregister(void);
extern int CWMCU_bus_write_serial(struct CWMCU_T *sensor, u8 * data,
int len);
extern int CWMCU_bus_read_serial(struct CWMCU_T *sensor, u8 * data,
int len);
extern int CWMCU_bus_read(struct CWMCU_T *sensor, u8 reg_addr, u8 * data,
u8 len);
extern int CWMCU_bus_write(struct CWMCU_T *sensor, u8 reg_addr, u8 * data,
u8 len);
extern void CWMCU_bus_init(void *bus_dev);
extern int CWMCU_probe(struct i2c_client *client);
extern void CWMCU_shutdown(struct CWMCU_T *sensor);
extern void CWMCU_suspend(struct CWMCU_T *sensor);
extern void CWMCU_resume(struct CWMCU_T *sensor);
extern void factory_active_sensor(int sensor_id, int enabled);
extern int factory_data_read(int sensor_id, int data_event[]);
extern int factory_set_calibrator_data(int sensor_id,
SENSOR_DATA * cali_data);
extern void factory_clear_calibrator_data(struct CWMCU_T *sensor,
int sensor_id);
extern void factory_get_calibrator_data(int sensor_id,
SENSOR_DATA * cali_data);
extern void factory_set_mcu_calibration_data(int sensor_id);
extern void init_factory_node(void);
extern int spi_rw_bytes_serial(u8 * wbuf, u8 * rbuf, u8 len);
extern int CWMCU_system_suspend(void);
extern void CWMCU_system_resume(void);
#ifdef __KERNEL__
#endif /* __KERNEL */
#endif /* __CWMCUSENSOR_H__ */