18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef __SSP_SENSORHUB_H__ 78c2ecf20Sopenharmony_ci#define __SSP_SENSORHUB_H__ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/delay.h> 108c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h> 118c2ecf20Sopenharmony_ci#include <linux/iio/common/ssp_sensors.h> 128c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 138c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define SSP_DEVICE_ID 0x55 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifdef SSP_DBG 188c2ecf20Sopenharmony_ci#define ssp_dbg(format, ...) pr_info("[SSP] "format, ##__VA_ARGS__) 198c2ecf20Sopenharmony_ci#else 208c2ecf20Sopenharmony_ci#define ssp_dbg(format, ...) 218c2ecf20Sopenharmony_ci#endif 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define SSP_SW_RESET_TIME 3000 248c2ecf20Sopenharmony_ci/* Sensor polling in ms */ 258c2ecf20Sopenharmony_ci#define SSP_DEFAULT_POLLING_DELAY 200 268c2ecf20Sopenharmony_ci#define SSP_DEFAULT_RETRIES 3 278c2ecf20Sopenharmony_ci#define SSP_DATA_PACKET_SIZE 960 288c2ecf20Sopenharmony_ci#define SSP_HEADER_BUFFER_SIZE 4 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cienum { 318c2ecf20Sopenharmony_ci SSP_KERNEL_BINARY = 0, 328c2ecf20Sopenharmony_ci SSP_KERNEL_CRASHED_BINARY, 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cienum { 368c2ecf20Sopenharmony_ci SSP_INITIALIZATION_STATE = 0, 378c2ecf20Sopenharmony_ci SSP_NO_SENSOR_STATE, 388c2ecf20Sopenharmony_ci SSP_ADD_SENSOR_STATE, 398c2ecf20Sopenharmony_ci SSP_RUNNING_SENSOR_STATE, 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* Firmware download STATE */ 438c2ecf20Sopenharmony_cienum { 448c2ecf20Sopenharmony_ci SSP_FW_DL_STATE_FAIL = -1, 458c2ecf20Sopenharmony_ci SSP_FW_DL_STATE_NONE = 0, 468c2ecf20Sopenharmony_ci SSP_FW_DL_STATE_NEED_TO_SCHEDULE, 478c2ecf20Sopenharmony_ci SSP_FW_DL_STATE_SCHEDULED, 488c2ecf20Sopenharmony_ci SSP_FW_DL_STATE_DOWNLOADING, 498c2ecf20Sopenharmony_ci SSP_FW_DL_STATE_SYNC, 508c2ecf20Sopenharmony_ci SSP_FW_DL_STATE_DONE, 518c2ecf20Sopenharmony_ci}; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define SSP_INVALID_REVISION 99999 548c2ecf20Sopenharmony_ci#define SSP_INVALID_REVISION2 0xffffff 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/* AP -> SSP Instruction */ 578c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD 0xa1 588c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_BYPASS_SENSOR_RM 0xa2 598c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_REMOVE_ALL 0xa3 608c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_CHANGE_DELAY 0xa4 618c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_LIBRARY_ADD 0xb1 628c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_LIBRARY_REMOVE 0xb2 638c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_LIB_NOTI 0xb4 648c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_INST_LIB_DATA 0xc1 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_GYRO_CAL 0xcd 678c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_ACCEL_CAL 0xce 688c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_SHUTDOWN 0xd0 698c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_WAKEUP 0xd1 708c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_SLEEP 0xd2 718c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_RESUME 0xd3 728c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_SUSPEND 0xd4 738c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_RESET 0xd5 748c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_POW_CONNECTED 0xd6 758c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_STATUS_POW_DISCONNECTED 0xd7 768c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE 0xda 778c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_DUMPMODE 0xdb 788c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_DUMP_CHECK 0xdc 798c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_BATCH_FLUSH 0xdd 808c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_BATCH_COUNT 0xdf 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_WHOAMI 0x0f 838c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_FIRMWARE_REV 0xf0 848c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_FORMATION 0xf1 858c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_PROXTHRESHOLD 0xf2 868c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_BARCODE_EMUL 0xf3 878c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_SCANNING 0xf4 888c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SET_MAGNETIC_HWOFFSET 0xf5 898c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_GET_MAGNETIC_HWOFFSET 0xf6 908c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_GESTURE_CURRENT 0xf7 918c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_GET_THERM 0xf8 928c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_GET_BIG_DATA 0xf9 938c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SET_BIG_DATA 0xfa 948c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_START_BIG_DATA 0xfb 958c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX 0xfd 968c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_SENSOR_TILT 0xea 978c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_SET_TIME 0xfe 988c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_MCU_GET_TIME 0xff 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci#define SSP_MSG2SSP_AP_FUSEROM 0x01 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* voice data */ 1038c2ecf20Sopenharmony_ci#define SSP_TYPE_WAKE_UP_VOICE_SERVICE 0x01 1048c2ecf20Sopenharmony_ci#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_AM 0x01 1058c2ecf20Sopenharmony_ci#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_GRAMMER 0x02 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci/* Factory Test */ 1088c2ecf20Sopenharmony_ci#define SSP_ACCELEROMETER_FACTORY 0x80 1098c2ecf20Sopenharmony_ci#define SSP_GYROSCOPE_FACTORY 0x81 1108c2ecf20Sopenharmony_ci#define SSP_GEOMAGNETIC_FACTORY 0x82 1118c2ecf20Sopenharmony_ci#define SSP_PRESSURE_FACTORY 0x85 1128c2ecf20Sopenharmony_ci#define SSP_GESTURE_FACTORY 0x86 1138c2ecf20Sopenharmony_ci#define SSP_TEMPHUMIDITY_CRC_FACTORY 0x88 1148c2ecf20Sopenharmony_ci#define SSP_GYROSCOPE_TEMP_FACTORY 0x8a 1158c2ecf20Sopenharmony_ci#define SSP_GYROSCOPE_DPS_FACTORY 0x8b 1168c2ecf20Sopenharmony_ci#define SSP_MCU_FACTORY 0x8c 1178c2ecf20Sopenharmony_ci#define SSP_MCU_SLEEP_FACTORY 0x8d 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* SSP -> AP ACK about write CMD */ 1208c2ecf20Sopenharmony_ci#define SSP_MSG_ACK 0x80 /* ACK from SSP to AP */ 1218c2ecf20Sopenharmony_ci#define SSP_MSG_NAK 0x70 /* NAK from SSP to AP */ 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistruct ssp_sensorhub_info { 1248c2ecf20Sopenharmony_ci char *fw_name; 1258c2ecf20Sopenharmony_ci char *fw_crashed_name; 1268c2ecf20Sopenharmony_ci unsigned int fw_rev; 1278c2ecf20Sopenharmony_ci const u8 * const mag_table; 1288c2ecf20Sopenharmony_ci const unsigned int mag_length; 1298c2ecf20Sopenharmony_ci}; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci/* ssp_msg options bit */ 1328c2ecf20Sopenharmony_ci#define SSP_RW 0 1338c2ecf20Sopenharmony_ci#define SSP_INDEX 3 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci#define SSP_AP2HUB_READ 0 1368c2ecf20Sopenharmony_ci#define SSP_AP2HUB_WRITE 1 1378c2ecf20Sopenharmony_ci#define SSP_HUB2AP_WRITE 2 1388c2ecf20Sopenharmony_ci#define SSP_AP2HUB_READY 3 1398c2ecf20Sopenharmony_ci#define SSP_AP2HUB_RETURN 4 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci/** 1428c2ecf20Sopenharmony_ci * struct ssp_data - ssp platformdata structure 1438c2ecf20Sopenharmony_ci * @spi: spi device 1448c2ecf20Sopenharmony_ci * @sensorhub_info: info about sensorhub board specific features 1458c2ecf20Sopenharmony_ci * @wdt_timer: watchdog timer 1468c2ecf20Sopenharmony_ci * @work_wdt: watchdog work 1478c2ecf20Sopenharmony_ci * @work_firmware: firmware upgrade work queue 1488c2ecf20Sopenharmony_ci * @work_refresh: refresh work queue for reset request from MCU 1498c2ecf20Sopenharmony_ci * @shut_down: shut down flag 1508c2ecf20Sopenharmony_ci * @mcu_dump_mode: mcu dump mode for debug 1518c2ecf20Sopenharmony_ci * @time_syncing: time syncing indication flag 1528c2ecf20Sopenharmony_ci * @timestamp: previous time in ns calculated for time syncing 1538c2ecf20Sopenharmony_ci * @check_status: status table for each sensor 1548c2ecf20Sopenharmony_ci * @com_fail_cnt: communication fail count 1558c2ecf20Sopenharmony_ci * @reset_cnt: reset count 1568c2ecf20Sopenharmony_ci * @timeout_cnt: timeout count 1578c2ecf20Sopenharmony_ci * @available_sensors: available sensors seen by sensorhub (bit array) 1588c2ecf20Sopenharmony_ci * @cur_firm_rev: cached current firmware revision 1598c2ecf20Sopenharmony_ci * @last_resume_state: last AP resume/suspend state used to handle the PM 1608c2ecf20Sopenharmony_ci * state of ssp 1618c2ecf20Sopenharmony_ci * @last_ap_state: (obsolete) sleep notification for MCU 1628c2ecf20Sopenharmony_ci * @sensor_enable: sensor enable mask 1638c2ecf20Sopenharmony_ci * @delay_buf: data acquisition intervals table 1648c2ecf20Sopenharmony_ci * @batch_latency_buf: yet unknown but existing in communication protocol 1658c2ecf20Sopenharmony_ci * @batch_opt_buf: yet unknown but existing in communication protocol 1668c2ecf20Sopenharmony_ci * @accel_position: yet unknown but existing in communication protocol 1678c2ecf20Sopenharmony_ci * @mag_position: yet unknown but existing in communication protocol 1688c2ecf20Sopenharmony_ci * @fw_dl_state: firmware download state 1698c2ecf20Sopenharmony_ci * @comm_lock: lock protecting the handshake 1708c2ecf20Sopenharmony_ci * @pending_lock: lock protecting pending list and completion 1718c2ecf20Sopenharmony_ci * @mcu_reset_gpiod: mcu reset line 1728c2ecf20Sopenharmony_ci * @ap_mcu_gpiod: ap to mcu gpio line 1738c2ecf20Sopenharmony_ci * @mcu_ap_gpiod: mcu to ap gpio line 1748c2ecf20Sopenharmony_ci * @pending_list: pending list for messages queued to be sent/read 1758c2ecf20Sopenharmony_ci * @sensor_devs: registered IIO devices table 1768c2ecf20Sopenharmony_ci * @enable_refcount: enable reference count for wdt (watchdog timer) 1778c2ecf20Sopenharmony_ci * @header_buffer: cache aligned buffer for packet header 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_cistruct ssp_data { 1808c2ecf20Sopenharmony_ci struct spi_device *spi; 1818c2ecf20Sopenharmony_ci const struct ssp_sensorhub_info *sensorhub_info; 1828c2ecf20Sopenharmony_ci struct timer_list wdt_timer; 1838c2ecf20Sopenharmony_ci struct work_struct work_wdt; 1848c2ecf20Sopenharmony_ci struct delayed_work work_refresh; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci bool shut_down; 1878c2ecf20Sopenharmony_ci bool mcu_dump_mode; 1888c2ecf20Sopenharmony_ci bool time_syncing; 1898c2ecf20Sopenharmony_ci int64_t timestamp; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci int check_status[SSP_SENSOR_MAX]; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci unsigned int com_fail_cnt; 1948c2ecf20Sopenharmony_ci unsigned int reset_cnt; 1958c2ecf20Sopenharmony_ci unsigned int timeout_cnt; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci unsigned int available_sensors; 1988c2ecf20Sopenharmony_ci unsigned int cur_firm_rev; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci char last_resume_state; 2018c2ecf20Sopenharmony_ci char last_ap_state; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci unsigned int sensor_enable; 2048c2ecf20Sopenharmony_ci u32 delay_buf[SSP_SENSOR_MAX]; 2058c2ecf20Sopenharmony_ci s32 batch_latency_buf[SSP_SENSOR_MAX]; 2068c2ecf20Sopenharmony_ci s8 batch_opt_buf[SSP_SENSOR_MAX]; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci int accel_position; 2098c2ecf20Sopenharmony_ci int mag_position; 2108c2ecf20Sopenharmony_ci int fw_dl_state; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci struct mutex comm_lock; 2138c2ecf20Sopenharmony_ci struct mutex pending_lock; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci struct gpio_desc *mcu_reset_gpiod; 2168c2ecf20Sopenharmony_ci struct gpio_desc *ap_mcu_gpiod; 2178c2ecf20Sopenharmony_ci struct gpio_desc *mcu_ap_gpiod; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci struct list_head pending_list; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci struct iio_dev *sensor_devs[SSP_SENSOR_MAX]; 2228c2ecf20Sopenharmony_ci atomic_t enable_refcount; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)] 2258c2ecf20Sopenharmony_ci ____cacheline_aligned; 2268c2ecf20Sopenharmony_ci}; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_civoid ssp_clean_pending_list(struct ssp_data *data); 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ciint ssp_command(struct ssp_data *data, char command, int arg); 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ciint ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type, 2338c2ecf20Sopenharmony_ci u8 *send_buf, u8 length); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ciint ssp_irq_msg(struct ssp_data *data); 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ciint ssp_get_chipid(struct ssp_data *data); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ciint ssp_set_magnetic_matrix(struct ssp_data *data); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ciunsigned int ssp_get_sensor_scanning_info(struct ssp_data *data); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ciunsigned int ssp_get_firmware_rev(struct ssp_data *data); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ciint ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci#endif /* __SSP_SENSORHUB_H__ */ 248