at v3.5-rc2 10 kB view raw
1/* 2 * External connector (extcon) class driver 3 * 4 * Copyright (C) 2012 Samsung Electronics 5 * Author: Donggeun Kim <dg77.kim@samsung.com> 6 * Author: MyungJoo Ham <myungjoo.ham@samsung.com> 7 * 8 * based on switch class driver 9 * Copyright (C) 2008 Google, Inc. 10 * Author: Mike Lockwood <lockwood@android.com> 11 * 12 * This software is licensed under the terms of the GNU General Public 13 * License version 2, as published by the Free Software Foundation, and 14 * may be copied, distributed, and modified under those terms. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21*/ 22 23#ifndef __LINUX_EXTCON_H__ 24#define __LINUX_EXTCON_H__ 25 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 EXTCON_MECHANICAL, 70}; 71extern const char *extcon_cable_name[]; 72 73struct extcon_cable; 74 75/** 76 * struct extcon_dev - An extcon device represents one external connector. 77 * @name The name of this extcon device. Parent device name is used 78 * if NULL. 79 * @supported_cable Array of supported cable name ending with NULL. 80 * If supported_cable is NULL, cable name related APIs 81 * are disabled. 82 * @mutually_exclusive Array of mutually exclusive set of cables that cannot 83 * be attached simultaneously. The array should be 84 * ending with NULL or be NULL (no mutually exclusive 85 * cables). For example, if it is { 0x7, 0x30, 0}, then, 86 * {0, 1}, {0, 1, 2}, {0, 2}, {1, 2}, or {4, 5} cannot 87 * be attached simulataneously. {0x7, 0} is equivalent to 88 * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there 89 * can be no simultaneous connections. 90 * @print_name An optional callback to override the method to print the 91 * name of the extcon device. 92 * @print_state An optional callback to override the method to print the 93 * status of the extcon device. 94 * @dev Device of this extcon. Do not provide at register-time. 95 * @state Attach/detach state of this extcon. Do not provide at 96 * register-time 97 * @nh Notifier for the state change events from this extcon 98 * @entry To support list of extcon devices so that uses can search 99 * for extcon devices based on the extcon name. 100 * @lock 101 * @max_supported Internal value to store the number of cables. 102 * @extcon_dev_type Device_type struct to provide attribute_groups 103 * customized for each extcon device. 104 * @cables Sysfs subdirectories. Each represents one cable. 105 * 106 * In most cases, users only need to provide "User initializing data" of 107 * this struct when registering an extcon. In some exceptional cases, 108 * optional callbacks may be needed. However, the values in "internal data" 109 * are overwritten by register function. 110 */ 111struct extcon_dev { 112 /* --- Optional user initializing data --- */ 113 const char *name; 114 const char **supported_cable; 115 const u32 *mutually_exclusive; 116 117 /* --- Optional callbacks to override class functions --- */ 118 ssize_t (*print_name)(struct extcon_dev *edev, char *buf); 119 ssize_t (*print_state)(struct extcon_dev *edev, char *buf); 120 121 /* --- Internal data. Please do not set. --- */ 122 struct device *dev; 123 u32 state; 124 struct raw_notifier_head nh; 125 struct list_head entry; 126 spinlock_t lock; /* could be called by irq handler */ 127 int max_supported; 128 129 /* /sys/class/extcon/.../cable.n/... */ 130 struct device_type extcon_dev_type; 131 struct extcon_cable *cables; 132 /* /sys/class/extcon/.../mutually_exclusive/... */ 133 struct attribute_group attr_g_muex; 134 struct attribute **attrs_muex; 135 struct device_attribute *d_attrs_muex; 136}; 137 138/** 139 * struct extcon_cable - An internal data for each cable of extcon device. 140 * @edev The extcon device 141 * @cable_index Index of this cable in the edev 142 * @attr_g Attribute group for the cable 143 * @attr_name "name" sysfs entry 144 * @attr_state "state" sysfs entry 145 * @attrs Array pointing to attr_name and attr_state for attr_g 146 */ 147struct extcon_cable { 148 struct extcon_dev *edev; 149 int cable_index; 150 151 struct attribute_group attr_g; 152 struct device_attribute attr_name; 153 struct device_attribute attr_state; 154 155 struct attribute *attrs[3]; /* to be fed to attr_g.attrs */ 156}; 157 158/** 159 * struct extcon_specific_cable_nb - An internal data for 160 * extcon_register_interest(). 161 * @internal_nb a notifier block bridging extcon notifier and cable notifier. 162 * @user_nb user provided notifier block for events from a specific cable. 163 * @cable_index the target cable. 164 * @edev the target extcon device. 165 * @previous_value the saved previous event value. 166 */ 167struct extcon_specific_cable_nb { 168 struct notifier_block internal_nb; 169 struct notifier_block *user_nb; 170 int cable_index; 171 struct extcon_dev *edev; 172 unsigned long previous_value; 173}; 174 175#if IS_ENABLED(CONFIG_EXTCON) 176 177/* 178 * Following APIs are for notifiers or configurations. 179 * Notifiers are the external port and connection devices. 180 */ 181extern int extcon_dev_register(struct extcon_dev *edev, struct device *dev); 182extern void extcon_dev_unregister(struct extcon_dev *edev); 183extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); 184 185/* 186 * get/set/update_state access the 32b encoded state value, which represents 187 * states of all possible cables of the multistate port. For example, if one 188 * calls extcon_set_state(edev, 0x7), it may mean that all the three cables 189 * are attached to the port. 190 */ 191static inline u32 extcon_get_state(struct extcon_dev *edev) 192{ 193 return edev->state; 194} 195 196extern int extcon_set_state(struct extcon_dev *edev, u32 state); 197extern int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state); 198 199/* 200 * get/set_cable_state access each bit of the 32b encoded state value. 201 * They are used to access the status of each cable based on the cable_name 202 * or cable_index, which is retrived by extcon_find_cable_index 203 */ 204extern int extcon_find_cable_index(struct extcon_dev *sdev, 205 const char *cable_name); 206extern int extcon_get_cable_state_(struct extcon_dev *edev, int cable_index); 207extern int extcon_set_cable_state_(struct extcon_dev *edev, int cable_index, 208 bool cable_state); 209 210extern int extcon_get_cable_state(struct extcon_dev *edev, 211 const char *cable_name); 212extern int extcon_set_cable_state(struct extcon_dev *edev, 213 const char *cable_name, bool cable_state); 214 215/* 216 * Following APIs are for notifiees (those who want to be notified) 217 * to register a callback for events from a specific cable of the extcon. 218 * Notifiees are the connected device drivers wanting to get notified by 219 * a specific external port of a connection device. 220 */ 221extern int extcon_register_interest(struct extcon_specific_cable_nb *obj, 222 const char *extcon_name, 223 const char *cable_name, 224 struct notifier_block *nb); 225extern int extcon_unregister_interest(struct extcon_specific_cable_nb *nb); 226 227/* 228 * Following APIs are to monitor every action of a notifier. 229 * Registerer gets notified for every external port of a connection device. 230 * Probably this could be used to debug an action of notifier; however, 231 * we do not recommend to use this at normal 'notifiee' device drivers who 232 * want to be notified by a specific external port of the notifier. 233 */ 234extern int extcon_register_notifier(struct extcon_dev *edev, 235 struct notifier_block *nb); 236extern int extcon_unregister_notifier(struct extcon_dev *edev, 237 struct notifier_block *nb); 238#else /* CONFIG_EXTCON */ 239static inline int extcon_dev_register(struct extcon_dev *edev, 240 struct device *dev) 241{ 242 return 0; 243} 244 245static inline void extcon_dev_unregister(struct extcon_dev *edev) { } 246 247static inline u32 extcon_get_state(struct extcon_dev *edev) 248{ 249 return 0; 250} 251 252static inline int extcon_set_state(struct extcon_dev *edev, u32 state) 253{ 254 return 0; 255} 256 257static inline int extcon_update_state(struct extcon_dev *edev, u32 mask, 258 u32 state) 259{ 260 return 0; 261} 262 263static inline int extcon_find_cable_index(struct extcon_dev *edev, 264 const char *cable_name) 265{ 266 return 0; 267} 268 269static inline int extcon_get_cable_state_(struct extcon_dev *edev, 270 int cable_index) 271{ 272 return 0; 273} 274 275static inline int extcon_set_cable_state_(struct extcon_dev *edev, 276 int cable_index, bool cable_state) 277{ 278 return 0; 279} 280 281static inline int extcon_get_cable_state(struct extcon_dev *edev, 282 const char *cable_name) 283{ 284 return 0; 285} 286 287static inline int extcon_set_cable_state(struct extcon_dev *edev, 288 const char *cable_name, int state) 289{ 290 return 0; 291} 292 293static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) 294{ 295 return NULL; 296} 297 298static inline int extcon_register_notifier(struct extcon_dev *edev, 299 struct notifier_block *nb) 300{ 301 return 0; 302} 303 304static inline int extcon_unregister_notifier(struct extcon_dev *edev, 305 struct notifier_block *nb) 306{ 307 return 0; 308} 309 310static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj, 311 const char *extcon_name, 312 const char *cable_name, 313 struct notifier_block *nb) 314{ 315 return 0; 316} 317 318static inline int extcon_unregister_interest(struct extcon_specific_cable_nb 319 *obj) 320{ 321 return 0; 322} 323#endif /* CONFIG_EXTCON */ 324#endif /* __LINUX_EXTCON_H__ */