hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
 */
 
#ifndef __SSP_SENSORHUB_H__
#define __SSP_SENSORHUB_H__
 
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/iio/common/ssp_sensors.h>
#include <linux/iio/iio.h>
#include <linux/spi/spi.h>
 
#define SSP_DEVICE_ID        0x55
 
#ifdef SSP_DBG
#define ssp_dbg(format, ...) pr_info("[SSP] "format, ##__VA_ARGS__)
#else
#define ssp_dbg(format, ...)
#endif
 
#define SSP_SW_RESET_TIME        3000
/* Sensor polling in ms */
#define SSP_DEFAULT_POLLING_DELAY    200
#define SSP_DEFAULT_RETRIES        3
#define SSP_DATA_PACKET_SIZE        960
#define SSP_HEADER_BUFFER_SIZE        4
 
enum {
   SSP_KERNEL_BINARY = 0,
   SSP_KERNEL_CRASHED_BINARY,
};
 
enum {
   SSP_INITIALIZATION_STATE = 0,
   SSP_NO_SENSOR_STATE,
   SSP_ADD_SENSOR_STATE,
   SSP_RUNNING_SENSOR_STATE,
};
 
/* Firmware download STATE */
enum {
   SSP_FW_DL_STATE_FAIL = -1,
   SSP_FW_DL_STATE_NONE = 0,
   SSP_FW_DL_STATE_NEED_TO_SCHEDULE,
   SSP_FW_DL_STATE_SCHEDULED,
   SSP_FW_DL_STATE_DOWNLOADING,
   SSP_FW_DL_STATE_SYNC,
   SSP_FW_DL_STATE_DONE,
};
 
#define SSP_INVALID_REVISION            99999
#define SSP_INVALID_REVISION2            0xffffff
 
/* AP -> SSP Instruction */
#define SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD    0xa1
#define SSP_MSG2SSP_INST_BYPASS_SENSOR_RM    0xa2
#define SSP_MSG2SSP_INST_REMOVE_ALL        0xa3
#define SSP_MSG2SSP_INST_CHANGE_DELAY        0xa4
#define SSP_MSG2SSP_INST_LIBRARY_ADD        0xb1
#define SSP_MSG2SSP_INST_LIBRARY_REMOVE        0xb2
#define SSP_MSG2SSP_INST_LIB_NOTI        0xb4
#define SSP_MSG2SSP_INST_LIB_DATA        0xc1
 
#define SSP_MSG2SSP_AP_MCU_SET_GYRO_CAL        0xcd
#define SSP_MSG2SSP_AP_MCU_SET_ACCEL_CAL    0xce
#define SSP_MSG2SSP_AP_STATUS_SHUTDOWN        0xd0
#define SSP_MSG2SSP_AP_STATUS_WAKEUP        0xd1
#define SSP_MSG2SSP_AP_STATUS_SLEEP        0xd2
#define SSP_MSG2SSP_AP_STATUS_RESUME        0xd3
#define SSP_MSG2SSP_AP_STATUS_SUSPEND        0xd4
#define SSP_MSG2SSP_AP_STATUS_RESET        0xd5
#define SSP_MSG2SSP_AP_STATUS_POW_CONNECTED    0xd6
#define SSP_MSG2SSP_AP_STATUS_POW_DISCONNECTED    0xd7
#define SSP_MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE    0xda
#define SSP_MSG2SSP_AP_MCU_SET_DUMPMODE        0xdb
#define SSP_MSG2SSP_AP_MCU_DUMP_CHECK        0xdc
#define SSP_MSG2SSP_AP_MCU_BATCH_FLUSH        0xdd
#define SSP_MSG2SSP_AP_MCU_BATCH_COUNT        0xdf
 
#define SSP_MSG2SSP_AP_WHOAMI                0x0f
#define SSP_MSG2SSP_AP_FIRMWARE_REV            0xf0
#define SSP_MSG2SSP_AP_SENSOR_FORMATION            0xf1
#define SSP_MSG2SSP_AP_SENSOR_PROXTHRESHOLD        0xf2
#define SSP_MSG2SSP_AP_SENSOR_BARCODE_EMUL        0xf3
#define SSP_MSG2SSP_AP_SENSOR_SCANNING            0xf4
#define SSP_MSG2SSP_AP_SET_MAGNETIC_HWOFFSET        0xf5
#define SSP_MSG2SSP_AP_GET_MAGNETIC_HWOFFSET        0xf6
#define SSP_MSG2SSP_AP_SENSOR_GESTURE_CURRENT        0xf7
#define SSP_MSG2SSP_AP_GET_THERM            0xf8
#define SSP_MSG2SSP_AP_GET_BIG_DATA            0xf9
#define SSP_MSG2SSP_AP_SET_BIG_DATA            0xfa
#define SSP_MSG2SSP_AP_START_BIG_DATA            0xfb
#define SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX    0xfd
#define SSP_MSG2SSP_AP_SENSOR_TILT            0xea
#define SSP_MSG2SSP_AP_MCU_SET_TIME            0xfe
#define SSP_MSG2SSP_AP_MCU_GET_TIME            0xff
 
#define SSP_MSG2SSP_AP_FUSEROM                0x01
 
/* voice data */
#define SSP_TYPE_WAKE_UP_VOICE_SERVICE            0x01
#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_AM        0x01
#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_GRAMMER    0x02
 
