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