xref: /openbmc/linux/drivers/iio/common/ssp_sensors/ssp.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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