1 /*
2  * Copyright (c) 2020 Linaro Ltd.
3  * Copyright (c) 2021 Gerson Fernando Budke
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /** @file
9  * @brief Atmel SAM0 MCU family devicetree helper macros
10  */
11 
12 #ifndef _ATMEL_SAM0_DT_H_
13 #define _ATMEL_SAM0_DT_H_
14 
15 /* Helper macro to get MCLK register address for corresponding
16  * that has corresponding clock enable bit.
17  */
18 #define MCLK_MASK_DT_INT_REG_ADDR(n) \
19 	(DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, mclk)) + \
20 	 DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, offset))
21 
22 /* Helper macros for use with ATMEL SAM0 DMAC controller
23  * return 0xff as default value if there is no 'dmas' property
24  */
25 #define ATMEL_SAM0_DT_INST_DMA_CELL(n, name, cell)		\
26 	COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas),		\
27 		    (DT_INST_DMAS_CELL_BY_NAME(n, name, cell)),	\
28 		    (0xff))
29 #define ATMEL_SAM0_DT_INST_DMA_TRIGSRC(n, name) \
30 	ATMEL_SAM0_DT_INST_DMA_CELL(n, name, trigsrc)
31 #define ATMEL_SAM0_DT_INST_DMA_CHANNEL(n, name) \
32 	ATMEL_SAM0_DT_INST_DMA_CELL(n, name, channel)
33 #define ATMEL_SAM0_DT_INST_DMA_CTLR(n, name)			\
34 	COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas),		\
35 		    (DT_INST_DMAS_CTLR_BY_NAME(n, name)),	\
36 		    (DT_INVALID_NODE))
37 
38 
39 /* Use to check if a sercom 'n' is enabled for a given 'compat' */
40 #define ATMEL_SAM0_DT_SERCOM_CHECK(n, compat) \
41 	DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(sercom##n), compat, okay)
42 
43 /* Use to check if TCC 'n' is enabled for a given 'compat' */
44 #define ATMEL_SAM0_DT_TCC_CHECK(n, compat) \
45 	DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(tcc##n), compat, okay)
46 
47 /* Common macro for use to set HCLK_FREQ_HZ */
48 #define ATMEL_SAM0_DT_CPU_CLK_FREQ_HZ \
49 	DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency)
50 
51 /* Devicetree related macros to construct pin mux config data */
52 
53 /* Get PIN associated with pinctrl-0 pin at index 'i' */
54 #define ATMEL_SAM0_PIN(node_id, i) \
55 	DT_PHA(DT_PINCTRL_0(node_id, i), atmel_pins, pin)
56 
57 /* Get PIO register address associated with pinctrl-0 pin at index 'i' */
58 #define ATMEL_SAM0_PIN_TO_PORT_REG_ADDR(node_id, i) \
59 	DT_REG_ADDR(DT_PHANDLE(DT_PINCTRL_0(node_id, i), atmel_pins))
60 
61 /* Get peripheral cfg associated wiith pinctrl-0 pin at index 'i' */
62 #define ATMEL_SAM0_PIN_PERIPH(node_id, i) \
63 	DT_PHA(DT_PINCTRL_0(node_id, i), atmel_pins, peripheral)
64 
65 /* Helper function for ATMEL_SAM_PIN_FLAGS */
66 #define ATMEL_SAM0_PIN_FLAG(node_id, i, flag) \
67 	DT_PROP(DT_PINCTRL_0(node_id, i), flag)
68 
69 /* Convert DT flags to SoC flags */
70 #define ATMEL_SAM0_PIN_FLAGS(node_id, i) \
71 	(ATMEL_SAM0_PIN_FLAG(node_id, i, bias_pull_up) << SOC_PORT_PULLUP_POS | \
72 	 ATMEL_SAM0_PIN_FLAG(node_id, i, bias_pull_down) << SOC_PORT_PULLUP_POS | \
73 	 ATMEL_SAM0_PIN_FLAG(node_id, i, input_enable) << SOC_PORT_INPUT_ENABLE_POS | \
74 	 ATMEL_SAM0_PIN_FLAG(node_id, i, output_enable) << SOC_PORT_OUTPUT_ENABLE_POS | \
75 	 ATMEL_SAM0_PIN_FLAG(node_id, i, pinmux_enable) << SOC_PORT_PMUXEN_ENABLE_POS)
76 
77 /* Construct a soc_port_pin element for pin cfg */
78 #define ATMEL_SAM0_DT_PORT(node_id, idx)					\
79 	{									\
80 		(PortGroup *)ATMEL_SAM0_PIN_TO_PORT_REG_ADDR(node_id, idx),	\
81 		ATMEL_SAM0_PIN(node_id, idx),					\
82 		ATMEL_SAM0_PIN_PERIPH(node_id, idx) << SOC_PORT_FUNC_POS |	\
83 		ATMEL_SAM0_PIN_FLAGS(node_id, idx)				\
84 	}
85 
86 /* Get the number of pins for pinctrl-0 */
87 #define ATMEL_SAM0_DT_NUM_PINS(node_id) DT_NUM_PINCTRLS_BY_IDX(node_id, 0)
88 
89 #define ATMEL_SAM0_DT_INST_NUM_PINS(inst) \
90 	ATMEL_SAM0_DT_NUM_PINS(DT_DRV_INST(inst))
91 
92 /* internal macro to structure things for use with UTIL_LISTIFY */
93 #define ATMEL_SAM0_DT_PIN_ELEM(idx, node_id) ATMEL_SAM0_DT_PORT(node_id, idx),
94 
95 /* Construct an array intializer for soc_port_pin for a device instance */
96 #define ATMEL_SAM0_DT_PINS(node_id)				\
97 	{ UTIL_LISTIFY(ATMEL_SAM0_DT_NUM_PINS(node_id),		\
98 		       ATMEL_SAM0_DT_PIN_ELEM, node_id)		\
99 	}
100 
101 #define ATMEL_SAM0_DT_INST_PINS(inst) \
102 	ATMEL_SAM0_DT_PINS(DT_DRV_INST(inst))
103 
104 #endif /* _ATMEL_SAM0_SOC_DT_H_ */
105