1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright © 2024 Intel Corporation */
3
4 #include <linux/acpi.h>
5 #include <linux/bitfield.h>
6 #include <linux/delay.h>
7 #include <linux/hid.h>
8
9 #include "intel-thc-dev.h"
10 #include "intel-thc-dma.h"
11
12 #include "quickspi-dev.h"
13 #include "quickspi-hid.h"
14 #include "quickspi-protocol.h"
15
16 /* THC uses HW to accelerate HID over SPI protocol, THC_M_PRT_DEV_INT_CAUSE
17 * register is used to store message header and body header, below definition
18 * let driver retrieve needed data filed easier from THC_M_PRT_DEV_INT_CAUSE
19 * register.
20 */
21 #define HIDSPI_IN_REP_BDY_HDR_REP_TYPE GENMASK(7, 0)
22
write_cmd_to_txdma(struct quickspi_device * qsdev,int report_type,int report_id,u8 * report_buf,const int report_buf_len)23 static int write_cmd_to_txdma(struct quickspi_device *qsdev,
24 int report_type, int report_id,
25 u8 *report_buf, const int report_buf_len)
26 {
27 struct output_report *write_buf;
28 int write_buf_len;
29 int ret;
30
31 write_buf = (struct output_report *)qsdev->report_buf;
32
33 write_buf->output_hdr.report_type = report_type;
34 write_buf->output_hdr.content_len = cpu_to_le16(report_buf_len);
35 write_buf->output_hdr.content_id = report_id;
36
37 if (report_buf && report_buf_len > 0)
38 memcpy(write_buf->content, report_buf, report_buf_len);
39
40 write_buf_len = HIDSPI_OUTPUT_REPORT_SIZE(report_buf_len);
41
42 ret = thc_dma_write(qsdev->thc_hw, write_buf, write_buf_len);
43 if (ret)
44 dev_err_once(qsdev->dev, "DMA write failed, ret = %d\n", ret);
45
46 return ret;
47 }
48
quickspi_get_device_descriptor(struct quickspi_device * qsdev)49 static int quickspi_get_device_descriptor(struct quickspi_device *qsdev)
50 {
51 u8 read_buf[HIDSPI_INPUT_DEVICE_DESCRIPTOR_SIZE];
52 struct output_report output_rep;
53 u32 input_len, read_len = 0;
54 u32 int_cause_val;
55 u8 input_rep_type;
56 int ret;
57
58 output_rep.output_hdr.report_type = DEVICE_DESCRIPTOR;
59 output_rep.output_hdr.content_len = 0;
60 output_rep.output_hdr.content_id = 0;
61
62 qsdev->nondma_int_received = false;
63
64 ret = thc_tic_pio_write(qsdev->thc_hw, qsdev->output_report_addr,
65 HIDSPI_OUTPUT_REPORT_SIZE(0), (u32 *)&output_rep);
66 if (ret) {
67 dev_err_once(qsdev->dev,
68 "Write DEVICE_DESCRIPTOR command failed, ret = %d\n", ret);
69 return ret;
70 }
71
72 ret = wait_event_interruptible_timeout(qsdev->nondma_int_received_wq,
73 qsdev->nondma_int_received,
74 QUICKSPI_ACK_WAIT_TIMEOUT * HZ);
75 if (ret <= 0 || !qsdev->nondma_int_received) {
76 dev_err_once(qsdev->dev, "Wait DEVICE_DESCRIPTOR timeout, ret:%d\n", ret);
77 return -ETIMEDOUT;
78 }
79 qsdev->nondma_int_received = false;
80
81 int_cause_val = thc_int_cause_read(qsdev->thc_hw);
82 input_len = FIELD_GET(HIDSPI_INPUT_HEADER_REPORT_LEN, int_cause_val);
83
84 input_len = input_len * sizeof(u32);
85 if (input_len != HIDSPI_INPUT_DEVICE_DESCRIPTOR_SIZE) {
86 dev_err_once(qsdev->dev, "Receive wrong DEVICE_DESCRIPTOR length, len = %u\n",
87 input_len);
88 return -EINVAL;
89 }
90
91 ret = thc_tic_pio_read(qsdev->thc_hw, qsdev->input_report_bdy_addr,
92 input_len, &read_len, (u32 *)read_buf);
93 if (ret || read_len != input_len) {
94 dev_err_once(qsdev->dev, "Read DEVICE_DESCRIPTOR failed, ret = %d\n", ret);
95 dev_err_once(qsdev->dev, "DEVICE_DESCRIPTOR expected len = %u, actual read = %u\n",
96 input_len, read_len);
97 return ret;
98 }
99
100 input_rep_type = ((struct input_report_body_header *)read_buf)->input_report_type;
101
102 if (input_rep_type == DEVICE_DESCRIPTOR_RESPONSE) {
103 memcpy(&qsdev->dev_desc,
104 read_buf + HIDSPI_INPUT_BODY_HEADER_SIZE,
105 HIDSPI_DEVICE_DESCRIPTOR_SIZE);
106
107 return 0;
108 }
109
110 dev_err_once(qsdev->dev, "Unexpected input report type: %d\n", input_rep_type);
111 return -EINVAL;
112 }
113
quickspi_get_report_descriptor(struct quickspi_device * qsdev)114 int quickspi_get_report_descriptor(struct quickspi_device *qsdev)
115 {
116 int ret;
117
118 ret = write_cmd_to_txdma(qsdev, REPORT_DESCRIPTOR, 0, NULL, 0);
119 if (ret) {
120 dev_err_once(qsdev->dev,
121 "Write REPORT_DESCRIPTOR command failed, ret = %d\n", ret);
122 return ret;
123 }
124
125 ret = wait_event_interruptible_timeout(qsdev->report_desc_got_wq,
126 qsdev->report_desc_got,
127 QUICKSPI_ACK_WAIT_TIMEOUT * HZ);
128 if (ret <= 0 || !qsdev->report_desc_got) {
129 dev_err_once(qsdev->dev, "Wait Report Descriptor timeout, ret:%d\n", ret);
130 return -ETIMEDOUT;
131 }
132 qsdev->report_desc_got = false;
133
134 return 0;
135 }
136
quickspi_set_power(struct quickspi_device * qsdev,enum hidspi_power_state power_state)137 int quickspi_set_power(struct quickspi_device *qsdev,
138 enum hidspi_power_state power_state)
139 {
140 u8 cmd_content = power_state;
141 int ret;
142
143 ret = write_cmd_to_txdma(qsdev, COMMAND_CONTENT,
144 HIDSPI_SET_POWER_CMD_ID,
145 &cmd_content,
146 sizeof(cmd_content));
147 if (ret) {
148 dev_err_once(qsdev->dev, "Write SET_POWER command failed, ret = %d\n", ret);
149 return ret;
150 }
151
152 return 0;
153 }
154
quickspi_handle_input_data(struct quickspi_device * qsdev,u32 buf_len)155 void quickspi_handle_input_data(struct quickspi_device *qsdev, u32 buf_len)
156 {
157 struct input_report_body_header *body_hdr;
158 struct input_report_body *input_body;
159 u8 *input_report;
160 u32 input_len;
161 int ret = 0;
162
163 input_body = (struct input_report_body *)qsdev->input_buf;
164 body_hdr = &input_body->body_hdr;
165 input_len = le16_to_cpu(body_hdr->content_len);
166
167 if (HIDSPI_INPUT_BODY_SIZE(input_len) > buf_len) {
168 dev_err_once(qsdev->dev, "Wrong input report length: %u",
169 input_len);
170 return;
171 }
172
173 switch (body_hdr->input_report_type) {
174 case REPORT_DESCRIPTOR_RESPONSE:
175 if (input_len != le16_to_cpu(qsdev->dev_desc.rep_desc_len)) {
176 dev_err_once(qsdev->dev, "Unexpected report descriptor length: %u\n",
177 input_len);
178 return;
179 }
180
181 memcpy(qsdev->report_descriptor, input_body->content, input_len);
182
183 qsdev->report_desc_got = true;
184 wake_up_interruptible(&qsdev->report_desc_got_wq);
185
186 break;
187
188 case COMMAND_RESPONSE:
189 if (body_hdr->content_id == HIDSPI_SET_POWER_CMD_ID) {
190 dev_dbg(qsdev->dev, "Receive set power on response\n");
191 } else {
192 dev_err_once(qsdev->dev, "Unknown command response type: %u\n",
193 body_hdr->content_id);
194 }
195
196 break;
197
198 case RESET_RESPONSE:
199 if (qsdev->state == QUICKSPI_RESETING) {
200 qsdev->reset_ack = true;
201 wake_up_interruptible(&qsdev->reset_ack_wq);
202 dev_dbg(qsdev->dev, "Receive HIR reset response\n");
203 } else {
204 dev_info(qsdev->dev, "Receive DIR\n");
205 }
206 break;
207
208 case GET_FEATURE_RESPONSE:
209 case GET_INPUT_REPORT_RESPONSE:
210 qsdev->report_len = sizeof(body_hdr->content_id) + input_len;
211 input_report = input_body->content - sizeof(body_hdr->content_id);
212
213 memcpy(qsdev->report_buf, input_report, qsdev->report_len);
214
215 qsdev->get_report_cmpl = true;
216 wake_up_interruptible(&qsdev->get_report_cmpl_wq);
217
218 break;
219
220 case SET_FEATURE_RESPONSE:
221 case OUTPUT_REPORT_RESPONSE:
222 qsdev->set_report_cmpl = true;
223 wake_up_interruptible(&qsdev->set_report_cmpl_wq);
224
225 break;
226
227 case DATA:
228 if (qsdev->state != QUICKSPI_ENABLED)
229 return;
230
231 if (input_len > le16_to_cpu(qsdev->dev_desc.max_input_len)) {
232 dev_err_once(qsdev->dev, "Unexpected too large input report length: %u\n",
233 input_len);
234 return;
235 }
236
237 input_len = sizeof(body_hdr->content_id) + input_len;
238 input_report = input_body->content - sizeof(body_hdr->content_id);
239
240 ret = quickspi_hid_send_report(qsdev, input_report, input_len);
241 if (ret)
242 dev_err_once(qsdev->dev, "Failed to send HID input report: %d\n", ret);
243
244 break;
245
246 default:
247 dev_err_once(qsdev->dev, "Unsupported input report type: %u\n",
248 body_hdr->input_report_type);
249 break;
250 }
251 }
252
acpi_tic_reset(struct quickspi_device * qsdev)253 static int acpi_tic_reset(struct quickspi_device *qsdev)
254 {
255 acpi_status status = 0;
256 acpi_handle handle;
257
258 if (!qsdev->acpi_dev)
259 return -ENODEV;
260
261 handle = acpi_device_handle(qsdev->acpi_dev);
262 status = acpi_execute_simple_method(handle, "_RST", 0);
263 if (ACPI_FAILURE(status)) {
264 dev_err_once(qsdev->dev,
265 "Failed to reset device through ACPI method, ret = %d\n", status);
266 return -EIO;
267 }
268
269 return 0;
270 }
271
reset_tic(struct quickspi_device * qsdev)272 int reset_tic(struct quickspi_device *qsdev)
273 {
274 u32 actual_read_len, read_len = 0;
275 u32 input_report_len, reset_response, int_cause_val;
276 u8 input_rep_type;
277 int ret;
278
279 qsdev->state = QUICKSPI_RESETING;
280
281 qsdev->reset_ack = false;
282
283 thc_int_trigger_type_select(qsdev->thc_hw, true);
284
285 ret = acpi_tic_reset(qsdev);
286 if (ret)
287 return ret;
288
289 ret = thc_interrupt_quiesce(qsdev->thc_hw, false);
290 if (ret)
291 return ret;
292
293 ret = wait_event_interruptible_timeout(qsdev->reset_ack_wq,
294 qsdev->reset_ack,
295 QUICKSPI_ACK_WAIT_TIMEOUT * HZ);
296 if (ret <= 0 || !qsdev->reset_ack) {
297 dev_err_once(qsdev->dev, "Wait RESET_RESPONSE timeout, ret:%d\n", ret);
298 return -ETIMEDOUT;
299 }
300
301 int_cause_val = thc_int_cause_read(qsdev->thc_hw);
302 input_report_len = FIELD_GET(HIDSPI_INPUT_HEADER_REPORT_LEN, int_cause_val);
303
304 read_len = input_report_len * sizeof(u32);
305 if (read_len != HIDSPI_INPUT_BODY_SIZE(0)) {
306 dev_err_once(qsdev->dev, "Receive wrong RESET_RESPONSE, len = %u\n",
307 read_len);
308 return -EINVAL;
309 }
310
311 /* Switch to edge trigger matching with HIDSPI protocol definition */
312 thc_int_trigger_type_select(qsdev->thc_hw, true);
313
314 ret = thc_tic_pio_read(qsdev->thc_hw, qsdev->input_report_bdy_addr,
315 read_len, &actual_read_len,
316 (u32 *)&reset_response);
317 if (ret || actual_read_len != read_len) {
318 dev_err_once(qsdev->dev, "Read RESET_RESPONSE body failed, ret = %d\n", ret);
319 dev_err_once(qsdev->dev, "RESET_RESPONSE body expected len = %u, actual = %u\n",
320 read_len, actual_read_len);
321 return ret;
322 }
323
324 input_rep_type = FIELD_GET(HIDSPI_IN_REP_BDY_HDR_REP_TYPE, reset_response);
325
326 if (input_rep_type == RESET_RESPONSE) {
327 dev_dbg(qsdev->dev, "RESET_RESPONSE received\n");
328 } else {
329 dev_err_once(qsdev->dev,
330 "Unexpected input report type: %d, expect RESET_RESPONSE\n",
331 input_rep_type);
332 return -EINVAL;
333 }
334
335 qsdev->state = QUICKSPI_RESET;
336
337 ret = quickspi_get_device_descriptor(qsdev);
338 if (ret)
339 return ret;
340
341 return 0;
342 }
343
quickspi_get_report(struct quickspi_device * qsdev,u8 report_type,unsigned int report_id,void * buf)344 int quickspi_get_report(struct quickspi_device *qsdev,
345 u8 report_type, unsigned int report_id, void *buf)
346 {
347 int rep_type;
348 int ret;
349
350 if (report_type == HID_INPUT_REPORT) {
351 rep_type = GET_INPUT_REPORT;
352 } else if (report_type == HID_FEATURE_REPORT) {
353 rep_type = GET_FEATURE;
354 } else {
355 dev_err_once(qsdev->dev, "Unsupported report type for GET REPORT: %d\n",
356 report_type);
357 return -EINVAL;
358 }
359
360 ret = write_cmd_to_txdma(qsdev, rep_type, report_id, NULL, 0);
361 if (ret) {
362 dev_err_once(qsdev->dev, "Write GET_REPORT command failed, ret = %d\n", ret);
363 return ret;
364 }
365
366 ret = wait_event_interruptible_timeout(qsdev->get_report_cmpl_wq,
367 qsdev->get_report_cmpl,
368 QUICKSPI_ACK_WAIT_TIMEOUT * HZ);
369 if (ret <= 0 || !qsdev->get_report_cmpl) {
370 dev_err_once(qsdev->dev, "Wait Get Report Response timeout, ret:%d\n", ret);
371 return -ETIMEDOUT;
372 }
373 qsdev->get_report_cmpl = false;
374
375 memcpy(buf, qsdev->report_buf, qsdev->report_len);
376
377 return qsdev->report_len;
378 }
379
quickspi_set_report(struct quickspi_device * qsdev,u8 report_type,unsigned int report_id,void * buf,u32 buf_len)380 int quickspi_set_report(struct quickspi_device *qsdev,
381 u8 report_type, unsigned int report_id,
382 void *buf, u32 buf_len)
383 {
384 int rep_type;
385 int ret;
386
387 if (report_type == HID_OUTPUT_REPORT) {
388 rep_type = OUTPUT_REPORT;
389 } else if (report_type == HID_FEATURE_REPORT) {
390 rep_type = SET_FEATURE;
391 } else {
392 dev_err_once(qsdev->dev, "Unsupported report type for SET REPORT: %d\n",
393 report_type);
394 return -EINVAL;
395 }
396
397 ret = write_cmd_to_txdma(qsdev, rep_type, report_id, buf + 1, buf_len - 1);
398 if (ret) {
399 dev_err_once(qsdev->dev, "Write SET_REPORT command failed, ret = %d\n", ret);
400 return ret;
401 }
402
403 ret = wait_event_interruptible_timeout(qsdev->set_report_cmpl_wq,
404 qsdev->set_report_cmpl,
405 QUICKSPI_ACK_WAIT_TIMEOUT * HZ);
406 if (ret <= 0 || !qsdev->set_report_cmpl) {
407 dev_err_once(qsdev->dev, "Wait Set Report Response timeout, ret:%d\n", ret);
408 return -ETIMEDOUT;
409 }
410 qsdev->set_report_cmpl = false;
411
412 return buf_len;
413 }
414