1 /*
2  * Copyright (c) 2023 Tokita, Hiroshi <tokita.hiroshi@fujitsu.com>
3  * Copyright (c) 2023 Yonatan Schachter
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/clock_control.h>
10 #include <zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <zephyr/drivers/reset.h>
13 
14 #define DT_DRV_COMPAT raspberrypi_pico_pio
15 
16 struct pio_rpi_pico_config {
17 	PIO pio;
18 	const struct device *clk_dev;
19 	clock_control_subsys_t clk_id;
20 	const struct reset_dt_spec reset;
21 };
22 
pio_rpi_pico_allocate_sm(const struct device * dev,size_t * sm)23 int pio_rpi_pico_allocate_sm(const struct device *dev, size_t *sm)
24 {
25 	const struct pio_rpi_pico_config *config = dev->config;
26 	int retval;
27 
28 	retval = pio_claim_unused_sm(config->pio, false);
29 	if (retval < 0) {
30 		return -EBUSY;
31 	}
32 
33 	*sm = (size_t)retval;
34 	return 0;
35 }
36 
pio_rpi_pico_get_pio(const struct device * dev)37 PIO pio_rpi_pico_get_pio(const struct device *dev)
38 {
39 	const struct pio_rpi_pico_config *config = dev->config;
40 
41 	return config->pio;
42 }
43 
pio_rpi_pico_init(const struct device * dev)44 static int pio_rpi_pico_init(const struct device *dev)
45 {
46 	const struct pio_rpi_pico_config *config = dev->config;
47 	int ret;
48 
49 	ret = clock_control_on(config->clk_dev, config->clk_id);
50 	if (ret < 0) {
51 		return ret;
52 	}
53 
54 	ret = reset_line_toggle_dt(&config->reset);
55 	if (ret < 0) {
56 		return ret;
57 	}
58 
59 	return 0;
60 }
61 
62 #define RPI_PICO_PIO_INIT(idx)                                                                     \
63 	static const struct pio_rpi_pico_config pio_rpi_pico_config_##idx = {                      \
64 		.pio = (PIO)DT_INST_REG_ADDR(idx),                                                 \
65 		.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)),                                \
66 		.clk_id = (clock_control_subsys_t)DT_INST_PHA_BY_IDX(0, clocks, 0, clk_id),        \
67 		.reset = RESET_DT_SPEC_INST_GET(idx),                                              \
68 	};                                                                                         \
69                                                                                                    \
70 	DEVICE_DT_INST_DEFINE(idx, &pio_rpi_pico_init, NULL, NULL, &pio_rpi_pico_config_##idx,     \
71 			      PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
72 
73 DT_INST_FOREACH_STATUS_OKAY(RPI_PICO_PIO_INIT)
74