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