class.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * USB Type-C Connector Class
  4. *
  5. * Copyright (C) 2017, Intel Corporation
  6. * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
  7. */
  8. #include <linux/device.h>
  9. #include <linux/module.h>
  10. #include <linux/mutex.h>
  11. #include <linux/slab.h>
  12. #include "bus.h"
  13. struct typec_plug {
  14. struct device dev;
  15. enum typec_plug_index index;
  16. struct ida mode_ids;
  17. };
  18. struct typec_cable {
  19. struct device dev;
  20. enum typec_plug_type type;
  21. struct usb_pd_identity *identity;
  22. unsigned int active:1;
  23. };
  24. struct typec_partner {
  25. struct device dev;
  26. unsigned int usb_pd:1;
  27. struct usb_pd_identity *identity;
  28. enum typec_accessory accessory;
  29. struct ida mode_ids;
  30. };
  31. struct typec_port {
  32. unsigned int id;
  33. struct device dev;
  34. struct ida mode_ids;
  35. int prefer_role;
  36. enum typec_data_role data_role;
  37. enum typec_role pwr_role;
  38. enum typec_role vconn_role;
  39. enum typec_pwr_opmode pwr_opmode;
  40. enum typec_port_type port_type;
  41. struct mutex port_type_lock;
  42. enum typec_orientation orientation;
  43. struct typec_switch *sw;
  44. struct typec_mux *mux;
  45. const struct typec_capability *cap;
  46. };
  47. #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev)
  48. #define to_typec_plug(_dev_) container_of(_dev_, struct typec_plug, dev)
  49. #define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev)
  50. #define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, dev)
  51. static const struct device_type typec_partner_dev_type;
  52. static const struct device_type typec_cable_dev_type;
  53. static const struct device_type typec_plug_dev_type;
  54. #define is_typec_partner(_dev_) (_dev_->type == &typec_partner_dev_type)
  55. #define is_typec_cable(_dev_) (_dev_->type == &typec_cable_dev_type)
  56. #define is_typec_plug(_dev_) (_dev_->type == &typec_plug_dev_type)
  57. static DEFINE_IDA(typec_index_ida);
  58. static struct class *typec_class;
  59. /* ------------------------------------------------------------------------- */
  60. /* Common attributes */
  61. static const char * const typec_accessory_modes[] = {
  62. [TYPEC_ACCESSORY_NONE] = "none",
  63. [TYPEC_ACCESSORY_AUDIO] = "analog_audio",
  64. [TYPEC_ACCESSORY_DEBUG] = "debug",
  65. };
  66. static struct usb_pd_identity *get_pd_identity(struct device *dev)
  67. {
  68. if (is_typec_partner(dev)) {
  69. struct typec_partner *partner = to_typec_partner(dev);
  70. return partner->identity;
  71. } else if (is_typec_cable(dev)) {
  72. struct typec_cable *cable = to_typec_cable(dev);
  73. return cable->identity;
  74. }
  75. return NULL;
  76. }
  77. static ssize_t id_header_show(struct device *dev, struct device_attribute *attr,
  78. char *buf)
  79. {
  80. struct usb_pd_identity *id = get_pd_identity(dev);
  81. return sprintf(buf, "0x%08x\n", id->id_header);
  82. }
  83. static DEVICE_ATTR_RO(id_header);
  84. static ssize_t cert_stat_show(struct device *dev, struct device_attribute *attr,
  85. char *buf)
  86. {
  87. struct usb_pd_identity *id = get_pd_identity(dev);
  88. return sprintf(buf, "0x%08x\n", id->cert_stat);
  89. }
  90. static DEVICE_ATTR_RO(cert_stat);
  91. static ssize_t product_show(struct device *dev, struct device_attribute *attr,
  92. char *buf)
  93. {
  94. struct usb_pd_identity *id = get_pd_identity(dev);
  95. return sprintf(buf, "0x%08x\n", id->product);
  96. }
  97. static DEVICE_ATTR_RO(product);
  98. static struct attribute *usb_pd_id_attrs[] = {
  99. &dev_attr_id_header.attr,
  100. &dev_attr_cert_stat.attr,
  101. &dev_attr_product.attr,
  102. NULL
  103. };
  104. static const struct attribute_group usb_pd_id_group = {
  105. .name = "identity",
  106. .attrs = usb_pd_id_attrs,
  107. };
  108. static const struct attribute_group *usb_pd_id_groups[] = {
  109. &usb_pd_id_group,
  110. NULL,
  111. };
  112. static void typec_report_identity(struct device *dev)
  113. {
  114. sysfs_notify(&dev->kobj, "identity", "id_header");
  115. sysfs_notify(&dev->kobj, "identity", "cert_stat");
  116. sysfs_notify(&dev->kobj, "identity", "product");
  117. }
  118. /* ------------------------------------------------------------------------- */
  119. /* Alternate Modes */
  120. static int altmode_match(struct device *dev, void *data)
  121. {
  122. struct typec_altmode *adev = to_typec_altmode(dev);
  123. struct typec_device_id *id = data;
  124. if (!is_typec_altmode(dev))
  125. return 0;
  126. return ((adev->svid == id->svid) && (adev->mode == id->mode));
  127. }
  128. static void typec_altmode_set_partner(struct altmode *altmode)
  129. {
  130. struct typec_altmode *adev = &altmode->adev;
  131. struct typec_device_id id = { adev->svid, adev->mode, };
  132. struct typec_port *port = typec_altmode2port(adev);
  133. struct altmode *partner;
  134. struct device *dev;
  135. dev = device_find_child(&port->dev, &id, altmode_match);
  136. if (!dev)
  137. return;
  138. /* Bind the port alt mode to the partner/plug alt mode. */
  139. partner = to_altmode(to_typec_altmode(dev));
  140. altmode->partner = partner;
  141. /* Bind the partner/plug alt mode to the port alt mode. */
  142. if (is_typec_plug(adev->dev.parent)) {
  143. struct typec_plug *plug = to_typec_plug(adev->dev.parent);
  144. partner->plug[plug->index] = altmode;
  145. } else {
  146. partner->partner = altmode;
  147. }
  148. }
  149. static void typec_altmode_put_partner(struct altmode *altmode)
  150. {
  151. struct altmode *partner = altmode->partner;
  152. struct typec_altmode *adev;
  153. if (!partner)
  154. return;
  155. adev = &partner->adev;
  156. if (is_typec_plug(adev->dev.parent)) {
  157. struct typec_plug *plug = to_typec_plug(adev->dev.parent);
  158. partner->plug[plug->index] = NULL;
  159. } else {
  160. partner->partner = NULL;
  161. }
  162. put_device(&adev->dev);
  163. }
  164. static int __typec_port_match(struct device *dev, const void *name)
  165. {
  166. return !strcmp((const char *)name, dev_name(dev));
  167. }
  168. static void *typec_port_match(struct device_connection *con, int ep, void *data)
  169. {
  170. return class_find_device(typec_class, NULL, con->endpoint[ep],
  171. __typec_port_match);
  172. }
  173. struct typec_altmode *
  174. typec_altmode_register_notifier(struct device *dev, u16 svid, u8 mode,
  175. struct notifier_block *nb)
  176. {
  177. struct typec_device_id id = { svid, mode, };
  178. struct device *altmode_dev;
  179. struct device *port_dev;
  180. struct altmode *altmode;
  181. int ret;
  182. /* Find the port linked to the caller */
  183. port_dev = device_connection_find_match(dev, NULL, NULL,
  184. typec_port_match);
  185. if (IS_ERR_OR_NULL(port_dev))
  186. return port_dev ? ERR_CAST(port_dev) : ERR_PTR(-ENODEV);
  187. /* Find the altmode with matching svid */
  188. altmode_dev = device_find_child(port_dev, &id, altmode_match);
  189. put_device(port_dev);
  190. if (!altmode_dev)
  191. return ERR_PTR(-ENODEV);
  192. altmode = to_altmode(to_typec_altmode(altmode_dev));
  193. /* Register notifier */
  194. ret = blocking_notifier_chain_register(&altmode->nh, nb);
  195. if (ret) {
  196. put_device(altmode_dev);
  197. return ERR_PTR(ret);
  198. }
  199. return &altmode->adev;
  200. }
  201. EXPORT_SYMBOL_GPL(typec_altmode_register_notifier);
  202. void typec_altmode_unregister_notifier(struct typec_altmode *adev,
  203. struct notifier_block *nb)
  204. {
  205. struct altmode *altmode = to_altmode(adev);
  206. blocking_notifier_chain_unregister(&altmode->nh, nb);
  207. put_device(&adev->dev);
  208. }
  209. EXPORT_SYMBOL_GPL(typec_altmode_unregister_notifier);
  210. /**
  211. * typec_altmode_update_active - Report Enter/Exit mode
  212. * @adev: Handle to the alternate mode
  213. * @active: True when the mode has been entered
  214. *
  215. * If a partner or cable plug executes Enter/Exit Mode command successfully, the
  216. * drivers use this routine to report the updated state of the mode.
  217. */
  218. void typec_altmode_update_active(struct typec_altmode *adev, bool active)
  219. {
  220. char dir[6];
  221. if (adev->active == active)
  222. return;
  223. if (!is_typec_port(adev->dev.parent)) {
  224. if (!active)
  225. module_put(adev->dev.driver->owner);
  226. else
  227. WARN_ON(!try_module_get(adev->dev.driver->owner));
  228. }
  229. adev->active = active;
  230. snprintf(dir, sizeof(dir), "mode%d", adev->mode);
  231. sysfs_notify(&adev->dev.kobj, dir, "active");
  232. sysfs_notify(&adev->dev.kobj, NULL, "active");
  233. kobject_uevent(&adev->dev.kobj, KOBJ_CHANGE);
  234. }
  235. EXPORT_SYMBOL_GPL(typec_altmode_update_active);
  236. /**
  237. * typec_altmode2port - Alternate Mode to USB Type-C port
  238. * @alt: The Alternate Mode
  239. *
  240. * Returns handle to the port that a cable plug or partner with @alt is
  241. * connected to.
  242. */
  243. struct typec_port *typec_altmode2port(struct typec_altmode *alt)
  244. {
  245. if (is_typec_plug(alt->dev.parent))
  246. return to_typec_port(alt->dev.parent->parent->parent);
  247. if (is_typec_partner(alt->dev.parent))
  248. return to_typec_port(alt->dev.parent->parent);
  249. if (is_typec_port(alt->dev.parent))
  250. return to_typec_port(alt->dev.parent);
  251. return NULL;
  252. }
  253. EXPORT_SYMBOL_GPL(typec_altmode2port);
  254. static ssize_t
  255. vdo_show(struct device *dev, struct device_attribute *attr, char *buf)
  256. {
  257. struct typec_altmode *alt = to_typec_altmode(dev);
  258. return sprintf(buf, "0x%08x\n", alt->vdo);
  259. }
  260. static DEVICE_ATTR_RO(vdo);
  261. static ssize_t
  262. description_show(struct device *dev, struct device_attribute *attr, char *buf)
  263. {
  264. struct typec_altmode *alt = to_typec_altmode(dev);
  265. return sprintf(buf, "%s\n", alt->desc ? alt->desc : "");
  266. }
  267. static DEVICE_ATTR_RO(description);
  268. static ssize_t
  269. active_show(struct device *dev, struct device_attribute *attr, char *buf)
  270. {
  271. struct typec_altmode *alt = to_typec_altmode(dev);
  272. return sprintf(buf, "%s\n", alt->active ? "yes" : "no");
  273. }
  274. static ssize_t active_store(struct device *dev, struct device_attribute *attr,
  275. const char *buf, size_t size)
  276. {
  277. struct typec_altmode *adev = to_typec_altmode(dev);
  278. struct altmode *altmode = to_altmode(adev);
  279. bool enter;
  280. int ret;
  281. ret = kstrtobool(buf, &enter);
  282. if (ret)
  283. return ret;
  284. if (adev->active == enter)
  285. return size;
  286. if (is_typec_port(adev->dev.parent)) {
  287. typec_altmode_update_active(adev, enter);
  288. /* Make sure that the partner exits the mode before disabling */
  289. if (altmode->partner && !enter && altmode->partner->adev.active)
  290. typec_altmode_exit(&altmode->partner->adev);
  291. } else if (altmode->partner) {
  292. if (enter && !altmode->partner->adev.active) {
  293. dev_warn(dev, "port has the mode disabled\n");
  294. return -EPERM;
  295. }
  296. }
  297. /* Note: If there is no driver, the mode will not be entered */
  298. if (adev->ops && adev->ops->activate) {
  299. ret = adev->ops->activate(adev, enter);
  300. if (ret)
  301. return ret;
  302. }
  303. return size;
  304. }
  305. static DEVICE_ATTR_RW(active);
  306. static ssize_t
  307. supported_roles_show(struct device *dev, struct device_attribute *attr,
  308. char *buf)
  309. {
  310. struct altmode *alt = to_altmode(to_typec_altmode(dev));
  311. ssize_t ret;
  312. switch (alt->roles) {
  313. case TYPEC_PORT_SRC:
  314. ret = sprintf(buf, "source\n");
  315. break;
  316. case TYPEC_PORT_SNK:
  317. ret = sprintf(buf, "sink\n");
  318. break;
  319. case TYPEC_PORT_DRP:
  320. default:
  321. ret = sprintf(buf, "source sink\n");
  322. break;
  323. }
  324. return ret;
  325. }
  326. static DEVICE_ATTR_RO(supported_roles);
  327. static ssize_t
  328. mode_show(struct device *dev, struct device_attribute *attr, char *buf)
  329. {
  330. struct typec_altmode *adev = to_typec_altmode(dev);
  331. return sprintf(buf, "%u\n", adev->mode);
  332. }
  333. static DEVICE_ATTR_RO(mode);
  334. static ssize_t
  335. svid_show(struct device *dev, struct device_attribute *attr, char *buf)
  336. {
  337. struct typec_altmode *adev = to_typec_altmode(dev);
  338. return sprintf(buf, "%04x\n", adev->svid);
  339. }
  340. static DEVICE_ATTR_RO(svid);
  341. static struct attribute *typec_altmode_attrs[] = {
  342. &dev_attr_active.attr,
  343. &dev_attr_mode.attr,
  344. &dev_attr_svid.attr,
  345. &dev_attr_vdo.attr,
  346. NULL
  347. };
  348. ATTRIBUTE_GROUPS(typec_altmode);
  349. static int altmode_id_get(struct device *dev)
  350. {
  351. struct ida *ids;
  352. if (is_typec_partner(dev))
  353. ids = &to_typec_partner(dev)->mode_ids;
  354. else if (is_typec_plug(dev))
  355. ids = &to_typec_plug(dev)->mode_ids;
  356. else
  357. ids = &to_typec_port(dev)->mode_ids;
  358. return ida_simple_get(ids, 0, 0, GFP_KERNEL);
  359. }
  360. static void altmode_id_remove(struct device *dev, int id)
  361. {
  362. struct ida *ids;
  363. if (is_typec_partner(dev))
  364. ids = &to_typec_partner(dev)->mode_ids;
  365. else if (is_typec_plug(dev))
  366. ids = &to_typec_plug(dev)->mode_ids;
  367. else
  368. ids = &to_typec_port(dev)->mode_ids;
  369. ida_simple_remove(ids, id);
  370. }
  371. static void typec_altmode_release(struct device *dev)
  372. {
  373. struct altmode *alt = to_altmode(to_typec_altmode(dev));
  374. typec_altmode_put_partner(alt);
  375. altmode_id_remove(alt->adev.dev.parent, alt->id);
  376. kfree(alt);
  377. }
  378. const struct device_type typec_altmode_dev_type = {
  379. .name = "typec_alternate_mode",
  380. .groups = typec_altmode_groups,
  381. .release = typec_altmode_release,
  382. };
  383. static struct typec_altmode *
  384. typec_register_altmode(struct device *parent,
  385. const struct typec_altmode_desc *desc)
  386. {
  387. unsigned int id = altmode_id_get(parent);
  388. bool is_port = is_typec_port(parent);
  389. struct altmode *alt;
  390. int ret;
  391. alt = kzalloc(sizeof(*alt), GFP_KERNEL);
  392. if (!alt)
  393. return ERR_PTR(-ENOMEM);
  394. alt->adev.svid = desc->svid;
  395. alt->adev.mode = desc->mode;
  396. alt->adev.vdo = desc->vdo;
  397. alt->roles = desc->roles;
  398. alt->id = id;
  399. alt->attrs[0] = &dev_attr_vdo.attr;
  400. alt->attrs[1] = &dev_attr_description.attr;
  401. alt->attrs[2] = &dev_attr_active.attr;
  402. if (is_port) {
  403. alt->attrs[3] = &dev_attr_supported_roles.attr;
  404. alt->adev.active = true; /* Enabled by default */
  405. }
  406. sprintf(alt->group_name, "mode%d", desc->mode);
  407. alt->group.name = alt->group_name;
  408. alt->group.attrs = alt->attrs;
  409. alt->groups[0] = &alt->group;
  410. alt->adev.dev.parent = parent;
  411. alt->adev.dev.groups = alt->groups;
  412. alt->adev.dev.type = &typec_altmode_dev_type;
  413. dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id);
  414. /* Link partners and plugs with the ports */
  415. if (is_port)
  416. BLOCKING_INIT_NOTIFIER_HEAD(&alt->nh);
  417. else
  418. typec_altmode_set_partner(alt);
  419. /* The partners are bind to drivers */
  420. if (is_typec_partner(parent))
  421. alt->adev.dev.bus = &typec_bus;
  422. ret = device_register(&alt->adev.dev);
  423. if (ret) {
  424. dev_err(parent, "failed to register alternate mode (%d)\n",
  425. ret);
  426. put_device(&alt->adev.dev);
  427. return ERR_PTR(ret);
  428. }
  429. return &alt->adev;
  430. }
  431. /**
  432. * typec_unregister_altmode - Unregister Alternate Mode
  433. * @adev: The alternate mode to be unregistered
  434. *
  435. * Unregister device created with typec_partner_register_altmode(),
  436. * typec_plug_register_altmode() or typec_port_register_altmode().
  437. */
  438. void typec_unregister_altmode(struct typec_altmode *adev)
  439. {
  440. if (IS_ERR_OR_NULL(adev))
  441. return;
  442. typec_mux_put(to_altmode(adev)->mux);
  443. device_unregister(&adev->dev);
  444. }
  445. EXPORT_SYMBOL_GPL(typec_unregister_altmode);
  446. /* ------------------------------------------------------------------------- */
  447. /* Type-C Partners */
  448. static ssize_t accessory_mode_show(struct device *dev,
  449. struct device_attribute *attr,
  450. char *buf)
  451. {
  452. struct typec_partner *p = to_typec_partner(dev);
  453. return sprintf(buf, "%s\n", typec_accessory_modes[p->accessory]);
  454. }
  455. static DEVICE_ATTR_RO(accessory_mode);
  456. static ssize_t supports_usb_power_delivery_show(struct device *dev,
  457. struct device_attribute *attr,
  458. char *buf)
  459. {
  460. struct typec_partner *p = to_typec_partner(dev);
  461. return sprintf(buf, "%s\n", p->usb_pd ? "yes" : "no");
  462. }
  463. static DEVICE_ATTR_RO(supports_usb_power_delivery);
  464. static struct attribute *typec_partner_attrs[] = {
  465. &dev_attr_accessory_mode.attr,
  466. &dev_attr_supports_usb_power_delivery.attr,
  467. NULL
  468. };
  469. ATTRIBUTE_GROUPS(typec_partner);
  470. static void typec_partner_release(struct device *dev)
  471. {
  472. struct typec_partner *partner = to_typec_partner(dev);
  473. ida_destroy(&partner->mode_ids);
  474. kfree(partner);
  475. }
  476. static const struct device_type typec_partner_dev_type = {
  477. .name = "typec_partner",
  478. .groups = typec_partner_groups,
  479. .release = typec_partner_release,
  480. };
  481. /**
  482. * typec_partner_set_identity - Report result from Discover Identity command
  483. * @partner: The partner updated identity values
  484. *
  485. * This routine is used to report that the result of Discover Identity USB power
  486. * delivery command has become available.
  487. */
  488. int typec_partner_set_identity(struct typec_partner *partner)
  489. {
  490. if (!partner->identity)
  491. return -EINVAL;
  492. typec_report_identity(&partner->dev);
  493. return 0;
  494. }
  495. EXPORT_SYMBOL_GPL(typec_partner_set_identity);
  496. /**
  497. * typec_partner_register_altmode - Register USB Type-C Partner Alternate Mode
  498. * @partner: USB Type-C Partner that supports the alternate mode
  499. * @desc: Description of the alternate mode
  500. *
  501. * This routine is used to register each alternate mode individually that
  502. * @partner has listed in response to Discover SVIDs command. The modes for a
  503. * SVID listed in response to Discover Modes command need to be listed in an
  504. * array in @desc.
  505. *
  506. * Returns handle to the alternate mode on success or NULL on failure.
  507. */
  508. struct typec_altmode *
  509. typec_partner_register_altmode(struct typec_partner *partner,
  510. const struct typec_altmode_desc *desc)
  511. {
  512. return typec_register_altmode(&partner->dev, desc);
  513. }
  514. EXPORT_SYMBOL_GPL(typec_partner_register_altmode);
  515. /**
  516. * typec_register_partner - Register a USB Type-C Partner
  517. * @port: The USB Type-C Port the partner is connected to
  518. * @desc: Description of the partner
  519. *
  520. * Registers a device for USB Type-C Partner described in @desc.
  521. *
  522. * Returns handle to the partner on success or ERR_PTR on failure.
  523. */
  524. struct typec_partner *typec_register_partner(struct typec_port *port,
  525. struct typec_partner_desc *desc)
  526. {
  527. struct typec_partner *partner;
  528. int ret;
  529. partner = kzalloc(sizeof(*partner), GFP_KERNEL);
  530. if (!partner)
  531. return ERR_PTR(-ENOMEM);
  532. ida_init(&partner->mode_ids);
  533. partner->usb_pd = desc->usb_pd;
  534. partner->accessory = desc->accessory;
  535. if (desc->identity) {
  536. /*
  537. * Creating directory for the identity only if the driver is
  538. * able to provide data to it.
  539. */
  540. partner->dev.groups = usb_pd_id_groups;
  541. partner->identity = desc->identity;
  542. }
  543. partner->dev.class = typec_class;
  544. partner->dev.parent = &port->dev;
  545. partner->dev.type = &typec_partner_dev_type;
  546. dev_set_name(&partner->dev, "%s-partner", dev_name(&port->dev));
  547. ret = device_register(&partner->dev);
  548. if (ret) {
  549. dev_err(&port->dev, "failed to register partner (%d)\n", ret);
  550. put_device(&partner->dev);
  551. return ERR_PTR(ret);
  552. }
  553. return partner;
  554. }
  555. EXPORT_SYMBOL_GPL(typec_register_partner);
  556. /**
  557. * typec_unregister_partner - Unregister a USB Type-C Partner
  558. * @partner: The partner to be unregistered
  559. *
  560. * Unregister device created with typec_register_partner().
  561. */
  562. void typec_unregister_partner(struct typec_partner *partner)
  563. {
  564. if (!IS_ERR_OR_NULL(partner))
  565. device_unregister(&partner->dev);
  566. }
  567. EXPORT_SYMBOL_GPL(typec_unregister_partner);
  568. /* ------------------------------------------------------------------------- */
  569. /* Type-C Cable Plugs */
  570. static void typec_plug_release(struct device *dev)
  571. {
  572. struct typec_plug *plug = to_typec_plug(dev);
  573. ida_destroy(&plug->mode_ids);
  574. kfree(plug);
  575. }
  576. static const struct device_type typec_plug_dev_type = {
  577. .name = "typec_plug",
  578. .release = typec_plug_release,
  579. };
  580. /**
  581. * typec_plug_register_altmode - Register USB Type-C Cable Plug Alternate Mode
  582. * @plug: USB Type-C Cable Plug that supports the alternate mode
  583. * @desc: Description of the alternate mode
  584. *
  585. * This routine is used to register each alternate mode individually that @plug
  586. * has listed in response to Discover SVIDs command. The modes for a SVID that
  587. * the plug lists in response to Discover Modes command need to be listed in an
  588. * array in @desc.
  589. *
  590. * Returns handle to the alternate mode on success or ERR_PTR on failure.
  591. */
  592. struct typec_altmode *
  593. typec_plug_register_altmode(struct typec_plug *plug,
  594. const struct typec_altmode_desc *desc)
  595. {
  596. return typec_register_altmode(&plug->dev, desc);
  597. }
  598. EXPORT_SYMBOL_GPL(typec_plug_register_altmode);
  599. /**
  600. * typec_register_plug - Register a USB Type-C Cable Plug
  601. * @cable: USB Type-C Cable with the plug
  602. * @desc: Description of the cable plug
  603. *
  604. * Registers a device for USB Type-C Cable Plug described in @desc. A USB Type-C
  605. * Cable Plug represents a plug with electronics in it that can response to USB
  606. * Power Delivery SOP Prime or SOP Double Prime packages.
  607. *
  608. * Returns handle to the cable plug on success or ERR_PTR on failure.
  609. */
  610. struct typec_plug *typec_register_plug(struct typec_cable *cable,
  611. struct typec_plug_desc *desc)
  612. {
  613. struct typec_plug *plug;
  614. char name[8];
  615. int ret;
  616. plug = kzalloc(sizeof(*plug), GFP_KERNEL);
  617. if (!plug)
  618. return ERR_PTR(-ENOMEM);
  619. sprintf(name, "plug%d", desc->index);
  620. ida_init(&plug->mode_ids);
  621. plug->index = desc->index;
  622. plug->dev.class = typec_class;
  623. plug->dev.parent = &cable->dev;
  624. plug->dev.type = &typec_plug_dev_type;
  625. dev_set_name(&plug->dev, "%s-%s", dev_name(cable->dev.parent), name);
  626. ret = device_register(&plug->dev);
  627. if (ret) {
  628. dev_err(&cable->dev, "failed to register plug (%d)\n", ret);
  629. put_device(&plug->dev);
  630. return ERR_PTR(ret);
  631. }
  632. return plug;
  633. }
  634. EXPORT_SYMBOL_GPL(typec_register_plug);
  635. /**
  636. * typec_unregister_plug - Unregister a USB Type-C Cable Plug
  637. * @plug: The cable plug to be unregistered
  638. *
  639. * Unregister device created with typec_register_plug().
  640. */
  641. void typec_unregister_plug(struct typec_plug *plug)
  642. {
  643. if (!IS_ERR_OR_NULL(plug))
  644. device_unregister(&plug->dev);
  645. }
  646. EXPORT_SYMBOL_GPL(typec_unregister_plug);
  647. /* Type-C Cables */
  648. static ssize_t
  649. type_show(struct device *dev, struct device_attribute *attr, char *buf)
  650. {
  651. struct typec_cable *cable = to_typec_cable(dev);
  652. return sprintf(buf, "%s\n", cable->active ? "active" : "passive");
  653. }
  654. static DEVICE_ATTR_RO(type);
  655. static const char * const typec_plug_types[] = {
  656. [USB_PLUG_NONE] = "unknown",
  657. [USB_PLUG_TYPE_A] = "type-a",
  658. [USB_PLUG_TYPE_B] = "type-b",
  659. [USB_PLUG_TYPE_C] = "type-c",
  660. [USB_PLUG_CAPTIVE] = "captive",
  661. };
  662. static ssize_t plug_type_show(struct device *dev,
  663. struct device_attribute *attr, char *buf)
  664. {
  665. struct typec_cable *cable = to_typec_cable(dev);
  666. return sprintf(buf, "%s\n", typec_plug_types[cable->type]);
  667. }
  668. static DEVICE_ATTR_RO(plug_type);
  669. static struct attribute *typec_cable_attrs[] = {
  670. &dev_attr_type.attr,
  671. &dev_attr_plug_type.attr,
  672. NULL
  673. };
  674. ATTRIBUTE_GROUPS(typec_cable);
  675. static void typec_cable_release(struct device *dev)
  676. {
  677. struct typec_cable *cable = to_typec_cable(dev);
  678. kfree(cable);
  679. }
  680. static const struct device_type typec_cable_dev_type = {
  681. .name = "typec_cable",
  682. .groups = typec_cable_groups,
  683. .release = typec_cable_release,
  684. };
  685. /**
  686. * typec_cable_set_identity - Report result from Discover Identity command
  687. * @cable: The cable updated identity values
  688. *
  689. * This routine is used to report that the result of Discover Identity USB power
  690. * delivery command has become available.
  691. */
  692. int typec_cable_set_identity(struct typec_cable *cable)
  693. {
  694. if (!cable->identity)
  695. return -EINVAL;
  696. typec_report_identity(&cable->dev);
  697. return 0;
  698. }
  699. EXPORT_SYMBOL_GPL(typec_cable_set_identity);
  700. /**
  701. * typec_register_cable - Register a USB Type-C Cable
  702. * @port: The USB Type-C Port the cable is connected to
  703. * @desc: Description of the cable
  704. *
  705. * Registers a device for USB Type-C Cable described in @desc. The cable will be
  706. * parent for the optional cable plug devises.
  707. *
  708. * Returns handle to the cable on success or ERR_PTR on failure.
  709. */
  710. struct typec_cable *typec_register_cable(struct typec_port *port,
  711. struct typec_cable_desc *desc)
  712. {
  713. struct typec_cable *cable;
  714. int ret;
  715. cable = kzalloc(sizeof(*cable), GFP_KERNEL);
  716. if (!cable)
  717. return ERR_PTR(-ENOMEM);
  718. cable->type = desc->type;
  719. cable->active = desc->active;
  720. if (desc->identity) {
  721. /*
  722. * Creating directory for the identity only if the driver is
  723. * able to provide data to it.
  724. */
  725. cable->dev.groups = usb_pd_id_groups;
  726. cable->identity = desc->identity;
  727. }
  728. cable->dev.class = typec_class;
  729. cable->dev.parent = &port->dev;
  730. cable->dev.type = &typec_cable_dev_type;
  731. dev_set_name(&cable->dev, "%s-cable", dev_name(&port->dev));
  732. ret = device_register(&cable->dev);
  733. if (ret) {
  734. dev_err(&port->dev, "failed to register cable (%d)\n", ret);
  735. put_device(&cable->dev);
  736. return ERR_PTR(ret);
  737. }
  738. return cable;
  739. }
  740. EXPORT_SYMBOL_GPL(typec_register_cable);
  741. /**
  742. * typec_unregister_cable - Unregister a USB Type-C Cable
  743. * @cable: The cable to be unregistered
  744. *
  745. * Unregister device created with typec_register_cable().
  746. */
  747. void typec_unregister_cable(struct typec_cable *cable)
  748. {
  749. if (!IS_ERR_OR_NULL(cable))
  750. device_unregister(&cable->dev);
  751. }
  752. EXPORT_SYMBOL_GPL(typec_unregister_cable);
  753. /* ------------------------------------------------------------------------- */
  754. /* USB Type-C ports */
  755. static const char * const typec_roles[] = {
  756. [TYPEC_SINK] = "sink",
  757. [TYPEC_SOURCE] = "source",
  758. };
  759. static const char * const typec_data_roles[] = {
  760. [TYPEC_DEVICE] = "device",
  761. [TYPEC_HOST] = "host",
  762. };
  763. static const char * const typec_port_power_roles[] = {
  764. [TYPEC_PORT_SRC] = "source",
  765. [TYPEC_PORT_SNK] = "sink",
  766. [TYPEC_PORT_DRP] = "dual",
  767. };
  768. static const char * const typec_port_data_roles[] = {
  769. [TYPEC_PORT_DFP] = "host",
  770. [TYPEC_PORT_UFP] = "device",
  771. [TYPEC_PORT_DRD] = "dual",
  772. };
  773. static const char * const typec_port_types_drp[] = {
  774. [TYPEC_PORT_SRC] = "dual [source] sink",
  775. [TYPEC_PORT_SNK] = "dual source [sink]",
  776. [TYPEC_PORT_DRP] = "[dual] source sink",
  777. };
  778. static ssize_t
  779. preferred_role_store(struct device *dev, struct device_attribute *attr,
  780. const char *buf, size_t size)
  781. {
  782. struct typec_port *port = to_typec_port(dev);
  783. int role;
  784. int ret;
  785. if (port->cap->type != TYPEC_PORT_DRP) {
  786. dev_dbg(dev, "Preferred role only supported with DRP ports\n");
  787. return -EOPNOTSUPP;
  788. }
  789. if (!port->cap->try_role) {
  790. dev_dbg(dev, "Setting preferred role not supported\n");
  791. return -EOPNOTSUPP;
  792. }
  793. role = sysfs_match_string(typec_roles, buf);
  794. if (role < 0) {
  795. if (sysfs_streq(buf, "none"))
  796. role = TYPEC_NO_PREFERRED_ROLE;
  797. else
  798. return -EINVAL;
  799. }
  800. ret = port->cap->try_role(port->cap, role);
  801. if (ret)
  802. return ret;
  803. port->prefer_role = role;
  804. return size;
  805. }
  806. static ssize_t
  807. preferred_role_show(struct device *dev, struct device_attribute *attr,
  808. char *buf)
  809. {
  810. struct typec_port *port = to_typec_port(dev);
  811. if (port->cap->type != TYPEC_PORT_DRP)
  812. return 0;
  813. if (port->prefer_role < 0)
  814. return 0;
  815. return sprintf(buf, "%s\n", typec_roles[port->prefer_role]);
  816. }
  817. static DEVICE_ATTR_RW(preferred_role);
  818. static ssize_t data_role_store(struct device *dev,
  819. struct device_attribute *attr,
  820. const char *buf, size_t size)
  821. {
  822. struct typec_port *port = to_typec_port(dev);
  823. int ret;
  824. if (!port->cap->dr_set) {
  825. dev_dbg(dev, "data role swapping not supported\n");
  826. return -EOPNOTSUPP;
  827. }
  828. ret = sysfs_match_string(typec_data_roles, buf);
  829. if (ret < 0)
  830. return ret;
  831. mutex_lock(&port->port_type_lock);
  832. if (port->cap->data != TYPEC_PORT_DRD) {
  833. ret = -EOPNOTSUPP;
  834. goto unlock_and_ret;
  835. }
  836. ret = port->cap->dr_set(port->cap, ret);
  837. if (ret)
  838. goto unlock_and_ret;
  839. ret = size;
  840. unlock_and_ret:
  841. mutex_unlock(&port->port_type_lock);
  842. return ret;
  843. }
  844. static ssize_t data_role_show(struct device *dev,
  845. struct device_attribute *attr, char *buf)
  846. {
  847. struct typec_port *port = to_typec_port(dev);
  848. if (port->cap->data == TYPEC_PORT_DRD)
  849. return sprintf(buf, "%s\n", port->data_role == TYPEC_HOST ?
  850. "[host] device" : "host [device]");
  851. return sprintf(buf, "[%s]\n", typec_data_roles[port->data_role]);
  852. }
  853. static DEVICE_ATTR_RW(data_role);
  854. static ssize_t power_role_store(struct device *dev,
  855. struct device_attribute *attr,
  856. const char *buf, size_t size)
  857. {
  858. struct typec_port *port = to_typec_port(dev);
  859. int ret;
  860. if (!port->cap->pd_revision) {
  861. dev_dbg(dev, "USB Power Delivery not supported\n");
  862. return -EOPNOTSUPP;
  863. }
  864. if (!port->cap->pr_set) {
  865. dev_dbg(dev, "power role swapping not supported\n");
  866. return -EOPNOTSUPP;
  867. }
  868. if (port->pwr_opmode != TYPEC_PWR_MODE_PD) {
  869. dev_dbg(dev, "partner unable to swap power role\n");
  870. return -EIO;
  871. }
  872. ret = sysfs_match_string(typec_roles, buf);
  873. if (ret < 0)
  874. return ret;
  875. mutex_lock(&port->port_type_lock);
  876. if (port->port_type != TYPEC_PORT_DRP) {
  877. dev_dbg(dev, "port type fixed at \"%s\"",
  878. typec_port_power_roles[port->port_type]);
  879. ret = -EOPNOTSUPP;
  880. goto unlock_and_ret;
  881. }
  882. ret = port->cap->pr_set(port->cap, ret);
  883. if (ret)
  884. goto unlock_and_ret;
  885. ret = size;
  886. unlock_and_ret:
  887. mutex_unlock(&port->port_type_lock);
  888. return ret;
  889. }
  890. static ssize_t power_role_show(struct device *dev,
  891. struct device_attribute *attr, char *buf)
  892. {
  893. struct typec_port *port = to_typec_port(dev);
  894. if (port->cap->type == TYPEC_PORT_DRP)
  895. return sprintf(buf, "%s\n", port->pwr_role == TYPEC_SOURCE ?
  896. "[source] sink" : "source [sink]");
  897. return sprintf(buf, "[%s]\n", typec_roles[port->pwr_role]);
  898. }
  899. static DEVICE_ATTR_RW(power_role);
  900. static ssize_t
  901. port_type_store(struct device *dev, struct device_attribute *attr,
  902. const char *buf, size_t size)
  903. {
  904. struct typec_port *port = to_typec_port(dev);
  905. int ret;
  906. enum typec_port_type type;
  907. if (!port->cap->port_type_set || port->cap->type != TYPEC_PORT_DRP) {
  908. dev_dbg(dev, "changing port type not supported\n");
  909. return -EOPNOTSUPP;
  910. }
  911. ret = sysfs_match_string(typec_port_power_roles, buf);
  912. if (ret < 0)
  913. return ret;
  914. type = ret;
  915. mutex_lock(&port->port_type_lock);
  916. if (port->port_type == type) {
  917. ret = size;
  918. goto unlock_and_ret;
  919. }
  920. ret = port->cap->port_type_set(port->cap, type);
  921. if (ret)
  922. goto unlock_and_ret;
  923. port->port_type = type;
  924. ret = size;
  925. unlock_and_ret:
  926. mutex_unlock(&port->port_type_lock);
  927. return ret;
  928. }
  929. static ssize_t
  930. port_type_show(struct device *dev, struct device_attribute *attr,
  931. char *buf)
  932. {
  933. struct typec_port *port = to_typec_port(dev);
  934. if (port->cap->type == TYPEC_PORT_DRP)
  935. return sprintf(buf, "%s\n",
  936. typec_port_types_drp[port->port_type]);
  937. return sprintf(buf, "[%s]\n", typec_port_power_roles[port->cap->type]);
  938. }
  939. static DEVICE_ATTR_RW(port_type);
  940. static const char * const typec_pwr_opmodes[] = {
  941. [TYPEC_PWR_MODE_USB] = "default",
  942. [TYPEC_PWR_MODE_1_5A] = "1.5A",
  943. [TYPEC_PWR_MODE_3_0A] = "3.0A",
  944. [TYPEC_PWR_MODE_PD] = "usb_power_delivery",
  945. };
  946. static ssize_t power_operation_mode_show(struct device *dev,
  947. struct device_attribute *attr,
  948. char *buf)
  949. {
  950. struct typec_port *port = to_typec_port(dev);
  951. return sprintf(buf, "%s\n", typec_pwr_opmodes[port->pwr_opmode]);
  952. }
  953. static DEVICE_ATTR_RO(power_operation_mode);
  954. static ssize_t vconn_source_store(struct device *dev,
  955. struct device_attribute *attr,
  956. const char *buf, size_t size)
  957. {
  958. struct typec_port *port = to_typec_port(dev);
  959. bool source;
  960. int ret;
  961. if (!port->cap->pd_revision) {
  962. dev_dbg(dev, "VCONN swap depends on USB Power Delivery\n");
  963. return -EOPNOTSUPP;
  964. }
  965. if (!port->cap->vconn_set) {
  966. dev_dbg(dev, "VCONN swapping not supported\n");
  967. return -EOPNOTSUPP;
  968. }
  969. ret = kstrtobool(buf, &source);
  970. if (ret)
  971. return ret;
  972. ret = port->cap->vconn_set(port->cap, (enum typec_role)source);
  973. if (ret)
  974. return ret;
  975. return size;
  976. }
  977. static ssize_t vconn_source_show(struct device *dev,
  978. struct device_attribute *attr, char *buf)
  979. {
  980. struct typec_port *port = to_typec_port(dev);
  981. return sprintf(buf, "%s\n",
  982. port->vconn_role == TYPEC_SOURCE ? "yes" : "no");
  983. }
  984. static DEVICE_ATTR_RW(vconn_source);
  985. static ssize_t supported_accessory_modes_show(struct device *dev,
  986. struct device_attribute *attr,
  987. char *buf)
  988. {
  989. struct typec_port *port = to_typec_port(dev);
  990. ssize_t ret = 0;
  991. int i;
  992. for (i = 0; i < ARRAY_SIZE(port->cap->accessory); i++) {
  993. if (port->cap->accessory[i])
  994. ret += sprintf(buf + ret, "%s ",
  995. typec_accessory_modes[port->cap->accessory[i]]);
  996. }
  997. if (!ret)
  998. return sprintf(buf, "none\n");
  999. buf[ret - 1] = '\n';
  1000. return ret;
  1001. }
  1002. static DEVICE_ATTR_RO(supported_accessory_modes);
  1003. static ssize_t usb_typec_revision_show(struct device *dev,
  1004. struct device_attribute *attr,
  1005. char *buf)
  1006. {
  1007. struct typec_port *port = to_typec_port(dev);
  1008. u16 rev = port->cap->revision;
  1009. return sprintf(buf, "%d.%d\n", (rev >> 8) & 0xff, (rev >> 4) & 0xf);
  1010. }
  1011. static DEVICE_ATTR_RO(usb_typec_revision);
  1012. static ssize_t usb_power_delivery_revision_show(struct device *dev,
  1013. struct device_attribute *attr,
  1014. char *buf)
  1015. {
  1016. struct typec_port *p = to_typec_port(dev);
  1017. return sprintf(buf, "%d\n", (p->cap->pd_revision >> 8) & 0xff);
  1018. }
  1019. static DEVICE_ATTR_RO(usb_power_delivery_revision);
  1020. static struct attribute *typec_attrs[] = {
  1021. &dev_attr_data_role.attr,
  1022. &dev_attr_power_operation_mode.attr,
  1023. &dev_attr_power_role.attr,
  1024. &dev_attr_preferred_role.attr,
  1025. &dev_attr_supported_accessory_modes.attr,
  1026. &dev_attr_usb_power_delivery_revision.attr,
  1027. &dev_attr_usb_typec_revision.attr,
  1028. &dev_attr_vconn_source.attr,
  1029. &dev_attr_port_type.attr,
  1030. NULL,
  1031. };
  1032. ATTRIBUTE_GROUPS(typec);
  1033. static int typec_uevent(struct device *dev, struct kobj_uevent_env *env)
  1034. {
  1035. int ret;
  1036. ret = add_uevent_var(env, "TYPEC_PORT=%s", dev_name(dev));
  1037. if (ret)
  1038. dev_err(dev, "failed to add uevent TYPEC_PORT\n");
  1039. return ret;
  1040. }
  1041. static void typec_release(struct device *dev)
  1042. {
  1043. struct typec_port *port = to_typec_port(dev);
  1044. ida_simple_remove(&typec_index_ida, port->id);
  1045. ida_destroy(&port->mode_ids);
  1046. typec_switch_put(port->sw);
  1047. typec_mux_put(port->mux);
  1048. kfree(port);
  1049. }
  1050. const struct device_type typec_port_dev_type = {
  1051. .name = "typec_port",
  1052. .groups = typec_groups,
  1053. .uevent = typec_uevent,
  1054. .release = typec_release,
  1055. };
  1056. /* --------------------------------------- */
  1057. /* Driver callbacks to report role updates */
  1058. /**
  1059. * typec_set_data_role - Report data role change
  1060. * @port: The USB Type-C Port where the role was changed
  1061. * @role: The new data role
  1062. *
  1063. * This routine is used by the port drivers to report data role changes.
  1064. */
  1065. void typec_set_data_role(struct typec_port *port, enum typec_data_role role)
  1066. {
  1067. if (port->data_role == role)
  1068. return;
  1069. port->data_role = role;
  1070. sysfs_notify(&port->dev.kobj, NULL, "data_role");
  1071. kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
  1072. }
  1073. EXPORT_SYMBOL_GPL(typec_set_data_role);
  1074. /**
  1075. * typec_set_pwr_role - Report power role change
  1076. * @port: The USB Type-C Port where the role was changed
  1077. * @role: The new data role
  1078. *
  1079. * This routine is used by the port drivers to report power role changes.
  1080. */
  1081. void typec_set_pwr_role(struct typec_port *port, enum typec_role role)
  1082. {
  1083. if (port->pwr_role == role)
  1084. return;
  1085. port->pwr_role = role;
  1086. sysfs_notify(&port->dev.kobj, NULL, "power_role");
  1087. kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
  1088. }
  1089. EXPORT_SYMBOL_GPL(typec_set_pwr_role);
  1090. /**
  1091. * typec_set_pwr_role - Report VCONN source change
  1092. * @port: The USB Type-C Port which VCONN role changed
  1093. * @role: Source when @port is sourcing VCONN, or Sink when it's not
  1094. *
  1095. * This routine is used by the port drivers to report if the VCONN source is
  1096. * changes.
  1097. */
  1098. void typec_set_vconn_role(struct typec_port *port, enum typec_role role)
  1099. {
  1100. if (port->vconn_role == role)
  1101. return;
  1102. port->vconn_role = role;
  1103. sysfs_notify(&port->dev.kobj, NULL, "vconn_source");
  1104. kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
  1105. }
  1106. EXPORT_SYMBOL_GPL(typec_set_vconn_role);
  1107. static int partner_match(struct device *dev, void *data)
  1108. {
  1109. return is_typec_partner(dev);
  1110. }
  1111. /**
  1112. * typec_set_pwr_opmode - Report changed power operation mode
  1113. * @port: The USB Type-C Port where the mode was changed
  1114. * @opmode: New power operation mode
  1115. *
  1116. * This routine is used by the port drivers to report changed power operation
  1117. * mode in @port. The modes are USB (default), 1.5A, 3.0A as defined in USB
  1118. * Type-C specification, and "USB Power Delivery" when the power levels are
  1119. * negotiated with methods defined in USB Power Delivery specification.
  1120. */
  1121. void typec_set_pwr_opmode(struct typec_port *port,
  1122. enum typec_pwr_opmode opmode)
  1123. {
  1124. struct device *partner_dev;
  1125. if (port->pwr_opmode == opmode)
  1126. return;
  1127. port->pwr_opmode = opmode;
  1128. sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode");
  1129. kobject_uevent(&port->dev.kobj, KOBJ_CHANGE);
  1130. partner_dev = device_find_child(&port->dev, NULL, partner_match);
  1131. if (partner_dev) {
  1132. struct typec_partner *partner = to_typec_partner(partner_dev);
  1133. if (opmode == TYPEC_PWR_MODE_PD && !partner->usb_pd) {
  1134. partner->usb_pd = 1;
  1135. sysfs_notify(&partner_dev->kobj, NULL,
  1136. "supports_usb_power_delivery");
  1137. }
  1138. put_device(partner_dev);
  1139. }
  1140. }
  1141. EXPORT_SYMBOL_GPL(typec_set_pwr_opmode);
  1142. /**
  1143. * typec_find_port_power_role - Get the typec port power capability
  1144. * @name: port power capability string
  1145. *
  1146. * This routine is used to find the typec_port_type by its string name.
  1147. *
  1148. * Returns typec_port_type if success, otherwise negative error code.
  1149. */
  1150. int typec_find_port_power_role(const char *name)
  1151. {
  1152. return match_string(typec_port_power_roles,
  1153. ARRAY_SIZE(typec_port_power_roles), name);
  1154. }
  1155. EXPORT_SYMBOL_GPL(typec_find_port_power_role);
  1156. /**
  1157. * typec_find_power_role - Find the typec one specific power role
  1158. * @name: power role string
  1159. *
  1160. * This routine is used to find the typec_role by its string name.
  1161. *
  1162. * Returns typec_role if success, otherwise negative error code.
  1163. */
  1164. int typec_find_power_role(const char *name)
  1165. {
  1166. return match_string(typec_roles, ARRAY_SIZE(typec_roles), name);
  1167. }
  1168. EXPORT_SYMBOL_GPL(typec_find_power_role);
  1169. /**
  1170. * typec_find_port_data_role - Get the typec port data capability
  1171. * @name: port data capability string
  1172. *
  1173. * This routine is used to find the typec_port_data by its string name.
  1174. *
  1175. * Returns typec_port_data if success, otherwise negative error code.
  1176. */
  1177. int typec_find_port_data_role(const char *name)
  1178. {
  1179. return match_string(typec_port_data_roles,
  1180. ARRAY_SIZE(typec_port_data_roles), name);
  1181. }
  1182. EXPORT_SYMBOL_GPL(typec_find_port_data_role);
  1183. /* ------------------------------------------ */
  1184. /* API for Multiplexer/DeMultiplexer Switches */
  1185. /**
  1186. * typec_set_orientation - Set USB Type-C cable plug orientation
  1187. * @port: USB Type-C Port
  1188. * @orientation: USB Type-C cable plug orientation
  1189. *
  1190. * Set cable plug orientation for @port.
  1191. */
  1192. int typec_set_orientation(struct typec_port *port,
  1193. enum typec_orientation orientation)
  1194. {
  1195. int ret;
  1196. if (port->sw) {
  1197. ret = port->sw->set(port->sw, orientation);
  1198. if (ret)
  1199. return ret;
  1200. }
  1201. port->orientation = orientation;
  1202. return 0;
  1203. }
  1204. EXPORT_SYMBOL_GPL(typec_set_orientation);
  1205. /**
  1206. * typec_get_orientation - Get USB Type-C cable plug orientation
  1207. * @port: USB Type-C Port
  1208. *
  1209. * Get current cable plug orientation for @port.
  1210. */
  1211. enum typec_orientation typec_get_orientation(struct typec_port *port)
  1212. {
  1213. return port->orientation;
  1214. }
  1215. EXPORT_SYMBOL_GPL(typec_get_orientation);
  1216. /**
  1217. * typec_set_mode - Set mode of operation for USB Type-C connector
  1218. * @port: USB Type-C connector
  1219. * @mode: Accessory Mode, USB Operation or Safe State
  1220. *
  1221. * Configure @port for Accessory Mode @mode. This function will configure the
  1222. * muxes needed for @mode.
  1223. */
  1224. int typec_set_mode(struct typec_port *port, int mode)
  1225. {
  1226. return port->mux ? port->mux->set(port->mux, mode) : 0;
  1227. }
  1228. EXPORT_SYMBOL_GPL(typec_set_mode);
  1229. /* --------------------------------------- */
  1230. /**
  1231. * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
  1232. * @port: USB Type-C Port that supports the alternate mode
  1233. * @desc: Description of the alternate mode
  1234. *
  1235. * This routine is used to register an alternate mode that @port is capable of
  1236. * supporting.
  1237. *
  1238. * Returns handle to the alternate mode on success or ERR_PTR on failure.
  1239. */
  1240. struct typec_altmode *
  1241. typec_port_register_altmode(struct typec_port *port,
  1242. const struct typec_altmode_desc *desc)
  1243. {
  1244. struct typec_altmode *adev;
  1245. struct typec_mux *mux;
  1246. char id[10];
  1247. sprintf(id, "id%04xm%02x", desc->svid, desc->mode);
  1248. mux = typec_mux_get(&port->dev, id);
  1249. if (IS_ERR(mux))
  1250. return ERR_CAST(mux);
  1251. adev = typec_register_altmode(&port->dev, desc);
  1252. if (IS_ERR(adev))
  1253. typec_mux_put(mux);
  1254. else
  1255. to_altmode(adev)->mux = mux;
  1256. return adev;
  1257. }
  1258. EXPORT_SYMBOL_GPL(typec_port_register_altmode);
  1259. /**
  1260. * typec_register_port - Register a USB Type-C Port
  1261. * @parent: Parent device
  1262. * @cap: Description of the port
  1263. *
  1264. * Registers a device for USB Type-C Port described in @cap.
  1265. *
  1266. * Returns handle to the port on success or ERR_PTR on failure.
  1267. */
  1268. struct typec_port *typec_register_port(struct device *parent,
  1269. const struct typec_capability *cap)
  1270. {
  1271. struct typec_port *port;
  1272. int ret;
  1273. int id;
  1274. port = kzalloc(sizeof(*port), GFP_KERNEL);
  1275. if (!port)
  1276. return ERR_PTR(-ENOMEM);
  1277. id = ida_simple_get(&typec_index_ida, 0, 0, GFP_KERNEL);
  1278. if (id < 0) {
  1279. kfree(port);
  1280. return ERR_PTR(id);
  1281. }
  1282. switch (cap->type) {
  1283. case TYPEC_PORT_SRC:
  1284. port->pwr_role = TYPEC_SOURCE;
  1285. port->vconn_role = TYPEC_SOURCE;
  1286. break;
  1287. case TYPEC_PORT_SNK:
  1288. port->pwr_role = TYPEC_SINK;
  1289. port->vconn_role = TYPEC_SINK;
  1290. break;
  1291. case TYPEC_PORT_DRP:
  1292. if (cap->prefer_role != TYPEC_NO_PREFERRED_ROLE)
  1293. port->pwr_role = cap->prefer_role;
  1294. else
  1295. port->pwr_role = TYPEC_SINK;
  1296. break;
  1297. }
  1298. switch (cap->data) {
  1299. case TYPEC_PORT_DFP:
  1300. port->data_role = TYPEC_HOST;
  1301. break;
  1302. case TYPEC_PORT_UFP:
  1303. port->data_role = TYPEC_DEVICE;
  1304. break;
  1305. case TYPEC_PORT_DRD:
  1306. if (cap->prefer_role == TYPEC_SOURCE)
  1307. port->data_role = TYPEC_HOST;
  1308. else
  1309. port->data_role = TYPEC_DEVICE;
  1310. break;
  1311. }
  1312. ida_init(&port->mode_ids);
  1313. mutex_init(&port->port_type_lock);
  1314. port->id = id;
  1315. port->cap = cap;
  1316. port->port_type = cap->type;
  1317. port->prefer_role = cap->prefer_role;
  1318. device_initialize(&port->dev);
  1319. port->dev.class = typec_class;
  1320. port->dev.parent = parent;
  1321. port->dev.fwnode = cap->fwnode;
  1322. port->dev.type = &typec_port_dev_type;
  1323. dev_set_name(&port->dev, "port%d", id);
  1324. port->sw = typec_switch_get(&port->dev);
  1325. if (IS_ERR(port->sw)) {
  1326. ret = PTR_ERR(port->sw);
  1327. put_device(&port->dev);
  1328. return ERR_PTR(ret);
  1329. }
  1330. port->mux = typec_mux_get(&port->dev, "typec-mux");
  1331. if (IS_ERR(port->mux)) {
  1332. ret = PTR_ERR(port->mux);
  1333. put_device(&port->dev);
  1334. return ERR_PTR(ret);
  1335. }
  1336. ret = device_add(&port->dev);
  1337. if (ret) {
  1338. dev_err(parent, "failed to register port (%d)\n", ret);
  1339. put_device(&port->dev);
  1340. return ERR_PTR(ret);
  1341. }
  1342. return port;
  1343. }
  1344. EXPORT_SYMBOL_GPL(typec_register_port);
  1345. /**
  1346. * typec_unregister_port - Unregister a USB Type-C Port
  1347. * @port: The port to be unregistered
  1348. *
  1349. * Unregister device created with typec_register_port().
  1350. */
  1351. void typec_unregister_port(struct typec_port *port)
  1352. {
  1353. if (!IS_ERR_OR_NULL(port))
  1354. device_unregister(&port->dev);
  1355. }
  1356. EXPORT_SYMBOL_GPL(typec_unregister_port);
  1357. static int __init typec_init(void)
  1358. {
  1359. int ret;
  1360. ret = bus_register(&typec_bus);
  1361. if (ret)
  1362. return ret;
  1363. typec_class = class_create(THIS_MODULE, "typec");
  1364. if (IS_ERR(typec_class)) {
  1365. bus_unregister(&typec_bus);
  1366. return PTR_ERR(typec_class);
  1367. }
  1368. return 0;
  1369. }
  1370. subsys_initcall(typec_init);
  1371. static void __exit typec_exit(void)
  1372. {
  1373. class_destroy(typec_class);
  1374. ida_destroy(&typec_index_ida);
  1375. bus_unregister(&typec_bus);
  1376. }
  1377. module_exit(typec_exit);
  1378. MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
  1379. MODULE_LICENSE("GPL v2");
  1380. MODULE_DESCRIPTION("USB Type-C Connector Class");