drivers: serial: Added support for raspberry pi

Added a serial driver for the RP2040. Only polling
API is supported.

Signed-off-by: Yonatan Schachter <yonatan.schachter@gmail.com>
diff --git a/CODEOWNERS b/CODEOWNERS
index d40046f..4ba97bc 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -354,6 +354,7 @@
 /drivers/serial/uart_mcux_iuart.c         @Mani-Sadhasivam
 /drivers/serial/Kconfig.rtt               @carlescufi @pkral78
 /drivers/serial/uart_rtt.c                @carlescufi @pkral78
+/drivers/serial/*rpi_pico*                @yonsch
 /drivers/serial/Kconfig.xlnx              @wjliang
 /drivers/serial/uart_xlnx_ps.c            @wjliang
 /drivers/serial/uart_xlnx_uartlite.c      @henrikbrixandersen
diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt
index acb5195..5eef4ea 100644
--- a/drivers/serial/CMakeLists.txt
+++ b/drivers/serial/CMakeLists.txt
@@ -32,6 +32,7 @@
 zephyr_library_sources_ifdef(CONFIG_UART_PSOC6 uart_psoc6.c)
 zephyr_library_sources_ifdef(CONFIG_UART_PL011 uart_pl011.c)
 zephyr_library_sources_ifdef(CONFIG_UART_RV32M1_LPUART uart_rv32m1_lpuart.c)
+zephyr_library_sources_ifdef(CONFIG_UART_RPI_PICO uart_rpi_pico.c)
 zephyr_library_sources_ifdef(CONFIG_UART_LITEUART uart_liteuart.c)
 zephyr_library_sources_ifdef(CONFIG_UART_RTT_DRIVER uart_rtt.c)
 zephyr_library_sources_ifdef(CONFIG_UART_XLNX_PS uart_xlnx_ps.c)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 2455174..3d11054 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -159,6 +159,8 @@
 
 source "drivers/serial/Kconfig.rv32m1_lpuart"
 
+source "drivers/serial/Kconfig.rpi_pico"
+
 source "drivers/serial/Kconfig.litex"
 
 source "drivers/serial/Kconfig.rtt"
diff --git a/drivers/serial/Kconfig.rpi_pico b/drivers/serial/Kconfig.rpi_pico
new file mode 100644
index 0000000..bab871b
--- /dev/null
+++ b/drivers/serial/Kconfig.rpi_pico
@@ -0,0 +1,11 @@
+# Copyright (c) 2021 Yonatan Schachter
+# SPDX-License-Identifier: Apache-2.0
+
+# Workaround for not being able to have commas in macro arguments
+DT_COMPAT_RPI_PICO_UART := raspberrypi,pico-uart
+
+config UART_RPI_PICO
+	bool "Raspberry Pi UART driver"
+	default $(dt_compat_enabled,$(DT_COMPAT_RPI_PICO_UART))
+	select SERIAL_HAS_DRIVER
+	select PICOSDK_USE_UART
diff --git a/drivers/serial/uart_rpi_pico.c b/drivers/serial/uart_rpi_pico.c
new file mode 100644
index 0000000..b0f4e28
--- /dev/null
+++ b/drivers/serial/uart_rpi_pico.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021, Yonatan Schachter
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <drivers/uart.h>
+#include <drivers/pinctrl.h>
+
+/* pico-sdk includes */
+#include <hardware/uart.h>
+
+#define DT_DRV_COMPAT raspberrypi_pico_uart
+
+struct uart_rpi_config {
+	uart_inst_t *const uart_dev;
+	uint32_t baudrate;
+	const struct pinctrl_dev_config *pcfg;
+};
+
+static int uart_rpi_poll_in(const struct device *dev, unsigned char *c)
+{
+	const struct uart_rpi_config *config = dev->config;
+
+	if (!uart_is_readable(config->uart_dev)) {
+		return -1;
+	}
+
+	*c = (unsigned char)uart_get_hw(config->uart_dev)->dr;
+	return 0;
+}
+
+static void uart_rpi_poll_out(const struct device *dev, unsigned char c)
+{
+	const struct uart_rpi_config *config = dev->config;
+
+	uart_putc_raw(config->uart_dev, c);
+}
+
+static int uart_rpi_init(const struct device *dev)
+{
+	const struct uart_rpi_config *config = dev->config;
+	int ret;
+
+	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
+	if (ret < 0) {
+		return ret;
+	}
+
+	uart_init(config->uart_dev, config->baudrate);
+
+	return 0;
+}
+
+static const struct uart_driver_api uart_rpi_driver_api = {
+	.poll_in = uart_rpi_poll_in,
+	.poll_out = uart_rpi_poll_out,
+};
+
+#define RPI_UART_INIT(idx)						\
+	PINCTRL_DT_INST_DEFINE(idx);					\
+	static const struct uart_rpi_config uart_rpi_cfg_##idx = {	\
+		.uart_dev = (uart_inst_t *)DT_INST_REG_ADDR(idx),	\
+		.baudrate = DT_INST_PROP(idx, current_speed),		\
+		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx),		\
+	};								\
+									\
+	DEVICE_DT_INST_DEFINE(idx, &uart_rpi_init,			\
+				NULL,					\
+				NULL,					\
+				&uart_rpi_cfg_##idx, PRE_KERNEL_1,	\
+				CONFIG_SERIAL_INIT_PRIORITY,		\
+				&uart_rpi_driver_api);
+
+DT_INST_FOREACH_STATUS_OKAY(RPI_UART_INIT)
diff --git a/dts/arm/rpi_pico/rp2040.dtsi b/dts/arm/rpi_pico/rp2040.dtsi
index 9cbe7c4..dd48076 100644
--- a/dts/arm/rpi_pico/rp2040.dtsi
+++ b/dts/arm/rpi_pico/rp2040.dtsi
@@ -50,6 +50,26 @@
 			status = "okay";
 			label = "PINCTRL";
 		};
+
+		uart0: uart@40034000 {
+			compatible = "raspberrypi,pico-uart";
+			reg = <0x40034000 DT_SIZE_K(4)>;
+			clocks = <&peripheral_clk>;
+			interrupts = <20 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
+			interrupt-names = "uart0";
+			label = "UART_0";
+			status = "disabled";
+		};
+
+		uart1: uart@40038000 {
+			compatible = "raspberrypi,pico-uart";
+			reg = <0x40038000 DT_SIZE_K(4)>;
+			clocks = <&peripheral_clk>;
+			interrupts = <21 RPI_PICO_DEFAULT_IRQ_PRIORITY>;
+			interrupt-names = "uart1";
+			label = "UART_1";
+			status = "disabled";
+		};
 	};
 };
 
diff --git a/dts/bindings/serial/raspberrypi,pico-uart.yaml b/dts/bindings/serial/raspberrypi,pico-uart.yaml
new file mode 100644
index 0000000..50c3bd4
--- /dev/null
+++ b/dts/bindings/serial/raspberrypi,pico-uart.yaml
@@ -0,0 +1,12 @@
+description: Raspberry Pi Pico UART
+
+compatible: "raspberrypi,pico-uart"
+
+include: [uart-controller.yaml, pinctrl-device.yaml]
+
+properties:
+    reg:
+      required: true
+
+    interrupts:
+      required: true