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