1 /* 2 * External connector (extcon) class driver 3 * 4 * Copyright (C) 2015 Samsung Electronics 5 * Author: Chanwoo Choi <[email protected]> 6 * 7 * Copyright (C) 2012 Samsung Electronics 8 * Author: Donggeun Kim <[email protected]> 9 * Author: MyungJoo Ham <[email protected]> 10 * 11 * based on switch class driver 12 * Copyright (C) 2008 Google, Inc. 13 * Author: Mike Lockwood <[email protected]> 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 type of supported external connectors 33 */ 34 #define EXTCON_TYPE_USB BIT(0) /* USB connector */ 35 #define EXTCON_TYPE_CHG BIT(1) /* Charger connector */ 36 #define EXTCON_TYPE_JACK BIT(2) /* Jack connector */ 37 #define EXTCON_TYPE_DISP BIT(3) /* Display connector */ 38 #define EXTCON_TYPE_MISC BIT(4) /* Miscellaneous connector */ 39 40 /* 41 * Define the unique id of supported external connectors 42 */ 43 #define EXTCON_NONE 0 44 45 /* USB external connector */ 46 #define EXTCON_USB 1 47 #define EXTCON_USB_HOST 2 48 49 /* 50 * Charging external connector 51 * 52 * When one SDP charger connector was reported, we should also report 53 * the USB connector, which means EXTCON_CHG_USB_SDP should always 54 * appear together with EXTCON_USB. The same as ACA charger connector, 55 * EXTCON_CHG_USB_ACA would normally appear with EXTCON_USB_HOST. 56 */ 57 #define EXTCON_CHG_USB_SDP 5 /* Standard Downstream Port */ 58 #define EXTCON_CHG_USB_DCP 6 /* Dedicated Charging Port */ 59 #define EXTCON_CHG_USB_CDP 7 /* Charging Downstream Port */ 60 #define EXTCON_CHG_USB_ACA 8 /* Accessory Charger Adapter */ 61 #define EXTCON_CHG_USB_FAST 9 62 #define EXTCON_CHG_USB_SLOW 10 63 #define EXTCON_CHG_WPT 11 /* Wireless Power Transfer */ 64 65 /* Jack external connector */ 66 #define EXTCON_JACK_MICROPHONE 20 67 #define EXTCON_JACK_HEADPHONE 21 68 #define EXTCON_JACK_LINE_IN 22 69 #define EXTCON_JACK_LINE_OUT 23 70 #define EXTCON_JACK_VIDEO_IN 24 71 #define EXTCON_JACK_VIDEO_OUT 25 72 #define EXTCON_JACK_SPDIF_IN 26 /* Sony Philips Digital InterFace */ 73 #define EXTCON_JACK_SPDIF_OUT 27 74 75 /* Display external connector */ 76 #define EXTCON_DISP_HDMI 40 /* High-Definition Multimedia Interface */ 77 #define EXTCON_DISP_MHL 41 /* Mobile High-Definition Link */ 78 #define EXTCON_DISP_DVI 42 /* Digital Visual Interface */ 79 #define EXTCON_DISP_VGA 43 /* Video Graphics Array */ 80 #define EXTCON_DISP_DP 44 /* Display Port */ 81 #define EXTCON_DISP_HMD 45 /* Head-Mounted Display */ 82 83 /* Miscellaneous external connector */ 84 #define EXTCON_DOCK 60 85 #define EXTCON_JIG 61 86 #define EXTCON_MECHANICAL 62 87 88 #define EXTCON_NUM 63 89 90 /* 91 * Define the property of supported external connectors. 92 * 93 * When adding the new extcon property, they *must* have 94 * the type/value/default information. Also, you *have to* 95 * modify the EXTCON_PROP_[type]_START/END definitions 96 * which mean the range of the supported properties 97 * for each extcon type. 98 * 99 * The naming style of property 100 * : EXTCON_PROP_[type]_[property name] 101 * 102 * EXTCON_PROP_USB_[property name] : USB property 103 * EXTCON_PROP_CHG_[property name] : Charger property 104 * EXTCON_PROP_JACK_[property name] : Jack property 105 * EXTCON_PROP_DISP_[property name] : Display property 106 */ 107 108 /* 109 * Properties of EXTCON_TYPE_USB. 110 * 111 * - EXTCON_PROP_USB_VBUS 112 * @type: integer (intval) 113 * @value: 0 (low) or 1 (high) 114 * @default: 0 (low) 115 * - EXTCON_PROP_USB_TYPEC_POLARITY 116 * @type: integer (intval) 117 * @value: 0 (normal) or 1 (flip) 118 * @default: 0 (normal) 119 * - EXTCON_PROP_USB_SS (SuperSpeed) 120 * @type: integer (intval) 121 * @value: 0 (USB/USB2) or 1 (USB3) 122 * @default: 0 (USB/USB2) 123 * 124 */ 125 #define EXTCON_PROP_USB_VBUS 0 126 #define EXTCON_PROP_USB_TYPEC_POLARITY 1 127 #define EXTCON_PROP_USB_SS 2 128 129 #define EXTCON_PROP_USB_MIN 0 130 #define EXTCON_PROP_USB_MAX 2 131 #define EXTCON_PROP_USB_CNT (EXTCON_PROP_USB_MAX - EXTCON_PROP_USB_MIN + 1) 132 133 /* Properties of EXTCON_TYPE_CHG. */ 134 #define EXTCON_PROP_CHG_MIN 50 135 #define EXTCON_PROP_CHG_MAX 50 136 #define EXTCON_PROP_CHG_CNT (EXTCON_PROP_CHG_MAX - EXTCON_PROP_CHG_MIN + 1) 137 138 /* Properties of EXTCON_TYPE_JACK. */ 139 #define EXTCON_PROP_JACK_MIN 100 140 #define EXTCON_PROP_JACK_MAX 100 141 #define EXTCON_PROP_JACK_CNT (EXTCON_PROP_JACK_MAX - EXTCON_PROP_JACK_MIN + 1) 142 143 /* 144 * Properties of EXTCON_TYPE_DISP. 145 * 146 * - EXTCON_PROP_DISP_HPD (Hot Plug Detect) 147 * @type: integer (intval) 148 * @value: 0 (no hpd) or 1 (hpd) 149 * @default: 0 (no hpd) 150 * 151 */ 152 #define EXTCON_PROP_DISP_HPD 150 153 154 /* Properties of EXTCON_TYPE_DISP. */ 155 #define EXTCON_PROP_DISP_MIN 150 156 #define EXTCON_PROP_DISP_MAX 151 157 #define EXTCON_PROP_DISP_CNT (EXTCON_PROP_DISP_MAX - EXTCON_PROP_DISP_MIN + 1) 158 159 /* 160 * Define the type of property's value. 161 * 162 * Define the property's value as union type. Because each property 163 * would need the different data type to store it. 164 */ 165 union extcon_property_value { 166 int intval; /* type : integer (intval) */ 167 }; 168 169 struct extcon_cable; 170 171 /** 172 * struct extcon_dev - An extcon device represents one external connector. 173 * @name: The name of this extcon device. Parent device name is 174 * used if NULL. 175 * @supported_cable: Array of supported cable names ending with EXTCON_NONE. 176 * If supported_cable is NULL, cable name related APIs 177 * are disabled. 178 * @mutually_exclusive: Array of mutually exclusive set of cables that cannot 179 * be attached simultaneously. The array should be 180 * ending with NULL or be NULL (no mutually exclusive 181 * cables). For example, if it is { 0x7, 0x30, 0}, then, 182 * {0, 1}, {0, 1, 2}, {0, 2}, {1, 2}, or {4, 5} cannot 183 * be attached simulataneously. {0x7, 0} is equivalent to 184 * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there 185 * can be no simultaneous connections. 186 * @dev: Device of this extcon. 187 * @state: Attach/detach state of this extcon. Do not provide at 188 * register-time. 189 * @nh: Notifier for the state change events from this extcon 190 * @entry: To support list of extcon devices so that users can 191 * search for extcon devices based on the extcon name. 192 * @lock: 193 * @max_supported: Internal value to store the number of cables. 194 * @extcon_dev_type: Device_type struct to provide attribute_groups 195 * customized for each extcon device. 196 * @cables: Sysfs subdirectories. Each represents one cable. 197 * 198 * In most cases, users only need to provide "User initializing data" of 199 * this struct when registering an extcon. In some exceptional cases, 200 * optional callbacks may be needed. However, the values in "internal data" 201 * are overwritten by register function. 202 */ 203 struct extcon_dev { 204 /* Optional user initializing data */ 205 const char *name; 206 const unsigned int *supported_cable; 207 const u32 *mutually_exclusive; 208 209 /* Internal data. Please do not set. */ 210 struct device dev; 211 struct raw_notifier_head *nh; 212 struct list_head entry; 213 int max_supported; 214 spinlock_t lock; /* could be called by irq handler */ 215 u32 state; 216 217 /* /sys/class/extcon/.../cable.n/... */ 218 struct device_type extcon_dev_type; 219 struct extcon_cable *cables; 220 221 /* /sys/class/extcon/.../mutually_exclusive/... */ 222 struct attribute_group attr_g_muex; 223 struct attribute **attrs_muex; 224 struct device_attribute *d_attrs_muex; 225 }; 226 227 #if IS_ENABLED(CONFIG_EXTCON) 228 229 /* 230 * Following APIs are for notifiers or configurations. 231 * Notifiers are the external port and connection devices. 232 */ 233 extern int extcon_dev_register(struct extcon_dev *edev); 234 extern void extcon_dev_unregister(struct extcon_dev *edev); 235 extern int devm_extcon_dev_register(struct device *dev, 236 struct extcon_dev *edev); 237 extern void devm_extcon_dev_unregister(struct device *dev, 238 struct extcon_dev *edev); 239 extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); 240 241 /* 242 * Following APIs control the memory of extcon device. 243 */ 244 extern struct extcon_dev *extcon_dev_allocate(const unsigned int *cable); 245 extern void extcon_dev_free(struct extcon_dev *edev); 246 extern struct extcon_dev *devm_extcon_dev_allocate(struct device *dev, 247 const unsigned int *cable); 248 extern void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev); 249 250 /* 251 * get/set_state access each bit of the 32b encoded state value. 252 * They are used to access the status of each cable based on the cable id. 253 */ 254 extern int extcon_get_state(struct extcon_dev *edev, unsigned int id); 255 extern int extcon_set_state(struct extcon_dev *edev, unsigned int id, 256 bool cable_state); 257 extern int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, 258 bool cable_state); 259 /* 260 * Synchronize the state and property data for a specific external connector. 261 */ 262 extern int extcon_sync(struct extcon_dev *edev, unsigned int id); 263 264 /* 265 * get/set_property access the property value of each external connector. 266 * They are used to access the property of each cable based on the property id. 267 */ 268 extern int extcon_get_property(struct extcon_dev *edev, unsigned int id, 269 unsigned int prop, 270 union extcon_property_value *prop_val); 271 extern int extcon_set_property(struct extcon_dev *edev, unsigned int id, 272 unsigned int prop, 273 union extcon_property_value prop_val); 274 extern int extcon_set_property_sync(struct extcon_dev *edev, unsigned int id, 275 unsigned int prop, 276 union extcon_property_value prop_val); 277 278 /* 279 * get/set_property_capability set the capability of the property for each 280 * external connector. They are used to set the capability of the property 281 * of each external connector based on the id and property. 282 */ 283 extern int extcon_get_property_capability(struct extcon_dev *edev, 284 unsigned int id, unsigned int prop); 285 extern int extcon_set_property_capability(struct extcon_dev *edev, 286 unsigned int id, unsigned int prop); 287 288 /* 289 * Following APIs are to monitor every action of a notifier. 290 * Registrar gets notified for every external port of a connection device. 291 * Probably this could be used to debug an action of notifier; however, 292 * we do not recommend to use this for normal 'notifiee' device drivers who 293 * want to be notified by a specific external port of the notifier. 294 */ 295 extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id, 296 struct notifier_block *nb); 297 extern int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id, 298 struct notifier_block *nb); 299 extern int devm_extcon_register_notifier(struct device *dev, 300 struct extcon_dev *edev, unsigned int id, 301 struct notifier_block *nb); 302 extern void devm_extcon_unregister_notifier(struct device *dev, 303 struct extcon_dev *edev, unsigned int id, 304 struct notifier_block *nb); 305 306 /* 307 * Following API get the extcon device from devicetree. 308 * This function use phandle of devicetree to get extcon device directly. 309 */ 310 extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, 311 int index); 312 313 /* Following API to get information of extcon device */ 314 extern const char *extcon_get_edev_name(struct extcon_dev *edev); 315 316 317 #else /* CONFIG_EXTCON */ 318 static inline int extcon_dev_register(struct extcon_dev *edev) 319 { 320 return 0; 321 } 322 323 static inline void extcon_dev_unregister(struct extcon_dev *edev) { } 324 325 static inline int devm_extcon_dev_register(struct device *dev, 326 struct extcon_dev *edev) 327 { 328 return -EINVAL; 329 } 330 331 static inline void devm_extcon_dev_unregister(struct device *dev, 332 struct extcon_dev *edev) { } 333 334 static inline struct extcon_dev *extcon_dev_allocate(const unsigned int *cable) 335 { 336 return ERR_PTR(-ENOSYS); 337 } 338 339 static inline void extcon_dev_free(struct extcon_dev *edev) { } 340 341 static inline struct extcon_dev *devm_extcon_dev_allocate(struct device *dev, 342 const unsigned int *cable) 343 { 344 return ERR_PTR(-ENOSYS); 345 } 346 347 static inline void devm_extcon_dev_free(struct extcon_dev *edev) { } 348 349 350 static inline int extcon_get_state(struct extcon_dev *edev, unsigned int id) 351 { 352 return 0; 353 } 354 355 static inline int extcon_set_state(struct extcon_dev *edev, unsigned int id, 356 bool cable_state) 357 { 358 return 0; 359 } 360 361 static inline int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, 362 bool cable_state) 363 { 364 return 0; 365 } 366 367 static inline int extcon_sync(struct extcon_dev *edev, unsigned int id) 368 { 369 return 0; 370 } 371 372 static inline int extcon_get_property(struct extcon_dev *edev, unsigned int id, 373 unsigned int prop, 374 union extcon_property_value *prop_val) 375 { 376 return 0; 377 } 378 static inline int extcon_set_property(struct extcon_dev *edev, unsigned int id, 379 unsigned int prop, 380 union extcon_property_value prop_val) 381 { 382 return 0; 383 } 384 385 static inline int extcon_set_property_sync(struct extcon_dev *edev, 386 unsigned int id, unsigned int prop, 387 union extcon_property_value prop_val) 388 { 389 return 0; 390 } 391 392 static inline int extcon_get_property_capability(struct extcon_dev *edev, 393 unsigned int id, unsigned int prop) 394 { 395 return 0; 396 } 397 398 static inline int extcon_set_property_capability(struct extcon_dev *edev, 399 unsigned int id, unsigned int prop) 400 { 401 return 0; 402 } 403 404 static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) 405 { 406 return NULL; 407 } 408 409 static inline int extcon_register_notifier(struct extcon_dev *edev, 410 unsigned int id, 411 struct notifier_block *nb) 412 { 413 return 0; 414 } 415 416 static inline int extcon_unregister_notifier(struct extcon_dev *edev, 417 unsigned int id, 418 struct notifier_block *nb) 419 { 420 return 0; 421 } 422 423 static inline int devm_extcon_register_notifier(struct device *dev, 424 struct extcon_dev *edev, unsigned int id, 425 struct notifier_block *nb) 426 { 427 return -ENOSYS; 428 } 429 430 static inline void devm_extcon_unregister_notifier(struct device *dev, 431 struct extcon_dev *edev, unsigned int id, 432 struct notifier_block *nb) { } 433 434 static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, 435 int index) 436 { 437 return ERR_PTR(-ENODEV); 438 } 439 #endif /* CONFIG_EXTCON */ 440 441 /* 442 * Following structure and API are deprecated. EXTCON remains the function 443 * definition to prevent the build break. 444 */ 445 struct extcon_specific_cable_nb { 446 struct notifier_block *user_nb; 447 int cable_index; 448 struct extcon_dev *edev; 449 unsigned long previous_value; 450 }; 451 452 static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj, 453 const char *extcon_name, const char *cable_name, 454 struct notifier_block *nb) 455 { 456 return -EINVAL; 457 } 458 459 static inline int extcon_unregister_interest(struct extcon_specific_cable_nb 460 *obj) 461 { 462 return -EINVAL; 463 } 464 465 static inline int extcon_get_cable_state_(struct extcon_dev *edev, unsigned int id) 466 { 467 return extcon_get_state(edev, id); 468 } 469 470 static inline int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id, 471 bool cable_state) 472 { 473 return extcon_set_state_sync(edev, id, cable_state); 474 } 475 #endif /* __LINUX_EXTCON_H__ */ 476