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 52*b357d34fSEtienne Carriere /** 53*b357d34fSEtienne Carriere * pinctrl_dt_get_func - Typedef of function to get a pin configuration from 54*b357d34fSEtienne Carriere * a device tree property 55*b357d34fSEtienne Carriere * 56*b357d34fSEtienne Carriere * @args: Pointer to device tree phandle arguments of the pin control reference 57*b357d34fSEtienne Carriere * @data: Pointer to data given at pinctrl_register_provider() call 58*b357d34fSEtienne Carriere * @out_pinconf: Output pin configuration reference upon success 59*b357d34fSEtienne Carriere */ 60*b357d34fSEtienne Carriere typedef TEE_Result (*pinctrl_dt_get_func)(struct dt_pargs *pargs, void *data, 61*b357d34fSEtienne 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 */ 73*b357d34fSEtienne Carriere static inline TEE_Result pinctrl_register_provider(const void *fdt, 74*b357d34fSEtienne Carriere int nodeoffset, 75*b357d34fSEtienne 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, 79*b357d34fSEtienne Carriere (get_of_device_func)func, data, 80*b357d34fSEtienne 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 */ 136*b357d34fSEtienne Carriere static inline TEE_Result 137*b357d34fSEtienne Carriere pinctrl_register_provider(const void *fdt __unused, int nodeoffset __unused, 138*b357d34fSEtienne 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 1439aec039eSClément Léger static inline 1449aec039eSClément Léger TEE_Result pinctrl_get_state_by_name(const void *fdt __unused, 1459aec039eSClément Léger int nodeoffset __unused, 1469aec039eSClément Léger const char *name __unused, 1479aec039eSClément Léger struct pinctrl_state **state __unused) 1489aec039eSClément Léger { 1499aec039eSClément Léger return TEE_ERROR_NOT_SUPPORTED; 1509aec039eSClément Léger } 1519aec039eSClément Léger 1529aec039eSClément Léger static inline 1539aec039eSClément Léger TEE_Result pinctrl_get_state_by_idx(const void *fdt __unused, 1549aec039eSClément Léger int nodeoffset __unused, 1559aec039eSClément Léger unsigned int pinctrl_id __unused, 1569aec039eSClément Léger struct pinctrl_state **state __unused) 1579aec039eSClément Léger { 1589aec039eSClément Léger return TEE_ERROR_NOT_SUPPORTED; 1599aec039eSClément Léger } 1609aec039eSClément Léger 1619aec039eSClément Léger static inline 1629aec039eSClément Léger void pinctrl_free_state(struct pinctrl_state *state __unused) 1639aec039eSClément Léger { 1649aec039eSClément Léger } 1659aec039eSClément Léger 1669aec039eSClément Léger static inline 1679aec039eSClément Léger TEE_Result pinctrl_apply_state(struct pinctrl_state *state __unused) 1689aec039eSClément Léger { 1699aec039eSClément Léger return TEE_ERROR_NOT_SUPPORTED; 1709aec039eSClément Léger } 1719aec039eSClément Léger 1729aec039eSClément Léger static inline 1739aec039eSClément Léger TEE_Result pinctrl_parse_dt_pin_modes(const void *fdt __unused, 1749aec039eSClément Léger int nodeoffset __unused, 1759aec039eSClément Léger bitstr_t **modes __unused) 1769aec039eSClément Léger { 1779aec039eSClément Léger return TEE_ERROR_NOT_SUPPORTED; 1789aec039eSClément Léger } 1799aec039eSClément Léger 1809aec039eSClément Léger #endif /* CFG_DRIVERS_PINCTRL */ 1819aec039eSClément Léger #endif /* __DRIVERS_PINCTRL_H */ 182