1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2023, Intel Corporation.
4 * Intel Visual Sensing Controller Transport Layer Linux driver
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>
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
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) + le16_to_cpu((pkt)->len) + VSC_TP_CRC_SIZE)
40 #define VSC_TP_MAX_PACKET_SIZE \
41 (sizeof(struct vsc_tp_packet) + 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) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
47 struct vsc_tp_packet
{
52 __u8 buf
[] __counted_by(len
);
56 /* do the actual data transfer */
57 struct spi_device
*spi
;
59 /* bind with mei framework */
60 struct platform_device
*pdev
;
62 struct gpio_desc
*wakeuphost
;
63 struct gpio_desc
*resetfw
;
64 struct gpio_desc
*wakeupfw
;
66 /* command sequence number */
74 wait_queue_head_t xfer_wait
;
76 vsc_tp_event_cb_t event_notify
;
77 void *event_notify_context
;
79 /* used to protect command download */
84 static const struct acpi_gpio_params wakeuphost_gpio
= { 0, 0, false };
85 static const struct acpi_gpio_params wakeuphostint_gpio
= { 1, 0, false };
86 static const struct acpi_gpio_params resetfw_gpio
= { 2, 0, false };
87 static const struct acpi_gpio_params wakeupfw
= { 3, 0, false };
89 static const struct acpi_gpio_mapping vsc_tp_acpi_gpios
[] = {
90 { "wakeuphost-gpios", &wakeuphost_gpio
, 1 },
91 { "wakeuphostint-gpios", &wakeuphostint_gpio
, 1 },
92 { "resetfw-gpios", &resetfw_gpio
, 1 },
93 { "wakeupfw-gpios", &wakeupfw
, 1 },
97 static irqreturn_t
vsc_tp_isr(int irq
, void *data
)
99 struct vsc_tp
*tp
= data
;
101 atomic_inc(&tp
->assert_cnt
);
103 wake_up(&tp
->xfer_wait
);
105 return IRQ_WAKE_THREAD
;
108 static irqreturn_t
vsc_tp_thread_isr(int irq
, void *data
)
110 struct vsc_tp
*tp
= data
;
112 if (tp
->event_notify
)
113 tp
->event_notify(tp
->event_notify_context
);
118 /* wakeup firmware and wait for response */
119 static int vsc_tp_wakeup_request(struct vsc_tp
*tp
)
123 gpiod_set_value_cansleep(tp
->wakeupfw
, 0);
125 ret
= wait_event_timeout(tp
->xfer_wait
,
126 atomic_read(&tp
->assert_cnt
),
127 VSC_TP_WAIT_FW_POLL_TIMEOUT
);
131 return read_poll_timeout(gpiod_get_value_cansleep
, ret
, ret
,
132 VSC_TP_WAIT_FW_POLL_DELAY_US
,
133 VSC_TP_WAIT_FW_POLL_TIMEOUT
, false,
137 static void vsc_tp_wakeup_release(struct vsc_tp
*tp
)
139 atomic_dec_if_positive(&tp
->assert_cnt
);
141 gpiod_set_value_cansleep(tp
->wakeupfw
, 1);
144 static int vsc_tp_dev_xfer(struct vsc_tp
*tp
, void *obuf
, void *ibuf
, size_t len
)
146 struct spi_message msg
= { 0 };
147 struct spi_transfer xfer
= {
153 spi_message_init_with_transfers(&msg
, &xfer
, 1);
155 return spi_sync_locked(tp
->spi
, &msg
);
158 static int vsc_tp_xfer_helper(struct vsc_tp
*tp
, struct vsc_tp_packet
*pkt
,
159 void *ibuf
, u16 ilen
)
161 int ret
, offset
= 0, cpy_len
, src_len
, dst_len
= sizeof(struct vsc_tp_packet
);
162 int next_xfer_len
= VSC_TP_PACKET_SIZE(pkt
) + VSC_TP_XFER_TIMEOUT_BYTES
;
163 u8
*src
, *crc_src
, *rx_buf
= tp
->rx_buf
;
164 int count_down
= VSC_TP_MAX_XFER_COUNT
;
165 u32 recv_crc
= 0, crc
= ~0;
166 struct vsc_tp_packet ack
;
167 u8
*dst
= (u8
*)&ack
;
171 ret
= vsc_tp_dev_xfer(tp
, pkt
, rx_buf
, next_xfer_len
);
174 memset(pkt
, 0, VSC_TP_MAX_XFER_SIZE
);
178 src_len
= next_xfer_len
;
180 src
= memchr(rx_buf
, VSC_TP_PACKET_SYNC
, next_xfer_len
);
184 src_len
= next_xfer_len
- (src
- rx_buf
);
187 /* traverse received data */
188 while (src_len
> 0) {
189 cpy_len
= min(src_len
, dst_len
);
190 memcpy(dst
, src
, cpy_len
);
197 if (offset
< sizeof(ack
)) {
199 crc
= crc32(crc
, crc_src
, cpy_len
);
204 if (le16_to_cpu(ack
.len
)) {
206 dst_len
= min(ilen
, le16_to_cpu(ack
.len
));
208 dst
= (u8
*)&recv_crc
;
209 dst_len
= sizeof(recv_crc
);
211 } else if (offset
< sizeof(ack
) + le16_to_cpu(ack
.len
)) {
213 crc
= crc32(crc
, crc_src
, cpy_len
);
216 int remain
= sizeof(ack
) + le16_to_cpu(ack
.len
) - offset
;
218 cpy_len
= min(src_len
, remain
);
220 crc
= crc32(crc
, src
, cpy_len
);
224 dst
= (u8
*)&recv_crc
;
225 dst_len
= sizeof(recv_crc
);
229 next_xfer_len
= VSC_TP_NEXT_XFER_LEN(le16_to_cpu(ack
.len
), offset
);
230 } else if (offset
< sizeof(ack
) + le16_to_cpu(ack
.len
) + VSC_TP_CRC_SIZE
) {
234 /* terminate the traverse */
238 next_xfer_len
= VSC_TP_NEXT_XFER_LEN(le16_to_cpu(ack
.len
), offset
);
241 } while (next_xfer_len
> 0 && --count_down
);
243 if (next_xfer_len
> 0)
246 if (~recv_crc
!= crc
|| le32_to_cpu(ack
.seq
) != tp
->seq
) {
247 dev_err(&tp
->spi
->dev
, "recv crc or seq error\n");
251 if (ack
.cmd
== VSC_TP_CMD_ACK
|| ack
.cmd
== VSC_TP_CMD_NACK
||
252 ack
.cmd
== VSC_TP_CMD_BUSY
) {
253 dev_err(&tp
->spi
->dev
, "recv cmd ack error\n");
257 return min(le16_to_cpu(ack
.len
), ilen
);
261 * vsc_tp_xfer - transfer data to firmware
262 * @tp: vsc_tp device handle
263 * @cmd: the command to be sent to the device
264 * @obuf: the tx buffer to be sent to the device
265 * @olen: the length of tx buffer
266 * @ibuf: the rx buffer to receive from the device
267 * @ilen: the length of rx buffer
268 * Return: the length of received data in case of success,
269 * otherwise negative value
271 int vsc_tp_xfer(struct vsc_tp
*tp
, u8 cmd
, const void *obuf
, size_t olen
,
272 void *ibuf
, size_t ilen
)
274 struct vsc_tp_packet
*pkt
= tp
->tx_buf
;
278 if (!obuf
|| !ibuf
|| olen
> VSC_TP_MAX_MSG_SIZE
)
281 guard(mutex
)(&tp
->mutex
);
283 pkt
->sync
= VSC_TP_PACKET_SYNC
;
285 pkt
->len
= cpu_to_le16(olen
);
286 pkt
->seq
= cpu_to_le32(++tp
->seq
);
287 memcpy(pkt
->buf
, obuf
, olen
);
289 crc
= ~crc32(~0, (u8
*)pkt
, sizeof(pkt
) + olen
);
290 memcpy(pkt
->buf
+ olen
, &crc
, sizeof(crc
));
292 ret
= vsc_tp_wakeup_request(tp
);
294 dev_err(&tp
->spi
->dev
, "wakeup firmware failed ret: %d\n", ret
);
296 ret
= vsc_tp_xfer_helper(tp
, pkt
, ibuf
, ilen
);
298 vsc_tp_wakeup_release(tp
);
302 EXPORT_SYMBOL_NS_GPL(vsc_tp_xfer
, "VSC_TP");
305 * vsc_tp_rom_xfer - transfer data to rom code
306 * @tp: vsc_tp device handle
307 * @obuf: the data buffer to be sent to the device
308 * @ibuf: the buffer to receive data from the device
309 * @len: the length of tx buffer and rx buffer
310 * Return: 0 in case of success, negative value in case of error
312 int vsc_tp_rom_xfer(struct vsc_tp
*tp
, const void *obuf
, void *ibuf
, size_t len
)
314 size_t words
= len
/ sizeof(__be32
);
317 if (len
% sizeof(__be32
) || len
> VSC_TP_MAX_MSG_SIZE
)
320 guard(mutex
)(&tp
->mutex
);
322 /* rom xfer is big endian */
323 cpu_to_be32_array(tp
->tx_buf
, obuf
, words
);
325 ret
= read_poll_timeout(gpiod_get_value_cansleep
, ret
,
326 !ret
, VSC_TP_ROM_XFER_POLL_DELAY_US
,
327 VSC_TP_ROM_XFER_POLL_TIMEOUT_US
, false,
330 dev_err(&tp
->spi
->dev
, "wait rom failed ret: %d\n", ret
);
334 ret
= vsc_tp_dev_xfer(tp
, tp
->tx_buf
, ibuf
? tp
->rx_buf
: NULL
, len
);
339 be32_to_cpu_array(ibuf
, tp
->rx_buf
, words
);
345 * vsc_tp_reset - reset vsc transport layer
346 * @tp: vsc_tp device handle
348 void vsc_tp_reset(struct vsc_tp
*tp
)
350 disable_irq(tp
->spi
->irq
);
352 /* toggle reset pin */
353 gpiod_set_value_cansleep(tp
->resetfw
, 0);
354 msleep(VSC_TP_RESET_PIN_TOGGLE_INTERVAL_MS
);
355 gpiod_set_value_cansleep(tp
->resetfw
, 1);
358 msleep(VSC_TP_ROM_BOOTUP_DELAY_MS
);
361 * Set default host wakeup pin to non-active
362 * to avoid unexpected host irq interrupt.
364 gpiod_set_value_cansleep(tp
->wakeupfw
, 1);
366 atomic_set(&tp
->assert_cnt
, 0);
368 EXPORT_SYMBOL_NS_GPL(vsc_tp_reset
, "VSC_TP");
371 * vsc_tp_need_read - check if device has data to sent
372 * @tp: vsc_tp device handle
373 * Return: true if device has data to sent, otherwise false
375 bool vsc_tp_need_read(struct vsc_tp
*tp
)
377 if (!atomic_read(&tp
->assert_cnt
))
379 if (!gpiod_get_value_cansleep(tp
->wakeuphost
))
381 if (!gpiod_get_value_cansleep(tp
->wakeupfw
))
386 EXPORT_SYMBOL_NS_GPL(vsc_tp_need_read
, "VSC_TP");
389 * vsc_tp_register_event_cb - register a callback function to receive event
390 * @tp: vsc_tp device handle
391 * @event_cb: callback function
392 * @context: execution context of event callback
393 * Return: 0 in case of success, negative value in case of error
395 int vsc_tp_register_event_cb(struct vsc_tp
*tp
, vsc_tp_event_cb_t event_cb
,
398 tp
->event_notify
= event_cb
;
399 tp
->event_notify_context
= context
;
403 EXPORT_SYMBOL_NS_GPL(vsc_tp_register_event_cb
, "VSC_TP");
406 * vsc_tp_request_irq - request irq for vsc_tp device
407 * @tp: vsc_tp device handle
409 int vsc_tp_request_irq(struct vsc_tp
*tp
)
411 struct spi_device
*spi
= tp
->spi
;
412 struct device
*dev
= &spi
->dev
;
415 irq_set_status_flags(spi
->irq
, IRQ_DISABLE_UNLAZY
);
416 ret
= request_threaded_irq(spi
->irq
, vsc_tp_isr
, vsc_tp_thread_isr
,
417 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
424 EXPORT_SYMBOL_NS_GPL(vsc_tp_request_irq
, "VSC_TP");
427 * vsc_tp_free_irq - free irq for vsc_tp device
428 * @tp: vsc_tp device handle
430 void vsc_tp_free_irq(struct vsc_tp
*tp
)
432 free_irq(tp
->spi
->irq
, tp
);
434 EXPORT_SYMBOL_NS_GPL(vsc_tp_free_irq
, "VSC_TP");
437 * vsc_tp_intr_synchronize - synchronize vsc_tp interrupt
438 * @tp: vsc_tp device handle
440 void vsc_tp_intr_synchronize(struct vsc_tp
*tp
)
442 synchronize_irq(tp
->spi
->irq
);
444 EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_synchronize
, "VSC_TP");
447 * vsc_tp_intr_enable - enable vsc_tp interrupt
448 * @tp: vsc_tp device handle
450 void vsc_tp_intr_enable(struct vsc_tp
*tp
)
452 enable_irq(tp
->spi
->irq
);
454 EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_enable
, "VSC_TP");
457 * vsc_tp_intr_disable - disable vsc_tp interrupt
458 * @tp: vsc_tp device handle
460 void vsc_tp_intr_disable(struct vsc_tp
*tp
)
462 disable_irq(tp
->spi
->irq
);
464 EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_disable
, "VSC_TP");
466 static int vsc_tp_match_any(struct acpi_device
*adev
, void *data
)
468 struct acpi_device
**__adev
= data
;
475 static int vsc_tp_probe(struct spi_device
*spi
)
478 struct platform_device_info pinfo
= {
481 .size_data
= sizeof(tp
),
482 .id
= PLATFORM_DEVID_NONE
,
484 struct device
*dev
= &spi
->dev
;
485 struct platform_device
*pdev
;
486 struct acpi_device
*adev
;
489 tp
= devm_kzalloc(dev
, sizeof(*tp
), GFP_KERNEL
);
493 tp
->tx_buf
= devm_kzalloc(dev
, VSC_TP_MAX_XFER_SIZE
, GFP_KERNEL
);
497 tp
->rx_buf
= devm_kzalloc(dev
, VSC_TP_MAX_XFER_SIZE
, GFP_KERNEL
);
501 ret
= devm_acpi_dev_add_driver_gpios(dev
, vsc_tp_acpi_gpios
);
505 tp
->wakeuphost
= devm_gpiod_get(dev
, "wakeuphost", GPIOD_IN
);
506 if (IS_ERR(tp
->wakeuphost
))
507 return PTR_ERR(tp
->wakeuphost
);
509 tp
->resetfw
= devm_gpiod_get(dev
, "resetfw", GPIOD_OUT_HIGH
);
510 if (IS_ERR(tp
->resetfw
))
511 return PTR_ERR(tp
->resetfw
);
513 tp
->wakeupfw
= devm_gpiod_get(dev
, "wakeupfw", GPIOD_OUT_HIGH
);
514 if (IS_ERR(tp
->wakeupfw
))
515 return PTR_ERR(tp
->wakeupfw
);
517 atomic_set(&tp
->assert_cnt
, 0);
518 init_waitqueue_head(&tp
->xfer_wait
);
521 irq_set_status_flags(spi
->irq
, IRQ_DISABLE_UNLAZY
);
522 ret
= request_threaded_irq(spi
->irq
, vsc_tp_isr
, vsc_tp_thread_isr
,
523 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
528 mutex_init(&tp
->mutex
);
530 /* only one child acpi device */
531 ret
= acpi_dev_for_each_child(ACPI_COMPANION(dev
),
532 vsc_tp_match_any
, &adev
);
535 goto err_destroy_lock
;
538 pinfo
.fwnode
= acpi_fwnode_handle(adev
);
539 pdev
= platform_device_register_full(&pinfo
);
542 goto err_destroy_lock
;
546 spi_set_drvdata(spi
, tp
);
551 mutex_destroy(&tp
->mutex
);
553 free_irq(spi
->irq
, tp
);
558 static void vsc_tp_remove(struct spi_device
*spi
)
560 struct vsc_tp
*tp
= spi_get_drvdata(spi
);
562 platform_device_unregister(tp
->pdev
);
564 mutex_destroy(&tp
->mutex
);
566 free_irq(spi
->irq
, tp
);
569 static void vsc_tp_shutdown(struct spi_device
*spi
)
571 struct vsc_tp
*tp
= spi_get_drvdata(spi
);
573 platform_device_unregister(tp
->pdev
);
575 mutex_destroy(&tp
->mutex
);
579 free_irq(spi
->irq
, tp
);
582 static const struct acpi_device_id vsc_tp_acpi_ids
[] = {
583 { "INTC1009" }, /* Raptor Lake */
584 { "INTC1058" }, /* Tiger Lake */
585 { "INTC1094" }, /* Alder Lake */
586 { "INTC10D0" }, /* Meteor Lake */
589 MODULE_DEVICE_TABLE(acpi
, vsc_tp_acpi_ids
);
591 static struct spi_driver vsc_tp_driver
= {
592 .probe
= vsc_tp_probe
,
593 .remove
= vsc_tp_remove
,
594 .shutdown
= vsc_tp_shutdown
,
597 .acpi_match_table
= vsc_tp_acpi_ids
,
600 module_spi_driver(vsc_tp_driver
);
602 MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
603 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
604 MODULE_DESCRIPTION("Intel Visual Sensing Controller Transport Layer");
605 MODULE_LICENSE("GPL");