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