aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/extcon.h
diff options
context:
space:
mode:
authorMyungJoo Ham <myungjoo.ham@samsung.com>2012-04-20 01:16:25 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-20 12:23:37 -0400
commit806d9dd71ff52ef09764585baaeec23afbb98560 (patch)
treee81291b139bac10e08d1cb376a22cac5c89a3b65 /include/linux/extcon.h
parent74c5d09bd562edc220d6e076b8f1e118819c178f (diff)
Extcon: support multiple states at a device.
One switch device (e.g., MUIC(MAX8997, MAX77686, ...), and some 30-pin devices) may have multiple cables attached. For example, one 30-pin port may inhabit a USB cable, an HDMI cable, and a mic. Thus, one switch device requires multiple state bits each representing a type of cable. For such purpose, we use the 32bit state variable; thus, up to 32 different type of cables may be defined for a switch device. The list of possible cables is defined by the array of cable names in the switch_dev struct given to the class. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> -- Changes from V7 - Bugfixed in _call_per_cable() (incorrect nb) (Chanwoo Choi) - Compiler error in header for !CONFIG_EXTCON (Chanwoo Choi) Changes from V5 - Sysfs style reformed: subdirectory per cable. - Updated standard cable names - Removed unnecessary printf - Bugfixes after testing Changes from V4 - Bugfixes after more testing at Exynos4412 boards with userspace processses. Changes from V3 - Bugfixes after more testing at Exynos4412 boards. Changes from V2 - State can be stored by user - Documentation updated Changes from RFC - Switch is renamed to extcon - Added kerneldoc comments - Added APIs to support "standard" cable names - Added helper APIs to support notifier block registration with cable name. - Regrouped function list in the header file. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/extcon.h')
-rw-r--r--include/linux/extcon.h185
1 files changed, 185 insertions, 0 deletions
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index c9c9afe12b47..20e24b32a17d 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -24,10 +24,60 @@
24#define __LINUX_EXTCON_H__ 24#define __LINUX_EXTCON_H__
25 25
26#include <linux/notifier.h> 26#include <linux/notifier.h>
27
28#define SUPPORTED_CABLE_MAX 32
29#define CABLE_NAME_MAX 30
30
31/*
32 * The standard cable name is to help support general notifier
33 * and notifee device drivers to share the common names.
34 * Please use standard cable names unless your notifier device has
35 * a very unique and abnormal cable or
36 * the cable type is supposed to be used with only one unique
37 * pair of notifier/notifee devices.
38 *
39 * Please add any other "standard" cables used with extcon dev.
40 *
41 * You may add a dot and number to specify version or specification
42 * of the specific cable if it is required. (e.g., "Fast-charger.18"
43 * and "Fast-charger.10" for 1.8A and 1.0A chargers)
44 * However, the notifee and notifier should be able to handle such
45 * string and if the notifee can negotiate the protocol or idenify,
46 * you don't need such convention. This convention is helpful when
47 * notifier can distinguish but notifiee cannot.
48 */
49enum extcon_cable_name {
50 EXTCON_USB = 0,
51 EXTCON_USB_HOST,
52 EXTCON_TA, /* Travel Adaptor */
53 EXTCON_FAST_CHARGER,
54 EXTCON_SLOW_CHARGER,
55 EXTCON_CHARGE_DOWNSTREAM, /* Charging an external device */
56 EXTCON_HDMI,
57 EXTCON_MHL,
58 EXTCON_DVI,
59 EXTCON_VGA,
60 EXTCON_DOCK,
61 EXTCON_LINE_IN,
62 EXTCON_LINE_OUT,
63 EXTCON_MIC_IN,
64 EXTCON_HEADPHONE_OUT,
65 EXTCON_SPDIF_IN,
66 EXTCON_SPDIF_OUT,
67 EXTCON_VIDEO_IN,
68 EXTCON_VIDEO_OUT,
69};
70extern const char *extcon_cable_name[];
71
72struct extcon_cable;
73
27/** 74/**
28 * struct extcon_dev - An extcon device represents one external connector. 75 * struct extcon_dev - An extcon device represents one external connector.
29 * @name The name of this extcon device. Parent device name is used 76 * @name The name of this extcon device. Parent device name is used
30 * if NULL. 77 * if NULL.
78 * @supported_cable Array of supported cable name ending with NULL.
79 * If supported_cable is NULL, cable name related APIs
80 * are disabled.
31 * @print_name An optional callback to override the method to print the 81 * @print_name An optional callback to override the method to print the
32 * name of the extcon device. 82 * name of the extcon device.
33 * @print_state An optional callback to override the method to print the 83 * @print_state An optional callback to override the method to print the
@@ -38,6 +88,11 @@
38 * @nh Notifier for the state change events from this extcon 88 * @nh Notifier for the state change events from this extcon
39 * @entry To support list of extcon devices so that uses can search 89 * @entry To support list of extcon devices so that uses can search
40 * for extcon devices based on the extcon name. 90 * for extcon devices based on the extcon name.
91 * @lock
92 * @max_supported Internal value to store the number of cables.
93 * @extcon_dev_type Device_type struct to provide attribute_groups
94 * customized for each extcon device.
95 * @cables Sysfs subdirectories. Each represents one cable.
41 * 96 *
42 * In most cases, users only need to provide "User initializing data" of 97 * In most cases, users only need to provide "User initializing data" of
43 * this struct when registering an extcon. In some exceptional cases, 98 * this struct when registering an extcon. In some exceptional cases,
@@ -47,6 +102,7 @@
47struct extcon_dev { 102struct extcon_dev {
48 /* --- Optional user initializing data --- */ 103 /* --- Optional user initializing data --- */
49 const char *name; 104 const char *name;
105 const char **supported_cable;
50 106
51 /* --- Optional callbacks to override class functions --- */ 107 /* --- Optional callbacks to override class functions --- */
52 ssize_t (*print_name)(struct extcon_dev *edev, char *buf); 108 ssize_t (*print_name)(struct extcon_dev *edev, char *buf);
@@ -57,6 +113,49 @@ struct extcon_dev {
57 u32 state; 113 u32 state;
58 struct raw_notifier_head nh; 114 struct raw_notifier_head nh;
59 struct list_head entry; 115 struct list_head entry;
116 spinlock_t lock; /* could be called by irq handler */
117 int max_supported;
118
119 /* /sys/class/extcon/.../cable.n/... */
120 struct device_type extcon_dev_type;
121 struct extcon_cable *cables;
122};
123
124/**
125 * struct extcon_cable - An internal data for each cable of extcon device.
126 * @edev The extcon device
127 * @cable_index Index of this cable in the edev
128 * @attr_g Attribute group for the cable
129 * @attr_name "name" sysfs entry
130 * @attr_state "state" sysfs entry
131 * @attrs Array pointing to attr_name and attr_state for attr_g
132 */
133struct extcon_cable {
134 struct extcon_dev *edev;
135 int cable_index;
136
137 struct attribute_group attr_g;
138 struct device_attribute attr_name;
139 struct device_attribute attr_state;
140
141 struct attribute *attrs[3]; /* to be fed to attr_g.attrs */
142};
143
144/**
145 * struct extcon_specific_cable_nb - An internal data for
146 * extcon_register_interest().
147 * @internal_nb a notifier block bridging extcon notifier and cable notifier.
148 * @user_nb user provided notifier block for events from a specific cable.
149 * @cable_index the target cable.
150 * @edev the target extcon device.
151 * @previous_value the saved previous event value.
152 */
153struct extcon_specific_cable_nb {
154 struct notifier_block internal_nb;
155 struct notifier_block *user_nb;
156 int cable_index;
157 struct extcon_dev *edev;
158 unsigned long previous_value;
60}; 159};
61 160
62#if IS_ENABLED(CONFIG_EXTCON) 161#if IS_ENABLED(CONFIG_EXTCON)
@@ -69,16 +168,54 @@ extern int extcon_dev_register(struct extcon_dev *edev, struct device *dev);
69extern void extcon_dev_unregister(struct extcon_dev *edev); 168extern void extcon_dev_unregister(struct extcon_dev *edev);
70extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); 169extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
71 170
171/*
172 * get/set/update_state access the 32b encoded state value, which represents
173 * states of all possible cables of the multistate port. For example, if one
174 * calls extcon_set_state(edev, 0x7), it may mean that all the three cables
175 * are attached to the port.
176 */
72static inline u32 extcon_get_state(struct extcon_dev *edev) 177static inline u32 extcon_get_state(struct extcon_dev *edev)
73{ 178{
74 return edev->state; 179 return edev->state;
75} 180}
76 181
77extern void extcon_set_state(struct extcon_dev *edev, u32 state); 182extern void extcon_set_state(struct extcon_dev *edev, u32 state);
183extern void extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state);
184
185/*
186 * get/set_cable_state access each bit of the 32b encoded state value.
187 * They are used to access the status of each cable based on the cable_name
188 * or cable_index, which is retrived by extcon_find_cable_index
189 */
190extern int extcon_find_cable_index(struct extcon_dev *sdev,
191 const char *cable_name);
192extern int extcon_get_cable_state_(struct extcon_dev *edev, int cable_index);
193extern int extcon_set_cable_state_(struct extcon_dev *edev, int cable_index,
194 bool cable_state);
195
196extern int extcon_get_cable_state(struct extcon_dev *edev,
197 const char *cable_name);
198extern int extcon_set_cable_state(struct extcon_dev *edev,
199 const char *cable_name, bool cable_state);
200
201/*
202 * Following APIs are for notifiees (those who want to be notified)
203 * to register a callback for events from a specific cable of the extcon.
204 * Notifiees are the connected device drivers wanting to get notified by
205 * a specific external port of a connection device.
206 */
207extern int extcon_register_interest(struct extcon_specific_cable_nb *obj,
208 const char *extcon_name,
209 const char *cable_name,
210 struct notifier_block *nb);
211extern int extcon_unregister_interest(struct extcon_specific_cable_nb *nb);
78 212
79/* 213/*
80 * Following APIs are to monitor every action of a notifier. 214 * Following APIs are to monitor every action of a notifier.
81 * Registerer gets notified for every external port of a connection device. 215 * Registerer gets notified for every external port of a connection device.
216 * Probably this could be used to debug an action of notifier; however,
217 * we do not recommend to use this at normal 'notifiee' device drivers who
218 * want to be notified by a specific external port of the notifier.
82 */ 219 */
83extern int extcon_register_notifier(struct extcon_dev *edev, 220extern int extcon_register_notifier(struct extcon_dev *edev,
84 struct notifier_block *nb); 221 struct notifier_block *nb);
@@ -99,6 +236,41 @@ static inline u32 extcon_get_state(struct extcon_dev *edev)
99} 236}
100 237
101static inline void extcon_set_state(struct extcon_dev *edev, u32 state) { } 238static inline void extcon_set_state(struct extcon_dev *edev, u32 state) { }
239
240static inline void extcon_update_state(struct extcon_dev *edev, u32 mask,
241 u32 state)
242{ }
243
244static inline int extcon_find_cable_index(struct extcon_dev *edev,
245 const char *cable_name)
246{
247 return 0;
248}
249
250static inline int extcon_get_cable_state_(struct extcon_dev *edev,
251 int cable_index)
252{
253 return 0;
254}
255
256static inline int extcon_set_cable_state_(struct extcon_dev *edev,
257 int cable_index, bool cable_state)
258{
259 return 0;
260}
261
262static inline int extcon_get_cable_state(struct extcon_dev *edev,
263 const char *cable_name)
264{
265 return 0;
266}
267
268static inline int extcon_set_cable_state(struct extcon_dev *edev,
269 const char *cable_name, int state)
270{
271 return 0;
272}
273
102static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) 274static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
103{ 275{
104 return NULL; 276 return NULL;
@@ -116,5 +288,18 @@ static inline int extcon_unregister_notifier(struct extcon_dev *edev,
116 return 0; 288 return 0;
117} 289}
118 290
291static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj,
292 const char *extcon_name,
293 const char *cable_name,
294 struct notifier_block *nb)
295{
296 return 0;
297}
298
299static inline int extcon_unregister_interest(struct extcon_specific_cable_nb
300 *obj)
301{
302 return 0;
303}
119#endif /* CONFIG_EXTCON */ 304#endif /* CONFIG_EXTCON */
120#endif /* __LINUX_EXTCON_H__ */ 305#endif /* __LINUX_EXTCON_H__ */