1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2023, Intel Corporation. 4 * Intel Visual Sensing Controller Transport Layer Linux driver 5 */ 6 7 #include <linux/acpi.h> 8 #include <linux/cleanup.h> 9 #include <linux/crc32.h> 10 #include <linux/delay.h> 11 #include <linux/device.h> 12 #include <linux/interrupt.h> 13 #include <linux/iopoll.h> 14 #include <linux/irq.h> 15 #include <linux/irqreturn.h> 16 #include <linux/module.h> 17 #include <linux/mutex.h> 18 #include <linux/platform_device.h> 19 #include <linux/spi/spi.h> 20 #include <linux/types.h> 21 22 #include "vsc-tp.h" 23 24 #define VSC_TP_RESET_PIN_TOGGLE_INTERVAL_MS 20 25 #define VSC_TP_ROM_BOOTUP_DELAY_MS 10 26 #define VSC_TP_ROM_XFER_POLL_TIMEOUT_US (500 * USEC_PER_MSEC) 27 #define VSC_TP_ROM_XFER_POLL_DELAY_US (20 * USEC_PER_MSEC) 28 #define VSC_TP_WAIT_FW_POLL_TIMEOUT (2 * HZ) 29 #define VSC_TP_WAIT_FW_POLL_DELAY_US (20 * USEC_PER_MSEC) 30 #define VSC_TP_MAX_XFER_COUNT 5 31 32 #define VSC_TP_PACKET_SYNC 0x31 33 #define VSC_TP_CRC_SIZE sizeof(u32) 34 #define VSC_TP_MAX_MSG_SIZE 2048 35 /* SPI xfer timeout size */ 36 #define VSC_TP_XFER_TIMEOUT_BYTES 700 37 #define VSC_TP_PACKET_PADDING_SIZE 1 38 #define VSC_TP_PACKET_SIZE(pkt) \ 39 (sizeof(struct vsc_tp_packet_hdr) + le16_to_cpu((pkt)->hdr.len) + VSC_TP_CRC_SIZE) 40 #define VSC_TP_MAX_PACKET_SIZE \ 41 (sizeof(struct vsc_tp_packet_hdr) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE) 42 #define VSC_TP_MAX_XFER_SIZE \ 43 (VSC_TP_MAX_PACKET_SIZE + VSC_TP_XFER_TIMEOUT_BYTES) 44 #define VSC_TP_NEXT_XFER_LEN(len, offset) \ 45 (len + sizeof(struct vsc_tp_packet_hdr) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE) 46 47 struct vsc_tp_packet_hdr { 48 __u8 sync; 49 __u8 cmd; 50 __le16 len; 51 __le32 seq; 52 }; 53 54 struct vsc_tp_packet { 55 struct vsc_tp_packet_hdr hdr; 56 __u8 buf[VSC_TP_MAX_XFER_SIZE - sizeof(struct vsc_tp_packet_hdr)]; 57 }; 58 59 struct vsc_tp { 60 /* do the actual data transfer */ 61 struct spi_device *spi; 62 63 /* bind with mei framework */ 64 struct platform_device *pdev; 65 66 struct gpio_desc *wakeuphost; 67 struct gpio_desc *resetfw; 68 struct gpio_desc *wakeupfw; 69 70 /* command sequence number */ 71 u32 seq; 72 73 /* command buffer */ 74 struct vsc_tp_packet *tx_buf; 75 struct vsc_tp_packet *rx_buf; 76 77 atomic_t assert_cnt; 78 wait_queue_head_t xfer_wait; 79 80 vsc_tp_event_cb_t event_notify; 81 void *event_notify_context; 82 83 /* used to protect command download */ 84 struct mutex mutex; 85 }; 86 87 /* GPIO resources */ 88 static const struct acpi_gpio_params wakeuphost_gpio = { 0, 0, false }; 89 static const struct acpi_gpio_params wakeuphostint_gpio = { 1, 0, false }; 90 static const struct acpi_gpio_params resetfw_gpio = { 2, 0, false }; 91 static const struct acpi_gpio_params wakeupfw = { 3, 0, false }; 92 93 static const struct acpi_gpio_mapping vsc_tp_acpi_gpios[] = { 94 { "wakeuphost-gpios", &wakeuphost_gpio, 1 }, 95 { "wakeuphostint-gpios", &wakeuphostint_gpio, 1 }, 96 { "resetfw-gpios", &resetfw_gpio, 1 }, 97 { "wakeupfw-gpios", &wakeupfw, 1 }, 98 {} 99 }; 100 101 static irqreturn_t vsc_tp_isr(int irq, void *data) 102 { 103 struct vsc_tp *tp = data; 104 105 atomic_inc(&tp->assert_cnt); 106 107 wake_up(&tp->xfer_wait); 108 109 return IRQ_WAKE_THREAD; 110 } 111 112 static irqreturn_t vsc_tp_thread_isr(int irq, void *data) 113 { 114 struct vsc_tp *tp = data; 115 116 if (tp->event_notify) 117 tp->event_notify(tp->event_notify_context); 118 119 return IRQ_HANDLED; 120 } 121 122 /* wakeup firmware and wait for response */ 123 static int vsc_tp_wakeup_request(struct vsc_tp *tp) 124 { 125 int ret; 126 127 gpiod_set_value_cansleep(tp->wakeupfw, 0); 128 129 ret = wait_event_timeout(tp->xfer_wait, 130 atomic_read(&tp->assert_cnt), 131 VSC_TP_WAIT_FW_POLL_TIMEOUT); 132 if (!ret) 133 return -ETIMEDOUT; 134 135 return read_poll_timeout(gpiod_get_value_cansleep, ret, ret, 136 VSC_TP_WAIT_FW_POLL_DELAY_US, 137 VSC_TP_WAIT_FW_POLL_TIMEOUT, false, 138 tp->wakeuphost); 139 } 140 141 static void vsc_tp_wakeup_release(struct vsc_tp *tp) 142 { 143 atomic_dec_if_positive(&tp->assert_cnt); 144 145 gpiod_set_value_cansleep(tp->wakeupfw, 1); 146 } 147 148 static int vsc_tp_dev_xfer(struct vsc_tp *tp, void *obuf, void *ibuf, size_t len) 149 { 150 struct spi_message msg = { 0 }; 151 struct spi_transfer xfer = { 152 .tx_buf = obuf, 153 .rx_buf = ibuf, 154 .len = len, 155 }; 156 157 spi_message_init_with_transfers(&msg, &xfer, 1); 158 159 return spi_sync_locked(tp->spi, &msg); 160 } 161 162 static int vsc_tp_xfer_helper(struct vsc_tp *tp, struct vsc_tp_packet *pkt, 163 void *ibuf, u16 ilen) 164 { 165 int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet_hdr); 166 int next_xfer_len = VSC_TP_PACKET_SIZE(pkt) + VSC_TP_XFER_TIMEOUT_BYTES; 167 u8 *src, *crc_src, *rx_buf = (u8 *)tp->rx_buf; 168 int count_down = VSC_TP_MAX_XFER_COUNT; 169 u32 recv_crc = 0, crc = ~0; 170 struct vsc_tp_packet_hdr ack; 171 u8 *dst = (u8 *)&ack; 172 bool synced = false; 173 174 do { 175 ret = vsc_tp_dev_xfer(tp, pkt, rx_buf, next_xfer_len); 176 if (ret) 177 return ret; 178 memset(pkt, 0, VSC_TP_MAX_XFER_SIZE); 179 180 if (synced) { 181 src = rx_buf; 182 src_len = next_xfer_len; 183 } else { 184 src = memchr(rx_buf, VSC_TP_PACKET_SYNC, next_xfer_len); 185 if (!src) 186 continue; 187 synced = true; 188 src_len = next_xfer_len - (src - rx_buf); 189 } 190 191 /* traverse received data */ 192 while (src_len > 0) { 193 cpy_len = min(src_len, dst_len); 194 memcpy(dst, src, cpy_len); 195 crc_src = src; 196 src += cpy_len; 197 src_len -= cpy_len; 198 dst += cpy_len; 199 dst_len -= cpy_len; 200 201 if (offset < sizeof(ack)) { 202 offset += cpy_len; 203 crc = crc32(crc, crc_src, cpy_len); 204 205 if (!src_len) 206 continue; 207 208 if (le16_to_cpu(ack.len)) { 209 dst = ibuf; 210 dst_len = min(ilen, le16_to_cpu(ack.len)); 211 } else { 212 dst = (u8 *)&recv_crc; 213 dst_len = sizeof(recv_crc); 214 } 215 } else if (offset < sizeof(ack) + le16_to_cpu(ack.len)) { 216 offset += cpy_len; 217 crc = crc32(crc, crc_src, cpy_len); 218 219 if (src_len) { 220 int remain = sizeof(ack) + le16_to_cpu(ack.len) - offset; 221 222 cpy_len = min(src_len, remain); 223 offset += cpy_len; 224 crc = crc32(crc, src, cpy_len); 225 src += cpy_len; 226 src_len -= cpy_len; 227 if (src_len) { 228 dst = (u8 *)&recv_crc; 229 dst_len = sizeof(recv_crc); 230 continue; 231 } 232 } 233 next_xfer_len = VSC_TP_NEXT_XFER_LEN(le16_to_cpu(ack.len), offset); 234 } else if (offset < sizeof(ack) + le16_to_cpu(ack.len) + VSC_TP_CRC_SIZE) { 235 offset += cpy_len; 236 237 if (src_len) { 238 /* terminate the traverse */ 239 next_xfer_len = 0; 240 break; 241 } 242 next_xfer_len = VSC_TP_NEXT_XFER_LEN(le16_to_cpu(ack.len), offset); 243 } 244 } 245 } while (next_xfer_len > 0 && --count_down); 246 247 if (next_xfer_len > 0) 248 return -EAGAIN; 249 250 if (~recv_crc != crc || le32_to_cpu(ack.seq) != tp->seq) { 251 dev_err(&tp->spi->dev, "recv crc or seq error\n"); 252 return -EINVAL; 253 } 254 255 if (ack.cmd == VSC_TP_CMD_ACK || ack.cmd == VSC_TP_CMD_NACK || 256 ack.cmd == VSC_TP_CMD_BUSY) { 257 dev_err(&tp->spi->dev, "recv cmd ack error\n"); 258 return -EAGAIN; 259 } 260 261 return min(le16_to_cpu(ack.len), ilen); 262 } 263 264 /** 265 * vsc_tp_xfer - transfer data to firmware 266 * @tp: vsc_tp device handle 267 * @cmd: the command to be sent to the device 268 * @obuf: the tx buffer to be sent to the device 269 * @olen: the length of tx buffer 270 * @ibuf: the rx buffer to receive from the device 271 * @ilen: the length of rx buffer 272 * Return: the length of received data in case of success, 273 * otherwise negative value 274 */ 275 int vsc_tp_xfer(struct vsc_tp *tp, u8 cmd, const void *obuf, size_t olen, 276 void *ibuf, size_t ilen) 277 { 278 struct vsc_tp_packet *pkt = tp->tx_buf; 279 u32 crc; 280 int ret; 281 282 if (!obuf || !ibuf || olen > VSC_TP_MAX_MSG_SIZE) 283 return -EINVAL; 284 285 guard(mutex)(&tp->mutex); 286 287 pkt->hdr.sync = VSC_TP_PACKET_SYNC; 288 pkt->hdr.cmd = cmd; 289 pkt->hdr.len = cpu_to_le16(olen); 290 pkt->hdr.seq = cpu_to_le32(++tp->seq); 291 memcpy(pkt->buf, obuf, olen); 292 293 crc = ~crc32(~0, (u8 *)pkt, sizeof(pkt) + olen); 294 memcpy(pkt->buf + olen, &crc, sizeof(crc)); 295 296 ret = vsc_tp_wakeup_request(tp); 297 if (unlikely(ret)) 298 dev_err(&tp->spi->dev, "wakeup firmware failed ret: %d\n", ret); 299 else 300 ret = vsc_tp_xfer_helper(tp, pkt, ibuf, ilen); 301 302 vsc_tp_wakeup_release(tp); 303 304 return ret; 305 } 306 EXPORT_SYMBOL_NS_GPL(vsc_tp_xfer, "VSC_TP"); 307 308 /** 309 * vsc_tp_rom_xfer - transfer data to rom code 310 * @tp: vsc_tp device handle 311 * @obuf: the data buffer to be sent to the device 312 * @ibuf: the buffer to receive data from the device 313 * @len: the length of tx buffer and rx buffer 314 * Return: 0 in case of success, negative value in case of error 315 */ 316 int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len) 317 { 318 size_t words = len / sizeof(__be32); 319 int ret; 320 321 if (len % sizeof(__be32) || len > VSC_TP_MAX_MSG_SIZE) 322 return -EINVAL; 323 324 guard(mutex)(&tp->mutex); 325 326 /* rom xfer is big endian */ 327 cpu_to_be32_array((u32 *)tp->tx_buf, obuf, words); 328 329 ret = read_poll_timeout(gpiod_get_value_cansleep, ret, 330 !ret, VSC_TP_ROM_XFER_POLL_DELAY_US, 331 VSC_TP_ROM_XFER_POLL_TIMEOUT_US, false, 332 tp->wakeuphost); 333 if (ret) { 334 dev_err(&tp->spi->dev, "wait rom failed ret: %d\n", ret); 335 return ret; 336 } 337 338 ret = vsc_tp_dev_xfer(tp, tp->tx_buf, ibuf ? tp->rx_buf : NULL, len); 339 if (ret) 340 return ret; 341 342 if (ibuf) 343 be32_to_cpu_array(ibuf, (u32 *)tp->rx_buf, words); 344 345 return ret; 346 } 347 348 /** 349 * vsc_tp_reset - reset vsc transport layer 350 * @tp: vsc_tp device handle 351 */ 352 void vsc_tp_reset(struct vsc_tp *tp) 353 { 354 disable_irq(tp->spi->irq); 355 356 /* toggle reset pin */ 357 gpiod_set_value_cansleep(tp->resetfw, 0); 358 msleep(VSC_TP_RESET_PIN_TOGGLE_INTERVAL_MS); 359 gpiod_set_value_cansleep(tp->resetfw, 1); 360 361 /* wait for ROM */ 362 msleep(VSC_TP_ROM_BOOTUP_DELAY_MS); 363 364 /* 365 * Set default host wakeup pin to non-active 366 * to avoid unexpected host irq interrupt. 367 */ 368 gpiod_set_value_cansleep(tp->wakeupfw, 1); 369 370 atomic_set(&tp->assert_cnt, 0); 371 } 372 EXPORT_SYMBOL_NS_GPL(vsc_tp_reset, "VSC_TP"); 373 374 /** 375 * vsc_tp_need_read - check if device has data to sent 376 * @tp: vsc_tp device handle 377 * Return: true if device has data to sent, otherwise false 378 */ 379 bool vsc_tp_need_read(struct vsc_tp *tp) 380 { 381 if (!atomic_read(&tp->assert_cnt)) 382 return false; 383 if (!gpiod_get_value_cansleep(tp->wakeuphost)) 384 return false; 385 if (!gpiod_get_value_cansleep(tp->wakeupfw)) 386 return false; 387 388 return true; 389 } 390 EXPORT_SYMBOL_NS_GPL(vsc_tp_need_read, "VSC_TP"); 391 392 /** 393 * vsc_tp_register_event_cb - register a callback function to receive event 394 * @tp: vsc_tp device handle 395 * @event_cb: callback function 396 * @context: execution context of event callback 397 * Return: 0 in case of success, negative value in case of error 398 */ 399 int vsc_tp_register_event_cb(struct vsc_tp *tp, vsc_tp_event_cb_t event_cb, 400 void *context) 401 { 402 tp->event_notify = event_cb; 403 tp->event_notify_context = context; 404 405 return 0; 406 } 407 EXPORT_SYMBOL_NS_GPL(vsc_tp_register_event_cb, "VSC_TP"); 408 409 /** 410 * vsc_tp_request_irq - request irq for vsc_tp device 411 * @tp: vsc_tp device handle 412 */ 413 int vsc_tp_request_irq(struct vsc_tp *tp) 414 { 415 struct spi_device *spi = tp->spi; 416 struct device *dev = &spi->dev; 417 int ret; 418 419 irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY); 420 ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr, 421 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 422 dev_name(dev), tp); 423 if (ret) 424 return ret; 425 426 return 0; 427 } 428 EXPORT_SYMBOL_NS_GPL(vsc_tp_request_irq, "VSC_TP"); 429 430 /** 431 * vsc_tp_free_irq - free irq for vsc_tp device 432 * @tp: vsc_tp device handle 433 */ 434 void vsc_tp_free_irq(struct vsc_tp *tp) 435 { 436 free_irq(tp->spi->irq, tp); 437 } 438 EXPORT_SYMBOL_NS_GPL(vsc_tp_free_irq, "VSC_TP"); 439 440 /** 441 * vsc_tp_intr_synchronize - synchronize vsc_tp interrupt 442 * @tp: vsc_tp device handle 443 */ 444 void vsc_tp_intr_synchronize(struct vsc_tp *tp) 445 { 446 synchronize_irq(tp->spi->irq); 447 } 448 EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_synchronize, "VSC_TP"); 449 450 /** 451 * vsc_tp_intr_enable - enable vsc_tp interrupt 452 * @tp: vsc_tp device handle 453 */ 454 void vsc_tp_intr_enable(struct vsc_tp *tp) 455 { 456 enable_irq(tp->spi->irq); 457 } 458 EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_enable, "VSC_TP"); 459 460 /** 461 * vsc_tp_intr_disable - disable vsc_tp interrupt 462 * @tp: vsc_tp device handle 463 */ 464 void vsc_tp_intr_disable(struct vsc_tp *tp) 465 { 466 disable_irq(tp->spi->irq); 467 } 468 EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_disable, "VSC_TP"); 469 470 static int vsc_tp_match_any(struct acpi_device *adev, void *data) 471 { 472 struct acpi_device **__adev = data; 473 474 *__adev = adev; 475 476 return 1; 477 } 478 479 static int vsc_tp_probe(struct spi_device *spi) 480 { 481 struct vsc_tp *tp; 482 struct platform_device_info pinfo = { 483 .name = "intel_vsc", 484 .data = &tp, 485 .size_data = sizeof(tp), 486 .id = PLATFORM_DEVID_NONE, 487 }; 488 struct device *dev = &spi->dev; 489 struct platform_device *pdev; 490 struct acpi_device *adev; 491 int ret; 492 493 tp = devm_kzalloc(dev, sizeof(*tp), GFP_KERNEL); 494 if (!tp) 495 return -ENOMEM; 496 497 tp->tx_buf = devm_kzalloc(dev, sizeof(*tp->tx_buf), GFP_KERNEL); 498 if (!tp->tx_buf) 499 return -ENOMEM; 500 501 tp->rx_buf = devm_kzalloc(dev, sizeof(*tp->rx_buf), GFP_KERNEL); 502 if (!tp->rx_buf) 503 return -ENOMEM; 504 505 ret = devm_acpi_dev_add_driver_gpios(dev, vsc_tp_acpi_gpios); 506 if (ret) 507 return ret; 508 509 tp->wakeuphost = devm_gpiod_get(dev, "wakeuphostint", GPIOD_IN); 510 if (IS_ERR(tp->wakeuphost)) 511 return PTR_ERR(tp->wakeuphost); 512 513 tp->resetfw = devm_gpiod_get(dev, "resetfw", GPIOD_OUT_HIGH); 514 if (IS_ERR(tp->resetfw)) 515 return PTR_ERR(tp->resetfw); 516 517 tp->wakeupfw = devm_gpiod_get(dev, "wakeupfw", GPIOD_OUT_HIGH); 518 if (IS_ERR(tp->wakeupfw)) 519 return PTR_ERR(tp->wakeupfw); 520 521 atomic_set(&tp->assert_cnt, 0); 522 init_waitqueue_head(&tp->xfer_wait); 523 tp->spi = spi; 524 525 irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY); 526 ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr, 527 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 528 dev_name(dev), tp); 529 if (ret) 530 return ret; 531 532 mutex_init(&tp->mutex); 533 534 /* only one child acpi device */ 535 ret = acpi_dev_for_each_child(ACPI_COMPANION(dev), 536 vsc_tp_match_any, &adev); 537 if (!ret) { 538 ret = -ENODEV; 539 goto err_destroy_lock; 540 } 541 542 pinfo.fwnode = acpi_fwnode_handle(adev); 543 pdev = platform_device_register_full(&pinfo); 544 if (IS_ERR(pdev)) { 545 ret = PTR_ERR(pdev); 546 goto err_destroy_lock; 547 } 548 549 tp->pdev = pdev; 550 spi_set_drvdata(spi, tp); 551 552 return 0; 553 554 err_destroy_lock: 555 mutex_destroy(&tp->mutex); 556 557 free_irq(spi->irq, tp); 558 559 return ret; 560 } 561 562 static void vsc_tp_remove(struct spi_device *spi) 563 { 564 struct vsc_tp *tp = spi_get_drvdata(spi); 565 566 platform_device_unregister(tp->pdev); 567 568 mutex_destroy(&tp->mutex); 569 570 free_irq(spi->irq, tp); 571 } 572 573 static void vsc_tp_shutdown(struct spi_device *spi) 574 { 575 struct vsc_tp *tp = spi_get_drvdata(spi); 576 577 platform_device_unregister(tp->pdev); 578 579 mutex_destroy(&tp->mutex); 580 581 vsc_tp_reset(tp); 582 583 free_irq(spi->irq, tp); 584 } 585 586 static const struct acpi_device_id vsc_tp_acpi_ids[] = { 587 { "INTC1009" }, /* Raptor Lake */ 588 { "INTC1058" }, /* Tiger Lake */ 589 { "INTC1094" }, /* Alder Lake */ 590 { "INTC10D0" }, /* Meteor Lake */ 591 {} 592 }; 593 MODULE_DEVICE_TABLE(acpi, vsc_tp_acpi_ids); 594 595 static struct spi_driver vsc_tp_driver = { 596 .probe = vsc_tp_probe, 597 .remove = vsc_tp_remove, 598 .shutdown = vsc_tp_shutdown, 599 .driver = { 600 .name = "vsc-tp", 601 .acpi_match_table = vsc_tp_acpi_ids, 602 }, 603 }; 604 module_spi_driver(vsc_tp_driver); 605 606 MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>"); 607 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>"); 608 MODULE_DESCRIPTION("Intel Visual Sensing Controller Transport Layer"); 609 MODULE_LICENSE("GPL"); 610