extcon.h 11 KB

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