1 /*
2  * Copyright (c) 2016-2017 Piotr Mienkowski
3  * Copyright (c) 2020-2022 Gerson Fernando Budke
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /** @file
8  * @brief Atmel SAM0 MCU family I/O Pin Controller (PORT)
9  */
10 
11 #ifndef ATMEL_SAM0_SOC_PORT_H_
12 #define ATMEL_SAM0_SOC_PORT_H_
13 
14 #include <soc.h>
15 
16 /*
17  * Pin flags/attributes
18  */
19 #define SOC_PORT_DEFAULT                (0)
20 
21 #define SOC_PORT_FLAGS_POS              (0)
22 #define SOC_PORT_FLAGS_MASK             (0x7B << SOC_PORT_FLAGS_POS)
23 #define SOC_PORT_PULLUP_POS             (SOC_PORT_FLAGS_POS)
24 #define SOC_PORT_PULLUP                 (1 << SOC_PORT_PULLUP_POS)
25 #define SOC_PORT_PULLDOWN_POS           (SOC_PORT_PULLUP_POS + 1U)
26 #define SOC_PORT_PULLDOWN               (1 << SOC_PORT_PULLDOWN_POS)
27 /* Open-Drain is a reserved entry at pinctrl driver */
28 #define SOC_GPIO_OPENDRAIN_POS          (SOC_PORT_PULLDOWN_POS + 1U)
29 /* Input-Enable means Input-Buffer, see dts/pinctrl/pincfg-node.yaml */
30 #define SOC_PORT_INPUT_ENABLE_POS       (SOC_GPIO_OPENDRAIN_POS + 1U)
31 #define SOC_PORT_INPUT_ENABLE           (1 << SOC_PORT_INPUT_ENABLE_POS)
32 /* Output-Enable, see dts/pinctrl/pincfg-node.yaml */
33 #define SOC_PORT_OUTPUT_ENABLE_POS      (SOC_PORT_INPUT_ENABLE_POS + 1U)
34 #define SOC_PORT_OUTPUT_ENABLE          (1 << SOC_PORT_OUTPUT_ENABLE_POS)
35 /* Drive-Strength, 0mA means normal, any other value means stronger */
36 #define SOC_PORT_STRENGTH_STRONGER_POS  (SOC_PORT_OUTPUT_ENABLE_POS + 1U)
37 #define SOC_PORT_STRENGTH_STRONGER      (1 << SOC_PORT_STRENGTH_STRONGER_POS)
38 /* Peripheral Multiplexer Enable */
39 #define SOC_PORT_PMUXEN_ENABLE_POS      (SOC_PORT_STRENGTH_STRONGER_POS + 1U)
40 #define SOC_PORT_PMUXEN_ENABLE          (1 << SOC_PORT_PMUXEN_ENABLE_POS)
41 
42 /* Bit field: SOC_PORT_FUNC */
43 #define SOC_PORT_FUNC_POS               (16U)
44 #define SOC_PORT_FUNC_MASK              (0xF << SOC_PORT_FUNC_POS)
45 
46 /** Connect pin to peripheral A. */
47 #define SOC_PORT_FUNC_A                 (0x0 << SOC_PORT_FUNC_POS)
48 /** Connect pin to peripheral B. */
49 #define SOC_PORT_FUNC_B                 (0x1 << SOC_PORT_FUNC_POS)
50 /** Connect pin to peripheral C. */
51 #define SOC_PORT_FUNC_C                 (0x2 << SOC_PORT_FUNC_POS)
52 /** Connect pin to peripheral D. */
53 #define SOC_PORT_FUNC_D                 (0x3 << SOC_PORT_FUNC_POS)
54 /** Connect pin to peripheral E. */
55 #define SOC_PORT_FUNC_E                 (0x4 << SOC_PORT_FUNC_POS)
56 /** Connect pin to peripheral F. */
57 #define SOC_PORT_FUNC_F                 (0x5 << SOC_PORT_FUNC_POS)
58 /** Connect pin to peripheral G. */
59 #define SOC_PORT_FUNC_G                 (0x6 << SOC_PORT_FUNC_POS)
60 /** Connect pin to peripheral H. */
61 #define SOC_PORT_FUNC_H                 (0x7 << SOC_PORT_FUNC_POS)
62 /** Connect pin to peripheral I. */
63 #define SOC_PORT_FUNC_I                 (0x8 << SOC_PORT_FUNC_POS)
64 /** Connect pin to peripheral J. */
65 #define SOC_PORT_FUNC_J                 (0x9 << SOC_PORT_FUNC_POS)
66 /** Connect pin to peripheral K. */
67 #define SOC_PORT_FUNC_K                 (0xa << SOC_PORT_FUNC_POS)
68 /** Connect pin to peripheral L. */
69 #define SOC_PORT_FUNC_L                 (0xb << SOC_PORT_FUNC_POS)
70 /** Connect pin to peripheral M. */
71 #define SOC_PORT_FUNC_M                 (0xc << SOC_PORT_FUNC_POS)
72 /** Connect pin to peripheral N. */
73 #define SOC_PORT_FUNC_N                 (0xd << SOC_PORT_FUNC_POS)
74 
75 struct soc_port_pin {
76 	PortGroup *regs;   /** pointer to registers of the I/O Pin Controller */
77 	uint32_t pinum;    /** pin number */
78 	uint32_t flags;    /** pin flags/attributes */
79 };
80 
81 /**
82  * @brief Configure PORT pin muxing.
83  *
84  * Configure one pin muxing belonging to some PORT.
85  *
86  * @param pg   PortGroup register
87  * @param pin  Pin number
88  * @param func Pin Function
89  */
90 int soc_port_pinmux_set(PortGroup *pg, uint32_t pin, uint32_t func);
91 
92 /**
93  * @brief Configure PORT pin.
94  *
95  * Configure one pin belonging to some PORT.
96  * Example scenarios:
97  * - configure pin(s) as input.
98  * - connect pin(s) to a peripheral B and enable pull-up.
99  *
100  * @remark During Reset, all PORT lines are configured as inputs with input
101  * buffers, output buffers and pull disabled.  When the device is set to the
102  * BACKUP sleep mode, even if the PORT configuration registers and input
103  * synchronizers will lose their contents (these will not be restored when
104  * PORT is powered up again), the latches in the pads will keep their current
105  * configuration, such as the output value and pull settings.  Refer to the
106  * Power Manager documentation for more features related to the I/O lines
107  * configuration in and out of BACKUP mode.  The PORT peripheral will continue
108  * operating in any Sleep mode where its source clock is running.
109  *
110  * @param pin  pin's configuration data such as pin mask, pin attributes, etc.
111  */
112 void soc_port_configure(const struct soc_port_pin *pin);
113 
114 /**
115  * @brief Configure a list of PORT pin(s).
116  *
117  * Configure an arbitrary amount of pins in an arbitrary way.  Each
118  * configuration entry is a single item in an array passed as an argument to
119  * the function.
120  *
121  * @param pins an array where each item contains pin's configuration data.
122  * @param size size of the pin list.
123  */
124 void soc_port_list_configure(const struct soc_port_pin pins[],
125 			     unsigned int size);
126 
127 #endif /* ATMEL_SAM0_SOC_PORT_H_ */
128