Line data Source code
1 0 : /*
2 : * Copyright (c) 2025 Core Devices LLC
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #ifndef INCLUDE_ZEPHYR_DRIVERS_DMA_SF32LB_H_
7 : #define INCLUDE_ZEPHYR_DRIVERS_DMA_SF32LB_H_
8 :
9 : #include <stdint.h>
10 :
11 : #include <zephyr/device.h>
12 : #include <zephyr/devicetree.h>
13 : #include <zephyr/drivers/dma.h>
14 : #include <zephyr/dt-bindings/dma/sf32lb-dma-config.h>
15 : #include <zephyr/sys/util.h>
16 :
17 : /**
18 : * @brief DMA (SF32LB specifics)
19 : * @defgroup dma_sf32lb DMA (SF32LB specifics)
20 : * @ingroup dma_interface
21 : * @{
22 : */
23 :
24 : /** @brief SF32LB DMA DT spec */
25 1 : struct sf32lb_dma_dt_spec {
26 : /** DMA controller */
27 1 : const struct device *dev;
28 : /** DMA channel */
29 1 : uint8_t channel;
30 : /** DMA request */
31 1 : uint8_t request;
32 : /** DMA configuration */
33 1 : uint8_t config;
34 : };
35 :
36 : /**
37 : * @brief Initialize a `sf32lb_dma_dt_spec` structure from a DT node.
38 : *
39 : * @param node_id DT node identifier
40 : */
41 1 : #define SF32LB_DMA_DT_SPEC_GET(node_id) \
42 : { \
43 : .dev = DEVICE_DT_GET(DT_DMAS_CTLR(node_id)), \
44 : .channel = DT_DMAS_CELL_BY_IDX(node_id, 0, channel), \
45 : .request = DT_DMAS_CELL_BY_IDX(node_id, 0, request), \
46 : .config = DT_DMAS_CELL_BY_IDX(node_id, 0, config), \
47 : }
48 :
49 : /**
50 : * @brief Initialize a `sf32lb_dma_dt_spec` structure from a DT node.
51 : *
52 : * @param node_id DT node identifier
53 : */
54 1 : #define SF32LB_DMA_DT_SPEC_GET_BY_NAME(node_id, name) \
55 : { \
56 : .dev = DEVICE_DT_GET(DT_DMAS_CTLR_BY_NAME(node_id, name)), \
57 : .channel = DT_DMAS_CELL_BY_NAME(node_id, name, channel), \
58 : .request = DT_DMAS_CELL_BY_NAME(node_id, name, request), \
59 : .config = DT_DMAS_CELL_BY_NAME(node_id, name, config), \
60 : }
61 :
62 : /**
63 : * @brief Initialize a `sf32lb_dma_dt_spec` structure from a DT instance.
64 : *
65 : * @param index DT instance index
66 : */
67 1 : #define SF32LB_DMA_DT_INST_SPEC_GET(index) SF32LB_DMA_DT_SPEC_GET(DT_DRV_INST(index))
68 :
69 : /**
70 : * @brief Initialize a `sf32lb_dma_dt_spec` structure from a DT instance.
71 : *
72 : * @param index DT instance index
73 : * @param name DMA name
74 : */
75 1 : #define SF32LB_DMA_DT_INST_SPEC_GET_BY_NAME(index, name) \
76 : SF32LB_DMA_DT_SPEC_GET_BY_NAME(DT_DRV_INST(index), name)
77 :
78 : /**
79 : * @brief Check if the DMA controller is ready
80 : *
81 : * @param spec SF32LB DMA DT spec
82 : *
83 : * @return true If the DMA controller is ready.
84 : * @return false If the DMA controller is not ready.
85 : */
86 1 : static inline bool sf32lb_dma_is_ready_dt(const struct sf32lb_dma_dt_spec *spec)
87 : {
88 : return device_is_ready(spec->dev);
89 : }
90 :
91 : /**
92 : * @brief Initialize a DMA configuration structure from a DT spec.
93 : *
94 : * This function sets the following fields in the dma_config structure:
95 : * - dma_slot
96 : * - channel_priority
97 : *
98 : * @param spec SF32LB DMA DT spec
99 : * @param[out] config DMA configuration
100 : */
101 1 : static inline void sf32lb_dma_config_init_dt(const struct sf32lb_dma_dt_spec *spec,
102 : struct dma_config *config)
103 : {
104 : config->dma_slot = spec->request;
105 : config->channel_priority = FIELD_GET(SF32LB_DMA_PL_MSK, spec->config);
106 : }
107 :
108 : /**
109 : * @brief Configure a DMA channel from a DT spec.
110 : *
111 : * @param spec SF32LB DMA DT spec
112 : * @param config DMA configuration
113 : *
114 : * @retval 0 If successful.
115 : * @retval -ENOTSUP If the configuration is not supported.
116 : * @retval -errno Other negative errno code failure (see dma_config()).
117 : */
118 1 : static inline int sf32lb_dma_config_dt(const struct sf32lb_dma_dt_spec *spec,
119 : struct dma_config *config)
120 : {
121 : return dma_config(spec->dev, spec->channel, config);
122 : }
123 :
124 : /**
125 : * @brief Start a DMA transfer from a DT spec.
126 : *
127 : * @param spec SF32LB DMA DT spec
128 : *
129 : * @retval 0 If successful.
130 : * @retval -errno Negative errno code failure (see dma_start()).
131 : */
132 1 : static inline int sf32lb_dma_start_dt(const struct sf32lb_dma_dt_spec *spec)
133 : {
134 : return dma_start(spec->dev, spec->channel);
135 : }
136 :
137 : /**
138 : * @brief Stop a DMA transfer from a DT spec.
139 : *
140 : * @param spec SF32LB DMA DT spec
141 : *
142 : * @retval 0 If successful.
143 : * @retval -errno Negative errno code failure (see dma_stop()).
144 : */
145 1 : static inline int sf32lb_dma_stop_dt(const struct sf32lb_dma_dt_spec *spec)
146 : {
147 : return dma_stop(spec->dev, spec->channel);
148 : }
149 :
150 : /**
151 : * @brief Reload a DMA transfer from a DT spec.
152 : *
153 : * @param spec SF32LB DMA DT spec
154 : * @param src Source address
155 : * @param dst Destination address
156 : * @param size Transfer size
157 : *
158 : * @retval 0 If successful.
159 : * @retval -errno Negative errno code failure (see dma_reload()).
160 : */
161 1 : static inline int sf32lb_dma_reload_dt(const struct sf32lb_dma_dt_spec *spec, uintptr_t src,
162 : uintptr_t dst, size_t size)
163 : {
164 : return dma_reload(spec->dev, spec->channel, src, dst, size);
165 : }
166 :
167 : /**
168 : * @brief Get the status of a DMA transfer from a DT spec.
169 : *
170 : * @param spec SF32LB DMA DT spec
171 : * @param[out] status Status output
172 : *
173 : * @retval 0 If successful.
174 : * @retval -errno Negative errno code failure (see dma_get_status()).
175 : */
176 1 : static inline int sf32lb_dma_get_status_dt(const struct sf32lb_dma_dt_spec *spec,
177 : struct dma_status *status)
178 : {
179 : return dma_get_status(spec->dev, spec->channel, status);
180 : }
181 :
182 : /** @} */
183 :
184 : #endif /* INCLUDE_ZEPHYR_DRIVERS_DMA_SF32LB_H_ */
|