1c942fddfSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 250dd64d5SKarol Wrona /* 350dd64d5SKarol Wrona * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved. 450dd64d5SKarol Wrona */ 550dd64d5SKarol Wrona 650dd64d5SKarol Wrona #ifndef __SSP_SENSORHUB_H__ 750dd64d5SKarol Wrona #define __SSP_SENSORHUB_H__ 850dd64d5SKarol Wrona 950dd64d5SKarol Wrona #include <linux/delay.h> 104cf01d6dSLinus Walleij #include <linux/gpio/consumer.h> 1150dd64d5SKarol Wrona #include <linux/iio/common/ssp_sensors.h> 1250dd64d5SKarol Wrona #include <linux/iio/iio.h> 1350dd64d5SKarol Wrona #include <linux/spi/spi.h> 1450dd64d5SKarol Wrona 1550dd64d5SKarol Wrona #define SSP_DEVICE_ID 0x55 1650dd64d5SKarol Wrona 1750dd64d5SKarol Wrona #ifdef SSP_DBG 1850dd64d5SKarol Wrona #define ssp_dbg(format, ...) pr_info("[SSP] "format, ##__VA_ARGS__) 1950dd64d5SKarol Wrona #else 2050dd64d5SKarol Wrona #define ssp_dbg(format, ...) 2150dd64d5SKarol Wrona #endif 2250dd64d5SKarol Wrona 2350dd64d5SKarol Wrona #define SSP_SW_RESET_TIME 3000 2450dd64d5SKarol Wrona /* Sensor polling in ms */ 2550dd64d5SKarol Wrona #define SSP_DEFAULT_POLLING_DELAY 200 2650dd64d5SKarol Wrona #define SSP_DEFAULT_RETRIES 3 2750dd64d5SKarol Wrona #define SSP_DATA_PACKET_SIZE 960 2850dd64d5SKarol Wrona #define SSP_HEADER_BUFFER_SIZE 4 2950dd64d5SKarol Wrona 3050dd64d5SKarol Wrona enum { 3150dd64d5SKarol Wrona SSP_KERNEL_BINARY = 0, 3250dd64d5SKarol Wrona SSP_KERNEL_CRASHED_BINARY, 3350dd64d5SKarol Wrona }; 3450dd64d5SKarol Wrona 3550dd64d5SKarol Wrona enum { 3650dd64d5SKarol Wrona SSP_INITIALIZATION_STATE = 0, 3750dd64d5SKarol Wrona SSP_NO_SENSOR_STATE, 3850dd64d5SKarol Wrona SSP_ADD_SENSOR_STATE, 3950dd64d5SKarol Wrona SSP_RUNNING_SENSOR_STATE, 4050dd64d5SKarol Wrona }; 4150dd64d5SKarol Wrona 4250dd64d5SKarol Wrona /* Firmware download STATE */ 4350dd64d5SKarol Wrona enum { 4450dd64d5SKarol Wrona SSP_FW_DL_STATE_FAIL = -1, 4550dd64d5SKarol Wrona SSP_FW_DL_STATE_NONE = 0, 4650dd64d5SKarol Wrona SSP_FW_DL_STATE_NEED_TO_SCHEDULE, 4750dd64d5SKarol Wrona SSP_FW_DL_STATE_SCHEDULED, 4850dd64d5SKarol Wrona SSP_FW_DL_STATE_DOWNLOADING, 4950dd64d5SKarol Wrona SSP_FW_DL_STATE_SYNC, 5050dd64d5SKarol Wrona SSP_FW_DL_STATE_DONE, 5150dd64d5SKarol Wrona }; 5250dd64d5SKarol Wrona 5350dd64d5SKarol Wrona #define SSP_INVALID_REVISION 99999 5450dd64d5SKarol Wrona #define SSP_INVALID_REVISION2 0xffffff 5550dd64d5SKarol Wrona 5650dd64d5SKarol Wrona /* AP -> SSP Instruction */ 5750dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD 0xa1 5850dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_BYPASS_SENSOR_RM 0xa2 5950dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_REMOVE_ALL 0xa3 6050dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_CHANGE_DELAY 0xa4 6150dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_LIBRARY_ADD 0xb1 6250dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_LIBRARY_REMOVE 0xb2 6350dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_LIB_NOTI 0xb4 6450dd64d5SKarol Wrona #define SSP_MSG2SSP_INST_LIB_DATA 0xc1 6550dd64d5SKarol Wrona 6650dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_SET_GYRO_CAL 0xcd 6750dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_SET_ACCEL_CAL 0xce 6850dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_SHUTDOWN 0xd0 6950dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_WAKEUP 0xd1 7050dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_SLEEP 0xd2 7150dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_RESUME 0xd3 7250dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_SUSPEND 0xd4 7350dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_RESET 0xd5 7450dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_POW_CONNECTED 0xd6 7550dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_STATUS_POW_DISCONNECTED 0xd7 7650dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE 0xda 7750dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_SET_DUMPMODE 0xdb 7850dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_DUMP_CHECK 0xdc 7950dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_BATCH_FLUSH 0xdd 8050dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_BATCH_COUNT 0xdf 8150dd64d5SKarol Wrona 8250dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_WHOAMI 0x0f 8350dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_FIRMWARE_REV 0xf0 8450dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SENSOR_FORMATION 0xf1 8550dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SENSOR_PROXTHRESHOLD 0xf2 8650dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SENSOR_BARCODE_EMUL 0xf3 8750dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SENSOR_SCANNING 0xf4 8850dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SET_MAGNETIC_HWOFFSET 0xf5 8950dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_GET_MAGNETIC_HWOFFSET 0xf6 9050dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SENSOR_GESTURE_CURRENT 0xf7 9150dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_GET_THERM 0xf8 9250dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_GET_BIG_DATA 0xf9 9350dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SET_BIG_DATA 0xfa 9450dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_START_BIG_DATA 0xfb 9550dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX 0xfd 9650dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_SENSOR_TILT 0xea 9750dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_SET_TIME 0xfe 9850dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_MCU_GET_TIME 0xff 9950dd64d5SKarol Wrona 10050dd64d5SKarol Wrona #define SSP_MSG2SSP_AP_FUSEROM 0x01 10150dd64d5SKarol Wrona 10250dd64d5SKarol Wrona /* voice data */ 10350dd64d5SKarol Wrona #define SSP_TYPE_WAKE_UP_VOICE_SERVICE 0x01 10450dd64d5SKarol Wrona #define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_AM 0x01 10550dd64d5SKarol Wrona #define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_GRAMMER 0x02 10650dd64d5SKarol Wrona 10750dd64d5SKarol Wrona /* Factory Test */ 10850dd64d5SKarol Wrona #define SSP_ACCELEROMETER_FACTORY 0x80 10950dd64d5SKarol Wrona #define SSP_GYROSCOPE_FACTORY 0x81 11050dd64d5SKarol Wrona #define SSP_GEOMAGNETIC_FACTORY 0x82 11150dd64d5SKarol Wrona #define SSP_PRESSURE_FACTORY 0x85 11250dd64d5SKarol Wrona #define SSP_GESTURE_FACTORY 0x86 11350dd64d5SKarol Wrona #define SSP_TEMPHUMIDITY_CRC_FACTORY 0x88 11450dd64d5SKarol Wrona #define SSP_GYROSCOPE_TEMP_FACTORY 0x8a 11550dd64d5SKarol Wrona #define SSP_GYROSCOPE_DPS_FACTORY 0x8b 11650dd64d5SKarol Wrona #define SSP_MCU_FACTORY 0x8c 11750dd64d5SKarol Wrona #define SSP_MCU_SLEEP_FACTORY 0x8d 11850dd64d5SKarol Wrona 11950dd64d5SKarol Wrona /* SSP -> AP ACK about write CMD */ 12050dd64d5SKarol Wrona #define SSP_MSG_ACK 0x80 /* ACK from SSP to AP */ 12150dd64d5SKarol Wrona #define SSP_MSG_NAK 0x70 /* NAK from SSP to AP */ 12250dd64d5SKarol Wrona 12350dd64d5SKarol Wrona struct ssp_sensorhub_info { 12450dd64d5SKarol Wrona char *fw_name; 12550dd64d5SKarol Wrona char *fw_crashed_name; 12650dd64d5SKarol Wrona unsigned int fw_rev; 12750dd64d5SKarol Wrona const u8 * const mag_table; 12850dd64d5SKarol Wrona const unsigned int mag_length; 12950dd64d5SKarol Wrona }; 13050dd64d5SKarol Wrona 13150dd64d5SKarol Wrona /* ssp_msg options bit */ 13250dd64d5SKarol Wrona #define SSP_RW 0 13350dd64d5SKarol Wrona #define SSP_INDEX 3 13450dd64d5SKarol Wrona 13550dd64d5SKarol Wrona #define SSP_AP2HUB_READ 0 13650dd64d5SKarol Wrona #define SSP_AP2HUB_WRITE 1 13750dd64d5SKarol Wrona #define SSP_HUB2AP_WRITE 2 13850dd64d5SKarol Wrona #define SSP_AP2HUB_READY 3 13950dd64d5SKarol Wrona #define SSP_AP2HUB_RETURN 4 14050dd64d5SKarol Wrona 14150dd64d5SKarol Wrona /** 14250dd64d5SKarol Wrona * struct ssp_data - ssp platformdata structure 14350dd64d5SKarol Wrona * @spi: spi device 14450dd64d5SKarol Wrona * @sensorhub_info: info about sensorhub board specific features 14550dd64d5SKarol Wrona * @wdt_timer: watchdog timer 14650dd64d5SKarol Wrona * @work_wdt: watchdog work 14750dd64d5SKarol Wrona * @work_firmware: firmware upgrade work queue 14850dd64d5SKarol Wrona * @work_refresh: refresh work queue for reset request from MCU 14950dd64d5SKarol Wrona * @shut_down: shut down flag 15050dd64d5SKarol Wrona * @mcu_dump_mode: mcu dump mode for debug 15150dd64d5SKarol Wrona * @time_syncing: time syncing indication flag 15250dd64d5SKarol Wrona * @timestamp: previous time in ns calculated for time syncing 15350dd64d5SKarol Wrona * @check_status: status table for each sensor 15450dd64d5SKarol Wrona * @com_fail_cnt: communication fail count 15550dd64d5SKarol Wrona * @reset_cnt: reset count 15650dd64d5SKarol Wrona * @timeout_cnt: timeout count 15750dd64d5SKarol Wrona * @available_sensors: available sensors seen by sensorhub (bit array) 15850dd64d5SKarol Wrona * @cur_firm_rev: cached current firmware revision 15950dd64d5SKarol Wrona * @last_resume_state: last AP resume/suspend state used to handle the PM 16050dd64d5SKarol Wrona * state of ssp 16150dd64d5SKarol Wrona * @last_ap_state: (obsolete) sleep notification for MCU 16250dd64d5SKarol Wrona * @sensor_enable: sensor enable mask 16350dd64d5SKarol Wrona * @delay_buf: data acquisition intervals table 16450dd64d5SKarol Wrona * @batch_latency_buf: yet unknown but existing in communication protocol 16550dd64d5SKarol Wrona * @batch_opt_buf: yet unknown but existing in communication protocol 16650dd64d5SKarol Wrona * @accel_position: yet unknown but existing in communication protocol 16750dd64d5SKarol Wrona * @mag_position: yet unknown but existing in communication protocol 16850dd64d5SKarol Wrona * @fw_dl_state: firmware download state 16950dd64d5SKarol Wrona * @comm_lock: lock protecting the handshake 17050dd64d5SKarol Wrona * @pending_lock: lock protecting pending list and completion 1714cf01d6dSLinus Walleij * @mcu_reset_gpiod: mcu reset line 1724cf01d6dSLinus Walleij * @ap_mcu_gpiod: ap to mcu gpio line 1734cf01d6dSLinus Walleij * @mcu_ap_gpiod: mcu to ap gpio line 17450dd64d5SKarol Wrona * @pending_list: pending list for messages queued to be sent/read 17550dd64d5SKarol Wrona * @sensor_devs: registered IIO devices table 17650dd64d5SKarol Wrona * @enable_refcount: enable reference count for wdt (watchdog timer) 17750dd64d5SKarol Wrona * @header_buffer: cache aligned buffer for packet header 17850dd64d5SKarol Wrona */ 17950dd64d5SKarol Wrona struct ssp_data { 18050dd64d5SKarol Wrona struct spi_device *spi; 18113e6bac8SJulia Lawall const struct ssp_sensorhub_info *sensorhub_info; 18250dd64d5SKarol Wrona struct timer_list wdt_timer; 18350dd64d5SKarol Wrona struct work_struct work_wdt; 18450dd64d5SKarol Wrona struct delayed_work work_refresh; 18550dd64d5SKarol Wrona 18650dd64d5SKarol Wrona bool shut_down; 18750dd64d5SKarol Wrona bool mcu_dump_mode; 18850dd64d5SKarol Wrona bool time_syncing; 18950dd64d5SKarol Wrona int64_t timestamp; 19050dd64d5SKarol Wrona 19150dd64d5SKarol Wrona int check_status[SSP_SENSOR_MAX]; 19250dd64d5SKarol Wrona 19350dd64d5SKarol Wrona unsigned int com_fail_cnt; 19450dd64d5SKarol Wrona unsigned int reset_cnt; 19550dd64d5SKarol Wrona unsigned int timeout_cnt; 19650dd64d5SKarol Wrona 19750dd64d5SKarol Wrona unsigned int available_sensors; 19850dd64d5SKarol Wrona unsigned int cur_firm_rev; 19950dd64d5SKarol Wrona 20050dd64d5SKarol Wrona char last_resume_state; 20150dd64d5SKarol Wrona char last_ap_state; 20250dd64d5SKarol Wrona 20350dd64d5SKarol Wrona unsigned int sensor_enable; 20450dd64d5SKarol Wrona u32 delay_buf[SSP_SENSOR_MAX]; 20550dd64d5SKarol Wrona s32 batch_latency_buf[SSP_SENSOR_MAX]; 20650dd64d5SKarol Wrona s8 batch_opt_buf[SSP_SENSOR_MAX]; 20750dd64d5SKarol Wrona 20850dd64d5SKarol Wrona int accel_position; 20950dd64d5SKarol Wrona int mag_position; 21050dd64d5SKarol Wrona int fw_dl_state; 21150dd64d5SKarol Wrona 21250dd64d5SKarol Wrona struct mutex comm_lock; 21350dd64d5SKarol Wrona struct mutex pending_lock; 21450dd64d5SKarol Wrona 2154cf01d6dSLinus Walleij struct gpio_desc *mcu_reset_gpiod; 2164cf01d6dSLinus Walleij struct gpio_desc *ap_mcu_gpiod; 2174cf01d6dSLinus Walleij struct gpio_desc *mcu_ap_gpiod; 21850dd64d5SKarol Wrona 21950dd64d5SKarol Wrona struct list_head pending_list; 22050dd64d5SKarol Wrona 22150dd64d5SKarol Wrona struct iio_dev *sensor_devs[SSP_SENSOR_MAX]; 22250dd64d5SKarol Wrona atomic_t enable_refcount; 22350dd64d5SKarol Wrona 224*314d2b19SJonathan Cameron __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)] __aligned(IIO_DMA_MINALIGN); 22550dd64d5SKarol Wrona }; 22650dd64d5SKarol Wrona 22750dd64d5SKarol Wrona void ssp_clean_pending_list(struct ssp_data *data); 22850dd64d5SKarol Wrona 22950dd64d5SKarol Wrona int ssp_command(struct ssp_data *data, char command, int arg); 23050dd64d5SKarol Wrona 23150dd64d5SKarol Wrona int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type, 23250dd64d5SKarol Wrona u8 *send_buf, u8 length); 23350dd64d5SKarol Wrona 23450dd64d5SKarol Wrona int ssp_irq_msg(struct ssp_data *data); 23550dd64d5SKarol Wrona 23650dd64d5SKarol Wrona int ssp_get_chipid(struct ssp_data *data); 23750dd64d5SKarol Wrona 23850dd64d5SKarol Wrona int ssp_set_magnetic_matrix(struct ssp_data *data); 23950dd64d5SKarol Wrona 24050dd64d5SKarol Wrona unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data); 24150dd64d5SKarol Wrona 24250dd64d5SKarol Wrona unsigned int ssp_get_firmware_rev(struct ssp_data *data); 24350dd64d5SKarol Wrona 24450dd64d5SKarol Wrona int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay); 24550dd64d5SKarol Wrona 24650dd64d5SKarol Wrona #endif /* __SSP_SENSORHUB_H__ */ 247