Lines Matching +full:cmd +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0-only
22 #include "vsc-tp.h"
39 (sizeof(struct vsc_tp_packet) + le16_to_cpu((pkt)->len) + VSC_TP_CRC_SIZE)
45 (len + sizeof(struct vsc_tp_packet) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
49 __u8 cmd; member
90 { "wakeuphost-gpios", &wakeuphost_gpio, 1 },
91 { "wakeuphostint-gpios", &wakeuphostint_gpio, 1 },
92 { "resetfw-gpios", &resetfw_gpio, 1 },
93 { "wakeupfw-gpios", &wakeupfw, 1 },
101 atomic_inc(&tp->assert_cnt); in vsc_tp_isr()
103 wake_up(&tp->xfer_wait); in vsc_tp_isr()
112 if (tp->event_notify) in vsc_tp_thread_isr()
113 tp->event_notify(tp->event_notify_context); in vsc_tp_thread_isr()
123 gpiod_set_value_cansleep(tp->wakeupfw, 0); in vsc_tp_wakeup_request()
125 ret = wait_event_timeout(tp->xfer_wait, in vsc_tp_wakeup_request()
126 atomic_read(&tp->assert_cnt), in vsc_tp_wakeup_request()
129 return -ETIMEDOUT; in vsc_tp_wakeup_request()
134 tp->wakeuphost); in vsc_tp_wakeup_request()
139 atomic_dec_if_positive(&tp->assert_cnt); in vsc_tp_wakeup_release()
141 gpiod_set_value_cansleep(tp->wakeupfw, 1); in vsc_tp_wakeup_release()
155 return spi_sync_locked(tp->spi, &msg); in vsc_tp_dev_xfer()
163 u8 *src, *crc_src, *rx_buf = tp->rx_buf; in vsc_tp_xfer_helper()
184 src_len = next_xfer_len - (src - rx_buf); in vsc_tp_xfer_helper()
193 src_len -= cpy_len; in vsc_tp_xfer_helper()
195 dst_len -= cpy_len; in vsc_tp_xfer_helper()
216 int remain = sizeof(ack) + le16_to_cpu(ack.len) - offset; in vsc_tp_xfer_helper()
222 src_len -= cpy_len; in vsc_tp_xfer_helper()
241 } while (next_xfer_len > 0 && --count_down); in vsc_tp_xfer_helper()
244 return -EAGAIN; in vsc_tp_xfer_helper()
246 if (~recv_crc != crc || le32_to_cpu(ack.seq) != tp->seq) { in vsc_tp_xfer_helper()
247 dev_err(&tp->spi->dev, "recv crc or seq error\n"); in vsc_tp_xfer_helper()
248 return -EINVAL; in vsc_tp_xfer_helper()
251 if (ack.cmd == VSC_TP_CMD_ACK || ack.cmd == VSC_TP_CMD_NACK || in vsc_tp_xfer_helper()
252 ack.cmd == VSC_TP_CMD_BUSY) { in vsc_tp_xfer_helper()
253 dev_err(&tp->spi->dev, "recv cmd ack error\n"); in vsc_tp_xfer_helper()
254 return -EAGAIN; in vsc_tp_xfer_helper()
261 * vsc_tp_xfer - transfer data to firmware
263 * @cmd: the command to be sent to the device
271 int vsc_tp_xfer(struct vsc_tp *tp, u8 cmd, const void *obuf, size_t olen, in vsc_tp_xfer() argument
274 struct vsc_tp_packet *pkt = tp->tx_buf; in vsc_tp_xfer()
279 return -EINVAL; in vsc_tp_xfer()
281 guard(mutex)(&tp->mutex); in vsc_tp_xfer()
283 pkt->sync = VSC_TP_PACKET_SYNC; in vsc_tp_xfer()
284 pkt->cmd = cmd; in vsc_tp_xfer()
285 pkt->len = cpu_to_le16(olen); in vsc_tp_xfer()
286 pkt->seq = cpu_to_le32(++tp->seq); in vsc_tp_xfer()
287 memcpy(pkt->buf, obuf, olen); in vsc_tp_xfer()
290 memcpy(pkt->buf + olen, &crc, sizeof(crc)); in vsc_tp_xfer()
294 dev_err(&tp->spi->dev, "wakeup firmware failed ret: %d\n", ret); in vsc_tp_xfer()
305 * vsc_tp_rom_xfer - transfer data to rom code
318 return -EINVAL; in vsc_tp_rom_xfer()
320 guard(mutex)(&tp->mutex); in vsc_tp_rom_xfer()
323 cpu_to_be32_array(tp->tx_buf, obuf, words); in vsc_tp_rom_xfer()
328 tp->wakeuphost); in vsc_tp_rom_xfer()
330 dev_err(&tp->spi->dev, "wait rom failed ret: %d\n", ret); in vsc_tp_rom_xfer()
334 ret = vsc_tp_dev_xfer(tp, tp->tx_buf, ibuf ? tp->rx_buf : NULL, len); in vsc_tp_rom_xfer()
339 be32_to_cpu_array(ibuf, tp->rx_buf, words); in vsc_tp_rom_xfer()
345 * vsc_tp_reset - reset vsc transport layer
350 disable_irq(tp->spi->irq); in vsc_tp_reset()
353 gpiod_set_value_cansleep(tp->resetfw, 0); in vsc_tp_reset()
355 gpiod_set_value_cansleep(tp->resetfw, 1); in vsc_tp_reset()
361 * Set default host wakeup pin to non-active in vsc_tp_reset()
364 gpiod_set_value_cansleep(tp->wakeupfw, 1); in vsc_tp_reset()
366 atomic_set(&tp->assert_cnt, 0); in vsc_tp_reset()
371 * vsc_tp_need_read - check if device has data to sent
377 if (!atomic_read(&tp->assert_cnt)) in vsc_tp_need_read()
379 if (!gpiod_get_value_cansleep(tp->wakeuphost)) in vsc_tp_need_read()
381 if (!gpiod_get_value_cansleep(tp->wakeupfw)) in vsc_tp_need_read()
389 * vsc_tp_register_event_cb - register a callback function to receive event
398 tp->event_notify = event_cb; in vsc_tp_register_event_cb()
399 tp->event_notify_context = context; in vsc_tp_register_event_cb()
406 * vsc_tp_request_irq - request irq for vsc_tp device
411 struct spi_device *spi = tp->spi; in vsc_tp_request_irq()
412 struct device *dev = &spi->dev; in vsc_tp_request_irq()
415 irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY); in vsc_tp_request_irq()
416 ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr, in vsc_tp_request_irq()
427 * vsc_tp_free_irq - free irq for vsc_tp device
432 free_irq(tp->spi->irq, tp); in vsc_tp_free_irq()
437 * vsc_tp_intr_synchronize - synchronize vsc_tp interrupt
442 synchronize_irq(tp->spi->irq); in vsc_tp_intr_synchronize()
447 * vsc_tp_intr_enable - enable vsc_tp interrupt
452 enable_irq(tp->spi->irq); in vsc_tp_intr_enable()
457 * vsc_tp_intr_disable - disable vsc_tp interrupt
462 disable_irq(tp->spi->irq); in vsc_tp_intr_disable()
484 struct device *dev = &spi->dev; in vsc_tp_probe()
491 return -ENOMEM; in vsc_tp_probe()
493 tp->tx_buf = devm_kzalloc(dev, VSC_TP_MAX_XFER_SIZE, GFP_KERNEL); in vsc_tp_probe()
494 if (!tp->tx_buf) in vsc_tp_probe()
495 return -ENOMEM; in vsc_tp_probe()
497 tp->rx_buf = devm_kzalloc(dev, VSC_TP_MAX_XFER_SIZE, GFP_KERNEL); in vsc_tp_probe()
498 if (!tp->rx_buf) in vsc_tp_probe()
499 return -ENOMEM; in vsc_tp_probe()
505 tp->wakeuphost = devm_gpiod_get(dev, "wakeuphostint", GPIOD_IN); in vsc_tp_probe()
506 if (IS_ERR(tp->wakeuphost)) in vsc_tp_probe()
507 return PTR_ERR(tp->wakeuphost); in vsc_tp_probe()
509 tp->resetfw = devm_gpiod_get(dev, "resetfw", GPIOD_OUT_HIGH); in vsc_tp_probe()
510 if (IS_ERR(tp->resetfw)) in vsc_tp_probe()
511 return PTR_ERR(tp->resetfw); in vsc_tp_probe()
513 tp->wakeupfw = devm_gpiod_get(dev, "wakeupfw", GPIOD_OUT_HIGH); in vsc_tp_probe()
514 if (IS_ERR(tp->wakeupfw)) in vsc_tp_probe()
515 return PTR_ERR(tp->wakeupfw); in vsc_tp_probe()
517 atomic_set(&tp->assert_cnt, 0); in vsc_tp_probe()
518 init_waitqueue_head(&tp->xfer_wait); in vsc_tp_probe()
519 tp->spi = spi; in vsc_tp_probe()
521 irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY); in vsc_tp_probe()
522 ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr, in vsc_tp_probe()
528 mutex_init(&tp->mutex); in vsc_tp_probe()
534 ret = -ENODEV; in vsc_tp_probe()
545 tp->pdev = pdev; in vsc_tp_probe()
551 mutex_destroy(&tp->mutex); in vsc_tp_probe()
553 free_irq(spi->irq, tp); in vsc_tp_probe()
562 platform_device_unregister(tp->pdev); in vsc_tp_remove()
564 mutex_destroy(&tp->mutex); in vsc_tp_remove()
566 free_irq(spi->irq, tp); in vsc_tp_remove()
573 platform_device_unregister(tp->pdev); in vsc_tp_shutdown()
575 mutex_destroy(&tp->mutex); in vsc_tp_shutdown()
579 free_irq(spi->irq, tp); in vsc_tp_shutdown()
596 .name = "vsc-tp",