/* Factory Test */
#define SSP_ACCELEROMETER_FACTORY            0x80
#define SSP_GYROSCOPE_FACTORY                0x81
#define SSP_GEOMAGNETIC_FACTORY                0x82
#define SSP_PRESSURE_FACTORY                0x85
#define SSP_GESTURE_FACTORY                0x86
#define SSP_TEMPHUMIDITY_CRC_FACTORY            0x88
#define SSP_GYROSCOPE_TEMP_FACTORY            0x8a
#define SSP_GYROSCOPE_DPS_FACTORY            0x8b
#define SSP_MCU_FACTORY                    0x8c
#define SSP_MCU_SLEEP_FACTORY                0x8d
 
/* SSP -> AP ACK about write CMD */
#define SSP_MSG_ACK        0x80    /* ACK from SSP to AP */
#define SSP_MSG_NAK        0x70    /* NAK from SSP to AP */
 
struct ssp_sensorhub_info {
   char *fw_name;
   char *fw_crashed_name;
   unsigned int fw_rev;
   const u8 * const mag_table;
   const unsigned int mag_length;
};
 
/* ssp_msg options bit */
#define SSP_RW        0
#define SSP_INDEX    3
 
#define SSP_AP2HUB_READ        0
#define SSP_AP2HUB_WRITE    1
#define SSP_HUB2AP_WRITE    2
#define SSP_AP2HUB_READY    3
#define SSP_AP2HUB_RETURN    4
 
/**
 * struct ssp_data - ssp platformdata structure
 * @spi:        spi device
 * @sensorhub_info:    info about sensorhub board specific features
 * @wdt_timer:        watchdog timer
 * @work_wdt:        watchdog work
 * @work_firmware:    firmware upgrade work queue
 * @work_refresh:    refresh work queue for reset request from MCU
 * @shut_down:        shut down flag
 * @mcu_dump_mode:    mcu dump mode for debug
 * @time_syncing:    time syncing indication flag
 * @timestamp:        previous time in ns calculated for time syncing
 * @check_status:    status table for each sensor
 * @com_fail_cnt:    communication fail count
 * @reset_cnt:        reset count
 * @timeout_cnt:    timeout count
 * @available_sensors:    available sensors seen by sensorhub (bit array)
 * @cur_firm_rev:    cached current firmware revision
 * @last_resume_state:    last AP resume/suspend state used to handle the PM
 *                      state of ssp
 * @last_ap_state:    (obsolete) sleep notification for MCU
 * @sensor_enable:    sensor enable mask
 * @delay_buf:        data acquisition intervals table
 * @batch_latency_buf:    yet unknown but existing in communication protocol
 * @batch_opt_buf:    yet unknown but existing in communication protocol
 * @accel_position:    yet unknown but existing in communication protocol
 * @mag_position:    yet unknown but existing in communication protocol
 * @fw_dl_state:    firmware download state
 * @comm_lock:        lock protecting the handshake
 * @pending_lock:    lock protecting pending list and completion
 * @mcu_reset_gpiod:    mcu reset line
 * @ap_mcu_gpiod:    ap to mcu gpio line
 * @mcu_ap_gpiod:    mcu to ap gpio line
 * @pending_list:    pending list for messages queued to be sent/read
 * @sensor_devs:    registered IIO devices table
 * @enable_refcount:    enable reference count for wdt (watchdog timer)
 * @header_buffer:    cache aligned buffer for packet header
 */
struct ssp_data {
   struct spi_device *spi;
   const struct ssp_sensorhub_info *sensorhub_info;
   struct timer_list wdt_timer;
   struct work_struct work_wdt;
   struct delayed_work work_refresh;
 
   bool shut_down;
   bool mcu_dump_mode;
   bool time_syncing;
   int64_t timestamp;
 
   int check_status[SSP_SENSOR_MAX];
 
   unsigned int com_fail_cnt;
   unsigned int reset_cnt;
   unsigned int timeout_cnt;
 
   unsigned int available_sensors;
   unsigned int cur_firm_rev;
 
   char last_resume_state;
   char last_ap_state;
 
   unsigned int sensor_enable;
   u32 delay_buf[SSP_SENSOR_MAX];
   s32 batch_latency_buf[SSP_SENSOR_MAX];
   s8 batch_opt_buf[SSP_SENSOR_MAX];
 
   int accel_position;
   int mag_position;
   int fw_dl_state;
 
   struct mutex comm_lock;
   struct mutex pending_lock;
 
   struct gpio_desc *mcu_reset_gpiod;
   struct gpio_desc *ap_mcu_gpiod;
   struct gpio_desc *mcu_ap_gpiod;
 
   struct list_head pending_list;
 
   struct iio_dev *sensor_devs[SSP_SENSOR_MAX];
   atomic_t enable_refcount;
 
   __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)]
       ____cacheline_aligned;
};
 
void ssp_clean_pending_list(struct ssp_data *data);
 
int ssp_command(struct ssp_data *data, char command, int arg);
 
int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type,
            u8 *send_buf, u8 length);
 
int ssp_irq_msg(struct ssp_data *data);
 
int ssp_get_chipid(struct ssp_data *data);
 
int ssp_set_magnetic_matrix(struct ssp_data *data);
 
unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data);
 
unsigned int ssp_get_firmware_rev(struct ssp_data *data);
 
int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay);
 
#endif /* __SSP_SENSORHUB_H__ */