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