1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved. 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #ifndef __SSP_SENSORHUB_H__ 7*4882a593Smuzhiyun #define __SSP_SENSORHUB_H__ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <linux/delay.h> 10*4882a593Smuzhiyun #include <linux/gpio/consumer.h> 11*4882a593Smuzhiyun #include <linux/iio/common/ssp_sensors.h> 12*4882a593Smuzhiyun #include <linux/iio/iio.h> 13*4882a593Smuzhiyun #include <linux/spi/spi.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #define SSP_DEVICE_ID 0x55 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #ifdef SSP_DBG 18*4882a593Smuzhiyun #define ssp_dbg(format, ...) pr_info("[SSP] "format, ##__VA_ARGS__) 19*4882a593Smuzhiyun #else 20*4882a593Smuzhiyun #define ssp_dbg(format, ...) 21*4882a593Smuzhiyun #endif 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #define SSP_SW_RESET_TIME 3000 24*4882a593Smuzhiyun /* Sensor polling in ms */ 25*4882a593Smuzhiyun #define SSP_DEFAULT_POLLING_DELAY 200 26*4882a593Smuzhiyun #define SSP_DEFAULT_RETRIES 3 27*4882a593Smuzhiyun #define SSP_DATA_PACKET_SIZE 960 28*4882a593Smuzhiyun #define SSP_HEADER_BUFFER_SIZE 4 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun enum { 31*4882a593Smuzhiyun SSP_KERNEL_BINARY = 0, 32*4882a593Smuzhiyun SSP_KERNEL_CRASHED_BINARY, 33*4882a593Smuzhiyun }; 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun enum { 36*4882a593Smuzhiyun SSP_INITIALIZATION_STATE = 0, 37*4882a593Smuzhiyun SSP_NO_SENSOR_STATE, 38*4882a593Smuzhiyun SSP_ADD_SENSOR_STATE, 39*4882a593Smuzhiyun SSP_RUNNING_SENSOR_STATE, 40*4882a593Smuzhiyun }; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* Firmware download STATE */ 43*4882a593Smuzhiyun enum { 44*4882a593Smuzhiyun SSP_FW_DL_STATE_FAIL = -1, 45*4882a593Smuzhiyun SSP_FW_DL_STATE_NONE = 0, 46*4882a593Smuzhiyun SSP_FW_DL_STATE_NEED_TO_SCHEDULE, 47*4882a593Smuzhiyun SSP_FW_DL_STATE_SCHEDULED, 48*4882a593Smuzhiyun SSP_FW_DL_STATE_DOWNLOADING, 49*4882a593Smuzhiyun SSP_FW_DL_STATE_SYNC, 50*4882a593Smuzhiyun SSP_FW_DL_STATE_DONE, 51*4882a593Smuzhiyun }; 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun #define SSP_INVALID_REVISION 99999 54*4882a593Smuzhiyun #define SSP_INVALID_REVISION2 0xffffff 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun /* AP -> SSP Instruction */ 57*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD 0xa1 58*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_BYPASS_SENSOR_RM 0xa2 59*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_REMOVE_ALL 0xa3 60*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_CHANGE_DELAY 0xa4 61*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_LIBRARY_ADD 0xb1 62*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_LIBRARY_REMOVE 0xb2 63*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_LIB_NOTI 0xb4 64*4882a593Smuzhiyun #define SSP_MSG2SSP_INST_LIB_DATA 0xc1 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_SET_GYRO_CAL 0xcd 67*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_SET_ACCEL_CAL 0xce 68*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_SHUTDOWN 0xd0 69*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_WAKEUP 0xd1 70*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_SLEEP 0xd2 71*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_RESUME 0xd3 72*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_SUSPEND 0xd4 73*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_RESET 0xd5 74*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_POW_CONNECTED 0xd6 75*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_STATUS_POW_DISCONNECTED 0xd7 76*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE 0xda 77*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_SET_DUMPMODE 0xdb 78*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_DUMP_CHECK 0xdc 79*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_BATCH_FLUSH 0xdd 80*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_BATCH_COUNT 0xdf 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_WHOAMI 0x0f 83*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_FIRMWARE_REV 0xf0 84*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SENSOR_FORMATION 0xf1 85*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SENSOR_PROXTHRESHOLD 0xf2 86*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SENSOR_BARCODE_EMUL 0xf3 87*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SENSOR_SCANNING 0xf4 88*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SET_MAGNETIC_HWOFFSET 0xf5 89*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_GET_MAGNETIC_HWOFFSET 0xf6 90*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SENSOR_GESTURE_CURRENT 0xf7 91*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_GET_THERM 0xf8 92*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_GET_BIG_DATA 0xf9 93*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SET_BIG_DATA 0xfa 94*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_START_BIG_DATA 0xfb 95*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX 0xfd 96*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_SENSOR_TILT 0xea 97*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_SET_TIME 0xfe 98*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_MCU_GET_TIME 0xff 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun #define SSP_MSG2SSP_AP_FUSEROM 0x01 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* voice data */ 103*4882a593Smuzhiyun #define SSP_TYPE_WAKE_UP_VOICE_SERVICE 0x01 104*4882a593Smuzhiyun #define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_AM 0x01 105*4882a593Smuzhiyun #define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_GRAMMER 0x02 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* Factory Test */ 108*4882a593Smuzhiyun #define SSP_ACCELEROMETER_FACTORY 0x80 109*4882a593Smuzhiyun #define SSP_GYROSCOPE_FACTORY 0x81 110*4882a593Smuzhiyun #define SSP_GEOMAGNETIC_FACTORY 0x82 111*4882a593Smuzhiyun #define SSP_PRESSURE_FACTORY 0x85 112*4882a593Smuzhiyun #define SSP_GESTURE_FACTORY 0x86 113*4882a593Smuzhiyun #define SSP_TEMPHUMIDITY_CRC_FACTORY 0x88 114*4882a593Smuzhiyun #define SSP_GYROSCOPE_TEMP_FACTORY 0x8a 115*4882a593Smuzhiyun #define SSP_GYROSCOPE_DPS_FACTORY 0x8b 116*4882a593Smuzhiyun #define SSP_MCU_FACTORY 0x8c 117*4882a593Smuzhiyun #define SSP_MCU_SLEEP_FACTORY 0x8d 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* SSP -> AP ACK about write CMD */ 120*4882a593Smuzhiyun #define SSP_MSG_ACK 0x80 /* ACK from SSP to AP */ 121*4882a593Smuzhiyun #define SSP_MSG_NAK 0x70 /* NAK from SSP to AP */ 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun struct ssp_sensorhub_info { 124*4882a593Smuzhiyun char *fw_name; 125*4882a593Smuzhiyun char *fw_crashed_name; 126*4882a593Smuzhiyun unsigned int fw_rev; 127*4882a593Smuzhiyun const u8 * const mag_table; 128*4882a593Smuzhiyun const unsigned int mag_length; 129*4882a593Smuzhiyun }; 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /* ssp_msg options bit */ 132*4882a593Smuzhiyun #define SSP_RW 0 133*4882a593Smuzhiyun #define SSP_INDEX 3 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun #define SSP_AP2HUB_READ 0 136*4882a593Smuzhiyun #define SSP_AP2HUB_WRITE 1 137*4882a593Smuzhiyun #define SSP_HUB2AP_WRITE 2 138*4882a593Smuzhiyun #define SSP_AP2HUB_READY 3 139*4882a593Smuzhiyun #define SSP_AP2HUB_RETURN 4 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun /** 142*4882a593Smuzhiyun * struct ssp_data - ssp platformdata structure 143*4882a593Smuzhiyun * @spi: spi device 144*4882a593Smuzhiyun * @sensorhub_info: info about sensorhub board specific features 145*4882a593Smuzhiyun * @wdt_timer: watchdog timer 146*4882a593Smuzhiyun * @work_wdt: watchdog work 147*4882a593Smuzhiyun * @work_firmware: firmware upgrade work queue 148*4882a593Smuzhiyun * @work_refresh: refresh work queue for reset request from MCU 149*4882a593Smuzhiyun * @shut_down: shut down flag 150*4882a593Smuzhiyun * @mcu_dump_mode: mcu dump mode for debug 151*4882a593Smuzhiyun * @time_syncing: time syncing indication flag 152*4882a593Smuzhiyun * @timestamp: previous time in ns calculated for time syncing 153*4882a593Smuzhiyun * @check_status: status table for each sensor 154*4882a593Smuzhiyun * @com_fail_cnt: communication fail count 155*4882a593Smuzhiyun * @reset_cnt: reset count 156*4882a593Smuzhiyun * @timeout_cnt: timeout count 157*4882a593Smuzhiyun * @available_sensors: available sensors seen by sensorhub (bit array) 158*4882a593Smuzhiyun * @cur_firm_rev: cached current firmware revision 159*4882a593Smuzhiyun * @last_resume_state: last AP resume/suspend state used to handle the PM 160*4882a593Smuzhiyun * state of ssp 161*4882a593Smuzhiyun * @last_ap_state: (obsolete) sleep notification for MCU 162*4882a593Smuzhiyun * @sensor_enable: sensor enable mask 163*4882a593Smuzhiyun * @delay_buf: data acquisition intervals table 164*4882a593Smuzhiyun * @batch_latency_buf: yet unknown but existing in communication protocol 165*4882a593Smuzhiyun * @batch_opt_buf: yet unknown but existing in communication protocol 166*4882a593Smuzhiyun * @accel_position: yet unknown but existing in communication protocol 167*4882a593Smuzhiyun * @mag_position: yet unknown but existing in communication protocol 168*4882a593Smuzhiyun * @fw_dl_state: firmware download state 169*4882a593Smuzhiyun * @comm_lock: lock protecting the handshake 170*4882a593Smuzhiyun * @pending_lock: lock protecting pending list and completion 171*4882a593Smuzhiyun * @mcu_reset_gpiod: mcu reset line 172*4882a593Smuzhiyun * @ap_mcu_gpiod: ap to mcu gpio line 173*4882a593Smuzhiyun * @mcu_ap_gpiod: mcu to ap gpio line 174*4882a593Smuzhiyun * @pending_list: pending list for messages queued to be sent/read 175*4882a593Smuzhiyun * @sensor_devs: registered IIO devices table 176*4882a593Smuzhiyun * @enable_refcount: enable reference count for wdt (watchdog timer) 177*4882a593Smuzhiyun * @header_buffer: cache aligned buffer for packet header 178*4882a593Smuzhiyun */ 179*4882a593Smuzhiyun struct ssp_data { 180*4882a593Smuzhiyun struct spi_device *spi; 181*4882a593Smuzhiyun const struct ssp_sensorhub_info *sensorhub_info; 182*4882a593Smuzhiyun struct timer_list wdt_timer; 183*4882a593Smuzhiyun struct work_struct work_wdt; 184*4882a593Smuzhiyun struct delayed_work work_refresh; 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun bool shut_down; 187*4882a593Smuzhiyun bool mcu_dump_mode; 188*4882a593Smuzhiyun bool time_syncing; 189*4882a593Smuzhiyun int64_t timestamp; 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun int check_status[SSP_SENSOR_MAX]; 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun unsigned int com_fail_cnt; 194*4882a593Smuzhiyun unsigned int reset_cnt; 195*4882a593Smuzhiyun unsigned int timeout_cnt; 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun unsigned int available_sensors; 198*4882a593Smuzhiyun unsigned int cur_firm_rev; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun char last_resume_state; 201*4882a593Smuzhiyun char last_ap_state; 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun unsigned int sensor_enable; 204*4882a593Smuzhiyun u32 delay_buf[SSP_SENSOR_MAX]; 205*4882a593Smuzhiyun s32 batch_latency_buf[SSP_SENSOR_MAX]; 206*4882a593Smuzhiyun s8 batch_opt_buf[SSP_SENSOR_MAX]; 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun int accel_position; 209*4882a593Smuzhiyun int mag_position; 210*4882a593Smuzhiyun int fw_dl_state; 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun struct mutex comm_lock; 213*4882a593Smuzhiyun struct mutex pending_lock; 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun struct gpio_desc *mcu_reset_gpiod; 216*4882a593Smuzhiyun struct gpio_desc *ap_mcu_gpiod; 217*4882a593Smuzhiyun struct gpio_desc *mcu_ap_gpiod; 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun struct list_head pending_list; 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun struct iio_dev *sensor_devs[SSP_SENSOR_MAX]; 222*4882a593Smuzhiyun atomic_t enable_refcount; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)] 225*4882a593Smuzhiyun ____cacheline_aligned; 226*4882a593Smuzhiyun }; 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun void ssp_clean_pending_list(struct ssp_data *data); 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun int ssp_command(struct ssp_data *data, char command, int arg); 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type, 233*4882a593Smuzhiyun u8 *send_buf, u8 length); 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun int ssp_irq_msg(struct ssp_data *data); 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun int ssp_get_chipid(struct ssp_data *data); 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun int ssp_set_magnetic_matrix(struct ssp_data *data); 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data); 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun unsigned int ssp_get_firmware_rev(struct ssp_data *data); 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay); 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun #endif /* __SSP_SENSORHUB_H__ */ 248