xref: /optee_os/core/include/drivers/pinctrl.h (revision 812f8b295e31dbc2ff672ab1cc36f8cd7aa362c4)
19aec039eSClément Léger /* SPDX-License-Identifier: BSD-2-Clause */
29aec039eSClément Léger /*
39aec039eSClément Léger  * Copyright (c) 2022-2023, Microchip
49aec039eSClément Léger  */
59aec039eSClément Léger 
69aec039eSClément Léger #ifndef __DRIVERS_PINCTRL_H
79aec039eSClément Léger #define __DRIVERS_PINCTRL_H
89aec039eSClément Léger 
99aec039eSClément Léger #include <bitstring.h>
109aec039eSClément Léger #include <kernel/dt_driver.h>
119aec039eSClément Léger #include <sys/queue.h>
129aec039eSClément Léger #include <tee_api_types.h>
139aec039eSClément Léger 
149aec039eSClément Léger enum pinctrl_dt_prop {
159aec039eSClément Léger 	/* Property "bias-disable" found in pinctrl node */
169aec039eSClément Léger 	PINCTRL_DT_PROP_BIAS_DISABLE,
179aec039eSClément Léger 	/* Property "bias-pull-up" found in pinctrl node */
189aec039eSClément Léger 	PINCTRL_DT_PROP_BIAS_PULL_UP,
199aec039eSClément Léger 	/* Property "bias-pull-down" found in pinctrl node */
209aec039eSClément Léger 	PINCTRL_DT_PROP_BIAS_PULL_DOWN,
219aec039eSClément Léger 	/* Terminal ID */
229aec039eSClément Léger 	PINCTRL_DT_PROP_MAX
239aec039eSClément Léger };
249aec039eSClément Léger 
259aec039eSClément Léger /*
269aec039eSClément Léger  * struct pinconf - Pinctrl device
279aec039eSClément Léger  * @ops: Operation handlers
289aec039eSClément Léger  * @priv: Pinctrl driver private data
299aec039eSClément Léger  */
309aec039eSClément Léger struct pinconf {
319aec039eSClément Léger 	const struct pinctrl_ops *ops;
329aec039eSClément Léger 	void *priv;
339aec039eSClément Léger };
349aec039eSClément Léger 
359aec039eSClément Léger /*
369aec039eSClément Léger  * struct pinctrl_state - Pinctrl configuration state
379aec039eSClément Léger  * @conf_count: Number of cells in @confs
389aec039eSClément Léger  * @confs: Array of pin configurations related to the pinctrl config state
399aec039eSClément Léger  */
409aec039eSClément Léger struct pinctrl_state {
419aec039eSClément Léger 	unsigned int conf_count;
429aec039eSClément Léger 	struct pinconf *confs[];
439aec039eSClément Léger };
449aec039eSClément Léger 
459aec039eSClément Léger struct pinctrl_ops {
469aec039eSClément Léger 	/* Apply a pinctrl configuration */
479aec039eSClément Léger 	TEE_Result (*conf_apply)(struct pinconf *conf);
489aec039eSClément Léger 	/* Release resources allocated for a pinctrl configuration */
499aec039eSClément Léger 	void (*conf_free)(struct pinconf *conf);
509aec039eSClément Léger };
519aec039eSClément Léger 
52b357d34fSEtienne Carriere /**
53b357d34fSEtienne Carriere  * pinctrl_dt_get_func - Typedef of function to get a pin configuration from
54b357d34fSEtienne Carriere  * a device tree property
55b357d34fSEtienne Carriere  *
56b357d34fSEtienne Carriere  * @args: Pointer to device tree phandle arguments of the pin control reference
57b357d34fSEtienne Carriere  * @data: Pointer to data given at pinctrl_register_provider() call
58b357d34fSEtienne Carriere  * @out_pinconf: Output pin configuration reference upon success
59b357d34fSEtienne Carriere  */
60b357d34fSEtienne Carriere typedef TEE_Result (*pinctrl_dt_get_func)(struct dt_pargs *pargs, void *data,
61b357d34fSEtienne Carriere 					  struct pinconf **out_pinconf);
629aec039eSClément Léger 
639aec039eSClément Léger #ifdef CFG_DRIVERS_PINCTRL
649aec039eSClément Léger /**
659aec039eSClément Léger  * pinctrl_dt_register_provider - Register a pinctrl controller provider
669aec039eSClément Léger  *
679aec039eSClément Léger  * @fdt: Device tree to work on
689aec039eSClément Léger  * @nodeoffset: Node offset of the pin controller
699aec039eSClément Léger  * @get_pinctrl: Callback to match the pin controller with a struct pinconf
709aec039eSClément Léger  * @data: Data which will be passed to the get_pinctrl callback
719aec039eSClément Léger  * Return a TEE_Result compliant value
729aec039eSClément Léger  */
pinctrl_register_provider(const void * fdt,int nodeoffset,pinctrl_dt_get_func func,void * data)73b357d34fSEtienne Carriere static inline TEE_Result pinctrl_register_provider(const void *fdt,
74b357d34fSEtienne Carriere 						   int nodeoffset,
75b357d34fSEtienne Carriere 						   pinctrl_dt_get_func func,
769aec039eSClément Léger 						   void *data)
779aec039eSClément Léger {
789aec039eSClément Léger 	return dt_driver_register_provider(fdt, nodeoffset,
79b357d34fSEtienne Carriere 					   (get_of_device_func)func, data,
80b357d34fSEtienne Carriere 					   DT_DRIVER_PINCTRL);
819aec039eSClément Léger }
829aec039eSClément Léger 
839aec039eSClément Léger /**
849aec039eSClément Léger  * pinctrl_get_state_by_name - Obtain a pinctrl state by name
859aec039eSClément Léger  *
869aec039eSClément Léger  * @fdt: Device tree to work on
879aec039eSClément Léger  * @nodeoffset: Node offset of the pin controller
889aec039eSClément Léger  * @name: name of the pinctrl state to obtain from device-tree
899aec039eSClément Léger  * @state: Pointer filled with the retrieved state, must be freed after use
909aec039eSClément Léger    using pinctrl_free_state()
919aec039eSClément Léger  * Return a TEE_Result compliant value
929aec039eSClément Léger  */
939aec039eSClément Léger TEE_Result pinctrl_get_state_by_name(const void *fdt, int nodeoffset,
949aec039eSClément Léger 				     const char *name,
959aec039eSClément Léger 				     struct pinctrl_state **state);
969aec039eSClément Léger 
979aec039eSClément Léger /**
989aec039eSClément Léger  * pinctrl_get_state_by_idx - Obtain a pinctrl state by index
999aec039eSClément Léger  *
1009aec039eSClément Léger  * @fdt: Device tree to work on
1019aec039eSClément Léger  * @nodeoffset: Node offset of the pin controller
1029aec039eSClément Léger  * @pinctrl_id: Index of the pinctrl state to obtain from device-tree
1039aec039eSClément Léger  * @state: Pointer filled with the retrieved state, must be freed after use
1049aec039eSClément Léger    using pinctrl_free_state()
1059aec039eSClément Léger  * Return a TEE_Result compliant value
1069aec039eSClément Léger  */
1079aec039eSClément Léger TEE_Result pinctrl_get_state_by_idx(const void *fdt, int nodeoffset,
1089aec039eSClément Léger 				    unsigned int pinctrl_id,
1099aec039eSClément Léger 				    struct pinctrl_state **state);
1109aec039eSClément Léger 
1119aec039eSClément Léger /**
1129aec039eSClément Léger  * pinctrl_free_state - Free a pinctrl state that was previously obtained
1139aec039eSClément Léger  *
1149aec039eSClément Léger  * @state: State to be freed
1159aec039eSClément Léger  */
1169aec039eSClément Léger void pinctrl_free_state(struct pinctrl_state *state);
1179aec039eSClément Léger 
1189aec039eSClément Léger /**
1199aec039eSClément Léger  * pinctrl_apply_state - apply a pinctrl state
1209aec039eSClément Léger  *
1219aec039eSClément Léger  * @state: State to be applied
1229aec039eSClément Léger  * Return a TEE_Result compliant value
1239aec039eSClément Léger  */
1249aec039eSClément Léger TEE_Result pinctrl_apply_state(struct pinctrl_state *state);
1259aec039eSClément Léger 
1269aec039eSClément Léger /*
1279aec039eSClément Léger  * pinctrl_parse_dt_pin_modes - Parse DT node properties
1289aec039eSClément Léger  * @fdt: Device tree to work on
1299aec039eSClément Léger  * @nodeoffset: Pinctrl node
1309aec039eSClément Léger  * @modes: Output allocated regulator properties
1319aec039eSClément Léger  * Return a TEE_Result compliant value
1329aec039eSClément Léger  */
1339aec039eSClément Léger TEE_Result pinctrl_parse_dt_pin_modes(const void *fdt, int nodeoffset,
1349aec039eSClément Léger 				      bitstr_t **modes);
1359aec039eSClément Léger #else /* CFG_DRIVERS_PINCTRL */
136b357d34fSEtienne Carriere static inline TEE_Result
pinctrl_register_provider(const void * fdt __unused,int nodeoffset __unused,get_of_device_func func __unused,void * data __unused)137b357d34fSEtienne Carriere pinctrl_register_provider(const void *fdt __unused, int nodeoffset __unused,
138b357d34fSEtienne Carriere 			  get_of_device_func func __unused, void *data __unused)
1399aec039eSClément Léger {
1409aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
1419aec039eSClément Léger }
1429aec039eSClément Léger 
143*812f8b29SEtienne Carriere static inline TEE_Result
pinctrl_get_state_by_name(const void * fdt __unused,int nodeoffset __unused,const char * name __unused,struct pinctrl_state ** state __unused)144*812f8b29SEtienne Carriere pinctrl_get_state_by_name(const void *fdt __unused, int nodeoffset __unused,
1459aec039eSClément Léger 			  const char *name __unused,
1469aec039eSClément Léger 			  struct pinctrl_state **state __unused)
1479aec039eSClément Léger {
1489aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
1499aec039eSClément Léger }
1509aec039eSClément Léger 
151*812f8b29SEtienne Carriere static inline TEE_Result
pinctrl_get_state_by_idx(const void * fdt __unused,int nodeoffset __unused,unsigned int pinctrl_id __unused,struct pinctrl_state ** state __unused)152*812f8b29SEtienne Carriere pinctrl_get_state_by_idx(const void *fdt __unused, int nodeoffset __unused,
1539aec039eSClément Léger 			 unsigned int pinctrl_id __unused,
1549aec039eSClément Léger 			 struct pinctrl_state **state __unused)
1559aec039eSClément Léger {
1569aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
1579aec039eSClément Léger }
1589aec039eSClément Léger 
pinctrl_free_state(struct pinctrl_state * state __unused)159*812f8b29SEtienne Carriere static inline void pinctrl_free_state(struct pinctrl_state *state __unused)
1609aec039eSClément Léger {
1619aec039eSClément Léger }
1629aec039eSClément Léger 
pinctrl_apply_state(struct pinctrl_state * s __unused)163*812f8b29SEtienne Carriere static inline TEE_Result pinctrl_apply_state(struct pinctrl_state *s __unused)
1649aec039eSClément Léger {
1659aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
1669aec039eSClément Léger }
1679aec039eSClément Léger 
pinctrl_parse_dt_pin_modes(const void * fdt __unused,int nodeoffset __unused,bitstr_t ** modes __unused)168*812f8b29SEtienne Carriere static inline TEE_Result pinctrl_parse_dt_pin_modes(const void *fdt __unused,
1699aec039eSClément Léger 						    int nodeoffset __unused,
1709aec039eSClément Léger 						    bitstr_t **modes __unused)
1719aec039eSClément Léger {
1729aec039eSClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
1739aec039eSClément Léger }
1749aec039eSClément Léger 
1759aec039eSClément Léger #endif /* CFG_DRIVERS_PINCTRL */
1769aec039eSClément Léger #endif /* __DRIVERS_PINCTRL_H */
177