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