1 /**
2  * @file
3  * @brief SPI Devicetree macro public API header file.
4  */
5 
6 /*
7  * Copyright (c) 2020 Nordic Semiconductor
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_DEVICETREE_SPI_H_
13 #define ZEPHYR_INCLUDE_DEVICETREE_SPI_H_
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @defgroup devicetree-spi Devicetree SPI API
21  * @ingroup devicetree
22  * @{
23  */
24 
25 /**
26  * @brief Does a SPI controller node have chip select GPIOs configured?
27  *
28  * SPI bus controllers use the "cs-gpios" property for configuring
29  * chip select GPIOs. Its value is a phandle-array which specifies the
30  * chip select lines.
31  *
32  * Example devicetree fragment:
33  *
34  *     spi1: spi@... {
35  *             compatible = "vnd,spi";
36  *             cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
37  *                        <&gpio2 20 GPIO_ACTIVE_LOW>;
38  *     };
39  *
40  *     spi2: spi@... {
41  *             compatible = "vnd,spi";
42  *     };
43  *
44  * Example usage:
45  *
46  *     DT_SPI_HAS_CS_GPIOS(DT_NODELABEL(spi1)) // 1
47  *     DT_SPI_HAS_CS_GPIOS(DT_NODELABEL(spi2)) // 0
48  *
49  * @param spi a SPI bus controller node identifier
50  * @return 1 if "spi" has a cs-gpios property, 0 otherwise
51  */
52 #define DT_SPI_HAS_CS_GPIOS(spi) DT_NODE_HAS_PROP(spi, cs_gpios)
53 
54 /**
55  * @brief Number of chip select GPIOs in a SPI controller's cs-gpios property
56  *
57  * Example devicetree fragment:
58  *
59  *     spi1: spi@... {
60  *             compatible = "vnd,spi";
61  *             cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
62  *                        <&gpio2 20 GPIO_ACTIVE_LOW>;
63  *     };
64  *
65  *     spi2: spi@... {
66  *             compatible = "vnd,spi";
67  *     };
68  *
69  * Example usage:
70  *
71  *     DT_SPI_NUM_CS_GPIOS(DT_NODELABEL(spi1)) // 2
72  *     DT_SPI_NUM_CS_GPIOS(DT_NODELABEL(spi2)) // 0
73  *
74  * @param spi a SPI bus controller node identifier
75  * @return Logical length of spi's cs-gpios property, or 0 if "spi" doesn't
76  *         have a cs-gpios property
77  */
78 #define DT_SPI_NUM_CS_GPIOS(spi) \
79 	COND_CODE_1(DT_SPI_HAS_CS_GPIOS(spi), \
80 		    (DT_PROP_LEN(spi, cs_gpios)), (0))
81 
82 /**
83  * @brief Does a SPI device have a chip select line configured?
84  * Example devicetree fragment:
85  *
86  *     spi1: spi@... {
87  *             compatible = "vnd,spi";
88  *             cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
89  *                        <&gpio2 20 GPIO_ACTIVE_LOW>;
90  *
91  *             a: spi-dev-a@0 {
92  *                     reg = <0>;
93  *             };
94  *
95  *             b: spi-dev-b@1 {
96  *                     reg = <1>;
97  *             };
98  *     };
99  *
100  *     spi2: spi@... {
101  *             compatible = "vnd,spi";
102  *             c: spi-dev-c@0 {
103  *                     reg = <0>;
104  *             };
105  *     };
106  *
107  * Example usage:
108  *
109  *     DT_SPI_DEV_HAS_CS_GPIOS(DT_NODELABEL(a)) // 1
110  *     DT_SPI_DEV_HAS_CS_GPIOS(DT_NODELABEL(b)) // 1
111  *     DT_SPI_DEV_HAS_CS_GPIOS(DT_NODELABEL(c)) // 0
112  *
113  * @param spi_dev a SPI device node identifier
114  * @return 1 if spi_dev's bus node DT_BUS(spi_dev) has a chip select
115  *         pin at index DT_REG_ADDR(spi_dev), 0 otherwise
116  */
117 #define DT_SPI_DEV_HAS_CS_GPIOS(spi_dev) DT_SPI_HAS_CS_GPIOS(DT_BUS(spi_dev))
118 
119 /**
120  * @brief Get a SPI device's chip select GPIO controller's node identifier
121  *
122  * Example devicetree fragment:
123  *
124  *     gpio1: gpio@... { ... };
125  *
126  *     gpio2: gpio@... { ... };
127  *
128  *     spi@... {
129  *             compatible = "vnd,spi";
130  *             cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
131  *                        <&gpio2 20 GPIO_ACTIVE_LOW>;
132  *
133  *             a: spi-dev-a@0 {
134  *                     reg = <0>;
135  *             };
136  *
137  *             b: spi-dev-b@1 {
138  *                     reg = <1>;
139  *             };
140  *     };
141  *
142  * Example usage:
143  *
144  *     DT_SPI_DEV_CS_GPIOS_CTLR(DT_NODELABEL(a)) // DT_NODELABEL(gpio1)
145  *     DT_SPI_DEV_CS_GPIOS_CTLR(DT_NODELABEL(b)) // DT_NODELABEL(gpio2)
146  *
147  * @param spi_dev a SPI device node identifier
148  * @return node identifier for spi_dev's chip select GPIO controller
149  */
150 #define DT_SPI_DEV_CS_GPIOS_CTLR(spi_dev) \
151 	DT_GPIO_CTLR_BY_IDX(DT_BUS(spi_dev), cs_gpios, DT_REG_ADDR(spi_dev))
152 
153 /**
154  * @brief Get a SPI device's chip select GPIO controller's label property
155  *
156  * Example devicetree fragment:
157  *
158  *     gpio1: gpio@... {
159  *             label = "GPIO_1";
160  *     };
161  *
162  *     gpio2: gpio@... {
163  *             label = "GPIO_2";
164  *     };
165  *
166  *     spi1: spi@... {
167  *             compatible = "vnd,spi";
168  *             cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
169  *                        <&gpio2 20 GPIO_ACTIVE_LOW>;
170  *
171  *             a: spi-dev-a@0 {
172  *                     reg = <0>;
173  *             };
174  *
175  *             b: spi-dev-b@1 {
176  *                     reg = <1>;
177  *             };
178  *     };
179  *
180  * Example usage:
181  *
182  *     DT_SPI_DEV_CS_GPIOS_LABEL(DT_NODELABEL(a)) // "GPIO_1"
183  *     DT_SPI_DEV_CS_GPIOS_LABEL(DT_NODELABEL(b)) // "GPIO_2"
184  *
185  * @param spi_dev a SPI device node identifier
186  * @return label property of spi_dev's chip select GPIO controller
187  */
188 #define DT_SPI_DEV_CS_GPIOS_LABEL(spi_dev) \
189 	DT_GPIO_LABEL_BY_IDX(DT_BUS(spi_dev), cs_gpios, DT_REG_ADDR(spi_dev))
190 
191 /**
192  * @brief Get a SPI device's chip select GPIO pin number
193  *
194  * It's an error if the GPIO specifier for spi_dev's entry in its
195  * bus node's cs-gpios property has no pin cell.
196  *
197  * Example devicetree fragment:
198  *
199  *     spi1: spi@... {
200  *             compatible = "vnd,spi";
201  *             cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
202  *                        <&gpio2 20 GPIO_ACTIVE_LOW>;
203  *
204  *             a: spi-dev-a@0 {
205  *                     reg = <0>;
206  *             };
207  *
208  *             b: spi-dev-b@1 {
209  *                     reg = <1>;
210  *             };
211  *     };
212  *
213  * Example usage:
214  *
215  *     DT_SPI_DEV_CS_GPIOS_PIN(DT_NODELABEL(a)) // 10
216  *     DT_SPI_DEV_CS_GPIOS_PIN(DT_NODELABEL(b)) // 20
217  *
218  * @param spi_dev a SPI device node identifier
219  * @return pin number of spi_dev's chip select GPIO
220  */
221 #define DT_SPI_DEV_CS_GPIOS_PIN(spi_dev) \
222 	DT_GPIO_PIN_BY_IDX(DT_BUS(spi_dev), cs_gpios, DT_REG_ADDR(spi_dev))
223 
224 /**
225  * @brief Get a SPI device's chip select GPIO flags
226  *
227  * Example devicetree fragment:
228  *
229  *     spi1: spi@... {
230  *             compatible = "vnd,spi";
231  *             cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
232  *
233  *             a: spi-dev-a@0 {
234  *                     reg = <0>;
235  *             };
236  *     };
237  *
238  * Example usage:
239  *
240  *     DT_SPI_DEV_CS_GPIOS_FLAGS(DT_NODELABEL(a)) // GPIO_ACTIVE_LOW
241  *
242  * If the GPIO specifier for spi_dev's entry in its bus node's
243  * cs-gpios property has no flags cell, this expands to zero.
244  *
245  * @param spi_dev a SPI device node identifier
246  * @return flags value of spi_dev's chip select GPIO specifier, or
247  *         zero if there is none
248  */
249 #define DT_SPI_DEV_CS_GPIOS_FLAGS(spi_dev) \
250 	DT_GPIO_FLAGS_BY_IDX(DT_BUS(spi_dev), cs_gpios, DT_REG_ADDR(spi_dev))
251 
252 /**
253  * @brief Equivalent to DT_SPI_DEV_HAS_CS_GPIOS(DT_DRV_INST(inst)).
254  * @param inst DT_DRV_COMPAT instance number
255  * @return 1 if the instance's bus has a CS pin at index
256  *         DT_INST_REG_ADDR(inst), 0 otherwise
257  * @see DT_SPI_DEV_HAS_CS_GPIOS()
258  */
259 #define DT_INST_SPI_DEV_HAS_CS_GPIOS(inst) \
260 	DT_SPI_DEV_HAS_CS_GPIOS(DT_DRV_INST(inst))
261 
262 /**
263  * @brief Get GPIO controller node identifier for a SPI device instance
264  * This is equivalent to DT_SPI_DEV_CS_GPIOS_CTLR(DT_DRV_INST(inst)).
265  * @param inst DT_DRV_COMPAT instance number
266  * @return node identifier for instance's chip select GPIO controller
267  * @see DT_SPI_DEV_CS_GPIOS_CTLR()
268  */
269 #define DT_INST_SPI_DEV_CS_GPIOS_CTLR(inst) \
270 	DT_SPI_DEV_CS_GPIOS_CTLR(DT_DRV_INST(inst))
271 
272 /**
273  * @brief Get GPIO controller name for a SPI device instance
274  * This is equivalent to DT_SPI_DEV_CS_GPIOS_LABEL(DT_DRV_INST(inst)).
275  * @param inst DT_DRV_COMPAT instance number
276  * @return label property of the instance's chip select GPIO controller
277  * @see DT_SPI_DEV_CS_GPIOS_LABEL()
278  */
279 #define DT_INST_SPI_DEV_CS_GPIOS_LABEL(inst) \
280 	DT_SPI_DEV_CS_GPIOS_LABEL(DT_DRV_INST(inst))
281 
282 /**
283  * @brief Equivalent to DT_SPI_DEV_CS_GPIOS_PIN(DT_DRV_INST(inst)).
284  * @param inst DT_DRV_COMPAT instance number
285  * @return pin number of the instance's chip select GPIO
286  * @see DT_SPI_DEV_CS_GPIOS_PIN()
287  */
288 #define DT_INST_SPI_DEV_CS_GPIOS_PIN(inst) \
289 	DT_SPI_DEV_CS_GPIOS_PIN(DT_DRV_INST(inst))
290 
291 /**
292  * @brief DT_SPI_DEV_CS_GPIOS_FLAGS(DT_DRV_INST(inst)).
293  * @param inst DT_DRV_COMPAT instance number
294  * @return flags value of the instance's chip select GPIO specifier,
295  *         or zero if there is none
296  * @see DT_SPI_DEV_CS_GPIOS_FLAGS()
297  */
298 #define DT_INST_SPI_DEV_CS_GPIOS_FLAGS(inst) \
299 	DT_SPI_DEV_CS_GPIOS_FLAGS(DT_DRV_INST(inst))
300 
301 /**
302  * @}
303  */
304 
305 #ifdef __cplusplus
306 }
307 #endif
308 
309 #endif  /* ZEPHYR_INCLUDE_DEVICETREE_SPI_H_ */
310