162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __SSP_SENSORHUB_H__ 762306a36Sopenharmony_ci#define __SSP_SENSORHUB_H__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/delay.h> 1062306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 1162306a36Sopenharmony_ci#include <linux/iio/common/ssp_sensors.h> 1262306a36Sopenharmony_ci#include <linux/iio/iio.h> 1362306a36Sopenharmony_ci#include <linux/spi/spi.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define SSP_DEVICE_ID 0x55 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#ifdef SSP_DBG 1862306a36Sopenharmony_ci#define ssp_dbg(format, ...) pr_info("[SSP] "format, ##__VA_ARGS__) 1962306a36Sopenharmony_ci#else 2062306a36Sopenharmony_ci#define ssp_dbg(format, ...) 2162306a36Sopenharmony_ci#endif 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define SSP_SW_RESET_TIME 3000 2462306a36Sopenharmony_ci/* Sensor polling in ms */ 2562306a36Sopenharmony_ci#define SSP_DEFAULT_POLLING_DELAY 200 2662306a36Sopenharmony_ci#define SSP_DEFAULT_RETRIES 3 2762306a36Sopenharmony_ci#define SSP_DATA_PACKET_SIZE 960 2862306a36Sopenharmony_ci#define SSP_HEADER_BUFFER_SIZE 4 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cienum { 3162306a36Sopenharmony_ci SSP_KERNEL_BINARY = 0, 3262306a36Sopenharmony_ci SSP_KERNEL_CRASHED_BINARY, 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cienum { 3662306a36Sopenharmony_ci SSP_INITIALIZATION_STATE = 0, 3762306a36Sopenharmony_ci SSP_NO_SENSOR_STATE, 3862306a36Sopenharmony_ci SSP_ADD_SENSOR_STATE, 3962306a36Sopenharmony_ci SSP_RUNNING_SENSOR_STATE, 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* Firmware download STATE */ 4362306a36Sopenharmony_cienum { 4462306a36Sopenharmony_ci SSP_FW_DL_STATE_FAIL = -1, 4562306a36Sopenharmony_ci SSP_FW_DL_STATE_NONE = 0, 4662306a36Sopenharmony_ci SSP_FW_DL_STATE_NEED_TO_SCHEDULE, 4762306a36Sopenharmony_ci SSP_FW_DL_STATE_SCHEDULED, 4862306a36Sopenharmony_ci SSP_FW_DL_STATE_DOWNLOADING, 4962306a36Sopenharmony_ci SSP_FW_DL_STATE_SYNC, 5062306a36Sopenharmony_ci SSP_FW_DL_STATE_DONE, 5162306a36Sopenharmony_ci}; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define SSP_INVALID_REVISION 99999 5462306a36Sopenharmony_ci#define SSP_INVALID_REVISION2 0xffffff 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* AP -> SSP Instruction */ 5762306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD 0xa1 5862306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_BYPASS_SENSOR_RM 0xa2 5962306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_REMOVE_ALL 0xa3 6062306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_CHANGE_DELAY 0xa4 6162306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_LIBRARY_ADD 0xb1 6262306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_LIBRARY_REMOVE 0xb2 6362306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_LIB_NOTI 0xb4 6462306a36Sopenharmony_ci#define SSP_MSG2SSP_INST_LIB_DATA 0xc1 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_GYRO_CAL 0xcd 6762306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_ACCEL_CAL 0xce 6862306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_SHUTDOWN 0xd0 6962306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_WAKEUP 0xd1 7062306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_SLEEP 0xd2 7162306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_RESUME 0xd3 7262306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_SUSPEND 0xd4 7362306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_RESET 0xd5 7462306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_POW_CONNECTED 0xd6 7562306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_POW_DISCONNECTED 0xd7 7662306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE 0xda 7762306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_DUMPMODE 0xdb 7862306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_DUMP_CHECK 0xdc 7962306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_BATCH_FLUSH 0xdd 8062306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_BATCH_COUNT 0xdf 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_WHOAMI 0x0f 8362306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_FIRMWARE_REV 0xf0 8462306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_FORMATION 0xf1 8562306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_PROXTHRESHOLD 0xf2 8662306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_BARCODE_EMUL 0xf3 8762306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_SCANNING 0xf4 8862306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SET_MAGNETIC_HWOFFSET 0xf5 8962306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_GET_MAGNETIC_HWOFFSET 0xf6 9062306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_GESTURE_CURRENT 0xf7 9162306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_GET_THERM 0xf8 9262306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_GET_BIG_DATA 0xf9 9362306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SET_BIG_DATA 0xfa 9462306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_START_BIG_DATA 0xfb 9562306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX 0xfd 9662306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_TILT 0xea 9762306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_TIME 0xfe 9862306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_GET_TIME 0xff 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci#define SSP_MSG2SSP_AP_FUSEROM 0x01 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* voice data */ 10362306a36Sopenharmony_ci#define SSP_TYPE_WAKE_UP_VOICE_SERVICE 0x01 10462306a36Sopenharmony_ci#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_AM 0x01 10562306a36Sopenharmony_ci#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_GRAMMER 0x02 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* Factory Test */ 10862306a36Sopenharmony_ci#define SSP_ACCELEROMETER_FACTORY 0x80 10962306a36Sopenharmony_ci#define SSP_GYROSCOPE_FACTORY 0x81 11062306a36Sopenharmony_ci#define SSP_GEOMAGNETIC_FACTORY 0x82 11162306a36Sopenharmony_ci#define SSP_PRESSURE_FACTORY 0x85 11262306a36Sopenharmony_ci#define SSP_GESTURE_FACTORY 0x86 11362306a36Sopenharmony_ci#define SSP_TEMPHUMIDITY_CRC_FACTORY 0x88 11462306a36Sopenharmony_ci#define SSP_GYROSCOPE_TEMP_FACTORY 0x8a 11562306a36Sopenharmony_ci#define SSP_GYROSCOPE_DPS_FACTORY 0x8b 11662306a36Sopenharmony_ci#define SSP_MCU_FACTORY 0x8c 11762306a36Sopenharmony_ci#define SSP_MCU_SLEEP_FACTORY 0x8d 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* SSP -> AP ACK about write CMD */ 12062306a36Sopenharmony_ci#define SSP_MSG_ACK 0x80 /* ACK from SSP to AP */ 12162306a36Sopenharmony_ci#define SSP_MSG_NAK 0x70 /* NAK from SSP to AP */ 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistruct ssp_sensorhub_info { 12462306a36Sopenharmony_ci char *fw_name; 12562306a36Sopenharmony_ci char *fw_crashed_name; 12662306a36Sopenharmony_ci unsigned int fw_rev; 12762306a36Sopenharmony_ci const u8 * const mag_table; 12862306a36Sopenharmony_ci const unsigned int mag_length; 12962306a36Sopenharmony_ci}; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/* ssp_msg options bit */ 13262306a36Sopenharmony_ci#define SSP_RW 0 13362306a36Sopenharmony_ci#define SSP_INDEX 3 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci#define SSP_AP2HUB_READ 0 13662306a36Sopenharmony_ci#define SSP_AP2HUB_WRITE 1 13762306a36Sopenharmony_ci#define SSP_HUB2AP_WRITE 2 13862306a36Sopenharmony_ci#define SSP_AP2HUB_READY 3 13962306a36Sopenharmony_ci#define SSP_AP2HUB_RETURN 4 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/** 14262306a36Sopenharmony_ci * struct ssp_data - ssp platformdata structure 14362306a36Sopenharmony_ci * @spi: spi device 14462306a36Sopenharmony_ci * @sensorhub_info: info about sensorhub board specific features 14562306a36Sopenharmony_ci * @wdt_timer: watchdog timer 14662306a36Sopenharmony_ci * @work_wdt: watchdog work 14762306a36Sopenharmony_ci * @work_firmware: firmware upgrade work queue 14862306a36Sopenharmony_ci * @work_refresh: refresh work queue for reset request from MCU 14962306a36Sopenharmony_ci * @shut_down: shut down flag 15062306a36Sopenharmony_ci * @mcu_dump_mode: mcu dump mode for debug 15162306a36Sopenharmony_ci * @time_syncing: time syncing indication flag 15262306a36Sopenharmony_ci * @timestamp: previous time in ns calculated for time syncing 15362306a36Sopenharmony_ci * @check_status: status table for each sensor 15462306a36Sopenharmony_ci * @com_fail_cnt: communication fail count 15562306a36Sopenharmony_ci * @reset_cnt: reset count 15662306a36Sopenharmony_ci * @timeout_cnt: timeout count 15762306a36Sopenharmony_ci * @available_sensors: available sensors seen by sensorhub (bit array) 15862306a36Sopenharmony_ci * @cur_firm_rev: cached current firmware revision 15962306a36Sopenharmony_ci * @last_resume_state: last AP resume/suspend state used to handle the PM 16062306a36Sopenharmony_ci * state of ssp 16162306a36Sopenharmony_ci * @last_ap_state: (obsolete) sleep notification for MCU 16262306a36Sopenharmony_ci * @sensor_enable: sensor enable mask 16362306a36Sopenharmony_ci * @delay_buf: data acquisition intervals table 16462306a36Sopenharmony_ci * @batch_latency_buf: yet unknown but existing in communication protocol 16562306a36Sopenharmony_ci * @batch_opt_buf: yet unknown but existing in communication protocol 16662306a36Sopenharmony_ci * @accel_position: yet unknown but existing in communication protocol 16762306a36Sopenharmony_ci * @mag_position: yet unknown but existing in communication protocol 16862306a36Sopenharmony_ci * @fw_dl_state: firmware download state 16962306a36Sopenharmony_ci * @comm_lock: lock protecting the handshake 17062306a36Sopenharmony_ci * @pending_lock: lock protecting pending list and completion 17162306a36Sopenharmony_ci * @mcu_reset_gpiod: mcu reset line 17262306a36Sopenharmony_ci * @ap_mcu_gpiod: ap to mcu gpio line 17362306a36Sopenharmony_ci * @mcu_ap_gpiod: mcu to ap gpio line 17462306a36Sopenharmony_ci * @pending_list: pending list for messages queued to be sent/read 17562306a36Sopenharmony_ci * @sensor_devs: registered IIO devices table 17662306a36Sopenharmony_ci * @enable_refcount: enable reference count for wdt (watchdog timer) 17762306a36Sopenharmony_ci * @header_buffer: cache aligned buffer for packet header 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_cistruct ssp_data { 18062306a36Sopenharmony_ci struct spi_device *spi; 18162306a36Sopenharmony_ci const struct ssp_sensorhub_info *sensorhub_info; 18262306a36Sopenharmony_ci struct timer_list wdt_timer; 18362306a36Sopenharmony_ci struct work_struct work_wdt; 18462306a36Sopenharmony_ci struct delayed_work work_refresh; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci bool shut_down; 18762306a36Sopenharmony_ci bool mcu_dump_mode; 18862306a36Sopenharmony_ci bool time_syncing; 18962306a36Sopenharmony_ci int64_t timestamp; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci int check_status[SSP_SENSOR_MAX]; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci unsigned int com_fail_cnt; 19462306a36Sopenharmony_ci unsigned int reset_cnt; 19562306a36Sopenharmony_ci unsigned int timeout_cnt; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci unsigned int available_sensors; 19862306a36Sopenharmony_ci unsigned int cur_firm_rev; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci char last_resume_state; 20162306a36Sopenharmony_ci char last_ap_state; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci unsigned int sensor_enable; 20462306a36Sopenharmony_ci u32 delay_buf[SSP_SENSOR_MAX]; 20562306a36Sopenharmony_ci s32 batch_latency_buf[SSP_SENSOR_MAX]; 20662306a36Sopenharmony_ci s8 batch_opt_buf[SSP_SENSOR_MAX]; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci int accel_position; 20962306a36Sopenharmony_ci int mag_position; 21062306a36Sopenharmony_ci int fw_dl_state; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci struct mutex comm_lock; 21362306a36Sopenharmony_ci struct mutex pending_lock; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci struct gpio_desc *mcu_reset_gpiod; 21662306a36Sopenharmony_ci struct gpio_desc *ap_mcu_gpiod; 21762306a36Sopenharmony_ci struct gpio_desc *mcu_ap_gpiod; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci struct list_head pending_list; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci struct iio_dev *sensor_devs[SSP_SENSOR_MAX]; 22262306a36Sopenharmony_ci atomic_t enable_refcount; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)] __aligned(IIO_DMA_MINALIGN); 22562306a36Sopenharmony_ci}; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_civoid ssp_clean_pending_list(struct ssp_data *data); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ciint ssp_command(struct ssp_data *data, char command, int arg); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ciint ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type, 23262306a36Sopenharmony_ci u8 *send_buf, u8 length); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ciint ssp_irq_msg(struct ssp_data *data); 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ciint ssp_get_chipid(struct ssp_data *data); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ciint ssp_set_magnetic_matrix(struct ssp_data *data); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ciunsigned int ssp_get_sensor_scanning_info(struct ssp_data *data); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ciunsigned int ssp_get_firmware_rev(struct ssp_data *data); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ciint ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci#endif /* __SSP_SENSORHUB_H__ */ 247