xref: /optee_os/core/include/drivers/pinctrl.h (revision 9aec039ec0d76c2e6a496e18cf79340658013425)
1*9aec039eSClément Léger /* SPDX-License-Identifier: BSD-2-Clause */
2*9aec039eSClément Léger /*
3*9aec039eSClément Léger  * Copyright (c) 2022-2023, Microchip
4*9aec039eSClément Léger  */
5*9aec039eSClément Léger 
6*9aec039eSClément Léger #ifndef __DRIVERS_PINCTRL_H
7*9aec039eSClément Léger #define __DRIVERS_PINCTRL_H
8*9aec039eSClément Léger 
9*9aec039eSClément Léger #include <bitstring.h>
10*9aec039eSClément Léger #include <kernel/dt_driver.h>
11*9aec039eSClément Léger #include <sys/queue.h>
12*9aec039eSClément Léger #include <tee_api_types.h>
13*9aec039eSClément Léger 
14*9aec039eSClément Léger enum pinctrl_dt_prop {
15*9aec039eSClément Léger 	/* Property "bias-disable" found in pinctrl node */
16*9aec039eSClément Léger 	PINCTRL_DT_PROP_BIAS_DISABLE,
17*9aec039eSClément Léger 	/* Property "bias-pull-up" found in pinctrl node */
18*9aec039eSClément Léger 	PINCTRL_DT_PROP_BIAS_PULL_UP,
19*9aec039eSClément Léger 	/* Property "bias-pull-down" found in pinctrl node */
20*9aec039eSClément Léger 	PINCTRL_DT_PROP_BIAS_PULL_DOWN,
21*9aec039eSClément Léger 	/* Terminal ID */
22*9aec039eSClément Léger 	PINCTRL_DT_PROP_MAX
23*9aec039eSClément Léger };
24*9aec039eSClément Léger 
25*9aec039eSClément Léger /*
26*9aec039eSClément Léger  * struct pinconf - Pinctrl device
27*9aec039eSClément Léger  * @ops: Operation handlers
28*9aec039eSClément Léger  * @priv: Pinctrl driver private data
29*9aec039eSClément Léger  */
30*9aec039eSClément Léger struct pinconf {
31*9aec039eSClément Léger 	const struct pinctrl_ops *ops;
32*9aec039eSClément Léger 	void *priv;
33*9aec039eSClément Léger };
34*9aec039eSClément Léger 
35*9aec039eSClément Léger /*
36*9aec039eSClément Léger  * struct pinctrl_state - Pinctrl configuration state
37*9aec039eSClément Léger  * @conf_count: Number of cells in @confs
38*9aec039eSClément Léger  * @confs: Array of pin configurations related to the pinctrl config state
39*9aec039eSClément Léger  */
40*9aec039eSClément Léger struct pinctrl_state {
41*9aec039eSClément Léger 	unsigned int conf_count;
42*9aec039eSClément Léger 	struct pinconf *confs[];
43*9aec039eSClément Léger };
44*9aec039eSClément Léger 
45*9aec039eSClément Léger struct pinctrl_ops {
46*9aec039eSClément Léger 	/* Apply a pinctrl configuration */
47*9aec039eSClément Léger 	TEE_Result (*conf_apply)(struct pinconf *conf);
48*9aec039eSClément Léger 	/* Release resources allocated for a pinctrl configuration */
49*9aec039eSClément Léger 	void (*conf_free)(struct pinconf *conf);
50*9aec039eSClément Léger };
51*9aec039eSClément Léger 
52*9aec039eSClément Léger typedef struct pinconf *(*pinctrl_dt_get_func)(struct dt_driver_phandle_args *a,
53*9aec039eSClément Léger 					       void *data, TEE_Result *res);
54*9aec039eSClément Léger 
55*9aec039eSClément Léger #ifdef CFG_DRIVERS_PINCTRL
56*9aec039eSClément Léger /**
57*9aec039eSClément Léger  * pinctrl_dt_register_provider - Register a pinctrl controller provider
58*9aec039eSClément Léger  *
59*9aec039eSClément Léger  * @fdt: Device tree to work on
60*9aec039eSClément Léger  * @nodeoffset: Node offset of the pin controller
61*9aec039eSClément Léger  * @get_pinctrl: Callback to match the pin controller with a struct pinconf
62*9aec039eSClément Léger  * @data: Data which will be passed to the get_pinctrl callback
63*9aec039eSClément Léger  * Return a TEE_Result compliant value
64*9aec039eSClément Léger  */
65*9aec039eSClément Léger static inline
66*9aec039eSClément Léger TEE_Result pinctrl_register_provider(const void *fdt, int nodeoffset,
67*9aec039eSClément Léger 				     pinctrl_dt_get_func get_pinctrl,
68*9aec039eSClément Léger 				     void *data)
69*9aec039eSClément Léger {
70*9aec039eSClément Léger 	return dt_driver_register_provider(fdt, nodeoffset,
71*9aec039eSClément Léger 					   (get_of_device_func)get_pinctrl,
72*9aec039eSClément Léger 					   data, DT_DRIVER_PINCTRL);
73*9aec039eSClément Léger }
74*9aec039eSClément Léger 
75*9aec039eSClément Léger /**
76*9aec039eSClément Léger  * pinctrl_get_state_by_name - Obtain a pinctrl state by name
77*9aec039eSClément Léger  *
78*9aec039eSClément Léger  * @fdt: Device tree to work on
79*9aec039eSClément Léger  * @nodeoffset: Node offset of the pin controller
80*9aec039eSClément Léger  * @name: name of the pinctrl state to obtain from device-tree
81*9aec039eSClément Léger  * @state: Pointer filled with the retrieved state, must be freed after use
82*9aec039eSClément Léger    using pinctrl_free_state()
83*9aec039eSClément Léger  * Return a TEE_Result compliant value
84*9aec039eSClément Léger  */
85*9aec039eSClément Léger TEE_Result pinctrl_get_state_by_name(const void *fdt, int nodeoffset,
86*9aec039eSClément Léger 				     const char *name,
87*9aec039eSClément Léger 				     struct pinctrl_state **state);
88*9aec039eSClément Léger 
89*9aec039eSClément Léger /**
90*9aec039eSClément Léger  * pinctrl_get_state_by_idx - Obtain a pinctrl state by index
91*9aec039eSClément Léger  *
92*9aec039eSClément Léger  * @fdt: Device tree to work on
93*9aec039eSClément Léger  * @nodeoffset: Node offset of the pin controller
94*9aec039eSClément Léger  * @pinctrl_id: Index of the pinctrl state to obtain from device-tree
95*9aec039eSClément Léger  * @state: Pointer filled with the retrieved state, must be freed after use
96*9aec039eSClément Léger    using pinctrl_free_state()
97*9aec039eSClément Léger  * Return a TEE_Result compliant value
98*9aec039eSClément Léger  */
99*9aec039eSClément Léger TEE_Result pinctrl_get_state_by_idx(const void *fdt, int nodeoffset,
100*9aec039eSClément Léger 				    unsigned int pinctrl_id,
101*9aec039eSClément Léger 				    struct pinctrl_state **state);
102*9aec039eSClément Léger 
103*9aec039eSClément Léger /**
104*9aec039eSClément Léger  * pinctrl_free_state - Free a pinctrl state that was previously obtained
105*9aec039eSClément Léger  *
106*9aec039eSClément Léger  * @state: State to be freed
107*9aec039eSClément Léger  */
108*9aec039eSClément Léger void pinctrl_free_state(struct pinctrl_state *state);
109*9aec039eSClément Léger 
110*9aec039eSClément Léger /**
111*9aec039eSClément Léger  * pinctrl_apply_state - apply a pinctrl state
112*9aec039eSClément Léger  *
113*9aec039eSClément Léger  * @state: State to be applied
114*9aec039eSClément Léger  * Return a TEE_Result compliant value
115*9aec039eSClément Léger  */
116*9aec039eSClément Léger TEE_Result pinctrl_apply_state(struct pinctrl_state *state);
117*9aec039eSClément Léger 
118*9aec039eSClément Léger /*
119*9aec039eSClément Léger  * pinctrl_parse_dt_pin_modes - Parse DT node properties
120*9aec039eSClément Léger  * @fdt: Device tree to work on
121*9aec039eSClément Léger  * @nodeoffset: Pinctrl node
122*9aec039eSClément Léger  * @modes: Output allocated regulator properties
123*9aec039eSClément Léger  * Return a TEE_Result compliant value
124*9aec039eSClément Léger  */
125*9aec039eSClément Léger TEE_Result pinctrl_parse_dt_pin_modes(const void *fdt, int nodeoffset,
126*9aec039eSClément Léger 				      bitstr_t **modes);
127*9aec039eSClément Léger #else /* CFG_DRIVERS_PINCTRL */
128*9aec039eSClément Léger static inline
129*9aec039eSClément Léger TEE_Result pinctrl_register_provider(const void *fdt __unused,
130*9aec039eSClément Léger 				     int nodeoffset __unused,
131*9aec039eSClément Léger 				     pinctrl_dt_get_func get_pinctrl __unused,
132*9aec039eSClément Léger 				     void *data __unused)
133*9aec039eSClément Léger {
134*9aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
135*9aec039eSClément Léger }
136*9aec039eSClément Léger 
137*9aec039eSClément Léger static inline
138*9aec039eSClément Léger TEE_Result pinctrl_get_state_by_name(const void *fdt __unused,
139*9aec039eSClément Léger 				     int nodeoffset __unused,
140*9aec039eSClément Léger 				     const char *name __unused,
141*9aec039eSClément Léger 				     struct pinctrl_state **state __unused)
142*9aec039eSClément Léger {
143*9aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
144*9aec039eSClément Léger }
145*9aec039eSClément Léger 
146*9aec039eSClément Léger static inline
147*9aec039eSClément Léger TEE_Result pinctrl_get_state_by_idx(const void *fdt __unused,
148*9aec039eSClément Léger 				    int nodeoffset __unused,
149*9aec039eSClément Léger 				    unsigned int pinctrl_id __unused,
150*9aec039eSClément Léger 				    struct pinctrl_state **state __unused)
151*9aec039eSClément Léger {
152*9aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
153*9aec039eSClément Léger }
154*9aec039eSClément Léger 
155*9aec039eSClément Léger static inline
156*9aec039eSClément Léger void pinctrl_free_state(struct pinctrl_state *state __unused)
157*9aec039eSClément Léger {
158*9aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
159*9aec039eSClément Léger }
160*9aec039eSClément Léger 
161*9aec039eSClément Léger static inline
162*9aec039eSClément Léger TEE_Result pinctrl_apply_state(struct pinctrl_state *state __unused)
163*9aec039eSClément Léger {
164*9aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
165*9aec039eSClément Léger }
166*9aec039eSClément Léger 
167*9aec039eSClément Léger static inline
168*9aec039eSClément Léger TEE_Result pinctrl_parse_dt_pin_modes(const void *fdt __unused,
169*9aec039eSClément Léger 				      int nodeoffset __unused,
170*9aec039eSClément Léger 				      bitstr_t **modes __unused)
171*9aec039eSClément Léger {
172*9aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
173*9aec039eSClément Léger }
174*9aec039eSClément Léger 
175*9aec039eSClément Léger #endif /* CFG_DRIVERS_PINCTRL */
176*9aec039eSClément Léger #endif /* __DRIVERS_PINCTRL_H */
177