1 /*
2  * Copyright (c) 2022 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT quicklogic_usbserialport_s3b
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/uart.h>
11 #include <eoss3_dev.h>
12 
13 #include "uart_ql_usbserialport_s3b.h"
14 
15 /*
16  * code is a modified version of usbserial driver from https://github.com/QuickLogic-Corp/qorc-sdk
17  * freertos_gateware/src/eoss3_hal_fpga_usbserial.c
18  * freertos_gateware/inc/eoss3_hal_fpga_usbserial.h
19  */
20 
21 volatile struct fpga_usbserial_regs *usbserial_regs
22 	= (struct fpga_usbserial_regs *)(FPGA_PERIPH_BASE);
23 
usbserial_tx_fifo_status(void)24 static uint32_t usbserial_tx_fifo_status(void)
25 {
26 	return usbserial_regs->m2u_fifo_flags;
27 }
28 
usbserial_tx_fifo_full(void)29 static bool usbserial_tx_fifo_full(void)
30 {
31 	return usbserial_tx_fifo_status() == USBSERIAL_TX_FIFO_FULL;
32 }
33 
usbserial_rx_fifo_status(void)34 static uint32_t usbserial_rx_fifo_status(void)
35 {
36 	return usbserial_regs->u2m_fifo_flags;
37 }
38 
usbserial_rx_fifo_empty(void)39 static bool usbserial_rx_fifo_empty(void)
40 {
41 	return usbserial_rx_fifo_status() == USBSERIAL_RX_FIFO_EMPTY;
42 }
43 
44 /**
45  * @brief Output a character in polled mode.
46  *
47  * Writes data to tx register. Waits for space if transmitter is full.
48  *
49  * @param dev UART device struct
50  * @param c Character to send
51  */
uart_usbserial_poll_out(const struct device * dev,unsigned char c)52 static void uart_usbserial_poll_out(const struct device *dev, unsigned char c)
53 {
54 	/* Wait for room in Tx FIFO */
55 	while (usbserial_tx_fifo_full()) {
56 		;
57 	}
58 	usbserial_regs->wdata = c;
59 }
60 
61 /**
62  * @brief Poll the device for input.
63  *
64  * @param dev UART device struct
65  * @param c Pointer to character
66  *
67  * @return 0 if a character arrived, -1 if the input buffer if empty.
68  */
uart_usbserial_poll_in(const struct device * dev,unsigned char * c)69 static int uart_usbserial_poll_in(const struct device *dev, unsigned char *c)
70 {
71 	if (usbserial_rx_fifo_empty()) {
72 		return -1;
73 	}
74 
75 	*c = usbserial_regs->rdata;
76 	return 0;
77 }
78 
79 static DEVICE_API(uart, uart_usbserial_driver_api) = {
80 	.poll_in		= uart_usbserial_poll_in,
81 	.poll_out		= uart_usbserial_poll_out,
82 };
83 
84 DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, PRE_KERNEL_1,
85 		      CONFIG_SERIAL_INIT_PRIORITY,
86 		      (void *)&uart_usbserial_driver_api);
87