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