···11+Samsung micro-USB 11-pin connector22+==================================33+44+Samsung micro-USB 11-pin connector is an extension of micro-USB connector.55+It is present in multiple Samsung mobile devices.66+It has additional pins to route MHL traffic simultanously with USB.77+88+The bindings are superset of usb-connector bindings for micro-USB connector[1].99+1010+Required properties:1111+- compatible: must be: "samsung,usb-connector-11pin", "usb-b-connector",1212+- type: must be "micro".1313+1414+Required nodes:1515+- any data bus to the connector should be modeled using the OF graph bindings1616+ specified in bindings/graph.txt, unless the bus is between parent node and1717+ the connector. Since single connector can have multpile data buses every bus1818+ has assigned OF graph port number as follows:1919+ 0: High Speed (HS),2020+ 3: Mobile High-Definition Link (MHL), specific to 11-pin Samsung micro-USB.2121+2222+[1]: bindings/connector/usb-connector.txt2323+2424+Example2525+-------2626+2727+Micro-USB connector with HS lines routed via controller (MUIC) and MHL lines2828+connected to HDMI-MHL bridge (sii8620):2929+3030+muic-max77843@66 {3131+ ...3232+ usb_con: connector {3333+ compatible = "samsung,usb-connector-11pin", "usb-b-connector";3434+ label = "micro-USB";3535+ type = "micro";3636+3737+ ports {3838+ #address-cells = <1>;3939+ #size-cells = <0>;4040+4141+ port@3 {4242+ reg = <3>;4343+ usb_con_mhl: endpoint {4444+ remote-endpoint = <&sii8620_mhl>;4545+ };4646+ };4747+ };4848+ };4949+};
···11+USB Connector22+=============33+44+USB connector node represents physical USB connector. It should be55+a child of USB interface controller.66+77+Required properties:88+- compatible: describes type of the connector, must be one of:99+ "usb-a-connector",1010+ "usb-b-connector",1111+ "usb-c-connector".1212+1313+Optional properties:1414+- label: symbolic name for the connector,1515+- type: size of the connector, should be specified in case of USB-A, USB-B1616+ non-fullsize connectors: "mini", "micro".1717+1818+Required nodes:1919+- any data bus to the connector should be modeled using the OF graph bindings2020+ specified in bindings/graph.txt, unless the bus is between parent node and2121+ the connector. Since single connector can have multpile data buses every bus2222+ has assigned OF graph port number as follows:2323+ 0: High Speed (HS), present in all connectors,2424+ 1: Super Speed (SS), present in SS capable connectors,2525+ 2: Sideband use (SBU), present in USB-C.2626+2727+Examples2828+--------2929+3030+1. Micro-USB connector with HS lines routed via controller (MUIC):3131+3232+muic-max77843@66 {3333+ ...3434+ usb_con: connector {3535+ compatible = "usb-b-connector";3636+ label = "micro-USB";3737+ type = "micro";3838+ };3939+};4040+4141+2. USB-C connector attached to CC controller (s2mm005), HS lines routed4242+to companion PMIC (max77865), SS lines to USB3 PHY and SBU to DisplayPort.4343+DisplayPort video lines are routed to the connector via SS mux in USB3 PHY.4444+4545+ccic: s2mm005@33 {4646+ ...4747+ usb_con: connector {4848+ compatible = "usb-c-connector";4949+ label = "USB-C";5050+5151+ ports {5252+ #address-cells = <1>;5353+ #size-cells = <0>;5454+5555+ port@0 {5656+ reg = <0>;5757+ usb_con_hs: endpoint {5858+ remote-endpoint = <&max77865_usbc_hs>;5959+ };6060+ };6161+ port@1 {6262+ reg = <1>;6363+ usb_con_ss: endpoint {6464+ remote-endpoint = <&usbdrd_phy_ss>;6565+ };6666+ };6767+ port@2 {6868+ reg = <2>;6969+ usb_con_sbu: endpoint {7070+ remote-endpoint = <&dp_aux>;7171+ };7272+ };7373+ };7474+ };7575+};
+34-10
drivers/extcon/extcon.c
···13361336EXPORT_SYMBOL_GPL(extcon_dev_unregister);1337133713381338#ifdef CONFIG_OF13391339+13401340+/*13411341+ * extcon_find_edev_by_node - Find the extcon device from devicetree.13421342+ * @node : OF node identifying edev13431343+ *13441344+ * Return the pointer of extcon device if success or ERR_PTR(err) if fail.13451345+ */13461346+struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)13471347+{13481348+ struct extcon_dev *edev;13491349+13501350+ mutex_lock(&extcon_dev_list_lock);13511351+ list_for_each_entry(edev, &extcon_dev_list, entry)13521352+ if (edev->dev.parent && edev->dev.parent->of_node == node)13531353+ goto out;13541354+ edev = ERR_PTR(-EPROBE_DEFER);13551355+out:13561356+ mutex_unlock(&extcon_dev_list_lock);13571357+13581358+ return edev;13591359+}13601360+13391361/*13401362 * extcon_get_edev_by_phandle - Get the extcon device from devicetree.13411363 * @dev : the instance to the given device···13851363 return ERR_PTR(-ENODEV);13861364 }1387136513881388- mutex_lock(&extcon_dev_list_lock);13891389- list_for_each_entry(edev, &extcon_dev_list, entry) {13901390- if (edev->dev.parent && edev->dev.parent->of_node == node) {13911391- mutex_unlock(&extcon_dev_list_lock);13921392- of_node_put(node);13931393- return edev;13941394- }13951395- }13961396- mutex_unlock(&extcon_dev_list_lock);13661366+ edev = extcon_find_edev_by_node(node);13971367 of_node_put(node);1398136813991399- return ERR_PTR(-EPROBE_DEFER);13691369+ return edev;14001370}13711371+14011372#else13731373+13741374+struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)13751375+{13761376+ return ERR_PTR(-ENOSYS);13771377+}13781378+14021379struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index)14031380{14041381 return ERR_PTR(-ENOSYS);14051382}13831383+14061384#endif /* CONFIG_OF */13851385+13861386+EXPORT_SYMBOL_GPL(extcon_find_edev_by_node);14071387EXPORT_SYMBOL_GPL(extcon_get_edev_by_phandle);1408138814091389/**
+94-3
drivers/gpu/drm/bridge/sil-sii8620.c
···17171818#include <linux/clk.h>1919#include <linux/delay.h>2020+#include <linux/extcon.h>2021#include <linux/gpio/consumer.h>2122#include <linux/i2c.h>2223#include <linux/interrupt.h>···2625#include <linux/list.h>2726#include <linux/module.h>2827#include <linux/mutex.h>2828+#include <linux/of_graph.h>2929#include <linux/regulator/consumer.h>3030#include <linux/slab.h>3131···8381 struct edid *edid;8482 unsigned int gen2_write_burst:1;8583 enum sii8620_mt_state mt_state;8484+ struct extcon_dev *extcon;8585+ struct notifier_block extcon_nb;8686+ struct work_struct extcon_wq;8787+ int cable_state;8688 struct list_head mt_queue;8789 struct {8890 int r_size;···21762170 ctx->rc_dev = rc_dev;21772171}2178217221732173+static void sii8620_cable_out(struct sii8620 *ctx)21742174+{21752175+ disable_irq(to_i2c_client(ctx->dev)->irq);21762176+ sii8620_hw_off(ctx);21772177+}21782178+21792179+static void sii8620_extcon_work(struct work_struct *work)21802180+{21812181+ struct sii8620 *ctx =21822182+ container_of(work, struct sii8620, extcon_wq);21832183+ int state = extcon_get_state(ctx->extcon, EXTCON_DISP_MHL);21842184+21852185+ if (state == ctx->cable_state)21862186+ return;21872187+21882188+ ctx->cable_state = state;21892189+21902190+ if (state > 0)21912191+ sii8620_cable_in(ctx);21922192+ else21932193+ sii8620_cable_out(ctx);21942194+}21952195+21962196+static int sii8620_extcon_notifier(struct notifier_block *self,21972197+ unsigned long event, void *ptr)21982198+{21992199+ struct sii8620 *ctx =22002200+ container_of(self, struct sii8620, extcon_nb);22012201+22022202+ schedule_work(&ctx->extcon_wq);22032203+22042204+ return NOTIFY_DONE;22052205+}22062206+22072207+static int sii8620_extcon_init(struct sii8620 *ctx)22082208+{22092209+ struct extcon_dev *edev;22102210+ struct device_node *musb, *muic;22112211+ int ret;22122212+22132213+ /* get micro-USB connector node */22142214+ musb = of_graph_get_remote_node(ctx->dev->of_node, 1, -1);22152215+ /* next get micro-USB Interface Controller node */22162216+ muic = of_get_next_parent(musb);22172217+22182218+ if (!muic) {22192219+ dev_info(ctx->dev, "no extcon found, switching to 'always on' mode\n");22202220+ return 0;22212221+ }22222222+22232223+ edev = extcon_find_edev_by_node(muic);22242224+ of_node_put(muic);22252225+ if (IS_ERR(edev)) {22262226+ if (PTR_ERR(edev) == -EPROBE_DEFER)22272227+ return -EPROBE_DEFER;22282228+ dev_err(ctx->dev, "Invalid or missing extcon\n");22292229+ return PTR_ERR(edev);22302230+ }22312231+22322232+ ctx->extcon = edev;22332233+ ctx->extcon_nb.notifier_call = sii8620_extcon_notifier;22342234+ INIT_WORK(&ctx->extcon_wq, sii8620_extcon_work);22352235+ ret = extcon_register_notifier(edev, EXTCON_DISP_MHL, &ctx->extcon_nb);22362236+ if (ret) {22372237+ dev_err(ctx->dev, "failed to register notifier for MHL\n");22382238+ return ret;22392239+ }22402240+22412241+ return 0;22422242+}22432243+21792244static inline struct sii8620 *bridge_to_sii8620(struct drm_bridge *bridge)21802245{21812246 return container_of(bridge, struct sii8620, bridge);···23792302 if (ret)23802303 return ret;2381230423052305+ ret = sii8620_extcon_init(ctx);23062306+ if (ret < 0) {23072307+ dev_err(ctx->dev, "failed to initialize EXTCON\n");23082308+ return ret;23092309+ }23102310+23822311 i2c_set_clientdata(client, ctx);2383231223842313 ctx->bridge.funcs = &sii8620_bridge_funcs;23852314 ctx->bridge.of_node = dev->of_node;23862315 drm_bridge_add(&ctx->bridge);2387231623882388- sii8620_cable_in(ctx);23172317+ if (!ctx->extcon)23182318+ sii8620_cable_in(ctx);2389231923902320 return 0;23912321}···24012317{24022318 struct sii8620 *ctx = i2c_get_clientdata(client);2403231924042404- disable_irq(to_i2c_client(ctx->dev)->irq);24052405- sii8620_hw_off(ctx);23202320+ if (ctx->extcon) {23212321+ extcon_unregister_notifier(ctx->extcon, EXTCON_DISP_MHL,23222322+ &ctx->extcon_nb);23232323+ flush_work(&ctx->extcon_wq);23242324+ if (ctx->cable_state > 0)23252325+ sii8620_cable_out(ctx);23262326+ } else {23272327+ sii8620_cable_out(ctx);23282328+ }24062329 drm_bridge_remove(&ctx->bridge);2407233024082331 return 0;
+6
include/linux/extcon.h
···230230 * Following APIs get the extcon_dev from devicetree or by through extcon name.231231 */232232extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);233233+extern struct extcon_dev *extcon_find_edev_by_node(struct device_node *node);233234extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,234235 int index);235236···280279 struct notifier_block *nb) { }281280282281static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)282282+{283283+ return ERR_PTR(-ENODEV);284284+}285285+286286+static inline struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)283287{284288 return ERR_PTR(-ENODEV);285289}