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