aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/pinctrl
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2011-10-19 12:14:33 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-01-03 03:10:04 -0500
commitae6b4d8588f4fc95520b0e62c4b1f474c82191a9 (patch)
tree3da8e553a6374f02e89b5a6ba52b83f34c3abea2 /include/linux/pinctrl
parentb4e3ac74d5cd4152f2ec6b3280b1ff3428952f7f (diff)
pinctrl: add a pin config interface
This add per-pin and per-group pin config interfaces for biasing, driving and other such electronic properties. The details of passed configurations are passed in an opaque unsigned long which may be dereferences to integer types, structs or lists on either side of the configuration interface. ChangeLog v1->v2: - Clear split of terminology: we now have pin controllers, and those may support two interfaces using vtables: pin multiplexing and pin configuration. - Break out pin configuration to its own C file, controllers may implement only config without mux, and vice versa, so keep each sub-functionality of pin controllers separate. Introduce CONFIG_PINCONF in Kconfig. - Implement some core logic around pin configuration in the pinconf.c file. - Remove UNKNOWN config states, these were just surplus baggage. - Remove FLOAT config state - HIGH_IMPEDANCE should be enough for everyone. - PIN_CONFIG_POWER_SOURCE added to handle switching the power supply for the pin logic between different sources - Explicit DISABLE config enums to turn schmitt-trigger, wakeup etc OFF. - Update documentation to reflect all the recent reasoning. ChangeLog v2->v3: - Twist API around to pass around arrays of config tuples instead of (param, value) pairs everywhere. - Explicit drive strength semantics for push/pull and similar drive modes, this shall be the number of drive stages vs nominal load impedance, which should match the actual electronics used in push/pull CMOS or TTY totempoles. - Drop load capacitance configuration - I probably don't know what I'm doing here so leave it out. - Drop PIN_CONFIG_INPUT_SCHMITT_OFF, instead the argument zero to PIN_CONFIG_INPUT_SCHMITT turns schmitt trigger off. - Drop PIN_CONFIG_NORMAL_POWER_MODE and have a well defined argument to PIN_CONFIG_LOW_POWER_MODE to get out of it instead. - Drop PIN_CONFIG_WAKEUP_ENABLE/DISABLE and just use PIN_CONFIG_WAKEUP with defined value zero to turn wakeup off. - Add PIN_CONFIG_INPUT_DEBOUNCE for configuring debounce time on input lines. - Fix a bug when we tried to configure pins for pin controllers without pinconf support. - Initialized debugfs properly so it works. - Initialize the mutex properly and lock around config tampering sections. - Check the return value from get_initial_config() properly. ChangeLog v3->v4: - Export the pin_config_get(), pin_config_set() and pin_config_group() functions. - Drop the entire concept of just getting initial config and keeping track of pin states internally, instead ask the pins what state they are in. Previous idea was plain wrong, if the device cannot keep track of its state, the driver should do it. - Drop the generic configuration layout, it seems this impose too much restriction on some pin controllers, so let them do things the way they want and split off support for generic config as an optional add-on. ChangeLog v4->v5: - Introduce two symmetric driver calls for group configuration, .pin_config_group_[get|set] and corresponding external calls. - Remove generic semantic meanings of return values from config calls, these belong in the generic config patch. Just pass the return value through instead. - Add a debugfs entry "pinconf-groups" to read status from group configuration only, also slam in a per-group debug callback in the pinconf_ops so custom drivers can display something meaningful for their pins. - Fix some dangling newline. - Drop dangling #else clause. - Update documentation to match the above. ChangeLog v5->v6: - Change to using a pin name as parameter for the [get|set]_config() functions, as suggested by Stephen Warren. This is more natural as names will be what a developer has access to in written documentation etc. ChangeLog v6->v7: - Refactor out by-pin and by-name get/set functions, only expose the by-name functions externally, expose the by-pin functions internally. - Show supported pin control functionality in the debugfs pinctrl-devices file. Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'include/linux/pinctrl')
-rw-r--r--include/linux/pinctrl/pinconf.h96
-rw-r--r--include/linux/pinctrl/pinctrl.h8
2 files changed, 102 insertions, 2 deletions
diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h
new file mode 100644
index 000000000000..d5b72e6e261d
--- /dev/null
+++ b/include/linux/pinctrl/pinconf.h
@@ -0,0 +1,96 @@
1/*
2 * Interface the pinconfig portions of the pinctrl subsystem
3 *
4 * Copyright (C) 2011 ST-Ericsson SA
5 * Written on behalf of Linaro for ST-Ericsson
6 * This interface is used in the core to keep track of pins.
7 *
8 * Author: Linus Walleij <linus.walleij@linaro.org>
9 *
10 * License terms: GNU General Public License (GPL) version 2
11 */
12#ifndef __LINUX_PINCTRL_PINCONF_H
13#define __LINUX_PINCTRL_PINCONF_H
14
15#ifdef CONFIG_PINCONF
16
17struct pinctrl_dev;
18
19/**
20 * struct pinconf_ops - pin config operations, to be implemented by
21 * pin configuration capable drivers.
22 * @pin_config_get: get the config of a certain pin, if the requested config
23 * is not available on this controller this should return -ENOTSUPP
24 * and if it is available but disabled it should return -EINVAL
25 * @pin_config_get: get the config of a certain pin
26 * @pin_config_set: configure an individual pin
27 * @pin_config_group_get: get configurations for an entire pin group
28 * @pin_config_group_set: configure all pins in a group
29 * @pin_config_dbg_show: optional debugfs display hook that will provide
30 * per-device info for a certain pin in debugfs
31 * @pin_config_group_dbg_show: optional debugfs display hook that will provide
32 * per-device info for a certain group in debugfs
33 */
34struct pinconf_ops {
35 int (*pin_config_get) (struct pinctrl_dev *pctldev,
36 unsigned pin,
37 unsigned long *config);
38 int (*pin_config_set) (struct pinctrl_dev *pctldev,
39 unsigned pin,
40 unsigned long config);
41 int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
42 unsigned selector,
43 unsigned long *config);
44 int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
45 unsigned selector,
46 unsigned long config);
47 void (*pin_config_dbg_show) (struct pinctrl_dev *pctldev,
48 struct seq_file *s,
49 unsigned offset);
50 void (*pin_config_group_dbg_show) (struct pinctrl_dev *pctldev,
51 struct seq_file *s,
52 unsigned selector);
53};
54
55extern int pin_config_get(struct pinctrl_dev *pctldev, const char *name,
56 unsigned long *config);
57extern int pin_config_set(struct pinctrl_dev *pctldev, const char *name,
58 unsigned long config);
59extern int pin_config_group_get(struct pinctrl_dev *pctldev,
60 const char *pin_group,
61 unsigned long *config);
62extern int pin_config_group_set(struct pinctrl_dev *pctldev,
63 const char *pin_group,
64 unsigned long config);
65
66#else
67
68static inline int pin_config_get(struct pinctrl_dev *pctldev, const char *name,
69 unsigned long *config)
70{
71 return 0;
72}
73
74static inline int pin_config_set(struct pinctrl_dev *pctldev, const char *name,
75 unsigned long config)
76{
77 return 0;
78}
79
80static inline int pin_config_group_get(struct pinctrl_dev *pctldev,
81 const char *pin_group,
82 unsigned long *config)
83{
84 return 0;
85}
86
87static inline int pin_config_group_set(struct pinctrl_dev *pctldev,
88 const char *pin_group,
89 unsigned long config)
90{
91 return 0;
92}
93
94#endif
95
96#endif /* __LINUX_PINCTRL_PINCONF_H */
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index f17fac4b51f1..9809a94f151b 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -21,6 +21,7 @@
21 21
22struct pinctrl_dev; 22struct pinctrl_dev;
23struct pinmux_ops; 23struct pinmux_ops;
24struct pinconf_ops;
24struct gpio_chip; 25struct gpio_chip;
25 26
26/** 27/**
@@ -97,7 +98,9 @@ struct pinctrl_ops {
97 * but may be equal to npins if you have no holes in the pin range. 98 * but may be equal to npins if you have no holes in the pin range.
98 * @pctlops: pin control operation vtable, to support global concepts like 99 * @pctlops: pin control operation vtable, to support global concepts like
99 * grouping of pins, this is optional. 100 * grouping of pins, this is optional.
100 * @pmxops: pinmux operation vtable, if you support pinmuxing in your driver 101 * @pmxops: pinmux operations vtable, if you support pinmuxing in your driver
102 * @confops: pin config operations vtable, if you support pin configuration in
103 * your driver
101 * @owner: module providing the pin controller, used for refcounting 104 * @owner: module providing the pin controller, used for refcounting
102 */ 105 */
103struct pinctrl_desc { 106struct pinctrl_desc {
@@ -107,6 +110,7 @@ struct pinctrl_desc {
107 unsigned int maxpin; 110 unsigned int maxpin;
108 struct pinctrl_ops *pctlops; 111 struct pinctrl_ops *pctlops;
109 struct pinmux_ops *pmxops; 112 struct pinmux_ops *pmxops;
113 struct pinconf_ops *confops;
110 struct module *owner; 114 struct module *owner;
111}; 115};
112 116
@@ -125,7 +129,7 @@ extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev);
125 129
126struct pinctrl_dev; 130struct pinctrl_dev;
127 131
128/* Sufficiently stupid default function when pinctrl is not in use */ 132/* Sufficiently stupid default functions when pinctrl is not in use */
129static inline bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) 133static inline bool pin_is_valid(struct pinctrl_dev *pctldev, int pin)
130{ 134{
131 return pin >= 0; 135 return pin >= 0;