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