18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Core private header for the pin control subsystem 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2011 ST-Ericsson SA 68c2ecf20Sopenharmony_ci * Written on behalf of Linaro for ST-Ericsson 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Author: Linus Walleij <linus.walleij@linaro.org> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/kref.h> 128c2ecf20Sopenharmony_ci#include <linux/mutex.h> 138c2ecf20Sopenharmony_ci#include <linux/radix-tree.h> 148c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf.h> 158c2ecf20Sopenharmony_ci#include <linux/pinctrl/machine.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistruct pinctrl_gpio_range; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/** 208c2ecf20Sopenharmony_ci * struct pinctrl_dev - pin control class device 218c2ecf20Sopenharmony_ci * @node: node to include this pin controller in the global pin controller list 228c2ecf20Sopenharmony_ci * @desc: the pin controller descriptor supplied when initializing this pin 238c2ecf20Sopenharmony_ci * controller 248c2ecf20Sopenharmony_ci * @pin_desc_tree: each pin descriptor for this pin controller is stored in 258c2ecf20Sopenharmony_ci * this radix tree 268c2ecf20Sopenharmony_ci * @pin_group_tree: optionally each pin group can be stored in this radix tree 278c2ecf20Sopenharmony_ci * @num_groups: optionally number of groups can be kept here 288c2ecf20Sopenharmony_ci * @pin_function_tree: optionally each function can be stored in this radix tree 298c2ecf20Sopenharmony_ci * @num_functions: optionally number of functions can be kept here 308c2ecf20Sopenharmony_ci * @gpio_ranges: a list of GPIO ranges that is handled by this pin controller, 318c2ecf20Sopenharmony_ci * ranges are added to this list at runtime 328c2ecf20Sopenharmony_ci * @dev: the device entry for this pin controller 338c2ecf20Sopenharmony_ci * @owner: module providing the pin controller, used for refcounting 348c2ecf20Sopenharmony_ci * @driver_data: driver data for drivers registering to the pin controller 358c2ecf20Sopenharmony_ci * subsystem 368c2ecf20Sopenharmony_ci * @p: result of pinctrl_get() for this device 378c2ecf20Sopenharmony_ci * @hog_default: default state for pins hogged by this device 388c2ecf20Sopenharmony_ci * @hog_sleep: sleep state for pins hogged by this device 398c2ecf20Sopenharmony_ci * @mutex: mutex taken on each pin controller specific action 408c2ecf20Sopenharmony_ci * @device_root: debugfs root for this device 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_cistruct pinctrl_dev { 438c2ecf20Sopenharmony_ci struct list_head node; 448c2ecf20Sopenharmony_ci struct pinctrl_desc *desc; 458c2ecf20Sopenharmony_ci struct radix_tree_root pin_desc_tree; 468c2ecf20Sopenharmony_ci#ifdef CONFIG_GENERIC_PINCTRL_GROUPS 478c2ecf20Sopenharmony_ci struct radix_tree_root pin_group_tree; 488c2ecf20Sopenharmony_ci unsigned int num_groups; 498c2ecf20Sopenharmony_ci#endif 508c2ecf20Sopenharmony_ci#ifdef CONFIG_GENERIC_PINMUX_FUNCTIONS 518c2ecf20Sopenharmony_ci struct radix_tree_root pin_function_tree; 528c2ecf20Sopenharmony_ci unsigned int num_functions; 538c2ecf20Sopenharmony_ci#endif 548c2ecf20Sopenharmony_ci struct list_head gpio_ranges; 558c2ecf20Sopenharmony_ci struct device *dev; 568c2ecf20Sopenharmony_ci struct module *owner; 578c2ecf20Sopenharmony_ci void *driver_data; 588c2ecf20Sopenharmony_ci struct pinctrl *p; 598c2ecf20Sopenharmony_ci struct pinctrl_state *hog_default; 608c2ecf20Sopenharmony_ci struct pinctrl_state *hog_sleep; 618c2ecf20Sopenharmony_ci struct mutex mutex; 628c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 638c2ecf20Sopenharmony_ci struct dentry *device_root; 648c2ecf20Sopenharmony_ci#endif 658c2ecf20Sopenharmony_ci}; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/** 688c2ecf20Sopenharmony_ci * struct pinctrl - per-device pin control state holder 698c2ecf20Sopenharmony_ci * @node: global list node 708c2ecf20Sopenharmony_ci * @dev: the device using this pin control handle 718c2ecf20Sopenharmony_ci * @states: a list of states for this device 728c2ecf20Sopenharmony_ci * @state: the current state 738c2ecf20Sopenharmony_ci * @dt_maps: the mapping table chunks dynamically parsed from device tree for 748c2ecf20Sopenharmony_ci * this device, if any 758c2ecf20Sopenharmony_ci * @users: reference count 768c2ecf20Sopenharmony_ci */ 778c2ecf20Sopenharmony_cistruct pinctrl { 788c2ecf20Sopenharmony_ci struct list_head node; 798c2ecf20Sopenharmony_ci struct device *dev; 808c2ecf20Sopenharmony_ci struct list_head states; 818c2ecf20Sopenharmony_ci struct pinctrl_state *state; 828c2ecf20Sopenharmony_ci struct list_head dt_maps; 838c2ecf20Sopenharmony_ci struct kref users; 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/** 878c2ecf20Sopenharmony_ci * struct pinctrl_state - a pinctrl state for a device 888c2ecf20Sopenharmony_ci * @node: list node for struct pinctrl's @states field 898c2ecf20Sopenharmony_ci * @name: the name of this state 908c2ecf20Sopenharmony_ci * @settings: a list of settings for this state 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_cistruct pinctrl_state { 938c2ecf20Sopenharmony_ci struct list_head node; 948c2ecf20Sopenharmony_ci const char *name; 958c2ecf20Sopenharmony_ci struct list_head settings; 968c2ecf20Sopenharmony_ci}; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci/** 998c2ecf20Sopenharmony_ci * struct pinctrl_setting_mux - setting data for MAP_TYPE_MUX_GROUP 1008c2ecf20Sopenharmony_ci * @group: the group selector to program 1018c2ecf20Sopenharmony_ci * @func: the function selector to program 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_cistruct pinctrl_setting_mux { 1048c2ecf20Sopenharmony_ci unsigned group; 1058c2ecf20Sopenharmony_ci unsigned func; 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/** 1098c2ecf20Sopenharmony_ci * struct pinctrl_setting_configs - setting data for MAP_TYPE_CONFIGS_* 1108c2ecf20Sopenharmony_ci * @group_or_pin: the group selector or pin ID to program 1118c2ecf20Sopenharmony_ci * @configs: a pointer to an array of config parameters/values to program into 1128c2ecf20Sopenharmony_ci * hardware. Each individual pin controller defines the format and meaning 1138c2ecf20Sopenharmony_ci * of config parameters. 1148c2ecf20Sopenharmony_ci * @num_configs: the number of entries in array @configs 1158c2ecf20Sopenharmony_ci */ 1168c2ecf20Sopenharmony_cistruct pinctrl_setting_configs { 1178c2ecf20Sopenharmony_ci unsigned group_or_pin; 1188c2ecf20Sopenharmony_ci unsigned long *configs; 1198c2ecf20Sopenharmony_ci unsigned num_configs; 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci/** 1238c2ecf20Sopenharmony_ci * struct pinctrl_setting - an individual mux or config setting 1248c2ecf20Sopenharmony_ci * @node: list node for struct pinctrl_settings's @settings field 1258c2ecf20Sopenharmony_ci * @type: the type of setting 1268c2ecf20Sopenharmony_ci * @pctldev: pin control device handling to be programmed. Not used for 1278c2ecf20Sopenharmony_ci * PIN_MAP_TYPE_DUMMY_STATE. 1288c2ecf20Sopenharmony_ci * @dev_name: the name of the device using this state 1298c2ecf20Sopenharmony_ci * @data: Data specific to the setting type 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_cistruct pinctrl_setting { 1328c2ecf20Sopenharmony_ci struct list_head node; 1338c2ecf20Sopenharmony_ci enum pinctrl_map_type type; 1348c2ecf20Sopenharmony_ci struct pinctrl_dev *pctldev; 1358c2ecf20Sopenharmony_ci const char *dev_name; 1368c2ecf20Sopenharmony_ci union { 1378c2ecf20Sopenharmony_ci struct pinctrl_setting_mux mux; 1388c2ecf20Sopenharmony_ci struct pinctrl_setting_configs configs; 1398c2ecf20Sopenharmony_ci } data; 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci/** 1438c2ecf20Sopenharmony_ci * struct pin_desc - pin descriptor for each physical pin in the arch 1448c2ecf20Sopenharmony_ci * @pctldev: corresponding pin control device 1458c2ecf20Sopenharmony_ci * @name: a name for the pin, e.g. the name of the pin/pad/finger on a 1468c2ecf20Sopenharmony_ci * datasheet or such 1478c2ecf20Sopenharmony_ci * @dynamic_name: if the name of this pin was dynamically allocated 1488c2ecf20Sopenharmony_ci * @drv_data: driver-defined per-pin data. pinctrl core does not touch this 1498c2ecf20Sopenharmony_ci * @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL. 1508c2ecf20Sopenharmony_ci * If non-zero, this pin is claimed by @owner. This field is an integer 1518c2ecf20Sopenharmony_ci * rather than a boolean, since pinctrl_get() might process multiple 1528c2ecf20Sopenharmony_ci * mapping table entries that refer to, and hence claim, the same group 1538c2ecf20Sopenharmony_ci * or pin, and each of these will increment the @usecount. 1548c2ecf20Sopenharmony_ci * @mux_owner: The name of device that called pinctrl_get(). 1558c2ecf20Sopenharmony_ci * @mux_setting: The most recent selected mux setting for this pin, if any. 1568c2ecf20Sopenharmony_ci * @gpio_owner: If pinctrl_gpio_request() was called for this pin, this is 1578c2ecf20Sopenharmony_ci * the name of the GPIO that "owns" this pin. 1588c2ecf20Sopenharmony_ci */ 1598c2ecf20Sopenharmony_cistruct pin_desc { 1608c2ecf20Sopenharmony_ci struct pinctrl_dev *pctldev; 1618c2ecf20Sopenharmony_ci const char *name; 1628c2ecf20Sopenharmony_ci bool dynamic_name; 1638c2ecf20Sopenharmony_ci void *drv_data; 1648c2ecf20Sopenharmony_ci /* These fields only added when supporting pinmux drivers */ 1658c2ecf20Sopenharmony_ci#ifdef CONFIG_PINMUX 1668c2ecf20Sopenharmony_ci unsigned mux_usecount; 1678c2ecf20Sopenharmony_ci const char *mux_owner; 1688c2ecf20Sopenharmony_ci const struct pinctrl_setting_mux *mux_setting; 1698c2ecf20Sopenharmony_ci const char *gpio_owner; 1708c2ecf20Sopenharmony_ci#endif 1718c2ecf20Sopenharmony_ci}; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/** 1748c2ecf20Sopenharmony_ci * struct pinctrl_maps - a list item containing part of the mapping table 1758c2ecf20Sopenharmony_ci * @node: mapping table list node 1768c2ecf20Sopenharmony_ci * @maps: array of mapping table entries 1778c2ecf20Sopenharmony_ci * @num_maps: the number of entries in @maps 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_cistruct pinctrl_maps { 1808c2ecf20Sopenharmony_ci struct list_head node; 1818c2ecf20Sopenharmony_ci const struct pinctrl_map *maps; 1828c2ecf20Sopenharmony_ci unsigned num_maps; 1838c2ecf20Sopenharmony_ci}; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci#ifdef CONFIG_GENERIC_PINCTRL_GROUPS 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci/** 1888c2ecf20Sopenharmony_ci * struct group_desc - generic pin group descriptor 1898c2ecf20Sopenharmony_ci * @name: name of the pin group 1908c2ecf20Sopenharmony_ci * @pins: array of pins that belong to the group 1918c2ecf20Sopenharmony_ci * @num_pins: number of pins in the group 1928c2ecf20Sopenharmony_ci * @data: pin controller driver specific data 1938c2ecf20Sopenharmony_ci */ 1948c2ecf20Sopenharmony_cistruct group_desc { 1958c2ecf20Sopenharmony_ci const char *name; 1968c2ecf20Sopenharmony_ci int *pins; 1978c2ecf20Sopenharmony_ci int num_pins; 1988c2ecf20Sopenharmony_ci void *data; 1998c2ecf20Sopenharmony_ci}; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ciint pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ciconst char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev, 2048c2ecf20Sopenharmony_ci unsigned int group_selector); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ciint pinctrl_generic_get_group_pins(struct pinctrl_dev *pctldev, 2078c2ecf20Sopenharmony_ci unsigned int group_selector, 2088c2ecf20Sopenharmony_ci const unsigned int **pins, 2098c2ecf20Sopenharmony_ci unsigned int *npins); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_cistruct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev, 2128c2ecf20Sopenharmony_ci unsigned int group_selector); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ciint pinctrl_generic_add_group(struct pinctrl_dev *pctldev, const char *name, 2158c2ecf20Sopenharmony_ci int *gpins, int ngpins, void *data); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ciint pinctrl_generic_remove_group(struct pinctrl_dev *pctldev, 2188c2ecf20Sopenharmony_ci unsigned int group_selector); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci#endif /* CONFIG_GENERIC_PINCTRL_GROUPS */ 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistruct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); 2238c2ecf20Sopenharmony_cistruct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np); 2248c2ecf20Sopenharmony_ciint pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); 2258c2ecf20Sopenharmony_ciconst char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin); 2268c2ecf20Sopenharmony_ciint pinctrl_get_group_selector(struct pinctrl_dev *pctldev, 2278c2ecf20Sopenharmony_ci const char *pin_group); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_cistatic inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, 2308c2ecf20Sopenharmony_ci unsigned int pin) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci return radix_tree_lookup(&pctldev->pin_desc_tree, pin); 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ciextern struct pinctrl_gpio_range * 2368c2ecf20Sopenharmony_cipinctrl_find_gpio_range_from_pin_nolock(struct pinctrl_dev *pctldev, 2378c2ecf20Sopenharmony_ci unsigned int pin); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ciextern int pinctrl_force_sleep(struct pinctrl_dev *pctldev); 2408c2ecf20Sopenharmony_ciextern int pinctrl_force_default(struct pinctrl_dev *pctldev); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ciextern struct mutex pinctrl_maps_mutex; 2438c2ecf20Sopenharmony_ciextern struct list_head pinctrl_maps; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci#define for_each_maps(_maps_node_, _i_, _map_) \ 2468c2ecf20Sopenharmony_ci list_for_each_entry(_maps_node_, &pinctrl_maps, node) \ 2478c2ecf20Sopenharmony_ci for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \ 2488c2ecf20Sopenharmony_ci _i_ < _maps_node_->num_maps; \ 2498c2ecf20Sopenharmony_ci _i_++, _map_ = &_maps_node_->maps[_i_]) 250