* [v4 PATCH 0/6] add USB Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Because the USB Connector is introduced and the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated, meanwhile there is no available common driver when use Type-B connector, typically using an input GPIO to detect USB ID pin. This patch series introduce a Type-B GPIO connector driver and try to replace the function provided by extcon-usb-gpio driver. v4 changes: 1. use switch_fwnode_match() to find fwnode suggested by Heikki 2. assign fwnode member of usb_role_switch struct suggested by Heikki 3. make [4/6] depend on [2] 3. remove linux/gpio.h suggested by Linus 4. put node when error happens [4/6] usb: roles: add API to get usb_role_switch by node [2] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h https://patchwork.kernel.org/patch/10909971/ v3 changes: 1. add GPIO direction, and use fixed-regulator for GPIO controlled VBUS regulator suggested by Rob; 2. rebuild fwnode_usb_role_switch_get() suggested by Andy and Heikki 3. treat the type-B connector as a virtual device; 4. change file name of driver again 5. select USB_ROLE_SWITCH in mtu3/Kconfig suggested by Heikki 6. rename ssusb_mode_manual_switch() to ssusb_mode_switch() v2 changes: 1. make binding clear, and add a extra compatible suggested by Hans Chunfeng Yun (6): dt-bindings: connector: add optional properties for Type-B dt-bindings: usb: add binding for Type-B GPIO connector driver dt-bindings: usb: mtu3: add properties about USB Role Switch usb: roles: add API to get usb_role_switch by node usb: roles: add USB Type-B GPIO connector driver usb: mtu3: register a USB Role Switch for dual role mode .../bindings/connector/usb-connector.txt | 14 + .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 +- .../bindings/usb/typeb-conn-gpio.txt | 49 +++ drivers/usb/mtu3/Kconfig | 1 + drivers/usb/mtu3/mtu3.h | 5 + drivers/usb/mtu3/mtu3_debugfs.c | 4 +- drivers/usb/mtu3/mtu3_dr.c | 48 ++- drivers/usb/mtu3/mtu3_dr.h | 6 +- drivers/usb/mtu3/mtu3_plat.c | 3 +- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/class.c | 25 ++ drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++ include/linux/usb/role.h | 8 + 14 files changed, 481 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt create mode 100644 drivers/usb/roles/typeb-conn-gpio.c -- 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4 PATCH 0/6] add USB Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun Because the USB Connector is introduced and the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated, meanwhile there is no available common driver when use Type-B connector, typically using an input GPIO to detect USB ID pin. This patch series introduce a Type-B GPIO connector driver and try to replace the function provided by extcon-usb-gpio driver. v4 changes: 1. use switch_fwnode_match() to find fwnode suggested by Heikki 2. assign fwnode member of usb_role_switch struct suggested by Heikki 3. make [4/6] depend on [2] 3. remove linux/gpio.h suggested by Linus 4. put node when error happens [4/6] usb: roles: add API to get usb_role_switch by node [2] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h https://patchwork.kernel.org/patch/10909971/ v3 changes: 1. add GPIO direction, and use fixed-regulator for GPIO controlled VBUS regulator suggested by Rob; 2. rebuild fwnode_usb_role_switch_get() suggested by Andy and Heikki 3. treat the type-B connector as a virtual device; 4. change file name of driver again 5. select USB_ROLE_SWITCH in mtu3/Kconfig suggested by Heikki 6. rename ssusb_mode_manual_switch() to ssusb_mode_switch() v2 changes: 1. make binding clear, and add a extra compatible suggested by Hans Chunfeng Yun (6): dt-bindings: connector: add optional properties for Type-B dt-bindings: usb: add binding for Type-B GPIO connector driver dt-bindings: usb: mtu3: add properties about USB Role Switch usb: roles: add API to get usb_role_switch by node usb: roles: add USB Type-B GPIO connector driver usb: mtu3: register a USB Role Switch for dual role mode .../bindings/connector/usb-connector.txt | 14 + .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 +- .../bindings/usb/typeb-conn-gpio.txt | 49 +++ drivers/usb/mtu3/Kconfig | 1 + drivers/usb/mtu3/mtu3.h | 5 + drivers/usb/mtu3/mtu3_debugfs.c | 4 +- drivers/usb/mtu3/mtu3_dr.c | 48 ++- drivers/usb/mtu3/mtu3_dr.h | 6 +- drivers/usb/mtu3/mtu3_plat.c | 3 +- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/class.c | 25 ++ drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++ include/linux/usb/role.h | 8 + 14 files changed, 481 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt create mode 100644 drivers/usb/roles/typeb-conn-gpio.c -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4 PATCH 0/6] add USB Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Because the USB Connector is introduced and the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated, meanwhile there is no available common driver when use Type-B connector, typically using an input GPIO to detect USB ID pin. This patch series introduce a Type-B GPIO connector driver and try to replace the function provided by extcon-usb-gpio driver. v4 changes: 1. use switch_fwnode_match() to find fwnode suggested by Heikki 2. assign fwnode member of usb_role_switch struct suggested by Heikki 3. make [4/6] depend on [2] 3. remove linux/gpio.h suggested by Linus 4. put node when error happens [4/6] usb: roles: add API to get usb_role_switch by node [2] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h https://patchwork.kernel.org/patch/10909971/ v3 changes: 1. add GPIO direction, and use fixed-regulator for GPIO controlled VBUS regulator suggested by Rob; 2. rebuild fwnode_usb_role_switch_get() suggested by Andy and Heikki 3. treat the type-B connector as a virtual device; 4. change file name of driver again 5. select USB_ROLE_SWITCH in mtu3/Kconfig suggested by Heikki 6. rename ssusb_mode_manual_switch() to ssusb_mode_switch() v2 changes: 1. make binding clear, and add a extra compatible suggested by Hans Chunfeng Yun (6): dt-bindings: connector: add optional properties for Type-B dt-bindings: usb: add binding for Type-B GPIO connector driver dt-bindings: usb: mtu3: add properties about USB Role Switch usb: roles: add API to get usb_role_switch by node usb: roles: add USB Type-B GPIO connector driver usb: mtu3: register a USB Role Switch for dual role mode .../bindings/connector/usb-connector.txt | 14 + .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 +- .../bindings/usb/typeb-conn-gpio.txt | 49 +++ drivers/usb/mtu3/Kconfig | 1 + drivers/usb/mtu3/mtu3.h | 5 + drivers/usb/mtu3/mtu3_debugfs.c | 4 +- drivers/usb/mtu3/mtu3_dr.c | 48 ++- drivers/usb/mtu3/mtu3_dr.h | 6 +- drivers/usb/mtu3/mtu3_plat.c | 3 +- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/class.c | 25 ++ drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++ include/linux/usb/role.h | 8 + 14 files changed, 481 insertions(+), 9 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt create mode 100644 drivers/usb/roles/typeb-conn-gpio.c -- 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 1/6] dt-bindings: connector: add optional properties for Type-B 2019-04-26 6:47 ` Chunfeng Yun (?) (?) @ 2019-04-26 6:47 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for usb-b-connector Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. add GPIO direction, and use fixed-regulator for GPIO controlled VBUS regulator suggested by Rob; v2 changes: 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans --- .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt b/Documentation/devicetree/bindings/connector/usb-connector.txt index a9a2f2fc44f2..e8f9e854fd11 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.txt +++ b/Documentation/devicetree/bindings/connector/usb-connector.txt @@ -17,6 +17,20 @@ Optional properties: - self-powered: Set this property if the usb device that has its own power source. +Optional properties for usb-b-connector: +- id-gpios: an input gpio for USB ID pin. +- vbus-gpios: an input gpio for USB VBUS pin, used to detect presence of + VBUS 5V. + see gpio/gpio.txt. +- vbus-supply: a phandle to the regulator for USB VBUS if needed when host + mode or dual role mode is supported. + Particularly, if use an output GPIO to control a VBUS regulator, should + model it as a regulator. + see regulator/fixed-regulator.yaml +- pinctrl-names : a pinctrl state named "default" is optional +- pinctrl-0 : pin control group + see pinctrl/pinctrl-bindings.txt + Optional properties for usb-c-connector: - power-role: should be one of "source", "sink" or "dual"(DRP) if typec connector has power support. -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 1/6] dt-bindings: connector: add optional properties for Type-B @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for usb-b-connector Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. add GPIO direction, and use fixed-regulator for GPIO controlled VBUS regulator suggested by Rob; v2 changes: 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans --- .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt b/Documentation/devicetree/bindings/connector/usb-connector.txt index a9a2f2fc44f2..e8f9e854fd11 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.txt +++ b/Documentation/devicetree/bindings/connector/usb-connector.txt @@ -17,6 +17,20 @@ Optional properties: - self-powered: Set this property if the usb device that has its own power source. +Optional properties for usb-b-connector: +- id-gpios: an input gpio for USB ID pin. +- vbus-gpios: an input gpio for USB VBUS pin, used to detect presence of + VBUS 5V. + see gpio/gpio.txt. +- vbus-supply: a phandle to the regulator for USB VBUS if needed when host + mode or dual role mode is supported. + Particularly, if use an output GPIO to control a VBUS regulator, should + model it as a regulator. + see regulator/fixed-regulator.yaml +- pinctrl-names : a pinctrl state named "default" is optional +- pinctrl-0 : pin control group + see pinctrl/pinctrl-bindings.txt + Optional properties for usb-c-connector: - power-role: should be one of "source", "sink" or "dual"(DRP) if typec connector has power support. -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [v4,1/6] dt-bindings: connector: add optional properties for Type-B @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for usb-b-connector Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. add GPIO direction, and use fixed-regulator for GPIO controlled VBUS regulator suggested by Rob; v2 changes: 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans --- .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt b/Documentation/devicetree/bindings/connector/usb-connector.txt index a9a2f2fc44f2..e8f9e854fd11 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.txt +++ b/Documentation/devicetree/bindings/connector/usb-connector.txt @@ -17,6 +17,20 @@ Optional properties: - self-powered: Set this property if the usb device that has its own power source. +Optional properties for usb-b-connector: +- id-gpios: an input gpio for USB ID pin. +- vbus-gpios: an input gpio for USB VBUS pin, used to detect presence of + VBUS 5V. + see gpio/gpio.txt. +- vbus-supply: a phandle to the regulator for USB VBUS if needed when host + mode or dual role mode is supported. + Particularly, if use an output GPIO to control a VBUS regulator, should + model it as a regulator. + see regulator/fixed-regulator.yaml +- pinctrl-names : a pinctrl state named "default" is optional +- pinctrl-0 : pin control group + see pinctrl/pinctrl-bindings.txt + Optional properties for usb-c-connector: - power-role: should be one of "source", "sink" or "dual"(DRP) if typec connector has power support. ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 1/6] dt-bindings: connector: add optional properties for Type-B @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for usb-b-connector Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. add GPIO direction, and use fixed-regulator for GPIO controlled VBUS regulator suggested by Rob; v2 changes: 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans --- .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt b/Documentation/devicetree/bindings/connector/usb-connector.txt index a9a2f2fc44f2..e8f9e854fd11 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.txt +++ b/Documentation/devicetree/bindings/connector/usb-connector.txt @@ -17,6 +17,20 @@ Optional properties: - self-powered: Set this property if the usb device that has its own power source. +Optional properties for usb-b-connector: +- id-gpios: an input gpio for USB ID pin. +- vbus-gpios: an input gpio for USB VBUS pin, used to detect presence of + VBUS 5V. + see gpio/gpio.txt. +- vbus-supply: a phandle to the regulator for USB VBUS if needed when host + mode or dual role mode is supported. + Particularly, if use an output GPIO to control a VBUS regulator, should + model it as a regulator. + see regulator/fixed-regulator.yaml +- pinctrl-names : a pinctrl state named "default" is optional +- pinctrl-0 : pin control group + see pinctrl/pinctrl-bindings.txt + Optional properties for usb-c-connector: - power-role: should be one of "source", "sink" or "dual"(DRP) if typec connector has power support. -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH v4 1/6] dt-bindings: connector: add optional properties for Type-B 2019-04-26 6:47 ` [PATCH v4 1/6] " Chunfeng Yun (?) (?) @ 2019-04-26 13:19 ` Rob Herring -1 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 13:19 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das, Linus Walleij On Fri, Apr 26, 2019 at 1:47 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for > usb-b-connector > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 no changes > > v3 changes: > 1. add GPIO direction, and use fixed-regulator for GPIO controlled > VBUS regulator suggested by Rob; > > v2 changes: > 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans > --- > .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) Reviewed-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 1/6] dt-bindings: connector: add optional properties for Type-B @ 2019-04-26 13:19 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 13:19 UTC (permalink / raw) To: Chunfeng Yun Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, Linux USB List, linux-kernel, Biju Das, Badhri Jagan Sridharan, Andy Shevchenko, moderated list:ARM/Mediatek SoC support, Min Guo, Matthias Brugger, Adam Thomson, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, Li Jun On Fri, Apr 26, 2019 at 1:47 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for > usb-b-connector > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 no changes > > v3 changes: > 1. add GPIO direction, and use fixed-regulator for GPIO controlled > VBUS regulator suggested by Rob; > > v2 changes: > 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans > --- > .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) Reviewed-by: Rob Herring <robh@kernel.org> _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,1/6] dt-bindings: connector: add optional properties for Type-B @ 2019-04-26 13:19 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 13:19 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das, Linus Walleij On Fri, Apr 26, 2019 at 1:47 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for > usb-b-connector > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 no changes > > v3 changes: > 1. add GPIO direction, and use fixed-regulator for GPIO controlled > VBUS regulator suggested by Rob; > > v2 changes: > 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans > --- > .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) Reviewed-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 1/6] dt-bindings: connector: add optional properties for Type-B @ 2019-04-26 13:19 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 13:19 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das On Fri, Apr 26, 2019 at 1:47 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > Add id-gpios, vbus-gpios, vbus-supply and pinctrl properties for > usb-b-connector > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 no changes > > v3 changes: > 1. add GPIO direction, and use fixed-regulator for GPIO controlled > VBUS regulator suggested by Rob; > > v2 changes: > 1. describe more clear for vbus-gpios and vbus-supply suggested by Hans > --- > .../bindings/connector/usb-connector.txt | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) Reviewed-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver 2019-04-26 6:47 ` Chunfeng Yun (?) (?) @ 2019-04-26 6:47 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij It's used to support dual role switch via GPIO when use Type-B receptacle, typically the USB ID pin is connected to an input GPIO pin Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. treat type-B connector as a virtual device, but not child device of USB controller's v2 changes: 1. new patch to make binding clear suggested by Hans --- .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt new file mode 100644 index 000000000000..d2e1c4e01b6d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt @@ -0,0 +1,49 @@ +USB Type-B GPIO Connector + +This is a virtual device used to switch dual role mode from the USB ID pin +connected to an input GPIO pin. + +Required properties: +- compatible : Should be "linux,typeb-conn-gpio" + +Sub-nodes: +- connector : should be present. + - compatible : should be "usb-b-connector". + - id-gpios, vbus-gpios : either one of them must be present, + and both can be present as well. + - vbus-supply : can be present if needed when supports dual role mode. + see connector/usb-connector.txt + +- port : should be present. + see graph.txt + +Example: + +rsw_iddig: role_sw_iddig { + compatible = "linux,typeb-conn-gpio"; + status = "okay"; + + connector { + compatible = "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; + vbus-supply = <&usb_p0_vbus>; + }; + + port { + bconn_ep: endpoint@0 { + remote-endpoint = <&usb_role_sw>; + }; + }; +}; + +&mtu3 { + status = "okay"; + + port { + usb_role_sw: endpoint@0 { + remote-endpoint = <&bconn_ep>; + }; + }; +}; -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun It's used to support dual role switch via GPIO when use Type-B receptacle, typically the USB ID pin is connected to an input GPIO pin Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. treat type-B connector as a virtual device, but not child device of USB controller's v2 changes: 1. new patch to make binding clear suggested by Hans --- .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt new file mode 100644 index 000000000000..d2e1c4e01b6d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt @@ -0,0 +1,49 @@ +USB Type-B GPIO Connector + +This is a virtual device used to switch dual role mode from the USB ID pin +connected to an input GPIO pin. + +Required properties: +- compatible : Should be "linux,typeb-conn-gpio" + +Sub-nodes: +- connector : should be present. + - compatible : should be "usb-b-connector". + - id-gpios, vbus-gpios : either one of them must be present, + and both can be present as well. + - vbus-supply : can be present if needed when supports dual role mode. + see connector/usb-connector.txt + +- port : should be present. + see graph.txt + +Example: + +rsw_iddig: role_sw_iddig { + compatible = "linux,typeb-conn-gpio"; + status = "okay"; + + connector { + compatible = "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; + vbus-supply = <&usb_p0_vbus>; + }; + + port { + bconn_ep: endpoint@0 { + remote-endpoint = <&usb_role_sw>; + }; + }; +}; + +&mtu3 { + status = "okay"; + + port { + usb_role_sw: endpoint@0 { + remote-endpoint = <&bconn_ep>; + }; + }; +}; -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [v4,2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij It's used to support dual role switch via GPIO when use Type-B receptacle, typically the USB ID pin is connected to an input GPIO pin Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. treat type-B connector as a virtual device, but not child device of USB controller's v2 changes: 1. new patch to make binding clear suggested by Hans --- .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt new file mode 100644 index 000000000000..d2e1c4e01b6d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt @@ -0,0 +1,49 @@ +USB Type-B GPIO Connector + +This is a virtual device used to switch dual role mode from the USB ID pin +connected to an input GPIO pin. + +Required properties: +- compatible : Should be "linux,typeb-conn-gpio" + +Sub-nodes: +- connector : should be present. + - compatible : should be "usb-b-connector". + - id-gpios, vbus-gpios : either one of them must be present, + and both can be present as well. + - vbus-supply : can be present if needed when supports dual role mode. + see connector/usb-connector.txt + +- port : should be present. + see graph.txt + +Example: + +rsw_iddig: role_sw_iddig { + compatible = "linux,typeb-conn-gpio"; + status = "okay"; + + connector { + compatible = "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; + vbus-supply = <&usb_p0_vbus>; + }; + + port { + bconn_ep: endpoint@0 { + remote-endpoint = <&usb_role_sw>; + }; + }; +}; + +&mtu3 { + status = "okay"; + + port { + usb_role_sw: endpoint@0 { + remote-endpoint = <&bconn_ep>; + }; + }; +}; ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij It's used to support dual role switch via GPIO when use Type-B receptacle, typically the USB ID pin is connected to an input GPIO pin Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 no changes v3 changes: 1. treat type-B connector as a virtual device, but not child device of USB controller's v2 changes: 1. new patch to make binding clear suggested by Hans --- .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt new file mode 100644 index 000000000000..d2e1c4e01b6d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt @@ -0,0 +1,49 @@ +USB Type-B GPIO Connector + +This is a virtual device used to switch dual role mode from the USB ID pin +connected to an input GPIO pin. + +Required properties: +- compatible : Should be "linux,typeb-conn-gpio" + +Sub-nodes: +- connector : should be present. + - compatible : should be "usb-b-connector". + - id-gpios, vbus-gpios : either one of them must be present, + and both can be present as well. + - vbus-supply : can be present if needed when supports dual role mode. + see connector/usb-connector.txt + +- port : should be present. + see graph.txt + +Example: + +rsw_iddig: role_sw_iddig { + compatible = "linux,typeb-conn-gpio"; + status = "okay"; + + connector { + compatible = "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; + vbus-supply = <&usb_p0_vbus>; + }; + + port { + bconn_ep: endpoint@0 { + remote-endpoint = <&usb_role_sw>; + }; + }; +}; + +&mtu3 { + status = "okay"; + + port { + usb_role_sw: endpoint@0 { + remote-endpoint = <&bconn_ep>; + }; + }; +}; -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-26 20:45 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 20:45 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, Apr 26, 2019 at 02:47:13PM +0800, Chunfeng Yun wrote: > It's used to support dual role switch via GPIO when use Type-B > receptacle, typically the USB ID pin is connected to an input > GPIO pin > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 no changes > > v3 changes: > 1. treat type-B connector as a virtual device, but not child device of > USB controller's > > v2 changes: > 1. new patch to make binding clear suggested by Hans > --- > .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ > 1 file changed, 49 insertions(+) > create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > new file mode 100644 > index 000000000000..d2e1c4e01b6d > --- /dev/null > +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > @@ -0,0 +1,49 @@ > +USB Type-B GPIO Connector > + > +This is a virtual device used to switch dual role mode from the USB ID pin > +connected to an input GPIO pin. > + > +Required properties: > +- compatible : Should be "linux,typeb-conn-gpio" There's no need for this virtual node. The USB host or device driver can instantiate a connector driver by walking the OF graph to the connector and creating a device. > + > +Sub-nodes: > +- connector : should be present. > + - compatible : should be "usb-b-connector". > + - id-gpios, vbus-gpios : either one of them must be present, > + and both can be present as well. > + - vbus-supply : can be present if needed when supports dual role mode. > + see connector/usb-connector.txt > + > +- port : should be present. > + see graph.txt > + > +Example: > + > +rsw_iddig: role_sw_iddig { > + compatible = "linux,typeb-conn-gpio"; > + status = "okay"; > + > + connector { > + compatible = "usb-b-connector"; > + label = "micro-USB"; > + type = "micro"; > + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; > + vbus-supply = <&usb_p0_vbus>; > + }; > + > + port { Humm, same mistake as Hikey patches... This goes under the connector node as defined in the connector binding. > + bconn_ep: endpoint@0 { > + remote-endpoint = <&usb_role_sw>; > + }; > + }; > +}; > + > +&mtu3 { > + status = "okay"; > + > + port { > + usb_role_sw: endpoint@0 { > + remote-endpoint = <&bconn_ep>; > + }; > + }; > +}; > -- > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-26 20:45 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 20:45 UTC (permalink / raw) To: Chunfeng Yun Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, linux-usb, linux-kernel, Biju Das, Badhri Jagan Sridharan, Andy Shevchenko, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun On Fri, Apr 26, 2019 at 02:47:13PM +0800, Chunfeng Yun wrote: > It's used to support dual role switch via GPIO when use Type-B > receptacle, typically the USB ID pin is connected to an input > GPIO pin > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 no changes > > v3 changes: > 1. treat type-B connector as a virtual device, but not child device of > USB controller's > > v2 changes: > 1. new patch to make binding clear suggested by Hans > --- > .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ > 1 file changed, 49 insertions(+) > create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > new file mode 100644 > index 000000000000..d2e1c4e01b6d > --- /dev/null > +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > @@ -0,0 +1,49 @@ > +USB Type-B GPIO Connector > + > +This is a virtual device used to switch dual role mode from the USB ID pin > +connected to an input GPIO pin. > + > +Required properties: > +- compatible : Should be "linux,typeb-conn-gpio" There's no need for this virtual node. The USB host or device driver can instantiate a connector driver by walking the OF graph to the connector and creating a device. > + > +Sub-nodes: > +- connector : should be present. > + - compatible : should be "usb-b-connector". > + - id-gpios, vbus-gpios : either one of them must be present, > + and both can be present as well. > + - vbus-supply : can be present if needed when supports dual role mode. > + see connector/usb-connector.txt > + > +- port : should be present. > + see graph.txt > + > +Example: > + > +rsw_iddig: role_sw_iddig { > + compatible = "linux,typeb-conn-gpio"; > + status = "okay"; > + > + connector { > + compatible = "usb-b-connector"; > + label = "micro-USB"; > + type = "micro"; > + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; > + vbus-supply = <&usb_p0_vbus>; > + }; > + > + port { Humm, same mistake as Hikey patches... This goes under the connector node as defined in the connector binding. > + bconn_ep: endpoint@0 { > + remote-endpoint = <&usb_role_sw>; > + }; > + }; > +}; > + > +&mtu3 { > + status = "okay"; > + > + port { > + usb_role_sw: endpoint@0 { > + remote-endpoint = <&bconn_ep>; > + }; > + }; > +}; > -- > 2.21.0 > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-26 20:45 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 20:45 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, Apr 26, 2019 at 02:47:13PM +0800, Chunfeng Yun wrote: > It's used to support dual role switch via GPIO when use Type-B > receptacle, typically the USB ID pin is connected to an input > GPIO pin > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 no changes > > v3 changes: > 1. treat type-B connector as a virtual device, but not child device of > USB controller's > > v2 changes: > 1. new patch to make binding clear suggested by Hans > --- > .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ > 1 file changed, 49 insertions(+) > create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > new file mode 100644 > index 000000000000..d2e1c4e01b6d > --- /dev/null > +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > @@ -0,0 +1,49 @@ > +USB Type-B GPIO Connector > + > +This is a virtual device used to switch dual role mode from the USB ID pin > +connected to an input GPIO pin. > + > +Required properties: > +- compatible : Should be "linux,typeb-conn-gpio" There's no need for this virtual node. The USB host or device driver can instantiate a connector driver by walking the OF graph to the connector and creating a device. > + > +Sub-nodes: > +- connector : should be present. > + - compatible : should be "usb-b-connector". > + - id-gpios, vbus-gpios : either one of them must be present, > + and both can be present as well. > + - vbus-supply : can be present if needed when supports dual role mode. > + see connector/usb-connector.txt > + > +- port : should be present. > + see graph.txt > + > +Example: > + > +rsw_iddig: role_sw_iddig { > + compatible = "linux,typeb-conn-gpio"; > + status = "okay"; > + > + connector { > + compatible = "usb-b-connector"; > + label = "micro-USB"; > + type = "micro"; > + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; > + vbus-supply = <&usb_p0_vbus>; > + }; > + > + port { Humm, same mistake as Hikey patches... This goes under the connector node as defined in the connector binding. > + bconn_ep: endpoint@0 { > + remote-endpoint = <&usb_role_sw>; > + }; > + }; > +}; > + > +&mtu3 { > + status = "okay"; > + > + port { > + usb_role_sw: endpoint@0 { > + remote-endpoint = <&bconn_ep>; > + }; > + }; > +}; > -- > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver 2019-04-26 20:45 ` [v4,2/6] " Rob Herring (?) (?) @ 2019-04-28 1:50 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 1:50 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, 2019-04-26 at 15:45 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:13PM +0800, Chunfeng Yun wrote: > > It's used to support dual role switch via GPIO when use Type-B > > receptacle, typically the USB ID pin is connected to an input > > GPIO pin > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 no changes > > > > v3 changes: > > 1. treat type-B connector as a virtual device, but not child device of > > USB controller's > > > > v2 changes: > > 1. new patch to make binding clear suggested by Hans > > --- > > .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ > > 1 file changed, 49 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > > > diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > new file mode 100644 > > index 000000000000..d2e1c4e01b6d > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > @@ -0,0 +1,49 @@ > > +USB Type-B GPIO Connector > > + > > +This is a virtual device used to switch dual role mode from the USB ID pin > > +connected to an input GPIO pin. > > + > > +Required properties: > > +- compatible : Should be "linux,typeb-conn-gpio" > > There's no need for this virtual node. The USB host or device driver can > instantiate a connector driver by walking the OF graph to the connector > and creating a device. Got it. > > > + > > +Sub-nodes: > > +- connector : should be present. > > + - compatible : should be "usb-b-connector". > > + - id-gpios, vbus-gpios : either one of them must be present, > > + and both can be present as well. > > + - vbus-supply : can be present if needed when supports dual role mode. > > + see connector/usb-connector.txt > > + > > +- port : should be present. > > + see graph.txt > > + > > +Example: > > + > > +rsw_iddig: role_sw_iddig { > > + compatible = "linux,typeb-conn-gpio"; > > + status = "okay"; > > + > > + connector { > > + compatible = "usb-b-connector"; > > + label = "micro-USB"; > > + type = "micro"; > > + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; > > + vbus-supply = <&usb_p0_vbus>; > > + }; > > + > > + port { > > Humm, same mistake as Hikey patches... > > This goes under the connector node as defined in the connector binding. Ok, will fix it. Thanks a lot. > > > + bconn_ep: endpoint@0 { > > + remote-endpoint = <&usb_role_sw>; > > + }; > > + }; > > +}; > > + > > +&mtu3 { > > + status = "okay"; > > + > > + port { > > + usb_role_sw: endpoint@0 { > > + remote-endpoint = <&bconn_ep>; > > + }; > > + }; > > +}; > > -- > > 2.21.0 > > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-28 1:50 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 1:50 UTC (permalink / raw) To: Rob Herring Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, linux-usb, linux-kernel, Biju Das, Badhri Jagan Sridharan, Andy Shevchenko, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun On Fri, 2019-04-26 at 15:45 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:13PM +0800, Chunfeng Yun wrote: > > It's used to support dual role switch via GPIO when use Type-B > > receptacle, typically the USB ID pin is connected to an input > > GPIO pin > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 no changes > > > > v3 changes: > > 1. treat type-B connector as a virtual device, but not child device of > > USB controller's > > > > v2 changes: > > 1. new patch to make binding clear suggested by Hans > > --- > > .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ > > 1 file changed, 49 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > > > diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > new file mode 100644 > > index 000000000000..d2e1c4e01b6d > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > @@ -0,0 +1,49 @@ > > +USB Type-B GPIO Connector > > + > > +This is a virtual device used to switch dual role mode from the USB ID pin > > +connected to an input GPIO pin. > > + > > +Required properties: > > +- compatible : Should be "linux,typeb-conn-gpio" > > There's no need for this virtual node. The USB host or device driver can > instantiate a connector driver by walking the OF graph to the connector > and creating a device. Got it. > > > + > > +Sub-nodes: > > +- connector : should be present. > > + - compatible : should be "usb-b-connector". > > + - id-gpios, vbus-gpios : either one of them must be present, > > + and both can be present as well. > > + - vbus-supply : can be present if needed when supports dual role mode. > > + see connector/usb-connector.txt > > + > > +- port : should be present. > > + see graph.txt > > + > > +Example: > > + > > +rsw_iddig: role_sw_iddig { > > + compatible = "linux,typeb-conn-gpio"; > > + status = "okay"; > > + > > + connector { > > + compatible = "usb-b-connector"; > > + label = "micro-USB"; > > + type = "micro"; > > + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; > > + vbus-supply = <&usb_p0_vbus>; > > + }; > > + > > + port { > > Humm, same mistake as Hikey patches... > > This goes under the connector node as defined in the connector binding. Ok, will fix it. Thanks a lot. > > > + bconn_ep: endpoint@0 { > > + remote-endpoint = <&usb_role_sw>; > > + }; > > + }; > > +}; > > + > > +&mtu3 { > > + status = "okay"; > > + > > + port { > > + usb_role_sw: endpoint@0 { > > + remote-endpoint = <&bconn_ep>; > > + }; > > + }; > > +}; > > -- > > 2.21.0 > > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-28 1:50 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 1:50 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, 2019-04-26 at 15:45 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:13PM +0800, Chunfeng Yun wrote: > > It's used to support dual role switch via GPIO when use Type-B > > receptacle, typically the USB ID pin is connected to an input > > GPIO pin > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 no changes > > > > v3 changes: > > 1. treat type-B connector as a virtual device, but not child device of > > USB controller's > > > > v2 changes: > > 1. new patch to make binding clear suggested by Hans > > --- > > .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ > > 1 file changed, 49 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > > > diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > new file mode 100644 > > index 000000000000..d2e1c4e01b6d > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > @@ -0,0 +1,49 @@ > > +USB Type-B GPIO Connector > > + > > +This is a virtual device used to switch dual role mode from the USB ID pin > > +connected to an input GPIO pin. > > + > > +Required properties: > > +- compatible : Should be "linux,typeb-conn-gpio" > > There's no need for this virtual node. The USB host or device driver can > instantiate a connector driver by walking the OF graph to the connector > and creating a device. Got it. > > > + > > +Sub-nodes: > > +- connector : should be present. > > + - compatible : should be "usb-b-connector". > > + - id-gpios, vbus-gpios : either one of them must be present, > > + and both can be present as well. > > + - vbus-supply : can be present if needed when supports dual role mode. > > + see connector/usb-connector.txt > > + > > +- port : should be present. > > + see graph.txt > > + > > +Example: > > + > > +rsw_iddig: role_sw_iddig { > > + compatible = "linux,typeb-conn-gpio"; > > + status = "okay"; > > + > > + connector { > > + compatible = "usb-b-connector"; > > + label = "micro-USB"; > > + type = "micro"; > > + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; > > + vbus-supply = <&usb_p0_vbus>; > > + }; > > + > > + port { > > Humm, same mistake as Hikey patches... > > This goes under the connector node as defined in the connector binding. Ok, will fix it. Thanks a lot. > > > + bconn_ep: endpoint@0 { > > + remote-endpoint = <&usb_role_sw>; > > + }; > > + }; > > +}; > > + > > +&mtu3 { > > + status = "okay"; > > + > > + port { > > + usb_role_sw: endpoint@0 { > > + remote-endpoint = <&bconn_ep>; > > + }; > > + }; > > +}; > > -- > > 2.21.0 > > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver @ 2019-04-28 1:50 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 1:50 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, 2019-04-26 at 15:45 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:13PM +0800, Chunfeng Yun wrote: > > It's used to support dual role switch via GPIO when use Type-B > > receptacle, typically the USB ID pin is connected to an input > > GPIO pin > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 no changes > > > > v3 changes: > > 1. treat type-B connector as a virtual device, but not child device of > > USB controller's > > > > v2 changes: > > 1. new patch to make binding clear suggested by Hans > > --- > > .../bindings/usb/typeb-conn-gpio.txt | 49 +++++++++++++++++++ > > 1 file changed, 49 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > > > diff --git a/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > new file mode 100644 > > index 000000000000..d2e1c4e01b6d > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/usb/typeb-conn-gpio.txt > > @@ -0,0 +1,49 @@ > > +USB Type-B GPIO Connector > > + > > +This is a virtual device used to switch dual role mode from the USB ID pin > > +connected to an input GPIO pin. > > + > > +Required properties: > > +- compatible : Should be "linux,typeb-conn-gpio" > > There's no need for this virtual node. The USB host or device driver can > instantiate a connector driver by walking the OF graph to the connector > and creating a device. Got it. > > > + > > +Sub-nodes: > > +- connector : should be present. > > + - compatible : should be "usb-b-connector". > > + - id-gpios, vbus-gpios : either one of them must be present, > > + and both can be present as well. > > + - vbus-supply : can be present if needed when supports dual role mode. > > + see connector/usb-connector.txt > > + > > +- port : should be present. > > + see graph.txt > > + > > +Example: > > + > > +rsw_iddig: role_sw_iddig { > > + compatible = "linux,typeb-conn-gpio"; > > + status = "okay"; > > + > > + connector { > > + compatible = "usb-b-connector"; > > + label = "micro-USB"; > > + type = "micro"; > > + id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>; > > + vbus-supply = <&usb_p0_vbus>; > > + }; > > + > > + port { > > Humm, same mistake as Hikey patches... > > This goes under the connector node as defined in the connector binding. Ok, will fix it. Thanks a lot. > > > + bconn_ep: endpoint@0 { > > + remote-endpoint = <&usb_role_sw>; > > + }; > > + }; > > +}; > > + > > +&mtu3 { > > + status = "okay"; > > + > > + port { > > + usb_role_sw: endpoint@0 { > > + remote-endpoint = <&bconn_ep>; > > + }; > > + }; > > +}; > > -- > > 2.21.0 > > ^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch 2019-04-26 6:47 ` Chunfeng Yun (?) (?) @ 2019-04-26 6:47 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Now the USB Role Switch is supported, so add properties about it Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4: no changes v3: no changes v2 changes: 1. fix typo 2. refer new binding about connector property --- .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt index 3382b5cb471d..6e004c4a89af 100644 --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt @@ -27,7 +27,9 @@ Optional properties: - ranges : allows valid 1:1 translation between child's address space and parent's address space - extcon : external connector for vbus and idpin changes detection, needed - when supports dual-role mode. + when supports dual-role mode; it's consiedered valid for compatibility + reasons, and not allowed for new bindings, use the property + usb-role-switch instead. - vbus-supply : reference to the VBUS regulator, needed when supports dual-role mode. - pinctrl-names : a pinctrl state named "default" is optional, and need be @@ -36,7 +38,8 @@ Optional properties: is not set. - pinctrl-0 : pin control group See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - + - usb-role-switch : use USB Role Switch to support dual-role switch, but + not extcon - maximum-speed : valid arguments are "super-speed", "high-speed" and "full-speed"; refer to usb/generic.txt - enable-manual-drd : supports manual dual-role switch via debugfs; usually @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example if host mode is enabled. The DT binding details of xhci can be found in: Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt +The port would be added as subnode if use usb-role-switch property + see graph.txt + Example: ssusb: usb@11271000 { compatible = "mediatek,mt8173-mtu3"; -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun Now the USB Role Switch is supported, so add properties about it Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4: no changes v3: no changes v2 changes: 1. fix typo 2. refer new binding about connector property --- .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt index 3382b5cb471d..6e004c4a89af 100644 --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt @@ -27,7 +27,9 @@ Optional properties: - ranges : allows valid 1:1 translation between child's address space and parent's address space - extcon : external connector for vbus and idpin changes detection, needed - when supports dual-role mode. + when supports dual-role mode; it's consiedered valid for compatibility + reasons, and not allowed for new bindings, use the property + usb-role-switch instead. - vbus-supply : reference to the VBUS regulator, needed when supports dual-role mode. - pinctrl-names : a pinctrl state named "default" is optional, and need be @@ -36,7 +38,8 @@ Optional properties: is not set. - pinctrl-0 : pin control group See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - + - usb-role-switch : use USB Role Switch to support dual-role switch, but + not extcon - maximum-speed : valid arguments are "super-speed", "high-speed" and "full-speed"; refer to usb/generic.txt - enable-manual-drd : supports manual dual-role switch via debugfs; usually @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example if host mode is enabled. The DT binding details of xhci can be found in: Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt +The port would be added as subnode if use usb-role-switch property + see graph.txt + Example: ssusb: usb@11271000 { compatible = "mediatek,mt8173-mtu3"; -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [v4,3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Now the USB Role Switch is supported, so add properties about it Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4: no changes v3: no changes v2 changes: 1. fix typo 2. refer new binding about connector property --- .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt index 3382b5cb471d..6e004c4a89af 100644 --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt @@ -27,7 +27,9 @@ Optional properties: - ranges : allows valid 1:1 translation between child's address space and parent's address space - extcon : external connector for vbus and idpin changes detection, needed - when supports dual-role mode. + when supports dual-role mode; it's consiedered valid for compatibility + reasons, and not allowed for new bindings, use the property + usb-role-switch instead. - vbus-supply : reference to the VBUS regulator, needed when supports dual-role mode. - pinctrl-names : a pinctrl state named "default" is optional, and need be @@ -36,7 +38,8 @@ Optional properties: is not set. - pinctrl-0 : pin control group See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - + - usb-role-switch : use USB Role Switch to support dual-role switch, but + not extcon - maximum-speed : valid arguments are "super-speed", "high-speed" and "full-speed"; refer to usb/generic.txt - enable-manual-drd : supports manual dual-role switch via debugfs; usually @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example if host mode is enabled. The DT binding details of xhci can be found in: Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt +The port would be added as subnode if use usb-role-switch property + see graph.txt + Example: ssusb: usb@11271000 { compatible = "mediatek,mt8173-mtu3"; ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Now the USB Role Switch is supported, so add properties about it Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4: no changes v3: no changes v2 changes: 1. fix typo 2. refer new binding about connector property --- .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt index 3382b5cb471d..6e004c4a89af 100644 --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt @@ -27,7 +27,9 @@ Optional properties: - ranges : allows valid 1:1 translation between child's address space and parent's address space - extcon : external connector for vbus and idpin changes detection, needed - when supports dual-role mode. + when supports dual-role mode; it's consiedered valid for compatibility + reasons, and not allowed for new bindings, use the property + usb-role-switch instead. - vbus-supply : reference to the VBUS regulator, needed when supports dual-role mode. - pinctrl-names : a pinctrl state named "default" is optional, and need be @@ -36,7 +38,8 @@ Optional properties: is not set. - pinctrl-0 : pin control group See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt - + - usb-role-switch : use USB Role Switch to support dual-role switch, but + not extcon - maximum-speed : valid arguments are "super-speed", "high-speed" and "full-speed"; refer to usb/generic.txt - enable-manual-drd : supports manual dual-role switch via debugfs; usually @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example if host mode is enabled. The DT binding details of xhci can be found in: Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt +The port would be added as subnode if use usb-role-switch property + see graph.txt + Example: ssusb: usb@11271000 { compatible = "mediatek,mt8173-mtu3"; -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-26 20:49 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 20:49 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > Now the USB Role Switch is supported, so add properties about it > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4: no changes > v3: no changes > > v2 changes: > 1. fix typo > 2. refer new binding about connector property > --- > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > index 3382b5cb471d..6e004c4a89af 100644 > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > @@ -27,7 +27,9 @@ Optional properties: > - ranges : allows valid 1:1 translation between child's address space and > parent's address space > - extcon : external connector for vbus and idpin changes detection, needed > - when supports dual-role mode. > + when supports dual-role mode; it's consiedered valid for compatibility > + reasons, and not allowed for new bindings, use the property > + usb-role-switch instead. > - vbus-supply : reference to the VBUS regulator, needed when supports > dual-role mode. > - pinctrl-names : a pinctrl state named "default" is optional, and need be > @@ -36,7 +38,8 @@ Optional properties: > is not set. > - pinctrl-0 : pin control group > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > - > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > + not extcon Coordinate with the Renesas and HiSilicon folks implementing the same thing and put this in a common spot. However, I think this should not even be needed as knowing the controller capabilities (based on the compatible) and knowing the type of connector should be enough information to tell you if dual role is supported or not. > - maximum-speed : valid arguments are "super-speed", "high-speed" and > "full-speed"; refer to usb/generic.txt > - enable-manual-drd : supports manual dual-role switch via debugfs; usually > @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example > if host mode is enabled. The DT binding details of xhci can be found in: > Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt > > +The port would be added as subnode if use usb-role-switch property > + see graph.txt > + > Example: > ssusb: usb@11271000 { > compatible = "mediatek,mt8173-mtu3"; > -- > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-26 20:49 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 20:49 UTC (permalink / raw) To: Chunfeng Yun Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, linux-usb, linux-kernel, Biju Das, Badhri Jagan Sridharan, Andy Shevchenko, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > Now the USB Role Switch is supported, so add properties about it > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4: no changes > v3: no changes > > v2 changes: > 1. fix typo > 2. refer new binding about connector property > --- > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > index 3382b5cb471d..6e004c4a89af 100644 > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > @@ -27,7 +27,9 @@ Optional properties: > - ranges : allows valid 1:1 translation between child's address space and > parent's address space > - extcon : external connector for vbus and idpin changes detection, needed > - when supports dual-role mode. > + when supports dual-role mode; it's consiedered valid for compatibility > + reasons, and not allowed for new bindings, use the property > + usb-role-switch instead. > - vbus-supply : reference to the VBUS regulator, needed when supports > dual-role mode. > - pinctrl-names : a pinctrl state named "default" is optional, and need be > @@ -36,7 +38,8 @@ Optional properties: > is not set. > - pinctrl-0 : pin control group > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > - > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > + not extcon Coordinate with the Renesas and HiSilicon folks implementing the same thing and put this in a common spot. However, I think this should not even be needed as knowing the controller capabilities (based on the compatible) and knowing the type of connector should be enough information to tell you if dual role is supported or not. > - maximum-speed : valid arguments are "super-speed", "high-speed" and > "full-speed"; refer to usb/generic.txt > - enable-manual-drd : supports manual dual-role switch via debugfs; usually > @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example > if host mode is enabled. The DT binding details of xhci can be found in: > Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt > > +The port would be added as subnode if use usb-role-switch property > + see graph.txt > + > Example: > ssusb: usb@11271000 { > compatible = "mediatek,mt8173-mtu3"; > -- > 2.21.0 > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-26 20:49 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-26 20:49 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > Now the USB Role Switch is supported, so add properties about it > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4: no changes > v3: no changes > > v2 changes: > 1. fix typo > 2. refer new binding about connector property > --- > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > index 3382b5cb471d..6e004c4a89af 100644 > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > @@ -27,7 +27,9 @@ Optional properties: > - ranges : allows valid 1:1 translation between child's address space and > parent's address space > - extcon : external connector for vbus and idpin changes detection, needed > - when supports dual-role mode. > + when supports dual-role mode; it's consiedered valid for compatibility > + reasons, and not allowed for new bindings, use the property > + usb-role-switch instead. > - vbus-supply : reference to the VBUS regulator, needed when supports > dual-role mode. > - pinctrl-names : a pinctrl state named "default" is optional, and need be > @@ -36,7 +38,8 @@ Optional properties: > is not set. > - pinctrl-0 : pin control group > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > - > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > + not extcon Coordinate with the Renesas and HiSilicon folks implementing the same thing and put this in a common spot. However, I think this should not even be needed as knowing the controller capabilities (based on the compatible) and knowing the type of connector should be enough information to tell you if dual role is supported or not. > - maximum-speed : valid arguments are "super-speed", "high-speed" and > "full-speed"; refer to usb/generic.txt > - enable-manual-drd : supports manual dual-role switch via debugfs; usually > @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example > if host mode is enabled. The DT binding details of xhci can be found in: > Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt > > +The port would be added as subnode if use usb-role-switch property > + see graph.txt > + > Example: > ssusb: usb@11271000 { > compatible = "mediatek,mt8173-mtu3"; > -- > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch 2019-04-26 20:49 ` [v4,3/6] " Rob Herring (?) (?) @ 2019-04-28 12:16 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 12:16 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > Now the USB Role Switch is supported, so add properties about it > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4: no changes > > v3: no changes > > > > v2 changes: > > 1. fix typo > > 2. refer new binding about connector property > > --- > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > index 3382b5cb471d..6e004c4a89af 100644 > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > @@ -27,7 +27,9 @@ Optional properties: > > - ranges : allows valid 1:1 translation between child's address space and > > parent's address space > > - extcon : external connector for vbus and idpin changes detection, needed > > - when supports dual-role mode. > > + when supports dual-role mode; it's consiedered valid for compatibility > > + reasons, and not allowed for new bindings, use the property > > + usb-role-switch instead. > > - vbus-supply : reference to the VBUS regulator, needed when supports > > dual-role mode. > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > @@ -36,7 +38,8 @@ Optional properties: > > is not set. > > - pinctrl-0 : pin control group > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > - > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > + not extcon > > Coordinate with the Renesas and HiSilicon folks implementing the same > thing and put this in a common spot. I'll prepare a patch for it, and CC Biju and Yu > However, I think this should not > even be needed as knowing the controller capabilities (based on the > compatible) and knowing the type of connector should be enough > information to tell you if dual role is supported or not. Some Dual-Role controller drivers already used extcon framework to handle role switch, if try to support the new USB Role Switch framework, the driver may want to know which way will be used. Sometimes users also want to use dual-role even use the type-A, such as use sys interface to handle role switch, so only knowing the connector type can't tell driver which way to use > > > - maximum-speed : valid arguments are "super-speed", "high-speed" and > > "full-speed"; refer to usb/generic.txt > > - enable-manual-drd : supports manual dual-role switch via debugfs; usually > > @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example > > if host mode is enabled. The DT binding details of xhci can be found in: > > Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt > > > > +The port would be added as subnode if use usb-role-switch property > > + see graph.txt > > + > > Example: > > ssusb: usb@11271000 { > > compatible = "mediatek,mt8173-mtu3"; > > -- > > 2.21.0 > > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-28 12:16 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 12:16 UTC (permalink / raw) To: Rob Herring Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, linux-usb, linux-kernel, Biju Das, Badhri Jagan Sridharan, Andy Shevchenko, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > Now the USB Role Switch is supported, so add properties about it > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4: no changes > > v3: no changes > > > > v2 changes: > > 1. fix typo > > 2. refer new binding about connector property > > --- > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > index 3382b5cb471d..6e004c4a89af 100644 > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > @@ -27,7 +27,9 @@ Optional properties: > > - ranges : allows valid 1:1 translation between child's address space and > > parent's address space > > - extcon : external connector for vbus and idpin changes detection, needed > > - when supports dual-role mode. > > + when supports dual-role mode; it's consiedered valid for compatibility > > + reasons, and not allowed for new bindings, use the property > > + usb-role-switch instead. > > - vbus-supply : reference to the VBUS regulator, needed when supports > > dual-role mode. > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > @@ -36,7 +38,8 @@ Optional properties: > > is not set. > > - pinctrl-0 : pin control group > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > - > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > + not extcon > > Coordinate with the Renesas and HiSilicon folks implementing the same > thing and put this in a common spot. I'll prepare a patch for it, and CC Biju and Yu > However, I think this should not > even be needed as knowing the controller capabilities (based on the > compatible) and knowing the type of connector should be enough > information to tell you if dual role is supported or not. Some Dual-Role controller drivers already used extcon framework to handle role switch, if try to support the new USB Role Switch framework, the driver may want to know which way will be used. Sometimes users also want to use dual-role even use the type-A, such as use sys interface to handle role switch, so only knowing the connector type can't tell driver which way to use > > > - maximum-speed : valid arguments are "super-speed", "high-speed" and > > "full-speed"; refer to usb/generic.txt > > - enable-manual-drd : supports manual dual-role switch via debugfs; usually > > @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example > > if host mode is enabled. The DT binding details of xhci can be found in: > > Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt > > > > +The port would be added as subnode if use usb-role-switch property > > + see graph.txt > > + > > Example: > > ssusb: usb@11271000 { > > compatible = "mediatek,mt8173-mtu3"; > > -- > > 2.21.0 > > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-28 12:16 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 12:16 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > Now the USB Role Switch is supported, so add properties about it > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4: no changes > > v3: no changes > > > > v2 changes: > > 1. fix typo > > 2. refer new binding about connector property > > --- > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > index 3382b5cb471d..6e004c4a89af 100644 > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > @@ -27,7 +27,9 @@ Optional properties: > > - ranges : allows valid 1:1 translation between child's address space and > > parent's address space > > - extcon : external connector for vbus and idpin changes detection, needed > > - when supports dual-role mode. > > + when supports dual-role mode; it's consiedered valid for compatibility > > + reasons, and not allowed for new bindings, use the property > > + usb-role-switch instead. > > - vbus-supply : reference to the VBUS regulator, needed when supports > > dual-role mode. > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > @@ -36,7 +38,8 @@ Optional properties: > > is not set. > > - pinctrl-0 : pin control group > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > - > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > + not extcon > > Coordinate with the Renesas and HiSilicon folks implementing the same > thing and put this in a common spot. I'll prepare a patch for it, and CC Biju and Yu > However, I think this should not > even be needed as knowing the controller capabilities (based on the > compatible) and knowing the type of connector should be enough > information to tell you if dual role is supported or not. Some Dual-Role controller drivers already used extcon framework to handle role switch, if try to support the new USB Role Switch framework, the driver may want to know which way will be used. Sometimes users also want to use dual-role even use the type-A, such as use sys interface to handle role switch, so only knowing the connector type can't tell driver which way to use > > > - maximum-speed : valid arguments are "super-speed", "high-speed" and > > "full-speed"; refer to usb/generic.txt > > - enable-manual-drd : supports manual dual-role switch via debugfs; usually > > @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example > > if host mode is enabled. The DT binding details of xhci can be found in: > > Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt > > > > +The port would be added as subnode if use usb-role-switch property > > + see graph.txt > > + > > Example: > > ssusb: usb@11271000 { > > compatible = "mediatek,mt8173-mtu3"; > > -- > > 2.21.0 > > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-28 12:16 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 12:16 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > Now the USB Role Switch is supported, so add properties about it > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4: no changes > > v3: no changes > > > > v2 changes: > > 1. fix typo > > 2. refer new binding about connector property > > --- > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > index 3382b5cb471d..6e004c4a89af 100644 > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > @@ -27,7 +27,9 @@ Optional properties: > > - ranges : allows valid 1:1 translation between child's address space and > > parent's address space > > - extcon : external connector for vbus and idpin changes detection, needed > > - when supports dual-role mode. > > + when supports dual-role mode; it's consiedered valid for compatibility > > + reasons, and not allowed for new bindings, use the property > > + usb-role-switch instead. > > - vbus-supply : reference to the VBUS regulator, needed when supports > > dual-role mode. > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > @@ -36,7 +38,8 @@ Optional properties: > > is not set. > > - pinctrl-0 : pin control group > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > - > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > + not extcon > > Coordinate with the Renesas and HiSilicon folks implementing the same > thing and put this in a common spot. I'll prepare a patch for it, and CC Biju and Yu > However, I think this should not > even be needed as knowing the controller capabilities (based on the > compatible) and knowing the type of connector should be enough > information to tell you if dual role is supported or not. Some Dual-Role controller drivers already used extcon framework to handle role switch, if try to support the new USB Role Switch framework, the driver may want to know which way will be used. Sometimes users also want to use dual-role even use the type-A, such as use sys interface to handle role switch, so only knowing the connector type can't tell driver which way to use > > > - maximum-speed : valid arguments are "super-speed", "high-speed" and > > "full-speed"; refer to usb/generic.txt > > - enable-manual-drd : supports manual dual-role switch via debugfs; usually > > @@ -61,6 +64,9 @@ The xhci should be added as subnode to mtu3 as shown in the following example > > if host mode is enabled. The DT binding details of xhci can be found in: > > Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt > > > > +The port would be added as subnode if use usb-role-switch property > > + see graph.txt > > + > > Example: > > ssusb: usb@11271000 { > > compatible = "mediatek,mt8173-mtu3"; > > -- > > 2.21.0 > > ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch 2019-04-28 12:16 ` [PATCH v4 3/6] " Chunfeng Yun (?) (?) @ 2019-04-29 16:25 ` Rob Herring -1 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-29 16:25 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das, Linus Walleij On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > Now the USB Role Switch is supported, so add properties about it > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > --- > > > v4: no changes > > > v3: no changes > > > > > > v2 changes: > > > 1. fix typo > > > 2. refer new binding about connector property > > > --- > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > index 3382b5cb471d..6e004c4a89af 100644 > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > @@ -27,7 +27,9 @@ Optional properties: > > > - ranges : allows valid 1:1 translation between child's address space and > > > parent's address space > > > - extcon : external connector for vbus and idpin changes detection, needed > > > - when supports dual-role mode. > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > + reasons, and not allowed for new bindings, use the property > > > + usb-role-switch instead. > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > dual-role mode. > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > @@ -36,7 +38,8 @@ Optional properties: > > > is not set. > > > - pinctrl-0 : pin control group > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > - > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > + not extcon > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > thing and put this in a common spot. > I'll prepare a patch for it, and CC Biju and Yu > > > However, I think this should not > > even be needed as knowing the controller capabilities (based on the > > compatible) and knowing the type of connector should be enough > > information to tell you if dual role is supported or not. > Some Dual-Role controller drivers already used extcon framework to > handle role switch, if try to support the new USB Role Switch framework, > the driver may want to know which way will be used. Wouldn't it know by presence of 'extcon' property or not? > Sometimes users also want to use dual-role even use the type-A, such as > use sys interface to handle role switch, so only knowing the connector > type can't tell driver which way to use That use case doesn't sound like something that should be in DT though. That would be possible for any controller that supports dual-role. Though perhaps that requires some specific Vbus wiring? Or a cable with Vbus disconnected. Either way, doesn't sound USB compliant. Rob ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-29 16:25 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-29 16:25 UTC (permalink / raw) To: Chunfeng Yun Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, Linux USB List, linux-kernel, Biju Das, Badhri Jagan Sridharan, Andy Shevchenko, moderated list:ARM/Mediatek SoC support, Min Guo, Matthias Brugger, Adam Thomson, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, Li Jun On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > Now the USB Role Switch is supported, so add properties about it > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > --- > > > v4: no changes > > > v3: no changes > > > > > > v2 changes: > > > 1. fix typo > > > 2. refer new binding about connector property > > > --- > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > index 3382b5cb471d..6e004c4a89af 100644 > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > @@ -27,7 +27,9 @@ Optional properties: > > > - ranges : allows valid 1:1 translation between child's address space and > > > parent's address space > > > - extcon : external connector for vbus and idpin changes detection, needed > > > - when supports dual-role mode. > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > + reasons, and not allowed for new bindings, use the property > > > + usb-role-switch instead. > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > dual-role mode. > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > @@ -36,7 +38,8 @@ Optional properties: > > > is not set. > > > - pinctrl-0 : pin control group > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > - > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > + not extcon > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > thing and put this in a common spot. > I'll prepare a patch for it, and CC Biju and Yu > > > However, I think this should not > > even be needed as knowing the controller capabilities (based on the > > compatible) and knowing the type of connector should be enough > > information to tell you if dual role is supported or not. > Some Dual-Role controller drivers already used extcon framework to > handle role switch, if try to support the new USB Role Switch framework, > the driver may want to know which way will be used. Wouldn't it know by presence of 'extcon' property or not? > Sometimes users also want to use dual-role even use the type-A, such as > use sys interface to handle role switch, so only knowing the connector > type can't tell driver which way to use That use case doesn't sound like something that should be in DT though. That would be possible for any controller that supports dual-role. Though perhaps that requires some specific Vbus wiring? Or a cable with Vbus disconnected. Either way, doesn't sound USB compliant. Rob _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-29 16:25 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-29 16:25 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das, Linus Walleij On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > Now the USB Role Switch is supported, so add properties about it > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > --- > > > v4: no changes > > > v3: no changes > > > > > > v2 changes: > > > 1. fix typo > > > 2. refer new binding about connector property > > > --- > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > index 3382b5cb471d..6e004c4a89af 100644 > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > @@ -27,7 +27,9 @@ Optional properties: > > > - ranges : allows valid 1:1 translation between child's address space and > > > parent's address space > > > - extcon : external connector for vbus and idpin changes detection, needed > > > - when supports dual-role mode. > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > + reasons, and not allowed for new bindings, use the property > > > + usb-role-switch instead. > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > dual-role mode. > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > @@ -36,7 +38,8 @@ Optional properties: > > > is not set. > > > - pinctrl-0 : pin control group > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > - > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > + not extcon > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > thing and put this in a common spot. > I'll prepare a patch for it, and CC Biju and Yu > > > However, I think this should not > > even be needed as knowing the controller capabilities (based on the > > compatible) and knowing the type of connector should be enough > > information to tell you if dual role is supported or not. > Some Dual-Role controller drivers already used extcon framework to > handle role switch, if try to support the new USB Role Switch framework, > the driver may want to know which way will be used. Wouldn't it know by presence of 'extcon' property or not? > Sometimes users also want to use dual-role even use the type-A, such as > use sys interface to handle role switch, so only knowing the connector > type can't tell driver which way to use That use case doesn't sound like something that should be in DT though. That would be possible for any controller that supports dual-role. Though perhaps that requires some specific Vbus wiring? Or a cable with Vbus disconnected. Either way, doesn't sound USB compliant. Rob ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-29 16:25 ` Rob Herring 0 siblings, 0 replies; 69+ messages in thread From: Rob Herring @ 2019-04-29 16:25 UTC (permalink / raw) To: Chunfeng Yun Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > Now the USB Role Switch is supported, so add properties about it > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > --- > > > v4: no changes > > > v3: no changes > > > > > > v2 changes: > > > 1. fix typo > > > 2. refer new binding about connector property > > > --- > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > index 3382b5cb471d..6e004c4a89af 100644 > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > @@ -27,7 +27,9 @@ Optional properties: > > > - ranges : allows valid 1:1 translation between child's address space and > > > parent's address space > > > - extcon : external connector for vbus and idpin changes detection, needed > > > - when supports dual-role mode. > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > + reasons, and not allowed for new bindings, use the property > > > + usb-role-switch instead. > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > dual-role mode. > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > @@ -36,7 +38,8 @@ Optional properties: > > > is not set. > > > - pinctrl-0 : pin control group > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > - > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > + not extcon > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > thing and put this in a common spot. > I'll prepare a patch for it, and CC Biju and Yu > > > However, I think this should not > > even be needed as knowing the controller capabilities (based on the > > compatible) and knowing the type of connector should be enough > > information to tell you if dual role is supported or not. > Some Dual-Role controller drivers already used extcon framework to > handle role switch, if try to support the new USB Role Switch framework, > the driver may want to know which way will be used. Wouldn't it know by presence of 'extcon' property or not? > Sometimes users also want to use dual-role even use the type-A, such as > use sys interface to handle role switch, so only knowing the connector > type can't tell driver which way to use That use case doesn't sound like something that should be in DT though. That would be possible for any controller that supports dual-role. Though perhaps that requires some specific Vbus wiring? Or a cable with Vbus disconnected. Either way, doesn't sound USB compliant. Rob ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch 2019-04-29 16:25 ` [PATCH v4 3/6] " Rob Herring (?) (?) @ 2019-04-30 6:57 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-30 6:57 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das, Linus Walleij On Mon, 2019-04-29 at 11:25 -0500, Rob Herring wrote: > On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > > Now the USB Role Switch is supported, so add properties about it > > > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > > --- > > > > v4: no changes > > > > v3: no changes > > > > > > > > v2 changes: > > > > 1. fix typo > > > > 2. refer new binding about connector property > > > > --- > > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > index 3382b5cb471d..6e004c4a89af 100644 > > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > @@ -27,7 +27,9 @@ Optional properties: > > > > - ranges : allows valid 1:1 translation between child's address space and > > > > parent's address space > > > > - extcon : external connector for vbus and idpin changes detection, needed > > > > - when supports dual-role mode. > > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > > + reasons, and not allowed for new bindings, use the property > > > > + usb-role-switch instead. > > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > > dual-role mode. > > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > > @@ -36,7 +38,8 @@ Optional properties: > > > > is not set. > > > > - pinctrl-0 : pin control group > > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > > - > > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > > + not extcon > > > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > > thing and put this in a common spot. > > I'll prepare a patch for it, and CC Biju and Yu > > > > > However, I think this should not > > > even be needed as knowing the controller capabilities (based on the > > > compatible) and knowing the type of connector should be enough > > > information to tell you if dual role is supported or not. > > Some Dual-Role controller drivers already used extcon framework to > > handle role switch, if try to support the new USB Role Switch framework, > > the driver may want to know which way will be used. > > Wouldn't it know by presence of 'extcon' property or not? non-presence of 'extcon' doesn't mean the driver need USB Role Switch, e.g. support manual role switch decided by user, of course, we can check some cases and then decide whether need USB Role Switch or not, maybe provide a property will make it easier. > > > Sometimes users also want to use dual-role even use the type-A, such as > > use sys interface to handle role switch, so only knowing the connector > > type can't tell driver which way to use > > That use case doesn't sound like something that should be in DT > though. That would be possible for any controller that supports > dual-role. I give manual role switch by sysfs interface a higher priority than other ways, if manual switch is enabled, e.g. 'extcon' will be ignored. this may be different from other USB dual-role controller drivers. > Though perhaps that requires some specific Vbus wiring? Or > a cable with Vbus disconnected. Yes, some projects use PMIC or Charger to detect Vbus, but some don't have Vbus detection circuit, and some even don't provide vbus pin > Either way, doesn't sound USB compliant. Yes, it's more related with customer usage, or cost down, anyway, it's better to support cases as many as possible. > > Rob ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-30 6:57 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-30 6:57 UTC (permalink / raw) To: Rob Herring Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, Linux USB List, linux-kernel, Biju Das, Badhri Jagan Sridharan, Andy Shevchenko, moderated list:ARM/Mediatek SoC support, Min Guo, Matthias Brugger, Adam Thomson, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, Li Jun On Mon, 2019-04-29 at 11:25 -0500, Rob Herring wrote: > On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > > Now the USB Role Switch is supported, so add properties about it > > > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > > --- > > > > v4: no changes > > > > v3: no changes > > > > > > > > v2 changes: > > > > 1. fix typo > > > > 2. refer new binding about connector property > > > > --- > > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > index 3382b5cb471d..6e004c4a89af 100644 > > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > @@ -27,7 +27,9 @@ Optional properties: > > > > - ranges : allows valid 1:1 translation between child's address space and > > > > parent's address space > > > > - extcon : external connector for vbus and idpin changes detection, needed > > > > - when supports dual-role mode. > > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > > + reasons, and not allowed for new bindings, use the property > > > > + usb-role-switch instead. > > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > > dual-role mode. > > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > > @@ -36,7 +38,8 @@ Optional properties: > > > > is not set. > > > > - pinctrl-0 : pin control group > > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > > - > > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > > + not extcon > > > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > > thing and put this in a common spot. > > I'll prepare a patch for it, and CC Biju and Yu > > > > > However, I think this should not > > > even be needed as knowing the controller capabilities (based on the > > > compatible) and knowing the type of connector should be enough > > > information to tell you if dual role is supported or not. > > Some Dual-Role controller drivers already used extcon framework to > > handle role switch, if try to support the new USB Role Switch framework, > > the driver may want to know which way will be used. > > Wouldn't it know by presence of 'extcon' property or not? non-presence of 'extcon' doesn't mean the driver need USB Role Switch, e.g. support manual role switch decided by user, of course, we can check some cases and then decide whether need USB Role Switch or not, maybe provide a property will make it easier. > > > Sometimes users also want to use dual-role even use the type-A, such as > > use sys interface to handle role switch, so only knowing the connector > > type can't tell driver which way to use > > That use case doesn't sound like something that should be in DT > though. That would be possible for any controller that supports > dual-role. I give manual role switch by sysfs interface a higher priority than other ways, if manual switch is enabled, e.g. 'extcon' will be ignored. this may be different from other USB dual-role controller drivers. > Though perhaps that requires some specific Vbus wiring? Or > a cable with Vbus disconnected. Yes, some projects use PMIC or Charger to detect Vbus, but some don't have Vbus detection circuit, and some even don't provide vbus pin > Either way, doesn't sound USB compliant. Yes, it's more related with customer usage, or cost down, anyway, it's better to support cases as many as possible. > > Rob _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-30 6:57 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-30 6:57 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das, Linus Walleij On Mon, 2019-04-29 at 11:25 -0500, Rob Herring wrote: > On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > > Now the USB Role Switch is supported, so add properties about it > > > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > > --- > > > > v4: no changes > > > > v3: no changes > > > > > > > > v2 changes: > > > > 1. fix typo > > > > 2. refer new binding about connector property > > > > --- > > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > index 3382b5cb471d..6e004c4a89af 100644 > > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > @@ -27,7 +27,9 @@ Optional properties: > > > > - ranges : allows valid 1:1 translation between child's address space and > > > > parent's address space > > > > - extcon : external connector for vbus and idpin changes detection, needed > > > > - when supports dual-role mode. > > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > > + reasons, and not allowed for new bindings, use the property > > > > + usb-role-switch instead. > > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > > dual-role mode. > > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > > @@ -36,7 +38,8 @@ Optional properties: > > > > is not set. > > > > - pinctrl-0 : pin control group > > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > > - > > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > > + not extcon > > > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > > thing and put this in a common spot. > > I'll prepare a patch for it, and CC Biju and Yu > > > > > However, I think this should not > > > even be needed as knowing the controller capabilities (based on the > > > compatible) and knowing the type of connector should be enough > > > information to tell you if dual role is supported or not. > > Some Dual-Role controller drivers already used extcon framework to > > handle role switch, if try to support the new USB Role Switch framework, > > the driver may want to know which way will be used. > > Wouldn't it know by presence of 'extcon' property or not? non-presence of 'extcon' doesn't mean the driver need USB Role Switch, e.g. support manual role switch decided by user, of course, we can check some cases and then decide whether need USB Role Switch or not, maybe provide a property will make it easier. > > > Sometimes users also want to use dual-role even use the type-A, such as > > use sys interface to handle role switch, so only knowing the connector > > type can't tell driver which way to use > > That use case doesn't sound like something that should be in DT > though. That would be possible for any controller that supports > dual-role. I give manual role switch by sysfs interface a higher priority than other ways, if manual switch is enabled, e.g. 'extcon' will be ignored. this may be different from other USB dual-role controller drivers. > Though perhaps that requires some specific Vbus wiring? Or > a cable with Vbus disconnected. Yes, some projects use PMIC or Charger to detect Vbus, but some don't have Vbus detection circuit, and some even don't provide vbus pin > Either way, doesn't sound USB compliant. Yes, it's more related with customer usage, or cost down, anyway, it's better to support cases as many as possible. > > Rob ^ permalink raw reply [flat|nested] 69+ messages in thread
* Re: [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch @ 2019-04-30 6:57 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-30 6:57 UTC (permalink / raw) To: Rob Herring Cc: Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, Linux USB List, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, moderated list:ARM/Mediatek SoC support, Biju Das On Mon, 2019-04-29 at 11:25 -0500, Rob Herring wrote: > On Sun, Apr 28, 2019 at 7:16 AM Chunfeng Yun <chunfeng.yun@mediatek.com> wrote: > > > > On Fri, 2019-04-26 at 15:49 -0500, Rob Herring wrote: > > > On Fri, Apr 26, 2019 at 02:47:14PM +0800, Chunfeng Yun wrote: > > > > Now the USB Role Switch is supported, so add properties about it > > > > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > > > --- > > > > v4: no changes > > > > v3: no changes > > > > > > > > v2 changes: > > > > 1. fix typo > > > > 2. refer new binding about connector property > > > > --- > > > > .../devicetree/bindings/usb/mediatek,mtu3.txt | 10 ++++++++-- > > > > 1 file changed, 8 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > index 3382b5cb471d..6e004c4a89af 100644 > > > > --- a/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt > > > > @@ -27,7 +27,9 @@ Optional properties: > > > > - ranges : allows valid 1:1 translation between child's address space and > > > > parent's address space > > > > - extcon : external connector for vbus and idpin changes detection, needed > > > > - when supports dual-role mode. > > > > + when supports dual-role mode; it's consiedered valid for compatibility > > > > + reasons, and not allowed for new bindings, use the property > > > > + usb-role-switch instead. > > > > - vbus-supply : reference to the VBUS regulator, needed when supports > > > > dual-role mode. > > > > - pinctrl-names : a pinctrl state named "default" is optional, and need be > > > > @@ -36,7 +38,8 @@ Optional properties: > > > > is not set. > > > > - pinctrl-0 : pin control group > > > > See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt > > > > - > > > > + - usb-role-switch : use USB Role Switch to support dual-role switch, but > > > > + not extcon > > > > > > Coordinate with the Renesas and HiSilicon folks implementing the same > > > thing and put this in a common spot. > > I'll prepare a patch for it, and CC Biju and Yu > > > > > However, I think this should not > > > even be needed as knowing the controller capabilities (based on the > > > compatible) and knowing the type of connector should be enough > > > information to tell you if dual role is supported or not. > > Some Dual-Role controller drivers already used extcon framework to > > handle role switch, if try to support the new USB Role Switch framework, > > the driver may want to know which way will be used. > > Wouldn't it know by presence of 'extcon' property or not? non-presence of 'extcon' doesn't mean the driver need USB Role Switch, e.g. support manual role switch decided by user, of course, we can check some cases and then decide whether need USB Role Switch or not, maybe provide a property will make it easier. > > > Sometimes users also want to use dual-role even use the type-A, such as > > use sys interface to handle role switch, so only knowing the connector > > type can't tell driver which way to use > > That use case doesn't sound like something that should be in DT > though. That would be possible for any controller that supports > dual-role. I give manual role switch by sysfs interface a higher priority than other ways, if manual switch is enabled, e.g. 'extcon' will be ignored. this may be different from other USB dual-role controller drivers. > Though perhaps that requires some specific Vbus wiring? Or > a cable with Vbus disconnected. Yes, some projects use PMIC or Charger to detect Vbus, but some don't have Vbus detection circuit, and some even don't provide vbus pin > Either way, doesn't sound USB compliant. Yes, it's more related with customer usage, or cost down, anyway, it's better to support cases as many as possible. > > Rob ^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node 2019-04-26 6:47 ` Chunfeng Yun (?) (?) @ 2019-04-26 6:47 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch by fwnode which register it. It's useful when there is not device_connection registered between two drivers and only knows the fwnode which register usb_role_switch. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. use switch_fwnode_match() to find fwnode suggested by Heikki 2. this patch now depends on [1] [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h https://patchwork.kernel.org/patch/10909971/ v3 changes: 1. use fwnodes instead of node suggested by Andy 2. rebuild the API suggested by Heikki v2 no changes --- drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ include/linux/usb/role.h | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index f45d8df5cfb8..994fcb979795 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/of.h> #include <linux/slab.h> static struct class *role_class; @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); +/** + * fwnode_usb_role_switch_get - Find USB role switch by it's parent fwnode + * @fwnode: The fwnode that register USB role switch + * + * Finds and returns role switch registered by @fwnode. The reference count + * for the found switch is incremented. + */ +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + struct usb_role_switch *sw; + struct device *dev; + + dev = class_find_device(role_class, NULL, fwnode, switch_fwnode_match); + if (!dev) + return ERR_PTR(-EPROBE_DEFER); + + sw = to_role_switch(dev); + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); + + return sw; +} +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); + /** * usb_role_switch_put - Release handle to a switch * @sw: USB Role Switch diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index da2b9641b877..35d460f9ec40 100644 --- a/include/linux/usb/role.h +++ b/include/linux/usb/role.h @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw); struct usb_role_switch *usb_role_switch_get(struct device *dev); void usb_role_switch_put(struct usb_role_switch *sw); +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); struct usb_role_switch * usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static inline struct usb_role_switch *usb_role_switch_get(struct device *dev) static inline void usb_role_switch_put(struct usb_role_switch *sw) { } +static inline struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + return ERR_PTR(-ENODEV); +} + static inline struct usb_role_switch * usb_role_switch_register(struct device *parent, const struct usb_role_switch_desc *desc) -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch by fwnode which register it. It's useful when there is not device_connection registered between two drivers and only knows the fwnode which register usb_role_switch. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. use switch_fwnode_match() to find fwnode suggested by Heikki 2. this patch now depends on [1] [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h https://patchwork.kernel.org/patch/10909971/ v3 changes: 1. use fwnodes instead of node suggested by Andy 2. rebuild the API suggested by Heikki v2 no changes --- drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ include/linux/usb/role.h | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index f45d8df5cfb8..994fcb979795 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/of.h> #include <linux/slab.h> static struct class *role_class; @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); +/** + * fwnode_usb_role_switch_get - Find USB role switch by it's parent fwnode + * @fwnode: The fwnode that register USB role switch + * + * Finds and returns role switch registered by @fwnode. The reference count + * for the found switch is incremented. + */ +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + struct usb_role_switch *sw; + struct device *dev; + + dev = class_find_device(role_class, NULL, fwnode, switch_fwnode_match); + if (!dev) + return ERR_PTR(-EPROBE_DEFER); + + sw = to_role_switch(dev); + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); + + return sw; +} +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); + /** * usb_role_switch_put - Release handle to a switch * @sw: USB Role Switch diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index da2b9641b877..35d460f9ec40 100644 --- a/include/linux/usb/role.h +++ b/include/linux/usb/role.h @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw); struct usb_role_switch *usb_role_switch_get(struct device *dev); void usb_role_switch_put(struct usb_role_switch *sw); +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); struct usb_role_switch * usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static inline struct usb_role_switch *usb_role_switch_get(struct device *dev) static inline void usb_role_switch_put(struct usb_role_switch *sw) { } +static inline struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + return ERR_PTR(-ENODEV); +} + static inline struct usb_role_switch * usb_role_switch_register(struct device *parent, const struct usb_role_switch_desc *desc) -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [v4,4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch by fwnode which register it. It's useful when there is not device_connection registered between two drivers and only knows the fwnode which register usb_role_switch. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. use switch_fwnode_match() to find fwnode suggested by Heikki 2. this patch now depends on [1] [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h https://patchwork.kernel.org/patch/10909971/ v3 changes: 1. use fwnodes instead of node suggested by Andy 2. rebuild the API suggested by Heikki v2 no changes --- drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ include/linux/usb/role.h | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index f45d8df5cfb8..994fcb979795 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/of.h> #include <linux/slab.h> static struct class *role_class; @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); +/** + * fwnode_usb_role_switch_get - Find USB role switch by it's parent fwnode + * @fwnode: The fwnode that register USB role switch + * + * Finds and returns role switch registered by @fwnode. The reference count + * for the found switch is incremented. + */ +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + struct usb_role_switch *sw; + struct device *dev; + + dev = class_find_device(role_class, NULL, fwnode, switch_fwnode_match); + if (!dev) + return ERR_PTR(-EPROBE_DEFER); + + sw = to_role_switch(dev); + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); + + return sw; +} +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); + /** * usb_role_switch_put - Release handle to a switch * @sw: USB Role Switch diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index da2b9641b877..35d460f9ec40 100644 --- a/include/linux/usb/role.h +++ b/include/linux/usb/role.h @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw); struct usb_role_switch *usb_role_switch_get(struct device *dev); void usb_role_switch_put(struct usb_role_switch *sw); +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); struct usb_role_switch * usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static inline struct usb_role_switch *usb_role_switch_get(struct device *dev) static inline void usb_role_switch_put(struct usb_role_switch *sw) { } +static inline struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + return ERR_PTR(-ENODEV); +} + static inline struct usb_role_switch * usb_role_switch_register(struct device *parent, const struct usb_role_switch_desc *desc) ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch by fwnode which register it. It's useful when there is not device_connection registered between two drivers and only knows the fwnode which register usb_role_switch. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. use switch_fwnode_match() to find fwnode suggested by Heikki 2. this patch now depends on [1] [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h https://patchwork.kernel.org/patch/10909971/ v3 changes: 1. use fwnodes instead of node suggested by Andy 2. rebuild the API suggested by Heikki v2 no changes --- drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ include/linux/usb/role.h | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index f45d8df5cfb8..994fcb979795 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/of.h> #include <linux/slab.h> static struct class *role_class; @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); +/** + * fwnode_usb_role_switch_get - Find USB role switch by it's parent fwnode + * @fwnode: The fwnode that register USB role switch + * + * Finds and returns role switch registered by @fwnode. The reference count + * for the found switch is incremented. + */ +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + struct usb_role_switch *sw; + struct device *dev; + + dev = class_find_device(role_class, NULL, fwnode, switch_fwnode_match); + if (!dev) + return ERR_PTR(-EPROBE_DEFER); + + sw = to_role_switch(dev); + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); + + return sw; +} +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); + /** * usb_role_switch_put - Release handle to a switch * @sw: USB Role Switch diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index da2b9641b877..35d460f9ec40 100644 --- a/include/linux/usb/role.h +++ b/include/linux/usb/role.h @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw); struct usb_role_switch *usb_role_switch_get(struct device *dev); void usb_role_switch_put(struct usb_role_switch *sw); +struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); struct usb_role_switch * usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static inline struct usb_role_switch *usb_role_switch_get(struct device *dev) static inline void usb_role_switch_put(struct usb_role_switch *sw) { } +static inline struct usb_role_switch * +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) +{ + return ERR_PTR(-ENODEV); +} + static inline struct usb_role_switch * usb_role_switch_register(struct device *parent, const struct usb_role_switch_desc *desc) -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* RE: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node 2019-04-26 6:47 ` [PATCH v4 4/6] " Chunfeng Yun (?) (?) @ 2019-04-26 7:02 ` Biju Das -1 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 7:02 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Linus Walleij Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > by fwnode which register it. > It's useful when there is not device_connection registered between two > drivers and only knows the fwnode which register usb_role_switch. > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Tested-by: Biju Das <biju.das@bp.renesas.com> > --- > v4 changes: > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > 2. this patch now depends on [1] > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > https://patchwork.kernel.org/patch/10909971/ > > v3 changes: > 1. use fwnodes instead of node suggested by Andy > 2. rebuild the API suggested by Heikki > > v2 no changes > --- > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > include/linux/usb/role.h | 8 ++++++++ > 2 files changed, 33 insertions(+) > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > f45d8df5cfb8..994fcb979795 100644 > --- a/drivers/usb/roles/class.c > +++ b/drivers/usb/roles/class.c > @@ -12,6 +12,7 @@ > #include <linux/device.h> > #include <linux/module.h> > #include <linux/mutex.h> > +#include <linux/of.h> Is it required? > #include <linux/slab.h> > > static struct class *role_class; > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > +/** > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > +fwnode > + * @fwnode: The fwnode that register USB role switch > + * > + * Finds and returns role switch registered by @fwnode. The reference > +count > + * for the found switch is incremented. > + */ > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + struct usb_role_switch *sw; > + struct device *dev; > + > + dev = class_find_device(role_class, NULL, fwnode, > switch_fwnode_match); > + if (!dev) > + return ERR_PTR(-EPROBE_DEFER); > + > + sw = to_role_switch(dev); > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > + > + return sw; > +} > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > + > /** > * usb_role_switch_put - Release handle to a switch > * @sw: USB Role Switch > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > da2b9641b877..35d460f9ec40 100644 > --- a/include/linux/usb/role.h > +++ b/include/linux/usb/role.h > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > usb_role_switch *sw); struct usb_role_switch *c(struct > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > struct usb_role_switch * > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > +static inline struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + return ERR_PTR(-ENODEV); > +} > + > static inline struct usb_role_switch * > usb_role_switch_register(struct device *parent, > const struct usb_role_switch_desc *desc) > -- > 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 7:02 ` Biju Das 0 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 7:02 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Linus Walleij, linux-usb, linux-kernel, Badhri Jagan Sridharan, Andy Shevchenko, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > by fwnode which register it. > It's useful when there is not device_connection registered between two > drivers and only knows the fwnode which register usb_role_switch. > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Tested-by: Biju Das <biju.das@bp.renesas.com> > --- > v4 changes: > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > 2. this patch now depends on [1] > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > https://patchwork.kernel.org/patch/10909971/ > > v3 changes: > 1. use fwnodes instead of node suggested by Andy > 2. rebuild the API suggested by Heikki > > v2 no changes > --- > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > include/linux/usb/role.h | 8 ++++++++ > 2 files changed, 33 insertions(+) > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > f45d8df5cfb8..994fcb979795 100644 > --- a/drivers/usb/roles/class.c > +++ b/drivers/usb/roles/class.c > @@ -12,6 +12,7 @@ > #include <linux/device.h> > #include <linux/module.h> > #include <linux/mutex.h> > +#include <linux/of.h> Is it required? > #include <linux/slab.h> > > static struct class *role_class; > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > +/** > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > +fwnode > + * @fwnode: The fwnode that register USB role switch > + * > + * Finds and returns role switch registered by @fwnode. The reference > +count > + * for the found switch is incremented. > + */ > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + struct usb_role_switch *sw; > + struct device *dev; > + > + dev = class_find_device(role_class, NULL, fwnode, > switch_fwnode_match); > + if (!dev) > + return ERR_PTR(-EPROBE_DEFER); > + > + sw = to_role_switch(dev); > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > + > + return sw; > +} > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > + > /** > * usb_role_switch_put - Release handle to a switch > * @sw: USB Role Switch > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > da2b9641b877..35d460f9ec40 100644 > --- a/include/linux/usb/role.h > +++ b/include/linux/usb/role.h > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > usb_role_switch *sw); struct usb_role_switch *c(struct > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > struct usb_role_switch * > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > +static inline struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + return ERR_PTR(-ENODEV); > +} > + > static inline struct usb_role_switch * > usb_role_switch_register(struct device *parent, > const struct usb_role_switch_desc *desc) > -- > 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 7:02 ` Biju Das 0 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 7:02 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Linus Walleij Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > by fwnode which register it. > It's useful when there is not device_connection registered between two > drivers and only knows the fwnode which register usb_role_switch. > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Tested-by: Biju Das <biju.das@bp.renesas.com> > --- > v4 changes: > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > 2. this patch now depends on [1] > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > https://patchwork.kernel.org/patch/10909971/ > > v3 changes: > 1. use fwnodes instead of node suggested by Andy > 2. rebuild the API suggested by Heikki > > v2 no changes > --- > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > include/linux/usb/role.h | 8 ++++++++ > 2 files changed, 33 insertions(+) > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > f45d8df5cfb8..994fcb979795 100644 > --- a/drivers/usb/roles/class.c > +++ b/drivers/usb/roles/class.c > @@ -12,6 +12,7 @@ > #include <linux/device.h> > #include <linux/module.h> > #include <linux/mutex.h> > +#include <linux/of.h> Is it required? > #include <linux/slab.h> > > static struct class *role_class; > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > +/** > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > +fwnode > + * @fwnode: The fwnode that register USB role switch > + * > + * Finds and returns role switch registered by @fwnode. The reference > +count > + * for the found switch is incremented. > + */ > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + struct usb_role_switch *sw; > + struct device *dev; > + > + dev = class_find_device(role_class, NULL, fwnode, > switch_fwnode_match); > + if (!dev) > + return ERR_PTR(-EPROBE_DEFER); > + > + sw = to_role_switch(dev); > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > + > + return sw; > +} > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > + > /** > * usb_role_switch_put - Release handle to a switch > * @sw: USB Role Switch > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > da2b9641b877..35d460f9ec40 100644 > --- a/include/linux/usb/role.h > +++ b/include/linux/usb/role.h > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > usb_role_switch *sw); struct usb_role_switch *c(struct > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > struct usb_role_switch * > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > +static inline struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + return ERR_PTR(-ENODEV); > +} > + > static inline struct usb_role_switch * > usb_role_switch_register(struct device *parent, > const struct usb_role_switch_desc *desc) > -- > 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 7:02 ` Biju Das 0 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 7:02 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Linus Walleij, linux-usb, linux-kernel, Badhri Jagan Sridharan, Andy Shevchenko, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > by fwnode which register it. > It's useful when there is not device_connection registered between two > drivers and only knows the fwnode which register usb_role_switch. > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Tested-by: Biju Das <biju.das@bp.renesas.com> > --- > v4 changes: > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > 2. this patch now depends on [1] > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > https://patchwork.kernel.org/patch/10909971/ > > v3 changes: > 1. use fwnodes instead of node suggested by Andy > 2. rebuild the API suggested by Heikki > > v2 no changes > --- > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > include/linux/usb/role.h | 8 ++++++++ > 2 files changed, 33 insertions(+) > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > f45d8df5cfb8..994fcb979795 100644 > --- a/drivers/usb/roles/class.c > +++ b/drivers/usb/roles/class.c > @@ -12,6 +12,7 @@ > #include <linux/device.h> > #include <linux/module.h> > #include <linux/mutex.h> > +#include <linux/of.h> Is it required? > #include <linux/slab.h> > > static struct class *role_class; > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > +/** > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > +fwnode > + * @fwnode: The fwnode that register USB role switch > + * > + * Finds and returns role switch registered by @fwnode. The reference > +count > + * for the found switch is incremented. > + */ > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + struct usb_role_switch *sw; > + struct device *dev; > + > + dev = class_find_device(role_class, NULL, fwnode, > switch_fwnode_match); > + if (!dev) > + return ERR_PTR(-EPROBE_DEFER); > + > + sw = to_role_switch(dev); > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > + > + return sw; > +} > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > + > /** > * usb_role_switch_put - Release handle to a switch > * @sw: USB Role Switch > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > da2b9641b877..35d460f9ec40 100644 > --- a/include/linux/usb/role.h > +++ b/include/linux/usb/role.h > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > usb_role_switch *sw); struct usb_role_switch *c(struct > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > +struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > struct usb_role_switch * > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > +static inline struct usb_role_switch * > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > + return ERR_PTR(-ENODEV); > +} > + > static inline struct usb_role_switch * > usb_role_switch_register(struct device *parent, > const struct usb_role_switch_desc *desc) > -- > 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node 2019-04-26 7:02 ` [PATCH v4 4/6] " Biju Das (?) (?) @ 2019-04-26 7:16 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 7:16 UTC (permalink / raw) To: Biju Das Cc: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Linus Walleij Hi Biju, On Fri, 2019-04-26 at 07:02 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > > by fwnode which register it. > > It's useful when there is not device_connection registered between two > > drivers and only knows the fwnode which register usb_role_switch. > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > Tested-by: Biju Das <biju.das@bp.renesas.com> > > --- > > v4 changes: > > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > > 2. this patch now depends on [1] > > > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > > https://patchwork.kernel.org/patch/10909971/ > > > > v3 changes: > > 1. use fwnodes instead of node suggested by Andy > > 2. rebuild the API suggested by Heikki > > > > v2 no changes > > --- > > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > > include/linux/usb/role.h | 8 ++++++++ > > 2 files changed, 33 insertions(+) > > > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > > f45d8df5cfb8..994fcb979795 100644 > > --- a/drivers/usb/roles/class.c > > +++ b/drivers/usb/roles/class.c > > @@ -12,6 +12,7 @@ > > #include <linux/device.h> > > #include <linux/module.h> > > #include <linux/mutex.h> > > +#include <linux/of.h> > > Is it required? Forgot to remove it after using fwnode instead of node, will remove it in next version Thanks a lot > > > #include <linux/slab.h> > > > > static struct class *role_class; > > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > > > +/** > > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > > +fwnode > > + * @fwnode: The fwnode that register USB role switch > > + * > > + * Finds and returns role switch registered by @fwnode. The reference > > +count > > + * for the found switch is incremented. > > + */ > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + struct usb_role_switch *sw; > > + struct device *dev; > > + > > + dev = class_find_device(role_class, NULL, fwnode, > > switch_fwnode_match); > > + if (!dev) > > + return ERR_PTR(-EPROBE_DEFER); > > + > > + sw = to_role_switch(dev); > > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > > + > > + return sw; > > +} > > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > > + > > /** > > * usb_role_switch_put - Release handle to a switch > > * @sw: USB Role Switch > > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > > da2b9641b877..35d460f9ec40 100644 > > --- a/include/linux/usb/role.h > > +++ b/include/linux/usb/role.h > > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > > usb_role_switch *sw); struct usb_role_switch *c(struct > > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > > > struct usb_role_switch * > > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > > > +static inline struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + return ERR_PTR(-ENODEV); > > +} > > + > > > static inline struct usb_role_switch * > > usb_role_switch_register(struct device *parent, > > const struct usb_role_switch_desc *desc) > > -- > > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 7:16 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 7:16 UTC (permalink / raw) To: Biju Das Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, Linus Walleij, linux-usb, linux-kernel, Badhri Jagan Sridharan, Andy Shevchenko, Rob Herring, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun Hi Biju, On Fri, 2019-04-26 at 07:02 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > > by fwnode which register it. > > It's useful when there is not device_connection registered between two > > drivers and only knows the fwnode which register usb_role_switch. > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > Tested-by: Biju Das <biju.das@bp.renesas.com> > > --- > > v4 changes: > > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > > 2. this patch now depends on [1] > > > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > > https://patchwork.kernel.org/patch/10909971/ > > > > v3 changes: > > 1. use fwnodes instead of node suggested by Andy > > 2. rebuild the API suggested by Heikki > > > > v2 no changes > > --- > > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > > include/linux/usb/role.h | 8 ++++++++ > > 2 files changed, 33 insertions(+) > > > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > > f45d8df5cfb8..994fcb979795 100644 > > --- a/drivers/usb/roles/class.c > > +++ b/drivers/usb/roles/class.c > > @@ -12,6 +12,7 @@ > > #include <linux/device.h> > > #include <linux/module.h> > > #include <linux/mutex.h> > > +#include <linux/of.h> > > Is it required? Forgot to remove it after using fwnode instead of node, will remove it in next version Thanks a lot > > > #include <linux/slab.h> > > > > static struct class *role_class; > > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > > > +/** > > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > > +fwnode > > + * @fwnode: The fwnode that register USB role switch > > + * > > + * Finds and returns role switch registered by @fwnode. The reference > > +count > > + * for the found switch is incremented. > > + */ > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + struct usb_role_switch *sw; > > + struct device *dev; > > + > > + dev = class_find_device(role_class, NULL, fwnode, > > switch_fwnode_match); > > + if (!dev) > > + return ERR_PTR(-EPROBE_DEFER); > > + > > + sw = to_role_switch(dev); > > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > > + > > + return sw; > > +} > > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > > + > > /** > > * usb_role_switch_put - Release handle to a switch > > * @sw: USB Role Switch > > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > > da2b9641b877..35d460f9ec40 100644 > > --- a/include/linux/usb/role.h > > +++ b/include/linux/usb/role.h > > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > > usb_role_switch *sw); struct usb_role_switch *c(struct > > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > > > struct usb_role_switch * > > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > > > +static inline struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + return ERR_PTR(-ENODEV); > > +} > > + > > > static inline struct usb_role_switch * > > usb_role_switch_register(struct device *parent, > > const struct usb_role_switch_desc *desc) > > -- > > 2.21.0 > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 7:16 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 7:16 UTC (permalink / raw) To: Biju Das Cc: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Linus Walleij Hi Biju, On Fri, 2019-04-26 at 07:02 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > > by fwnode which register it. > > It's useful when there is not device_connection registered between two > > drivers and only knows the fwnode which register usb_role_switch. > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > Tested-by: Biju Das <biju.das@bp.renesas.com> > > --- > > v4 changes: > > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > > 2. this patch now depends on [1] > > > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > > https://patchwork.kernel.org/patch/10909971/ > > > > v3 changes: > > 1. use fwnodes instead of node suggested by Andy > > 2. rebuild the API suggested by Heikki > > > > v2 no changes > > --- > > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > > include/linux/usb/role.h | 8 ++++++++ > > 2 files changed, 33 insertions(+) > > > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > > f45d8df5cfb8..994fcb979795 100644 > > --- a/drivers/usb/roles/class.c > > +++ b/drivers/usb/roles/class.c > > @@ -12,6 +12,7 @@ > > #include <linux/device.h> > > #include <linux/module.h> > > #include <linux/mutex.h> > > +#include <linux/of.h> > > Is it required? Forgot to remove it after using fwnode instead of node, will remove it in next version Thanks a lot > > > #include <linux/slab.h> > > > > static struct class *role_class; > > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > > > +/** > > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > > +fwnode > > + * @fwnode: The fwnode that register USB role switch > > + * > > + * Finds and returns role switch registered by @fwnode. The reference > > +count > > + * for the found switch is incremented. > > + */ > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + struct usb_role_switch *sw; > > + struct device *dev; > > + > > + dev = class_find_device(role_class, NULL, fwnode, > > switch_fwnode_match); > > + if (!dev) > > + return ERR_PTR(-EPROBE_DEFER); > > + > > + sw = to_role_switch(dev); > > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > > + > > + return sw; > > +} > > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > > + > > /** > > * usb_role_switch_put - Release handle to a switch > > * @sw: USB Role Switch > > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > > da2b9641b877..35d460f9ec40 100644 > > --- a/include/linux/usb/role.h > > +++ b/include/linux/usb/role.h > > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > > usb_role_switch *sw); struct usb_role_switch *c(struct > > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > > > struct usb_role_switch * > > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > > > +static inline struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + return ERR_PTR(-ENODEV); > > +} > > + > > > static inline struct usb_role_switch * > > usb_role_switch_register(struct device *parent, > > const struct usb_role_switch_desc *desc) > > -- > > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node @ 2019-04-26 7:16 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 7:16 UTC (permalink / raw) To: Biju Das Cc: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek@lists.infradead.org Hi Biju, On Fri, 2019-04-26 at 07:02 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node > > > > Add fwnode_usb_role_switch_get() to make easier to get usb_role_switch > > by fwnode which register it. > > It's useful when there is not device_connection registered between two > > drivers and only knows the fwnode which register usb_role_switch. > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > Tested-by: Biju Das <biju.das@bp.renesas.com> > > --- > > v4 changes: > > 1. use switch_fwnode_match() to find fwnode suggested by Heikki > > 2. this patch now depends on [1] > > > > [1] [v6,08/13] usb: roles: Introduce stubs for the exiting functions in role.h > > https://patchwork.kernel.org/patch/10909971/ > > > > v3 changes: > > 1. use fwnodes instead of node suggested by Andy > > 2. rebuild the API suggested by Heikki > > > > v2 no changes > > --- > > drivers/usb/roles/class.c | 25 +++++++++++++++++++++++++ > > include/linux/usb/role.h | 8 ++++++++ > > 2 files changed, 33 insertions(+) > > > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index > > f45d8df5cfb8..994fcb979795 100644 > > --- a/drivers/usb/roles/class.c > > +++ b/drivers/usb/roles/class.c > > @@ -12,6 +12,7 @@ > > #include <linux/device.h> > > #include <linux/module.h> > > #include <linux/mutex.h> > > +#include <linux/of.h> > > Is it required? Forgot to remove it after using fwnode instead of node, will remove it in next version Thanks a lot > > > #include <linux/slab.h> > > > > static struct class *role_class; > > @@ -135,6 +136,30 @@ struct usb_role_switch *usb_role_switch_get(struct > > device *dev) } EXPORT_SYMBOL_GPL(usb_role_switch_get); > > > > +/** > > + * fwnode_usb_role_switch_get - Find USB role switch by it's parent > > +fwnode > > + * @fwnode: The fwnode that register USB role switch > > + * > > + * Finds and returns role switch registered by @fwnode. The reference > > +count > > + * for the found switch is incremented. > > + */ > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + struct usb_role_switch *sw; > > + struct device *dev; > > + > > + dev = class_find_device(role_class, NULL, fwnode, > > switch_fwnode_match); > > + if (!dev) > > + return ERR_PTR(-EPROBE_DEFER); > > + > > + sw = to_role_switch(dev); > > + WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); > > + > > + return sw; > > +} > > +EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get); > > + > > /** > > * usb_role_switch_put - Release handle to a switch > > * @sw: USB Role Switch > > diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h index > > da2b9641b877..35d460f9ec40 100644 > > --- a/include/linux/usb/role.h > > +++ b/include/linux/usb/role.h > > @@ -48,6 +48,8 @@ int usb_role_switch_set_role(struct usb_role_switch > > *sw, enum usb_role role); enum usb_role usb_role_switch_get_role(struct > > usb_role_switch *sw); struct usb_role_switch *c(struct > > device *dev); void usb_role_switch_put(struct usb_role_switch *sw); > > +struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode); > > > struct usb_role_switch * > > usb_role_switch_register(struct device *parent, @@ -72,6 +74,12 @@ static > > inline struct usb_role_switch *usb_role_switch_get(struct device *dev) > > > > static inline void usb_role_switch_put(struct usb_role_switch *sw) { } > > > > +static inline struct usb_role_switch * > > +fwnode_usb_role_switch_get(struct fwnode_handle *fwnode) { > > + return ERR_PTR(-ENODEV); > > +} > > + > > > static inline struct usb_role_switch * > > usb_role_switch_register(struct device *parent, > > const struct usb_role_switch_desc *desc) > > -- > > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver 2019-04-26 6:47 ` Chunfeng Yun (?) (?) @ 2019-04-26 6:47 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Due to the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated when use Type-B connector. This patch introduces a driver of Type-B connector which typically uses an input GPIO to detect USB ID pin, and try to replace the function provided by extcon-usb-gpio driver Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. remove linux/gpio.h suggested by Linus 2. put node when error happens v3 changes: 1. treat bype-B connector as a virtual device; 2. change file name again v2 changes: 1. file name is changed 2. use new compatible --- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 drivers/usb/roles/typeb-conn-gpio.c diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index f8b31aa67526..d1156e18a81a 100644 --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI To compile the driver as a module, choose M here: the module will be called intel-xhci-usb-role-switch. +config TYPEB_CONN_GPIO + tristate "USB Type-B GPIO Connector" + depends on GPIOLIB + help + The driver supports USB role switch between host and device via GPIO + based USB cable detection, used typically if an input GPIO is used + to detect USB ID pin. + + To compile the driver as a module, choose M here: the module will + be called typeb-conn-gpio.ko + endif # USB_ROLE_SWITCH diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index 757a7d2797eb..5d5620d9d113 100644 --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o roles-y := class.o obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb-conn-gpio.c new file mode 100644 index 000000000000..097d2ca12a12 --- /dev/null +++ b/drivers/usb/roles/typeb-conn-gpio.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * USB Type-B GPIO Connector Driver + * + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> + * + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c + */ + +#include <linux/device.h> +#include <linux/gpio/consumer.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/usb/role.h> + +#define USB_GPIO_DEB_MS 20 /* ms */ +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ + +#define USB_CONN_IRQF \ + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT) + +struct usb_conn_info { + struct device *dev; + struct usb_role_switch *role_sw; + enum usb_role last_role; + struct regulator *vbus; + struct delayed_work dw_det; + unsigned long debounce_jiffies; + + struct gpio_desc *id_gpiod; + struct gpio_desc *vbus_gpiod; + int id_irq; + int vbus_irq; +}; + +/** + * "DEVICE" = VBUS and "HOST" = !ID, so we have: + * Both "DEVICE" and "HOST" can't be set as active at the same time + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive + * even if VBUS is on. + * + * Role | ID | VBUS + * ------------------------------------ + * [1] DEVICE | H | H + * [2] NONE | H | L + * [3] HOST | L | H + * [4] HOST | L | L + * + * In case we have only one of these signals: + * - VBUS only - we want to distinguish between [1] and [2], so ID is always 1 + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID + */ +static void usb_conn_detect_cable(struct work_struct *work) +{ + struct usb_conn_info *info; + enum usb_role role; + int id, vbus, ret; + + info = container_of(to_delayed_work(work), + struct usb_conn_info, dw_det); + + /* check ID and VBUS */ + id = info->id_gpiod ? + gpiod_get_value_cansleep(info->id_gpiod) : 1; + vbus = info->vbus_gpiod ? + gpiod_get_value_cansleep(info->vbus_gpiod) : id; + + if (!id) + role = USB_ROLE_HOST; + else if (vbus) + role = USB_ROLE_DEVICE; + else + role = USB_ROLE_NONE; + + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", + info->last_role, role, id, vbus); + + if (info->last_role == role) { + dev_warn(info->dev, "repeated role: %d\n", role); + return; + } + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + ret = usb_role_switch_set_role(info->role_sw, role); + if (ret) + dev_err(info->dev, "failed to set role: %d\n", ret); + + if (role == USB_ROLE_HOST) { + ret = regulator_enable(info->vbus); + if (ret) + dev_err(info->dev, "enable vbus regulator failed\n"); + } + + info->last_role = role; + + dev_dbg(info->dev, "vbus regulator is %s\n", + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); +} + +static void usb_conn_queue_dwork(struct usb_conn_info *info, + unsigned long delay) +{ + queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay); +} + +static irqreturn_t usb_conn_isr(int irq, void *dev_id) +{ + struct usb_conn_info *info = dev_id; + + usb_conn_queue_dwork(info, info->debounce_jiffies); + + return IRQ_HANDLED; +} + +static int usb_conn_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *parent; + struct device_node *child; + struct usb_conn_info *info; + int ret = 0; + + if (!np) + return -EINVAL; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = dev; + + child = of_get_child_by_name(np, "connector"); + if (!child) { + dev_err(dev, "failed to find connector node\n"); + return -ENODEV; + } + + info->id_gpiod = devm_gpiod_get_from_of_node( + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); + if (IS_ERR(info->id_gpiod)) { + of_node_put(child); + return PTR_ERR(info->id_gpiod); + } + + info->vbus_gpiod = devm_gpiod_get_from_of_node( + dev, child, "vbus-gpios", 0, GPIOD_IN, + "vbuspin"); + if (IS_ERR(info->vbus_gpiod)) { + of_node_put(child); + return PTR_ERR(info->vbus_gpiod); + } + + if (!info->id_gpiod && !info->vbus_gpiod) { + dev_err(dev, "failed to get gpios\n"); + return -ENODEV; + } + + of_node_put(child); + + if (info->id_gpiod) + ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEB_US); + if (!ret && info->vbus_gpiod) + ret = gpiod_set_debounce(info->vbus_gpiod, USB_GPIO_DEB_US); + if (ret < 0) + info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEB_MS); + + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); + + info->vbus = devm_regulator_get(dev, "vbus"); + if (IS_ERR(info->vbus)) { + dev_err(dev, "failed to get vbus\n"); + return PTR_ERR(info->vbus); + } + + child = of_graph_get_endpoint_by_regs(np, -1, 0); + parent = of_graph_get_remote_port_parent(child); + info->role_sw = fwnode_usb_role_switch_get(of_fwnode_handle(parent)); + of_node_put(child); + of_node_put(parent); + if (IS_ERR(info->role_sw)) { + dev_err(dev, "failed to get role switch\n"); + return PTR_ERR(info->role_sw); + } + + if (info->id_gpiod) { + info->id_irq = gpiod_to_irq(info->id_gpiod); + if (info->id_irq < 0) { + dev_err(dev, "failed to get ID IRQ\n"); + return info->id_irq; + } + + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request ID IRQ\n"); + return ret; + } + } + + if (info->vbus_gpiod) { + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); + if (info->vbus_irq < 0) { + dev_err(dev, "failed to get VBUS IRQ\n"); + return info->vbus_irq; + } + + ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request VBUS IRQ\n"); + return ret; + } + } + + platform_set_drvdata(pdev, info); + + /* Perform initial detection */ + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static int usb_conn_remove(struct platform_device *pdev) +{ + struct usb_conn_info *info = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&info->dw_det); + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + usb_role_switch_put(info->role_sw); + + return 0; +} + +static int __maybe_unused usb_conn_suspend(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + if (info->id_gpiod) + disable_irq(info->id_irq); + if (info->vbus_gpiod) + disable_irq(info->vbus_irq); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int __maybe_unused usb_conn_resume(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + pinctrl_pm_select_default_state(dev); + + if (info->id_gpiod) + enable_irq(info->id_irq); + if (info->vbus_gpiod) + enable_irq(info->vbus_irq); + + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, + usb_conn_suspend, usb_conn_resume); + +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? &usb_conn_pm_ops : NULL) + +static const struct of_device_id usb_conn_dt_match[] = { + { .compatible = "linux,typeb-conn-gpio", }, + { } +}; +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); + +static struct platform_driver usb_conn_driver = { + .probe = usb_conn_probe, + .remove = usb_conn_remove, + .driver = { + .name = "typeb-conn-gpio", + .pm = DEV_PMS_OPS, + .of_match_table = usb_conn_dt_match, + }, +}; + +module_platform_driver(usb_conn_driver); + +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); +MODULE_LICENSE("GPL v2"); -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun Due to the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated when use Type-B connector. This patch introduces a driver of Type-B connector which typically uses an input GPIO to detect USB ID pin, and try to replace the function provided by extcon-usb-gpio driver Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. remove linux/gpio.h suggested by Linus 2. put node when error happens v3 changes: 1. treat bype-B connector as a virtual device; 2. change file name again v2 changes: 1. file name is changed 2. use new compatible --- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 drivers/usb/roles/typeb-conn-gpio.c diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index f8b31aa67526..d1156e18a81a 100644 --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI To compile the driver as a module, choose M here: the module will be called intel-xhci-usb-role-switch. +config TYPEB_CONN_GPIO + tristate "USB Type-B GPIO Connector" + depends on GPIOLIB + help + The driver supports USB role switch between host and device via GPIO + based USB cable detection, used typically if an input GPIO is used + to detect USB ID pin. + + To compile the driver as a module, choose M here: the module will + be called typeb-conn-gpio.ko + endif # USB_ROLE_SWITCH diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index 757a7d2797eb..5d5620d9d113 100644 --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o roles-y := class.o obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb-conn-gpio.c new file mode 100644 index 000000000000..097d2ca12a12 --- /dev/null +++ b/drivers/usb/roles/typeb-conn-gpio.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * USB Type-B GPIO Connector Driver + * + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> + * + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c + */ + +#include <linux/device.h> +#include <linux/gpio/consumer.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/usb/role.h> + +#define USB_GPIO_DEB_MS 20 /* ms */ +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ + +#define USB_CONN_IRQF \ + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT) + +struct usb_conn_info { + struct device *dev; + struct usb_role_switch *role_sw; + enum usb_role last_role; + struct regulator *vbus; + struct delayed_work dw_det; + unsigned long debounce_jiffies; + + struct gpio_desc *id_gpiod; + struct gpio_desc *vbus_gpiod; + int id_irq; + int vbus_irq; +}; + +/** + * "DEVICE" = VBUS and "HOST" = !ID, so we have: + * Both "DEVICE" and "HOST" can't be set as active at the same time + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive + * even if VBUS is on. + * + * Role | ID | VBUS + * ------------------------------------ + * [1] DEVICE | H | H + * [2] NONE | H | L + * [3] HOST | L | H + * [4] HOST | L | L + * + * In case we have only one of these signals: + * - VBUS only - we want to distinguish between [1] and [2], so ID is always 1 + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID + */ +static void usb_conn_detect_cable(struct work_struct *work) +{ + struct usb_conn_info *info; + enum usb_role role; + int id, vbus, ret; + + info = container_of(to_delayed_work(work), + struct usb_conn_info, dw_det); + + /* check ID and VBUS */ + id = info->id_gpiod ? + gpiod_get_value_cansleep(info->id_gpiod) : 1; + vbus = info->vbus_gpiod ? + gpiod_get_value_cansleep(info->vbus_gpiod) : id; + + if (!id) + role = USB_ROLE_HOST; + else if (vbus) + role = USB_ROLE_DEVICE; + else + role = USB_ROLE_NONE; + + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", + info->last_role, role, id, vbus); + + if (info->last_role == role) { + dev_warn(info->dev, "repeated role: %d\n", role); + return; + } + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + ret = usb_role_switch_set_role(info->role_sw, role); + if (ret) + dev_err(info->dev, "failed to set role: %d\n", ret); + + if (role == USB_ROLE_HOST) { + ret = regulator_enable(info->vbus); + if (ret) + dev_err(info->dev, "enable vbus regulator failed\n"); + } + + info->last_role = role; + + dev_dbg(info->dev, "vbus regulator is %s\n", + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); +} + +static void usb_conn_queue_dwork(struct usb_conn_info *info, + unsigned long delay) +{ + queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay); +} + +static irqreturn_t usb_conn_isr(int irq, void *dev_id) +{ + struct usb_conn_info *info = dev_id; + + usb_conn_queue_dwork(info, info->debounce_jiffies); + + return IRQ_HANDLED; +} + +static int usb_conn_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *parent; + struct device_node *child; + struct usb_conn_info *info; + int ret = 0; + + if (!np) + return -EINVAL; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = dev; + + child = of_get_child_by_name(np, "connector"); + if (!child) { + dev_err(dev, "failed to find connector node\n"); + return -ENODEV; + } + + info->id_gpiod = devm_gpiod_get_from_of_node( + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); + if (IS_ERR(info->id_gpiod)) { + of_node_put(child); + return PTR_ERR(info->id_gpiod); + } + + info->vbus_gpiod = devm_gpiod_get_from_of_node( + dev, child, "vbus-gpios", 0, GPIOD_IN, + "vbuspin"); + if (IS_ERR(info->vbus_gpiod)) { + of_node_put(child); + return PTR_ERR(info->vbus_gpiod); + } + + if (!info->id_gpiod && !info->vbus_gpiod) { + dev_err(dev, "failed to get gpios\n"); + return -ENODEV; + } + + of_node_put(child); + + if (info->id_gpiod) + ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEB_US); + if (!ret && info->vbus_gpiod) + ret = gpiod_set_debounce(info->vbus_gpiod, USB_GPIO_DEB_US); + if (ret < 0) + info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEB_MS); + + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); + + info->vbus = devm_regulator_get(dev, "vbus"); + if (IS_ERR(info->vbus)) { + dev_err(dev, "failed to get vbus\n"); + return PTR_ERR(info->vbus); + } + + child = of_graph_get_endpoint_by_regs(np, -1, 0); + parent = of_graph_get_remote_port_parent(child); + info->role_sw = fwnode_usb_role_switch_get(of_fwnode_handle(parent)); + of_node_put(child); + of_node_put(parent); + if (IS_ERR(info->role_sw)) { + dev_err(dev, "failed to get role switch\n"); + return PTR_ERR(info->role_sw); + } + + if (info->id_gpiod) { + info->id_irq = gpiod_to_irq(info->id_gpiod); + if (info->id_irq < 0) { + dev_err(dev, "failed to get ID IRQ\n"); + return info->id_irq; + } + + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request ID IRQ\n"); + return ret; + } + } + + if (info->vbus_gpiod) { + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); + if (info->vbus_irq < 0) { + dev_err(dev, "failed to get VBUS IRQ\n"); + return info->vbus_irq; + } + + ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request VBUS IRQ\n"); + return ret; + } + } + + platform_set_drvdata(pdev, info); + + /* Perform initial detection */ + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static int usb_conn_remove(struct platform_device *pdev) +{ + struct usb_conn_info *info = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&info->dw_det); + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + usb_role_switch_put(info->role_sw); + + return 0; +} + +static int __maybe_unused usb_conn_suspend(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + if (info->id_gpiod) + disable_irq(info->id_irq); + if (info->vbus_gpiod) + disable_irq(info->vbus_irq); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int __maybe_unused usb_conn_resume(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + pinctrl_pm_select_default_state(dev); + + if (info->id_gpiod) + enable_irq(info->id_irq); + if (info->vbus_gpiod) + enable_irq(info->vbus_irq); + + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, + usb_conn_suspend, usb_conn_resume); + +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? &usb_conn_pm_ops : NULL) + +static const struct of_device_id usb_conn_dt_match[] = { + { .compatible = "linux,typeb-conn-gpio", }, + { } +}; +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); + +static struct platform_driver usb_conn_driver = { + .probe = usb_conn_probe, + .remove = usb_conn_remove, + .driver = { + .name = "typeb-conn-gpio", + .pm = DEV_PMS_OPS, + .of_match_table = usb_conn_dt_match, + }, +}; + +module_platform_driver(usb_conn_driver); + +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); +MODULE_LICENSE("GPL v2"); -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [v4,5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Due to the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated when use Type-B connector. This patch introduces a driver of Type-B connector which typically uses an input GPIO to detect USB ID pin, and try to replace the function provided by extcon-usb-gpio driver Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. remove linux/gpio.h suggested by Linus 2. put node when error happens v3 changes: 1. treat bype-B connector as a virtual device; 2. change file name again v2 changes: 1. file name is changed 2. use new compatible --- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 drivers/usb/roles/typeb-conn-gpio.c diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index f8b31aa67526..d1156e18a81a 100644 --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI To compile the driver as a module, choose M here: the module will be called intel-xhci-usb-role-switch. +config TYPEB_CONN_GPIO + tristate "USB Type-B GPIO Connector" + depends on GPIOLIB + help + The driver supports USB role switch between host and device via GPIO + based USB cable detection, used typically if an input GPIO is used + to detect USB ID pin. + + To compile the driver as a module, choose M here: the module will + be called typeb-conn-gpio.ko + endif # USB_ROLE_SWITCH diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index 757a7d2797eb..5d5620d9d113 100644 --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o roles-y := class.o obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb-conn-gpio.c new file mode 100644 index 000000000000..097d2ca12a12 --- /dev/null +++ b/drivers/usb/roles/typeb-conn-gpio.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * USB Type-B GPIO Connector Driver + * + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> + * + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c + */ + +#include <linux/device.h> +#include <linux/gpio/consumer.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/usb/role.h> + +#define USB_GPIO_DEB_MS 20 /* ms */ +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ + +#define USB_CONN_IRQF \ + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT) + +struct usb_conn_info { + struct device *dev; + struct usb_role_switch *role_sw; + enum usb_role last_role; + struct regulator *vbus; + struct delayed_work dw_det; + unsigned long debounce_jiffies; + + struct gpio_desc *id_gpiod; + struct gpio_desc *vbus_gpiod; + int id_irq; + int vbus_irq; +}; + +/** + * "DEVICE" = VBUS and "HOST" = !ID, so we have: + * Both "DEVICE" and "HOST" can't be set as active at the same time + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive + * even if VBUS is on. + * + * Role | ID | VBUS + * ------------------------------------ + * [1] DEVICE | H | H + * [2] NONE | H | L + * [3] HOST | L | H + * [4] HOST | L | L + * + * In case we have only one of these signals: + * - VBUS only - we want to distinguish between [1] and [2], so ID is always 1 + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID + */ +static void usb_conn_detect_cable(struct work_struct *work) +{ + struct usb_conn_info *info; + enum usb_role role; + int id, vbus, ret; + + info = container_of(to_delayed_work(work), + struct usb_conn_info, dw_det); + + /* check ID and VBUS */ + id = info->id_gpiod ? + gpiod_get_value_cansleep(info->id_gpiod) : 1; + vbus = info->vbus_gpiod ? + gpiod_get_value_cansleep(info->vbus_gpiod) : id; + + if (!id) + role = USB_ROLE_HOST; + else if (vbus) + role = USB_ROLE_DEVICE; + else + role = USB_ROLE_NONE; + + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", + info->last_role, role, id, vbus); + + if (info->last_role == role) { + dev_warn(info->dev, "repeated role: %d\n", role); + return; + } + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + ret = usb_role_switch_set_role(info->role_sw, role); + if (ret) + dev_err(info->dev, "failed to set role: %d\n", ret); + + if (role == USB_ROLE_HOST) { + ret = regulator_enable(info->vbus); + if (ret) + dev_err(info->dev, "enable vbus regulator failed\n"); + } + + info->last_role = role; + + dev_dbg(info->dev, "vbus regulator is %s\n", + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); +} + +static void usb_conn_queue_dwork(struct usb_conn_info *info, + unsigned long delay) +{ + queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay); +} + +static irqreturn_t usb_conn_isr(int irq, void *dev_id) +{ + struct usb_conn_info *info = dev_id; + + usb_conn_queue_dwork(info, info->debounce_jiffies); + + return IRQ_HANDLED; +} + +static int usb_conn_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *parent; + struct device_node *child; + struct usb_conn_info *info; + int ret = 0; + + if (!np) + return -EINVAL; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = dev; + + child = of_get_child_by_name(np, "connector"); + if (!child) { + dev_err(dev, "failed to find connector node\n"); + return -ENODEV; + } + + info->id_gpiod = devm_gpiod_get_from_of_node( + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); + if (IS_ERR(info->id_gpiod)) { + of_node_put(child); + return PTR_ERR(info->id_gpiod); + } + + info->vbus_gpiod = devm_gpiod_get_from_of_node( + dev, child, "vbus-gpios", 0, GPIOD_IN, + "vbuspin"); + if (IS_ERR(info->vbus_gpiod)) { + of_node_put(child); + return PTR_ERR(info->vbus_gpiod); + } + + if (!info->id_gpiod && !info->vbus_gpiod) { + dev_err(dev, "failed to get gpios\n"); + return -ENODEV; + } + + of_node_put(child); + + if (info->id_gpiod) + ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEB_US); + if (!ret && info->vbus_gpiod) + ret = gpiod_set_debounce(info->vbus_gpiod, USB_GPIO_DEB_US); + if (ret < 0) + info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEB_MS); + + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); + + info->vbus = devm_regulator_get(dev, "vbus"); + if (IS_ERR(info->vbus)) { + dev_err(dev, "failed to get vbus\n"); + return PTR_ERR(info->vbus); + } + + child = of_graph_get_endpoint_by_regs(np, -1, 0); + parent = of_graph_get_remote_port_parent(child); + info->role_sw = fwnode_usb_role_switch_get(of_fwnode_handle(parent)); + of_node_put(child); + of_node_put(parent); + if (IS_ERR(info->role_sw)) { + dev_err(dev, "failed to get role switch\n"); + return PTR_ERR(info->role_sw); + } + + if (info->id_gpiod) { + info->id_irq = gpiod_to_irq(info->id_gpiod); + if (info->id_irq < 0) { + dev_err(dev, "failed to get ID IRQ\n"); + return info->id_irq; + } + + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request ID IRQ\n"); + return ret; + } + } + + if (info->vbus_gpiod) { + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); + if (info->vbus_irq < 0) { + dev_err(dev, "failed to get VBUS IRQ\n"); + return info->vbus_irq; + } + + ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request VBUS IRQ\n"); + return ret; + } + } + + platform_set_drvdata(pdev, info); + + /* Perform initial detection */ + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static int usb_conn_remove(struct platform_device *pdev) +{ + struct usb_conn_info *info = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&info->dw_det); + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + usb_role_switch_put(info->role_sw); + + return 0; +} + +static int __maybe_unused usb_conn_suspend(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + if (info->id_gpiod) + disable_irq(info->id_irq); + if (info->vbus_gpiod) + disable_irq(info->vbus_irq); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int __maybe_unused usb_conn_resume(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + pinctrl_pm_select_default_state(dev); + + if (info->id_gpiod) + enable_irq(info->id_irq); + if (info->vbus_gpiod) + enable_irq(info->vbus_irq); + + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, + usb_conn_suspend, usb_conn_resume); + +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? &usb_conn_pm_ops : NULL) + +static const struct of_device_id usb_conn_dt_match[] = { + { .compatible = "linux,typeb-conn-gpio", }, + { } +}; +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); + +static struct platform_driver usb_conn_driver = { + .probe = usb_conn_probe, + .remove = usb_conn_remove, + .driver = { + .name = "typeb-conn-gpio", + .pm = DEV_PMS_OPS, + .of_match_table = usb_conn_dt_match, + }, +}; + +module_platform_driver(usb_conn_driver); + +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); +MODULE_LICENSE("GPL v2"); ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Due to the requirement of usb-connector.txt binding, the old way using extcon to support USB Dual-Role switch is now deprecated when use Type-B connector. This patch introduces a driver of Type-B connector which typically uses an input GPIO to detect USB ID pin, and try to replace the function provided by extcon-usb-gpio driver Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. remove linux/gpio.h suggested by Linus 2. put node when error happens v3 changes: 1. treat bype-B connector as a virtual device; 2. change file name again v2 changes: 1. file name is changed 2. use new compatible --- drivers/usb/roles/Kconfig | 11 + drivers/usb/roles/Makefile | 1 + drivers/usb/roles/typeb-conn-gpio.c | 305 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 drivers/usb/roles/typeb-conn-gpio.c diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index f8b31aa67526..d1156e18a81a 100644 --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI To compile the driver as a module, choose M here: the module will be called intel-xhci-usb-role-switch. +config TYPEB_CONN_GPIO + tristate "USB Type-B GPIO Connector" + depends on GPIOLIB + help + The driver supports USB role switch between host and device via GPIO + based USB cable detection, used typically if an input GPIO is used + to detect USB ID pin. + + To compile the driver as a module, choose M here: the module will + be called typeb-conn-gpio.ko + endif # USB_ROLE_SWITCH diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index 757a7d2797eb..5d5620d9d113 100644 --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o roles-y := class.o obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb-conn-gpio.c new file mode 100644 index 000000000000..097d2ca12a12 --- /dev/null +++ b/drivers/usb/roles/typeb-conn-gpio.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * USB Type-B GPIO Connector Driver + * + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> + * + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c + */ + +#include <linux/device.h> +#include <linux/gpio/consumer.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/usb/role.h> + +#define USB_GPIO_DEB_MS 20 /* ms */ +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ + +#define USB_CONN_IRQF \ + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT) + +struct usb_conn_info { + struct device *dev; + struct usb_role_switch *role_sw; + enum usb_role last_role; + struct regulator *vbus; + struct delayed_work dw_det; + unsigned long debounce_jiffies; + + struct gpio_desc *id_gpiod; + struct gpio_desc *vbus_gpiod; + int id_irq; + int vbus_irq; +}; + +/** + * "DEVICE" = VBUS and "HOST" = !ID, so we have: + * Both "DEVICE" and "HOST" can't be set as active at the same time + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive + * even if VBUS is on. + * + * Role | ID | VBUS + * ------------------------------------ + * [1] DEVICE | H | H + * [2] NONE | H | L + * [3] HOST | L | H + * [4] HOST | L | L + * + * In case we have only one of these signals: + * - VBUS only - we want to distinguish between [1] and [2], so ID is always 1 + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID + */ +static void usb_conn_detect_cable(struct work_struct *work) +{ + struct usb_conn_info *info; + enum usb_role role; + int id, vbus, ret; + + info = container_of(to_delayed_work(work), + struct usb_conn_info, dw_det); + + /* check ID and VBUS */ + id = info->id_gpiod ? + gpiod_get_value_cansleep(info->id_gpiod) : 1; + vbus = info->vbus_gpiod ? + gpiod_get_value_cansleep(info->vbus_gpiod) : id; + + if (!id) + role = USB_ROLE_HOST; + else if (vbus) + role = USB_ROLE_DEVICE; + else + role = USB_ROLE_NONE; + + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", + info->last_role, role, id, vbus); + + if (info->last_role == role) { + dev_warn(info->dev, "repeated role: %d\n", role); + return; + } + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + ret = usb_role_switch_set_role(info->role_sw, role); + if (ret) + dev_err(info->dev, "failed to set role: %d\n", ret); + + if (role == USB_ROLE_HOST) { + ret = regulator_enable(info->vbus); + if (ret) + dev_err(info->dev, "enable vbus regulator failed\n"); + } + + info->last_role = role; + + dev_dbg(info->dev, "vbus regulator is %s\n", + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); +} + +static void usb_conn_queue_dwork(struct usb_conn_info *info, + unsigned long delay) +{ + queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay); +} + +static irqreturn_t usb_conn_isr(int irq, void *dev_id) +{ + struct usb_conn_info *info = dev_id; + + usb_conn_queue_dwork(info, info->debounce_jiffies); + + return IRQ_HANDLED; +} + +static int usb_conn_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct device_node *parent; + struct device_node *child; + struct usb_conn_info *info; + int ret = 0; + + if (!np) + return -EINVAL; + + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = dev; + + child = of_get_child_by_name(np, "connector"); + if (!child) { + dev_err(dev, "failed to find connector node\n"); + return -ENODEV; + } + + info->id_gpiod = devm_gpiod_get_from_of_node( + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); + if (IS_ERR(info->id_gpiod)) { + of_node_put(child); + return PTR_ERR(info->id_gpiod); + } + + info->vbus_gpiod = devm_gpiod_get_from_of_node( + dev, child, "vbus-gpios", 0, GPIOD_IN, + "vbuspin"); + if (IS_ERR(info->vbus_gpiod)) { + of_node_put(child); + return PTR_ERR(info->vbus_gpiod); + } + + if (!info->id_gpiod && !info->vbus_gpiod) { + dev_err(dev, "failed to get gpios\n"); + return -ENODEV; + } + + of_node_put(child); + + if (info->id_gpiod) + ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEB_US); + if (!ret && info->vbus_gpiod) + ret = gpiod_set_debounce(info->vbus_gpiod, USB_GPIO_DEB_US); + if (ret < 0) + info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEB_MS); + + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); + + info->vbus = devm_regulator_get(dev, "vbus"); + if (IS_ERR(info->vbus)) { + dev_err(dev, "failed to get vbus\n"); + return PTR_ERR(info->vbus); + } + + child = of_graph_get_endpoint_by_regs(np, -1, 0); + parent = of_graph_get_remote_port_parent(child); + info->role_sw = fwnode_usb_role_switch_get(of_fwnode_handle(parent)); + of_node_put(child); + of_node_put(parent); + if (IS_ERR(info->role_sw)) { + dev_err(dev, "failed to get role switch\n"); + return PTR_ERR(info->role_sw); + } + + if (info->id_gpiod) { + info->id_irq = gpiod_to_irq(info->id_gpiod); + if (info->id_irq < 0) { + dev_err(dev, "failed to get ID IRQ\n"); + return info->id_irq; + } + + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request ID IRQ\n"); + return ret; + } + } + + if (info->vbus_gpiod) { + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); + if (info->vbus_irq < 0) { + dev_err(dev, "failed to get VBUS IRQ\n"); + return info->vbus_irq; + } + + ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL, + usb_conn_isr, USB_CONN_IRQF, + pdev->name, info); + if (ret < 0) { + dev_err(dev, "failed to request VBUS IRQ\n"); + return ret; + } + } + + platform_set_drvdata(pdev, info); + + /* Perform initial detection */ + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static int usb_conn_remove(struct platform_device *pdev) +{ + struct usb_conn_info *info = platform_get_drvdata(pdev); + + cancel_delayed_work_sync(&info->dw_det); + + if (info->last_role == USB_ROLE_HOST) + regulator_disable(info->vbus); + + usb_role_switch_put(info->role_sw); + + return 0; +} + +static int __maybe_unused usb_conn_suspend(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + if (info->id_gpiod) + disable_irq(info->id_irq); + if (info->vbus_gpiod) + disable_irq(info->vbus_irq); + + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int __maybe_unused usb_conn_resume(struct device *dev) +{ + struct usb_conn_info *info = dev_get_drvdata(dev); + + pinctrl_pm_select_default_state(dev); + + if (info->id_gpiod) + enable_irq(info->id_irq); + if (info->vbus_gpiod) + enable_irq(info->vbus_irq); + + usb_conn_queue_dwork(info, 0); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, + usb_conn_suspend, usb_conn_resume); + +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? &usb_conn_pm_ops : NULL) + +static const struct of_device_id usb_conn_dt_match[] = { + { .compatible = "linux,typeb-conn-gpio", }, + { } +}; +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); + +static struct platform_driver usb_conn_driver = { + .probe = usb_conn_probe, + .remove = usb_conn_remove, + .driver = { + .name = "typeb-conn-gpio", + .pm = DEV_PMS_OPS, + .of_match_table = usb_conn_dt_match, + }, +}; + +module_platform_driver(usb_conn_driver); + +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); +MODULE_LICENSE("GPL v2"); -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* RE: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver 2019-04-26 6:47 ` [PATCH v4 5/6] " Chunfeng Yun (?) (?) @ 2019-04-26 9:22 ` Biju Das -1 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 9:22 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Linus Walleij Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > Due to the requirement of usb-connector.txt binding, the old way using > extcon to support USB Dual-Role switch is now deprecated when use Type-B > connector. > This patch introduces a driver of Type-B connector which typically uses an > input GPIO to detect USB ID pin, and try to replace the function provided by > extcon-usb-gpio driver > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 changes: > 1. remove linux/gpio.h suggested by Linus > 2. put node when error happens > > v3 changes: > 1. treat bype-B connector as a virtual device; > 2. change file name again > > v2 changes: > 1. file name is changed > 2. use new compatible > --- > drivers/usb/roles/Kconfig | 11 + > drivers/usb/roles/Makefile | 1 + > drivers/usb/roles/typeb-conn-gpio.c | 305 > ++++++++++++++++++++++++++++ > 3 files changed, 317 insertions(+) > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > f8b31aa67526..d1156e18a81a 100644 > --- a/drivers/usb/roles/Kconfig > +++ b/drivers/usb/roles/Kconfig > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > To compile the driver as a module, choose M here: the module will > be called intel-xhci-usb-role-switch. > > +config TYPEB_CONN_GPIO > + tristate "USB Type-B GPIO Connector" > + depends on GPIOLIB > + help > + The driver supports USB role switch between host and device via > GPIO > + based USB cable detection, used typically if an input GPIO is used > + to detect USB ID pin. > + > + To compile the driver as a module, choose M here: the module will > + be called typeb-conn-gpio.ko > + > endif # USB_ROLE_SWITCH > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > 757a7d2797eb..5d5620d9d113 100644 > --- a/drivers/usb/roles/Makefile > +++ b/drivers/usb/roles/Makefile > @@ -3,3 +3,4 @@ > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > roles-y := class.o > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > switch.o > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > conn-gpio.c > new file mode 100644 > index 000000000000..097d2ca12a12 > --- /dev/null > +++ b/drivers/usb/roles/typeb-conn-gpio.c > @@ -0,0 +1,305 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * USB Type-B GPIO Connector Driver > + * > + * Copyright (C) 2019 MediaTek Inc. > + * > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > + * > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > + > +#include <linux/device.h> > +#include <linux/gpio/consumer.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/of_graph.h> > +#include <linux/pinctrl/consumer.h> > +#include <linux/platform_device.h> > +#include <linux/regulator/consumer.h> > +#include <linux/usb/role.h> > + > +#define USB_GPIO_DEB_MS 20 /* ms */ > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > */ > + > +#define USB_CONN_IRQF \ > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > IRQF_ONESHOT) > + > +struct usb_conn_info { > + struct device *dev; > + struct usb_role_switch *role_sw; > + enum usb_role last_role; > + struct regulator *vbus; > + struct delayed_work dw_det; > + unsigned long debounce_jiffies; > + > + struct gpio_desc *id_gpiod; > + struct gpio_desc *vbus_gpiod; > + int id_irq; > + int vbus_irq; > +}; > + > +/** > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > + * Both "DEVICE" and "HOST" can't be set as active at the same time > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > + * even if VBUS is on. > + * > + * Role | ID | VBUS > + * ------------------------------------ > + * [1] DEVICE | H | H > + * [2] NONE | H | L > + * [3] HOST | L | H > + * [4] HOST | L | L > + * > + * In case we have only one of these signals: > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > +always 1 > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > + struct usb_conn_info *info; > + enum usb_role role; > + int id, vbus, ret; > + > + info = container_of(to_delayed_work(work), > + struct usb_conn_info, dw_det); > + > + /* check ID and VBUS */ > + id = info->id_gpiod ? > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > + vbus = info->vbus_gpiod ? > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > + > + if (!id) > + role = USB_ROLE_HOST; > + else if (vbus) > + role = USB_ROLE_DEVICE; > + else > + role = USB_ROLE_NONE; > + > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > + info->last_role, role, id, vbus); > + > + if (info->last_role == role) { > + dev_warn(info->dev, "repeated role: %d\n", role); > + return; > + } > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + ret = usb_role_switch_set_role(info->role_sw, role); > + if (ret) > + dev_err(info->dev, "failed to set role: %d\n", ret); > + > + if (role == USB_ROLE_HOST) { > + ret = regulator_enable(info->vbus); > + if (ret) > + dev_err(info->dev, "enable vbus regulator failed\n"); > + } > + > + info->last_role = role; > + > + dev_dbg(info->dev, "vbus regulator is %s\n", > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > + > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > + unsigned long delay) > +{ > + queue_delayed_work(system_power_efficient_wq, &info- > >dw_det, delay); } > + > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > + struct usb_conn_info *info = dev_id; > + > + usb_conn_queue_dwork(info, info->debounce_jiffies); > + > + return IRQ_HANDLED; > +} > + > +static int usb_conn_probe(struct platform_device *pdev) { > + struct device *dev = &pdev->dev; > + struct device_node *np = dev->of_node; > + struct device_node *parent; > + struct device_node *child; > + struct usb_conn_info *info; > + int ret = 0; > + > + if (!np) > + return -EINVAL; > + > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + info->dev = dev; > + > + child = of_get_child_by_name(np, "connector"); > + if (!child) { > + dev_err(dev, "failed to find connector node\n"); > + return -ENODEV; > + } > + > + info->id_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > + if (IS_ERR(info->id_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->id_gpiod); > + } > + > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "vbus-gpios", 0, GPIOD_IN, > + "vbuspin"); > + if (IS_ERR(info->vbus_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->vbus_gpiod); > + } > + > + if (!info->id_gpiod && !info->vbus_gpiod) { > + dev_err(dev, "failed to get gpios\n"); > + return -ENODEV; > + } > + > + of_node_put(child); > + > + if (info->id_gpiod) > + ret = gpiod_set_debounce(info->id_gpiod, > USB_GPIO_DEB_US); > + if (!ret && info->vbus_gpiod) > + ret = gpiod_set_debounce(info->vbus_gpiod, > USB_GPIO_DEB_US); > + if (ret < 0) > + info->debounce_jiffies = > msecs_to_jiffies(USB_GPIO_DEB_MS); > + > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > + > + info->vbus = devm_regulator_get(dev, "vbus"); > + if (IS_ERR(info->vbus)) { > + dev_err(dev, "failed to get vbus\n"); > + return PTR_ERR(info->vbus); > + } > + > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > + parent = of_graph_get_remote_port_parent(child); > + info->role_sw = > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > + of_node_put(child); > + of_node_put(parent); > + if (IS_ERR(info->role_sw)) { > + dev_err(dev, "failed to get role switch\n"); > + return PTR_ERR(info->role_sw); > + } > + > + if (info->id_gpiod) { > + info->id_irq = gpiod_to_irq(info->id_gpiod); > + if (info->id_irq < 0) { > + dev_err(dev, "failed to get ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return info->id_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + if (info->vbus_gpiod) { > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > + if (info->vbus_irq < 0) { > + dev_err(dev, "failed to get VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); > + return info->vbus_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + platform_set_drvdata(pdev, info); > + > + /* Perform initial detection */ > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static int usb_conn_remove(struct platform_device *pdev) { > + struct usb_conn_info *info = platform_get_drvdata(pdev); > + > + cancel_delayed_work_sync(&info->dw_det); > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + usb_role_switch_put(info->role_sw); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + if (info->id_gpiod) > + disable_irq(info->id_irq); > + if (info->vbus_gpiod) > + disable_irq(info->vbus_irq); > + > + pinctrl_pm_select_sleep_state(dev); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_resume(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + pinctrl_pm_select_default_state(dev); > + > + if (info->id_gpiod) > + enable_irq(info->id_irq); > + if (info->vbus_gpiod) > + enable_irq(info->vbus_irq); > + > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > + usb_conn_suspend, usb_conn_resume); > + > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > &usb_conn_pm_ops : > +NULL) > + > +static const struct of_device_id usb_conn_dt_match[] = { > + { .compatible = "linux,typeb-conn-gpio", }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > + > +static struct platform_driver usb_conn_driver = { > + .probe = usb_conn_probe, > + .remove = usb_conn_remove, > + .driver = { > + .name = "typeb-conn-gpio", > + .pm = DEV_PMS_OPS, > + .of_match_table = usb_conn_dt_match, > + }, > +}; > + > +module_platform_driver(usb_conn_driver); > + > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > +MODULE_LICENSE("GPL v2"); > -- > 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-26 9:22 ` Biju Das 0 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 9:22 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Linus Walleij, linux-usb, linux-kernel, Badhri Jagan Sridharan, Andy Shevchenko, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > Due to the requirement of usb-connector.txt binding, the old way using > extcon to support USB Dual-Role switch is now deprecated when use Type-B > connector. > This patch introduces a driver of Type-B connector which typically uses an > input GPIO to detect USB ID pin, and try to replace the function provided by > extcon-usb-gpio driver > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 changes: > 1. remove linux/gpio.h suggested by Linus > 2. put node when error happens > > v3 changes: > 1. treat bype-B connector as a virtual device; > 2. change file name again > > v2 changes: > 1. file name is changed > 2. use new compatible > --- > drivers/usb/roles/Kconfig | 11 + > drivers/usb/roles/Makefile | 1 + > drivers/usb/roles/typeb-conn-gpio.c | 305 > ++++++++++++++++++++++++++++ > 3 files changed, 317 insertions(+) > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > f8b31aa67526..d1156e18a81a 100644 > --- a/drivers/usb/roles/Kconfig > +++ b/drivers/usb/roles/Kconfig > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > To compile the driver as a module, choose M here: the module will > be called intel-xhci-usb-role-switch. > > +config TYPEB_CONN_GPIO > + tristate "USB Type-B GPIO Connector" > + depends on GPIOLIB > + help > + The driver supports USB role switch between host and device via > GPIO > + based USB cable detection, used typically if an input GPIO is used > + to detect USB ID pin. > + > + To compile the driver as a module, choose M here: the module will > + be called typeb-conn-gpio.ko > + > endif # USB_ROLE_SWITCH > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > 757a7d2797eb..5d5620d9d113 100644 > --- a/drivers/usb/roles/Makefile > +++ b/drivers/usb/roles/Makefile > @@ -3,3 +3,4 @@ > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > roles-y := class.o > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > switch.o > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > conn-gpio.c > new file mode 100644 > index 000000000000..097d2ca12a12 > --- /dev/null > +++ b/drivers/usb/roles/typeb-conn-gpio.c > @@ -0,0 +1,305 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * USB Type-B GPIO Connector Driver > + * > + * Copyright (C) 2019 MediaTek Inc. > + * > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > + * > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > + > +#include <linux/device.h> > +#include <linux/gpio/consumer.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/of_graph.h> > +#include <linux/pinctrl/consumer.h> > +#include <linux/platform_device.h> > +#include <linux/regulator/consumer.h> > +#include <linux/usb/role.h> > + > +#define USB_GPIO_DEB_MS 20 /* ms */ > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > */ > + > +#define USB_CONN_IRQF \ > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > IRQF_ONESHOT) > + > +struct usb_conn_info { > + struct device *dev; > + struct usb_role_switch *role_sw; > + enum usb_role last_role; > + struct regulator *vbus; > + struct delayed_work dw_det; > + unsigned long debounce_jiffies; > + > + struct gpio_desc *id_gpiod; > + struct gpio_desc *vbus_gpiod; > + int id_irq; > + int vbus_irq; > +}; > + > +/** > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > + * Both "DEVICE" and "HOST" can't be set as active at the same time > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > + * even if VBUS is on. > + * > + * Role | ID | VBUS > + * ------------------------------------ > + * [1] DEVICE | H | H > + * [2] NONE | H | L > + * [3] HOST | L | H > + * [4] HOST | L | L > + * > + * In case we have only one of these signals: > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > +always 1 > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > + struct usb_conn_info *info; > + enum usb_role role; > + int id, vbus, ret; > + > + info = container_of(to_delayed_work(work), > + struct usb_conn_info, dw_det); > + > + /* check ID and VBUS */ > + id = info->id_gpiod ? > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > + vbus = info->vbus_gpiod ? > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > + > + if (!id) > + role = USB_ROLE_HOST; > + else if (vbus) > + role = USB_ROLE_DEVICE; > + else > + role = USB_ROLE_NONE; > + > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > + info->last_role, role, id, vbus); > + > + if (info->last_role == role) { > + dev_warn(info->dev, "repeated role: %d\n", role); > + return; > + } > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + ret = usb_role_switch_set_role(info->role_sw, role); > + if (ret) > + dev_err(info->dev, "failed to set role: %d\n", ret); > + > + if (role == USB_ROLE_HOST) { > + ret = regulator_enable(info->vbus); > + if (ret) > + dev_err(info->dev, "enable vbus regulator failed\n"); > + } > + > + info->last_role = role; > + > + dev_dbg(info->dev, "vbus regulator is %s\n", > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > + > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > + unsigned long delay) > +{ > + queue_delayed_work(system_power_efficient_wq, &info- > >dw_det, delay); } > + > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > + struct usb_conn_info *info = dev_id; > + > + usb_conn_queue_dwork(info, info->debounce_jiffies); > + > + return IRQ_HANDLED; > +} > + > +static int usb_conn_probe(struct platform_device *pdev) { > + struct device *dev = &pdev->dev; > + struct device_node *np = dev->of_node; > + struct device_node *parent; > + struct device_node *child; > + struct usb_conn_info *info; > + int ret = 0; > + > + if (!np) > + return -EINVAL; > + > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + info->dev = dev; > + > + child = of_get_child_by_name(np, "connector"); > + if (!child) { > + dev_err(dev, "failed to find connector node\n"); > + return -ENODEV; > + } > + > + info->id_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > + if (IS_ERR(info->id_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->id_gpiod); > + } > + > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "vbus-gpios", 0, GPIOD_IN, > + "vbuspin"); > + if (IS_ERR(info->vbus_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->vbus_gpiod); > + } > + > + if (!info->id_gpiod && !info->vbus_gpiod) { > + dev_err(dev, "failed to get gpios\n"); > + return -ENODEV; > + } > + > + of_node_put(child); > + > + if (info->id_gpiod) > + ret = gpiod_set_debounce(info->id_gpiod, > USB_GPIO_DEB_US); > + if (!ret && info->vbus_gpiod) > + ret = gpiod_set_debounce(info->vbus_gpiod, > USB_GPIO_DEB_US); > + if (ret < 0) > + info->debounce_jiffies = > msecs_to_jiffies(USB_GPIO_DEB_MS); > + > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > + > + info->vbus = devm_regulator_get(dev, "vbus"); > + if (IS_ERR(info->vbus)) { > + dev_err(dev, "failed to get vbus\n"); > + return PTR_ERR(info->vbus); > + } > + > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > + parent = of_graph_get_remote_port_parent(child); > + info->role_sw = > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > + of_node_put(child); > + of_node_put(parent); > + if (IS_ERR(info->role_sw)) { > + dev_err(dev, "failed to get role switch\n"); > + return PTR_ERR(info->role_sw); > + } > + > + if (info->id_gpiod) { > + info->id_irq = gpiod_to_irq(info->id_gpiod); > + if (info->id_irq < 0) { > + dev_err(dev, "failed to get ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return info->id_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + if (info->vbus_gpiod) { > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > + if (info->vbus_irq < 0) { > + dev_err(dev, "failed to get VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); > + return info->vbus_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + platform_set_drvdata(pdev, info); > + > + /* Perform initial detection */ > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static int usb_conn_remove(struct platform_device *pdev) { > + struct usb_conn_info *info = platform_get_drvdata(pdev); > + > + cancel_delayed_work_sync(&info->dw_det); > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + usb_role_switch_put(info->role_sw); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + if (info->id_gpiod) > + disable_irq(info->id_irq); > + if (info->vbus_gpiod) > + disable_irq(info->vbus_irq); > + > + pinctrl_pm_select_sleep_state(dev); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_resume(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + pinctrl_pm_select_default_state(dev); > + > + if (info->id_gpiod) > + enable_irq(info->id_irq); > + if (info->vbus_gpiod) > + enable_irq(info->vbus_irq); > + > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > + usb_conn_suspend, usb_conn_resume); > + > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > &usb_conn_pm_ops : > +NULL) > + > +static const struct of_device_id usb_conn_dt_match[] = { > + { .compatible = "linux,typeb-conn-gpio", }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > + > +static struct platform_driver usb_conn_driver = { > + .probe = usb_conn_probe, > + .remove = usb_conn_remove, > + .driver = { > + .name = "typeb-conn-gpio", > + .pm = DEV_PMS_OPS, > + .of_match_table = usb_conn_dt_match, > + }, > +}; > + > +module_platform_driver(usb_conn_driver); > + > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > +MODULE_LICENSE("GPL v2"); > -- > 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-26 9:22 ` Biju Das 0 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 9:22 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Linus Walleij Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > Due to the requirement of usb-connector.txt binding, the old way using > extcon to support USB Dual-Role switch is now deprecated when use Type-B > connector. > This patch introduces a driver of Type-B connector which typically uses an > input GPIO to detect USB ID pin, and try to replace the function provided by > extcon-usb-gpio driver > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 changes: > 1. remove linux/gpio.h suggested by Linus > 2. put node when error happens > > v3 changes: > 1. treat bype-B connector as a virtual device; > 2. change file name again > > v2 changes: > 1. file name is changed > 2. use new compatible > --- > drivers/usb/roles/Kconfig | 11 + > drivers/usb/roles/Makefile | 1 + > drivers/usb/roles/typeb-conn-gpio.c | 305 > ++++++++++++++++++++++++++++ > 3 files changed, 317 insertions(+) > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > f8b31aa67526..d1156e18a81a 100644 > --- a/drivers/usb/roles/Kconfig > +++ b/drivers/usb/roles/Kconfig > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > To compile the driver as a module, choose M here: the module will > be called intel-xhci-usb-role-switch. > > +config TYPEB_CONN_GPIO > + tristate "USB Type-B GPIO Connector" > + depends on GPIOLIB > + help > + The driver supports USB role switch between host and device via > GPIO > + based USB cable detection, used typically if an input GPIO is used > + to detect USB ID pin. > + > + To compile the driver as a module, choose M here: the module will > + be called typeb-conn-gpio.ko > + > endif # USB_ROLE_SWITCH > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > 757a7d2797eb..5d5620d9d113 100644 > --- a/drivers/usb/roles/Makefile > +++ b/drivers/usb/roles/Makefile > @@ -3,3 +3,4 @@ > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > roles-y := class.o > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > switch.o > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > conn-gpio.c > new file mode 100644 > index 000000000000..097d2ca12a12 > --- /dev/null > +++ b/drivers/usb/roles/typeb-conn-gpio.c > @@ -0,0 +1,305 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * USB Type-B GPIO Connector Driver > + * > + * Copyright (C) 2019 MediaTek Inc. > + * > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > + * > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > + > +#include <linux/device.h> > +#include <linux/gpio/consumer.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/of_graph.h> > +#include <linux/pinctrl/consumer.h> > +#include <linux/platform_device.h> > +#include <linux/regulator/consumer.h> > +#include <linux/usb/role.h> > + > +#define USB_GPIO_DEB_MS 20 /* ms */ > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > */ > + > +#define USB_CONN_IRQF \ > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > IRQF_ONESHOT) > + > +struct usb_conn_info { > + struct device *dev; > + struct usb_role_switch *role_sw; > + enum usb_role last_role; > + struct regulator *vbus; > + struct delayed_work dw_det; > + unsigned long debounce_jiffies; > + > + struct gpio_desc *id_gpiod; > + struct gpio_desc *vbus_gpiod; > + int id_irq; > + int vbus_irq; > +}; > + > +/** > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > + * Both "DEVICE" and "HOST" can't be set as active at the same time > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > + * even if VBUS is on. > + * > + * Role | ID | VBUS > + * ------------------------------------ > + * [1] DEVICE | H | H > + * [2] NONE | H | L > + * [3] HOST | L | H > + * [4] HOST | L | L > + * > + * In case we have only one of these signals: > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > +always 1 > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > + struct usb_conn_info *info; > + enum usb_role role; > + int id, vbus, ret; > + > + info = container_of(to_delayed_work(work), > + struct usb_conn_info, dw_det); > + > + /* check ID and VBUS */ > + id = info->id_gpiod ? > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > + vbus = info->vbus_gpiod ? > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > + > + if (!id) > + role = USB_ROLE_HOST; > + else if (vbus) > + role = USB_ROLE_DEVICE; > + else > + role = USB_ROLE_NONE; > + > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > + info->last_role, role, id, vbus); > + > + if (info->last_role == role) { > + dev_warn(info->dev, "repeated role: %d\n", role); > + return; > + } > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + ret = usb_role_switch_set_role(info->role_sw, role); > + if (ret) > + dev_err(info->dev, "failed to set role: %d\n", ret); > + > + if (role == USB_ROLE_HOST) { > + ret = regulator_enable(info->vbus); > + if (ret) > + dev_err(info->dev, "enable vbus regulator failed\n"); > + } > + > + info->last_role = role; > + > + dev_dbg(info->dev, "vbus regulator is %s\n", > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > + > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > + unsigned long delay) > +{ > + queue_delayed_work(system_power_efficient_wq, &info- > >dw_det, delay); } > + > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > + struct usb_conn_info *info = dev_id; > + > + usb_conn_queue_dwork(info, info->debounce_jiffies); > + > + return IRQ_HANDLED; > +} > + > +static int usb_conn_probe(struct platform_device *pdev) { > + struct device *dev = &pdev->dev; > + struct device_node *np = dev->of_node; > + struct device_node *parent; > + struct device_node *child; > + struct usb_conn_info *info; > + int ret = 0; > + > + if (!np) > + return -EINVAL; > + > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + info->dev = dev; > + > + child = of_get_child_by_name(np, "connector"); > + if (!child) { > + dev_err(dev, "failed to find connector node\n"); > + return -ENODEV; > + } > + > + info->id_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > + if (IS_ERR(info->id_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->id_gpiod); > + } > + > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "vbus-gpios", 0, GPIOD_IN, > + "vbuspin"); > + if (IS_ERR(info->vbus_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->vbus_gpiod); > + } > + > + if (!info->id_gpiod && !info->vbus_gpiod) { > + dev_err(dev, "failed to get gpios\n"); > + return -ENODEV; > + } > + > + of_node_put(child); > + > + if (info->id_gpiod) > + ret = gpiod_set_debounce(info->id_gpiod, > USB_GPIO_DEB_US); > + if (!ret && info->vbus_gpiod) > + ret = gpiod_set_debounce(info->vbus_gpiod, > USB_GPIO_DEB_US); > + if (ret < 0) > + info->debounce_jiffies = > msecs_to_jiffies(USB_GPIO_DEB_MS); > + > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > + > + info->vbus = devm_regulator_get(dev, "vbus"); > + if (IS_ERR(info->vbus)) { > + dev_err(dev, "failed to get vbus\n"); > + return PTR_ERR(info->vbus); > + } > + > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > + parent = of_graph_get_remote_port_parent(child); > + info->role_sw = > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > + of_node_put(child); > + of_node_put(parent); > + if (IS_ERR(info->role_sw)) { > + dev_err(dev, "failed to get role switch\n"); > + return PTR_ERR(info->role_sw); > + } > + > + if (info->id_gpiod) { > + info->id_irq = gpiod_to_irq(info->id_gpiod); > + if (info->id_irq < 0) { > + dev_err(dev, "failed to get ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return info->id_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + if (info->vbus_gpiod) { > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > + if (info->vbus_irq < 0) { > + dev_err(dev, "failed to get VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); > + return info->vbus_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + platform_set_drvdata(pdev, info); > + > + /* Perform initial detection */ > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static int usb_conn_remove(struct platform_device *pdev) { > + struct usb_conn_info *info = platform_get_drvdata(pdev); > + > + cancel_delayed_work_sync(&info->dw_det); > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + usb_role_switch_put(info->role_sw); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + if (info->id_gpiod) > + disable_irq(info->id_irq); > + if (info->vbus_gpiod) > + disable_irq(info->vbus_irq); > + > + pinctrl_pm_select_sleep_state(dev); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_resume(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + pinctrl_pm_select_default_state(dev); > + > + if (info->id_gpiod) > + enable_irq(info->id_irq); > + if (info->vbus_gpiod) > + enable_irq(info->vbus_irq); > + > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > + usb_conn_suspend, usb_conn_resume); > + > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > &usb_conn_pm_ops : > +NULL) > + > +static const struct of_device_id usb_conn_dt_match[] = { > + { .compatible = "linux,typeb-conn-gpio", }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > + > +static struct platform_driver usb_conn_driver = { > + .probe = usb_conn_probe, > + .remove = usb_conn_remove, > + .driver = { > + .name = "typeb-conn-gpio", > + .pm = DEV_PMS_OPS, > + .of_match_table = usb_conn_dt_match, > + }, > +}; > + > +module_platform_driver(usb_conn_driver); > + > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > +MODULE_LICENSE("GPL v2"); > -- > 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-26 9:22 ` Biju Das 0 siblings, 0 replies; 69+ messages in thread From: Biju Das @ 2019-04-26 9:22 UTC (permalink / raw) To: Chunfeng Yun, Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Linus Walleij Hi Chunfeng Yun, Thanks for the patch. > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > Due to the requirement of usb-connector.txt binding, the old way using > extcon to support USB Dual-Role switch is now deprecated when use Type-B > connector. > This patch introduces a driver of Type-B connector which typically uses an > input GPIO to detect USB ID pin, and try to replace the function provided by > extcon-usb-gpio driver > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > --- > v4 changes: > 1. remove linux/gpio.h suggested by Linus > 2. put node when error happens > > v3 changes: > 1. treat bype-B connector as a virtual device; > 2. change file name again > > v2 changes: > 1. file name is changed > 2. use new compatible > --- > drivers/usb/roles/Kconfig | 11 + > drivers/usb/roles/Makefile | 1 + > drivers/usb/roles/typeb-conn-gpio.c | 305 > ++++++++++++++++++++++++++++ > 3 files changed, 317 insertions(+) > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > f8b31aa67526..d1156e18a81a 100644 > --- a/drivers/usb/roles/Kconfig > +++ b/drivers/usb/roles/Kconfig > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > To compile the driver as a module, choose M here: the module will > be called intel-xhci-usb-role-switch. > > +config TYPEB_CONN_GPIO > + tristate "USB Type-B GPIO Connector" > + depends on GPIOLIB > + help > + The driver supports USB role switch between host and device via > GPIO > + based USB cable detection, used typically if an input GPIO is used > + to detect USB ID pin. > + > + To compile the driver as a module, choose M here: the module will > + be called typeb-conn-gpio.ko > + > endif # USB_ROLE_SWITCH > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > 757a7d2797eb..5d5620d9d113 100644 > --- a/drivers/usb/roles/Makefile > +++ b/drivers/usb/roles/Makefile > @@ -3,3 +3,4 @@ > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > roles-y := class.o > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > switch.o > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > conn-gpio.c > new file mode 100644 > index 000000000000..097d2ca12a12 > --- /dev/null > +++ b/drivers/usb/roles/typeb-conn-gpio.c > @@ -0,0 +1,305 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * USB Type-B GPIO Connector Driver > + * > + * Copyright (C) 2019 MediaTek Inc. > + * > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > + * > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > + > +#include <linux/device.h> > +#include <linux/gpio/consumer.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/of_graph.h> > +#include <linux/pinctrl/consumer.h> > +#include <linux/platform_device.h> > +#include <linux/regulator/consumer.h> > +#include <linux/usb/role.h> > + > +#define USB_GPIO_DEB_MS 20 /* ms */ > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > */ > + > +#define USB_CONN_IRQF \ > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > IRQF_ONESHOT) > + > +struct usb_conn_info { > + struct device *dev; > + struct usb_role_switch *role_sw; > + enum usb_role last_role; > + struct regulator *vbus; > + struct delayed_work dw_det; > + unsigned long debounce_jiffies; > + > + struct gpio_desc *id_gpiod; > + struct gpio_desc *vbus_gpiod; > + int id_irq; > + int vbus_irq; > +}; > + > +/** > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > + * Both "DEVICE" and "HOST" can't be set as active at the same time > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > + * even if VBUS is on. > + * > + * Role | ID | VBUS > + * ------------------------------------ > + * [1] DEVICE | H | H > + * [2] NONE | H | L > + * [3] HOST | L | H > + * [4] HOST | L | L > + * > + * In case we have only one of these signals: > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > +always 1 > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > + struct usb_conn_info *info; > + enum usb_role role; > + int id, vbus, ret; > + > + info = container_of(to_delayed_work(work), > + struct usb_conn_info, dw_det); > + > + /* check ID and VBUS */ > + id = info->id_gpiod ? > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > + vbus = info->vbus_gpiod ? > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > + > + if (!id) > + role = USB_ROLE_HOST; > + else if (vbus) > + role = USB_ROLE_DEVICE; > + else > + role = USB_ROLE_NONE; > + > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > + info->last_role, role, id, vbus); > + > + if (info->last_role == role) { > + dev_warn(info->dev, "repeated role: %d\n", role); > + return; > + } > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + ret = usb_role_switch_set_role(info->role_sw, role); > + if (ret) > + dev_err(info->dev, "failed to set role: %d\n", ret); > + > + if (role == USB_ROLE_HOST) { > + ret = regulator_enable(info->vbus); > + if (ret) > + dev_err(info->dev, "enable vbus regulator failed\n"); > + } > + > + info->last_role = role; > + > + dev_dbg(info->dev, "vbus regulator is %s\n", > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > + > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > + unsigned long delay) > +{ > + queue_delayed_work(system_power_efficient_wq, &info- > >dw_det, delay); } > + > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > + struct usb_conn_info *info = dev_id; > + > + usb_conn_queue_dwork(info, info->debounce_jiffies); > + > + return IRQ_HANDLED; > +} > + > +static int usb_conn_probe(struct platform_device *pdev) { > + struct device *dev = &pdev->dev; > + struct device_node *np = dev->of_node; > + struct device_node *parent; > + struct device_node *child; > + struct usb_conn_info *info; > + int ret = 0; > + > + if (!np) > + return -EINVAL; > + > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + info->dev = dev; > + > + child = of_get_child_by_name(np, "connector"); > + if (!child) { > + dev_err(dev, "failed to find connector node\n"); > + return -ENODEV; > + } > + > + info->id_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > + if (IS_ERR(info->id_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->id_gpiod); > + } > + > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > + dev, child, "vbus-gpios", 0, GPIOD_IN, > + "vbuspin"); > + if (IS_ERR(info->vbus_gpiod)) { > + of_node_put(child); > + return PTR_ERR(info->vbus_gpiod); > + } > + > + if (!info->id_gpiod && !info->vbus_gpiod) { > + dev_err(dev, "failed to get gpios\n"); > + return -ENODEV; > + } > + > + of_node_put(child); > + > + if (info->id_gpiod) > + ret = gpiod_set_debounce(info->id_gpiod, > USB_GPIO_DEB_US); > + if (!ret && info->vbus_gpiod) > + ret = gpiod_set_debounce(info->vbus_gpiod, > USB_GPIO_DEB_US); > + if (ret < 0) > + info->debounce_jiffies = > msecs_to_jiffies(USB_GPIO_DEB_MS); > + > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > + > + info->vbus = devm_regulator_get(dev, "vbus"); > + if (IS_ERR(info->vbus)) { > + dev_err(dev, "failed to get vbus\n"); > + return PTR_ERR(info->vbus); > + } > + > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > + parent = of_graph_get_remote_port_parent(child); > + info->role_sw = > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > + of_node_put(child); > + of_node_put(parent); > + if (IS_ERR(info->role_sw)) { > + dev_err(dev, "failed to get role switch\n"); > + return PTR_ERR(info->role_sw); > + } > + > + if (info->id_gpiod) { > + info->id_irq = gpiod_to_irq(info->id_gpiod); > + if (info->id_irq < 0) { > + dev_err(dev, "failed to get ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return info->id_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request ID IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + if (info->vbus_gpiod) { > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > + if (info->vbus_irq < 0) { > + dev_err(dev, "failed to get VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); > + return info->vbus_irq; > + } > + > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > NULL, > + usb_conn_isr, > USB_CONN_IRQF, > + pdev->name, info); > + if (ret < 0) { > + dev_err(dev, "failed to request VBUS IRQ\n"); May be usb_role_switch_put(info->role_sw); ?? > + return ret; > + } > + } > + > + platform_set_drvdata(pdev, info); > + > + /* Perform initial detection */ > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static int usb_conn_remove(struct platform_device *pdev) { > + struct usb_conn_info *info = platform_get_drvdata(pdev); > + > + cancel_delayed_work_sync(&info->dw_det); > + > + if (info->last_role == USB_ROLE_HOST) > + regulator_disable(info->vbus); > + > + usb_role_switch_put(info->role_sw); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + if (info->id_gpiod) > + disable_irq(info->id_irq); > + if (info->vbus_gpiod) > + disable_irq(info->vbus_irq); > + > + pinctrl_pm_select_sleep_state(dev); > + > + return 0; > +} > + > +static int __maybe_unused usb_conn_resume(struct device *dev) { > + struct usb_conn_info *info = dev_get_drvdata(dev); > + > + pinctrl_pm_select_default_state(dev); > + > + if (info->id_gpiod) > + enable_irq(info->id_irq); > + if (info->vbus_gpiod) > + enable_irq(info->vbus_irq); > + > + usb_conn_queue_dwork(info, 0); > + > + return 0; > +} > + > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > + usb_conn_suspend, usb_conn_resume); > + > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > &usb_conn_pm_ops : > +NULL) > + > +static const struct of_device_id usb_conn_dt_match[] = { > + { .compatible = "linux,typeb-conn-gpio", }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > + > +static struct platform_driver usb_conn_driver = { > + .probe = usb_conn_probe, > + .remove = usb_conn_remove, > + .driver = { > + .name = "typeb-conn-gpio", > + .pm = DEV_PMS_OPS, > + .of_match_table = usb_conn_dt_match, > + }, > +}; > + > +module_platform_driver(usb_conn_driver); > + > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > +MODULE_LICENSE("GPL v2"); > -- > 2.21.0 ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver 2019-04-26 9:22 ` [PATCH v4 5/6] " Biju Das (?) (?) @ 2019-04-28 9:26 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 9:26 UTC (permalink / raw) To: Biju Das Cc: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek Hi Biju, On Fri, 2019-04-26 at 09:22 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > > > Due to the requirement of usb-connector.txt binding, the old way using > > extcon to support USB Dual-Role switch is now deprecated when use Type-B > > connector. > > This patch introduces a driver of Type-B connector which typically uses an > > input GPIO to detect USB ID pin, and try to replace the function provided by > > extcon-usb-gpio driver > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 changes: > > 1. remove linux/gpio.h suggested by Linus > > 2. put node when error happens > > > > v3 changes: > > 1. treat bype-B connector as a virtual device; > > 2. change file name again > > > > v2 changes: > > 1. file name is changed > > 2. use new compatible > > --- > > drivers/usb/roles/Kconfig | 11 + > > drivers/usb/roles/Makefile | 1 + > > drivers/usb/roles/typeb-conn-gpio.c | 305 > > ++++++++++++++++++++++++++++ > > 3 files changed, 317 insertions(+) > > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > > f8b31aa67526..d1156e18a81a 100644 > > --- a/drivers/usb/roles/Kconfig > > +++ b/drivers/usb/roles/Kconfig > > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > > To compile the driver as a module, choose M here: the module will > > be called intel-xhci-usb-role-switch. > > > > +config TYPEB_CONN_GPIO > > + tristate "USB Type-B GPIO Connector" > > + depends on GPIOLIB > > + help > > + The driver supports USB role switch between host and device via > > GPIO > > + based USB cable detection, used typically if an input GPIO is used > > + to detect USB ID pin. > > + > > + To compile the driver as a module, choose M here: the module will > > + be called typeb-conn-gpio.ko > > + > > endif # USB_ROLE_SWITCH > > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > > 757a7d2797eb..5d5620d9d113 100644 > > --- a/drivers/usb/roles/Makefile > > +++ b/drivers/usb/roles/Makefile > > @@ -3,3 +3,4 @@ > > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > > roles-y := class.o > > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > > switch.o > > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > > conn-gpio.c > > new file mode 100644 > > index 000000000000..097d2ca12a12 > > --- /dev/null > > +++ b/drivers/usb/roles/typeb-conn-gpio.c > > @@ -0,0 +1,305 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * USB Type-B GPIO Connector Driver > > + * > > + * Copyright (C) 2019 MediaTek Inc. > > + * > > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > > + * > > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > > + > > +#include <linux/device.h> > > +#include <linux/gpio/consumer.h> > > +#include <linux/interrupt.h> > > +#include <linux/irq.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/of_graph.h> > > +#include <linux/pinctrl/consumer.h> > > +#include <linux/platform_device.h> > > +#include <linux/regulator/consumer.h> > > +#include <linux/usb/role.h> > > + > > +#define USB_GPIO_DEB_MS 20 /* ms */ > > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > > */ > > + > > +#define USB_CONN_IRQF \ > > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > > IRQF_ONESHOT) > > + > > +struct usb_conn_info { > > + struct device *dev; > > + struct usb_role_switch *role_sw; > > + enum usb_role last_role; > > + struct regulator *vbus; > > + struct delayed_work dw_det; > > + unsigned long debounce_jiffies; > > + > > + struct gpio_desc *id_gpiod; > > + struct gpio_desc *vbus_gpiod; > > + int id_irq; > > + int vbus_irq; > > +}; > > + > > +/** > > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > > + * Both "DEVICE" and "HOST" can't be set as active at the same time > > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > > + * even if VBUS is on. > > + * > > + * Role | ID | VBUS > > + * ------------------------------------ > > + * [1] DEVICE | H | H > > + * [2] NONE | H | L > > + * [3] HOST | L | H > > + * [4] HOST | L | L > > + * > > + * In case we have only one of these signals: > > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > > +always 1 > > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > > + struct usb_conn_info *info; > > + enum usb_role role; > > + int id, vbus, ret; > > + > > + info = container_of(to_delayed_work(work), > > + struct usb_conn_info, dw_det); > > + > > + /* check ID and VBUS */ > > + id = info->id_gpiod ? > > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > > + vbus = info->vbus_gpiod ? > > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > > + > > + if (!id) > > + role = USB_ROLE_HOST; > > + else if (vbus) > > + role = USB_ROLE_DEVICE; > > + else > > + role = USB_ROLE_NONE; > > + > > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > > + info->last_role, role, id, vbus); > > + > > + if (info->last_role == role) { > > + dev_warn(info->dev, "repeated role: %d\n", role); > > + return; > > + } > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + ret = usb_role_switch_set_role(info->role_sw, role); > > + if (ret) > > + dev_err(info->dev, "failed to set role: %d\n", ret); > > + > > + if (role == USB_ROLE_HOST) { > > + ret = regulator_enable(info->vbus); > > + if (ret) > > + dev_err(info->dev, "enable vbus regulator failed\n"); > > + } > > + > > + info->last_role = role; > > + > > + dev_dbg(info->dev, "vbus regulator is %s\n", > > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > > + > > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > > + unsigned long delay) > > +{ > > + queue_delayed_work(system_power_efficient_wq, &info- > > >dw_det, delay); } > > + > > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > > + struct usb_conn_info *info = dev_id; > > + > > + usb_conn_queue_dwork(info, info->debounce_jiffies); > > + > > + return IRQ_HANDLED; > > +} > > + > > +static int usb_conn_probe(struct platform_device *pdev) { > > + struct device *dev = &pdev->dev; > > + struct device_node *np = dev->of_node; > > + struct device_node *parent; > > + struct device_node *child; > > + struct usb_conn_info *info; > > + int ret = 0; > > + > > + if (!np) > > + return -EINVAL; > > + > > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > > + if (!info) > > + return -ENOMEM; > > + > > + info->dev = dev; > > + > > + child = of_get_child_by_name(np, "connector"); > > + if (!child) { > > + dev_err(dev, "failed to find connector node\n"); > > + return -ENODEV; > > + } > > + > > + info->id_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > > + if (IS_ERR(info->id_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->id_gpiod); > > + } > > + > > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "vbus-gpios", 0, GPIOD_IN, > > + "vbuspin"); > > + if (IS_ERR(info->vbus_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->vbus_gpiod); > > + } > > + > > + if (!info->id_gpiod && !info->vbus_gpiod) { > > + dev_err(dev, "failed to get gpios\n"); > > + return -ENODEV; > > + } > > + > > + of_node_put(child); > > + > > + if (info->id_gpiod) > > + ret = gpiod_set_debounce(info->id_gpiod, > > USB_GPIO_DEB_US); > > + if (!ret && info->vbus_gpiod) > > + ret = gpiod_set_debounce(info->vbus_gpiod, > > USB_GPIO_DEB_US); > > + if (ret < 0) > > + info->debounce_jiffies = > > msecs_to_jiffies(USB_GPIO_DEB_MS); > > + > > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > > + > > + info->vbus = devm_regulator_get(dev, "vbus"); > > + if (IS_ERR(info->vbus)) { > > + dev_err(dev, "failed to get vbus\n"); > > + return PTR_ERR(info->vbus); > > + } > > + > > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > > + parent = of_graph_get_remote_port_parent(child); > > + info->role_sw = > > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > > + of_node_put(child); > > + of_node_put(parent); > > + if (IS_ERR(info->role_sw)) { > > + dev_err(dev, "failed to get role switch\n"); > > + return PTR_ERR(info->role_sw); > > + } > > + > > + if (info->id_gpiod) { > > + info->id_irq = gpiod_to_irq(info->id_gpiod); > > + if (info->id_irq < 0) { > > + dev_err(dev, "failed to get ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? Good catch, will fix it. Thanks > > + return info->id_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + if (info->vbus_gpiod) { > > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > > + if (info->vbus_irq < 0) { > > + dev_err(dev, "failed to get VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); > > + return info->vbus_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > > NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + platform_set_drvdata(pdev, info); > > + > > + /* Perform initial detection */ > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static int usb_conn_remove(struct platform_device *pdev) { > > + struct usb_conn_info *info = platform_get_drvdata(pdev); > > + > > + cancel_delayed_work_sync(&info->dw_det); > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + usb_role_switch_put(info->role_sw); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + if (info->id_gpiod) > > + disable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + disable_irq(info->vbus_irq); > > + > > + pinctrl_pm_select_sleep_state(dev); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_resume(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + pinctrl_pm_select_default_state(dev); > > + > > + if (info->id_gpiod) > > + enable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + enable_irq(info->vbus_irq); > > + > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > > + usb_conn_suspend, usb_conn_resume); > > + > > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > > &usb_conn_pm_ops : > > +NULL) > > + > > +static const struct of_device_id usb_conn_dt_match[] = { > > + { .compatible = "linux,typeb-conn-gpio", }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > > + > > +static struct platform_driver usb_conn_driver = { > > + .probe = usb_conn_probe, > > + .remove = usb_conn_remove, > > + .driver = { > > + .name = "typeb-conn-gpio", > > + .pm = DEV_PMS_OPS, > > + .of_match_table = usb_conn_dt_match, > > + }, > > +}; > > + > > +module_platform_driver(usb_conn_driver); > > + > > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > > +MODULE_LICENSE("GPL v2"); > > -- > > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-28 9:26 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 9:26 UTC (permalink / raw) To: Biju Das Cc: Mark Rutland, devicetree, Heikki Krogerus, Hans de Goede, Greg Kroah-Hartman, linux-usb, linux-kernel, Badhri Jagan Sridharan, Andy Shevchenko, Rob Herring, linux-mediatek, Min Guo, Matthias Brugger, Adam Thomson, linux-arm-kernel, Li Jun Hi Biju, On Fri, 2019-04-26 at 09:22 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > > > Due to the requirement of usb-connector.txt binding, the old way using > > extcon to support USB Dual-Role switch is now deprecated when use Type-B > > connector. > > This patch introduces a driver of Type-B connector which typically uses an > > input GPIO to detect USB ID pin, and try to replace the function provided by > > extcon-usb-gpio driver > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 changes: > > 1. remove linux/gpio.h suggested by Linus > > 2. put node when error happens > > > > v3 changes: > > 1. treat bype-B connector as a virtual device; > > 2. change file name again > > > > v2 changes: > > 1. file name is changed > > 2. use new compatible > > --- > > drivers/usb/roles/Kconfig | 11 + > > drivers/usb/roles/Makefile | 1 + > > drivers/usb/roles/typeb-conn-gpio.c | 305 > > ++++++++++++++++++++++++++++ > > 3 files changed, 317 insertions(+) > > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > > f8b31aa67526..d1156e18a81a 100644 > > --- a/drivers/usb/roles/Kconfig > > +++ b/drivers/usb/roles/Kconfig > > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > > To compile the driver as a module, choose M here: the module will > > be called intel-xhci-usb-role-switch. > > > > +config TYPEB_CONN_GPIO > > + tristate "USB Type-B GPIO Connector" > > + depends on GPIOLIB > > + help > > + The driver supports USB role switch between host and device via > > GPIO > > + based USB cable detection, used typically if an input GPIO is used > > + to detect USB ID pin. > > + > > + To compile the driver as a module, choose M here: the module will > > + be called typeb-conn-gpio.ko > > + > > endif # USB_ROLE_SWITCH > > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > > 757a7d2797eb..5d5620d9d113 100644 > > --- a/drivers/usb/roles/Makefile > > +++ b/drivers/usb/roles/Makefile > > @@ -3,3 +3,4 @@ > > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > > roles-y := class.o > > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > > switch.o > > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > > conn-gpio.c > > new file mode 100644 > > index 000000000000..097d2ca12a12 > > --- /dev/null > > +++ b/drivers/usb/roles/typeb-conn-gpio.c > > @@ -0,0 +1,305 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * USB Type-B GPIO Connector Driver > > + * > > + * Copyright (C) 2019 MediaTek Inc. > > + * > > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > > + * > > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > > + > > +#include <linux/device.h> > > +#include <linux/gpio/consumer.h> > > +#include <linux/interrupt.h> > > +#include <linux/irq.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/of_graph.h> > > +#include <linux/pinctrl/consumer.h> > > +#include <linux/platform_device.h> > > +#include <linux/regulator/consumer.h> > > +#include <linux/usb/role.h> > > + > > +#define USB_GPIO_DEB_MS 20 /* ms */ > > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > > */ > > + > > +#define USB_CONN_IRQF \ > > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > > IRQF_ONESHOT) > > + > > +struct usb_conn_info { > > + struct device *dev; > > + struct usb_role_switch *role_sw; > > + enum usb_role last_role; > > + struct regulator *vbus; > > + struct delayed_work dw_det; > > + unsigned long debounce_jiffies; > > + > > + struct gpio_desc *id_gpiod; > > + struct gpio_desc *vbus_gpiod; > > + int id_irq; > > + int vbus_irq; > > +}; > > + > > +/** > > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > > + * Both "DEVICE" and "HOST" can't be set as active at the same time > > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > > + * even if VBUS is on. > > + * > > + * Role | ID | VBUS > > + * ------------------------------------ > > + * [1] DEVICE | H | H > > + * [2] NONE | H | L > > + * [3] HOST | L | H > > + * [4] HOST | L | L > > + * > > + * In case we have only one of these signals: > > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > > +always 1 > > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > > + struct usb_conn_info *info; > > + enum usb_role role; > > + int id, vbus, ret; > > + > > + info = container_of(to_delayed_work(work), > > + struct usb_conn_info, dw_det); > > + > > + /* check ID and VBUS */ > > + id = info->id_gpiod ? > > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > > + vbus = info->vbus_gpiod ? > > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > > + > > + if (!id) > > + role = USB_ROLE_HOST; > > + else if (vbus) > > + role = USB_ROLE_DEVICE; > > + else > > + role = USB_ROLE_NONE; > > + > > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > > + info->last_role, role, id, vbus); > > + > > + if (info->last_role == role) { > > + dev_warn(info->dev, "repeated role: %d\n", role); > > + return; > > + } > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + ret = usb_role_switch_set_role(info->role_sw, role); > > + if (ret) > > + dev_err(info->dev, "failed to set role: %d\n", ret); > > + > > + if (role == USB_ROLE_HOST) { > > + ret = regulator_enable(info->vbus); > > + if (ret) > > + dev_err(info->dev, "enable vbus regulator failed\n"); > > + } > > + > > + info->last_role = role; > > + > > + dev_dbg(info->dev, "vbus regulator is %s\n", > > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > > + > > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > > + unsigned long delay) > > +{ > > + queue_delayed_work(system_power_efficient_wq, &info- > > >dw_det, delay); } > > + > > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > > + struct usb_conn_info *info = dev_id; > > + > > + usb_conn_queue_dwork(info, info->debounce_jiffies); > > + > > + return IRQ_HANDLED; > > +} > > + > > +static int usb_conn_probe(struct platform_device *pdev) { > > + struct device *dev = &pdev->dev; > > + struct device_node *np = dev->of_node; > > + struct device_node *parent; > > + struct device_node *child; > > + struct usb_conn_info *info; > > + int ret = 0; > > + > > + if (!np) > > + return -EINVAL; > > + > > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > > + if (!info) > > + return -ENOMEM; > > + > > + info->dev = dev; > > + > > + child = of_get_child_by_name(np, "connector"); > > + if (!child) { > > + dev_err(dev, "failed to find connector node\n"); > > + return -ENODEV; > > + } > > + > > + info->id_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > > + if (IS_ERR(info->id_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->id_gpiod); > > + } > > + > > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "vbus-gpios", 0, GPIOD_IN, > > + "vbuspin"); > > + if (IS_ERR(info->vbus_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->vbus_gpiod); > > + } > > + > > + if (!info->id_gpiod && !info->vbus_gpiod) { > > + dev_err(dev, "failed to get gpios\n"); > > + return -ENODEV; > > + } > > + > > + of_node_put(child); > > + > > + if (info->id_gpiod) > > + ret = gpiod_set_debounce(info->id_gpiod, > > USB_GPIO_DEB_US); > > + if (!ret && info->vbus_gpiod) > > + ret = gpiod_set_debounce(info->vbus_gpiod, > > USB_GPIO_DEB_US); > > + if (ret < 0) > > + info->debounce_jiffies = > > msecs_to_jiffies(USB_GPIO_DEB_MS); > > + > > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > > + > > + info->vbus = devm_regulator_get(dev, "vbus"); > > + if (IS_ERR(info->vbus)) { > > + dev_err(dev, "failed to get vbus\n"); > > + return PTR_ERR(info->vbus); > > + } > > + > > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > > + parent = of_graph_get_remote_port_parent(child); > > + info->role_sw = > > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > > + of_node_put(child); > > + of_node_put(parent); > > + if (IS_ERR(info->role_sw)) { > > + dev_err(dev, "failed to get role switch\n"); > > + return PTR_ERR(info->role_sw); > > + } > > + > > + if (info->id_gpiod) { > > + info->id_irq = gpiod_to_irq(info->id_gpiod); > > + if (info->id_irq < 0) { > > + dev_err(dev, "failed to get ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? Good catch, will fix it. Thanks > > + return info->id_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + if (info->vbus_gpiod) { > > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > > + if (info->vbus_irq < 0) { > > + dev_err(dev, "failed to get VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); > > + return info->vbus_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > > NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + platform_set_drvdata(pdev, info); > > + > > + /* Perform initial detection */ > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static int usb_conn_remove(struct platform_device *pdev) { > > + struct usb_conn_info *info = platform_get_drvdata(pdev); > > + > > + cancel_delayed_work_sync(&info->dw_det); > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + usb_role_switch_put(info->role_sw); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + if (info->id_gpiod) > > + disable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + disable_irq(info->vbus_irq); > > + > > + pinctrl_pm_select_sleep_state(dev); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_resume(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + pinctrl_pm_select_default_state(dev); > > + > > + if (info->id_gpiod) > > + enable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + enable_irq(info->vbus_irq); > > + > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > > + usb_conn_suspend, usb_conn_resume); > > + > > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > > &usb_conn_pm_ops : > > +NULL) > > + > > +static const struct of_device_id usb_conn_dt_match[] = { > > + { .compatible = "linux,typeb-conn-gpio", }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > > + > > +static struct platform_driver usb_conn_driver = { > > + .probe = usb_conn_probe, > > + .remove = usb_conn_remove, > > + .driver = { > > + .name = "typeb-conn-gpio", > > + .pm = DEV_PMS_OPS, > > + .of_match_table = usb_conn_dt_match, > > + }, > > +}; > > + > > +module_platform_driver(usb_conn_driver); > > + > > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > > +MODULE_LICENSE("GPL v2"); > > -- > > 2.21.0 > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 69+ messages in thread
* [v4,5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-28 9:26 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 9:26 UTC (permalink / raw) To: Biju Das Cc: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek Hi Biju, On Fri, 2019-04-26 at 09:22 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > > > Due to the requirement of usb-connector.txt binding, the old way using > > extcon to support USB Dual-Role switch is now deprecated when use Type-B > > connector. > > This patch introduces a driver of Type-B connector which typically uses an > > input GPIO to detect USB ID pin, and try to replace the function provided by > > extcon-usb-gpio driver > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 changes: > > 1. remove linux/gpio.h suggested by Linus > > 2. put node when error happens > > > > v3 changes: > > 1. treat bype-B connector as a virtual device; > > 2. change file name again > > > > v2 changes: > > 1. file name is changed > > 2. use new compatible > > --- > > drivers/usb/roles/Kconfig | 11 + > > drivers/usb/roles/Makefile | 1 + > > drivers/usb/roles/typeb-conn-gpio.c | 305 > > ++++++++++++++++++++++++++++ > > 3 files changed, 317 insertions(+) > > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > > f8b31aa67526..d1156e18a81a 100644 > > --- a/drivers/usb/roles/Kconfig > > +++ b/drivers/usb/roles/Kconfig > > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > > To compile the driver as a module, choose M here: the module will > > be called intel-xhci-usb-role-switch. > > > > +config TYPEB_CONN_GPIO > > + tristate "USB Type-B GPIO Connector" > > + depends on GPIOLIB > > + help > > + The driver supports USB role switch between host and device via > > GPIO > > + based USB cable detection, used typically if an input GPIO is used > > + to detect USB ID pin. > > + > > + To compile the driver as a module, choose M here: the module will > > + be called typeb-conn-gpio.ko > > + > > endif # USB_ROLE_SWITCH > > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > > 757a7d2797eb..5d5620d9d113 100644 > > --- a/drivers/usb/roles/Makefile > > +++ b/drivers/usb/roles/Makefile > > @@ -3,3 +3,4 @@ > > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > > roles-y := class.o > > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > > switch.o > > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > > conn-gpio.c > > new file mode 100644 > > index 000000000000..097d2ca12a12 > > --- /dev/null > > +++ b/drivers/usb/roles/typeb-conn-gpio.c > > @@ -0,0 +1,305 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * USB Type-B GPIO Connector Driver > > + * > > + * Copyright (C) 2019 MediaTek Inc. > > + * > > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > > + * > > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > > + > > +#include <linux/device.h> > > +#include <linux/gpio/consumer.h> > > +#include <linux/interrupt.h> > > +#include <linux/irq.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/of_graph.h> > > +#include <linux/pinctrl/consumer.h> > > +#include <linux/platform_device.h> > > +#include <linux/regulator/consumer.h> > > +#include <linux/usb/role.h> > > + > > +#define USB_GPIO_DEB_MS 20 /* ms */ > > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > > */ > > + > > +#define USB_CONN_IRQF \ > > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > > IRQF_ONESHOT) > > + > > +struct usb_conn_info { > > + struct device *dev; > > + struct usb_role_switch *role_sw; > > + enum usb_role last_role; > > + struct regulator *vbus; > > + struct delayed_work dw_det; > > + unsigned long debounce_jiffies; > > + > > + struct gpio_desc *id_gpiod; > > + struct gpio_desc *vbus_gpiod; > > + int id_irq; > > + int vbus_irq; > > +}; > > + > > +/** > > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > > + * Both "DEVICE" and "HOST" can't be set as active at the same time > > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > > + * even if VBUS is on. > > + * > > + * Role | ID | VBUS > > + * ------------------------------------ > > + * [1] DEVICE | H | H > > + * [2] NONE | H | L > > + * [3] HOST | L | H > > + * [4] HOST | L | L > > + * > > + * In case we have only one of these signals: > > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > > +always 1 > > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > > + struct usb_conn_info *info; > > + enum usb_role role; > > + int id, vbus, ret; > > + > > + info = container_of(to_delayed_work(work), > > + struct usb_conn_info, dw_det); > > + > > + /* check ID and VBUS */ > > + id = info->id_gpiod ? > > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > > + vbus = info->vbus_gpiod ? > > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > > + > > + if (!id) > > + role = USB_ROLE_HOST; > > + else if (vbus) > > + role = USB_ROLE_DEVICE; > > + else > > + role = USB_ROLE_NONE; > > + > > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > > + info->last_role, role, id, vbus); > > + > > + if (info->last_role == role) { > > + dev_warn(info->dev, "repeated role: %d\n", role); > > + return; > > + } > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + ret = usb_role_switch_set_role(info->role_sw, role); > > + if (ret) > > + dev_err(info->dev, "failed to set role: %d\n", ret); > > + > > + if (role == USB_ROLE_HOST) { > > + ret = regulator_enable(info->vbus); > > + if (ret) > > + dev_err(info->dev, "enable vbus regulator failed\n"); > > + } > > + > > + info->last_role = role; > > + > > + dev_dbg(info->dev, "vbus regulator is %s\n", > > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > > + > > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > > + unsigned long delay) > > +{ > > + queue_delayed_work(system_power_efficient_wq, &info- > > >dw_det, delay); } > > + > > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > > + struct usb_conn_info *info = dev_id; > > + > > + usb_conn_queue_dwork(info, info->debounce_jiffies); > > + > > + return IRQ_HANDLED; > > +} > > + > > +static int usb_conn_probe(struct platform_device *pdev) { > > + struct device *dev = &pdev->dev; > > + struct device_node *np = dev->of_node; > > + struct device_node *parent; > > + struct device_node *child; > > + struct usb_conn_info *info; > > + int ret = 0; > > + > > + if (!np) > > + return -EINVAL; > > + > > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > > + if (!info) > > + return -ENOMEM; > > + > > + info->dev = dev; > > + > > + child = of_get_child_by_name(np, "connector"); > > + if (!child) { > > + dev_err(dev, "failed to find connector node\n"); > > + return -ENODEV; > > + } > > + > > + info->id_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > > + if (IS_ERR(info->id_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->id_gpiod); > > + } > > + > > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "vbus-gpios", 0, GPIOD_IN, > > + "vbuspin"); > > + if (IS_ERR(info->vbus_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->vbus_gpiod); > > + } > > + > > + if (!info->id_gpiod && !info->vbus_gpiod) { > > + dev_err(dev, "failed to get gpios\n"); > > + return -ENODEV; > > + } > > + > > + of_node_put(child); > > + > > + if (info->id_gpiod) > > + ret = gpiod_set_debounce(info->id_gpiod, > > USB_GPIO_DEB_US); > > + if (!ret && info->vbus_gpiod) > > + ret = gpiod_set_debounce(info->vbus_gpiod, > > USB_GPIO_DEB_US); > > + if (ret < 0) > > + info->debounce_jiffies = > > msecs_to_jiffies(USB_GPIO_DEB_MS); > > + > > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > > + > > + info->vbus = devm_regulator_get(dev, "vbus"); > > + if (IS_ERR(info->vbus)) { > > + dev_err(dev, "failed to get vbus\n"); > > + return PTR_ERR(info->vbus); > > + } > > + > > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > > + parent = of_graph_get_remote_port_parent(child); > > + info->role_sw = > > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > > + of_node_put(child); > > + of_node_put(parent); > > + if (IS_ERR(info->role_sw)) { > > + dev_err(dev, "failed to get role switch\n"); > > + return PTR_ERR(info->role_sw); > > + } > > + > > + if (info->id_gpiod) { > > + info->id_irq = gpiod_to_irq(info->id_gpiod); > > + if (info->id_irq < 0) { > > + dev_err(dev, "failed to get ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? Good catch, will fix it. Thanks > > + return info->id_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + if (info->vbus_gpiod) { > > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > > + if (info->vbus_irq < 0) { > > + dev_err(dev, "failed to get VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); > > + return info->vbus_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > > NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + platform_set_drvdata(pdev, info); > > + > > + /* Perform initial detection */ > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static int usb_conn_remove(struct platform_device *pdev) { > > + struct usb_conn_info *info = platform_get_drvdata(pdev); > > + > > + cancel_delayed_work_sync(&info->dw_det); > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + usb_role_switch_put(info->role_sw); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + if (info->id_gpiod) > > + disable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + disable_irq(info->vbus_irq); > > + > > + pinctrl_pm_select_sleep_state(dev); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_resume(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + pinctrl_pm_select_default_state(dev); > > + > > + if (info->id_gpiod) > > + enable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + enable_irq(info->vbus_irq); > > + > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > > + usb_conn_suspend, usb_conn_resume); > > + > > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > > &usb_conn_pm_ops : > > +NULL) > > + > > +static const struct of_device_id usb_conn_dt_match[] = { > > + { .compatible = "linux,typeb-conn-gpio", }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > > + > > +static struct platform_driver usb_conn_driver = { > > + .probe = usb_conn_probe, > > + .remove = usb_conn_remove, > > + .driver = { > > + .name = "typeb-conn-gpio", > > + .pm = DEV_PMS_OPS, > > + .of_match_table = usb_conn_dt_match, > > + }, > > +}; > > + > > +module_platform_driver(usb_conn_driver); > > + > > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > > +MODULE_LICENSE("GPL v2"); > > -- > > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* RE: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver @ 2019-04-28 9:26 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-28 9:26 UTC (permalink / raw) To: Biju Das Cc: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus, Mark Rutland, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek@lists.infradead.org Hi Biju, On Fri, 2019-04-26 at 09:22 +0000, Biju Das wrote: > Hi Chunfeng Yun, > > Thanks for the patch. > > > Subject: [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver > > > > Due to the requirement of usb-connector.txt binding, the old way using > > extcon to support USB Dual-Role switch is now deprecated when use Type-B > > connector. > > This patch introduces a driver of Type-B connector which typically uses an > > input GPIO to detect USB ID pin, and try to replace the function provided by > > extcon-usb-gpio driver > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> > > --- > > v4 changes: > > 1. remove linux/gpio.h suggested by Linus > > 2. put node when error happens > > > > v3 changes: > > 1. treat bype-B connector as a virtual device; > > 2. change file name again > > > > v2 changes: > > 1. file name is changed > > 2. use new compatible > > --- > > drivers/usb/roles/Kconfig | 11 + > > drivers/usb/roles/Makefile | 1 + > > drivers/usb/roles/typeb-conn-gpio.c | 305 > > ++++++++++++++++++++++++++++ > > 3 files changed, 317 insertions(+) > > create mode 100644 drivers/usb/roles/typeb-conn-gpio.c > > > > diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index > > f8b31aa67526..d1156e18a81a 100644 > > --- a/drivers/usb/roles/Kconfig > > +++ b/drivers/usb/roles/Kconfig > > @@ -26,4 +26,15 @@ config USB_ROLES_INTEL_XHCI > > To compile the driver as a module, choose M here: the module will > > be called intel-xhci-usb-role-switch. > > > > +config TYPEB_CONN_GPIO > > + tristate "USB Type-B GPIO Connector" > > + depends on GPIOLIB > > + help > > + The driver supports USB role switch between host and device via > > GPIO > > + based USB cable detection, used typically if an input GPIO is used > > + to detect USB ID pin. > > + > > + To compile the driver as a module, choose M here: the module will > > + be called typeb-conn-gpio.ko > > + > > endif # USB_ROLE_SWITCH > > diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index > > 757a7d2797eb..5d5620d9d113 100644 > > --- a/drivers/usb/roles/Makefile > > +++ b/drivers/usb/roles/Makefile > > @@ -3,3 +3,4 @@ > > obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o > > roles-y := class.o > > obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role- > > switch.o > > +obj-$(CONFIG_TYPEB_CONN_GPIO) += typeb-conn-gpio.o > > diff --git a/drivers/usb/roles/typeb-conn-gpio.c b/drivers/usb/roles/typeb- > > conn-gpio.c > > new file mode 100644 > > index 000000000000..097d2ca12a12 > > --- /dev/null > > +++ b/drivers/usb/roles/typeb-conn-gpio.c > > @@ -0,0 +1,305 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * USB Type-B GPIO Connector Driver > > + * > > + * Copyright (C) 2019 MediaTek Inc. > > + * > > + * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> > > + * > > + * Some code borrowed from drivers/extcon/extcon-usb-gpio.c */ > > + > > +#include <linux/device.h> > > +#include <linux/gpio/consumer.h> > > +#include <linux/interrupt.h> > > +#include <linux/irq.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/of_graph.h> > > +#include <linux/pinctrl/consumer.h> > > +#include <linux/platform_device.h> > > +#include <linux/regulator/consumer.h> > > +#include <linux/usb/role.h> > > + > > +#define USB_GPIO_DEB_MS 20 /* ms */ > > +#define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us > > */ > > + > > +#define USB_CONN_IRQF \ > > + (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > > IRQF_ONESHOT) > > + > > +struct usb_conn_info { > > + struct device *dev; > > + struct usb_role_switch *role_sw; > > + enum usb_role last_role; > > + struct regulator *vbus; > > + struct delayed_work dw_det; > > + unsigned long debounce_jiffies; > > + > > + struct gpio_desc *id_gpiod; > > + struct gpio_desc *vbus_gpiod; > > + int id_irq; > > + int vbus_irq; > > +}; > > + > > +/** > > + * "DEVICE" = VBUS and "HOST" = !ID, so we have: > > + * Both "DEVICE" and "HOST" can't be set as active at the same time > > + * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive > > + * even if VBUS is on. > > + * > > + * Role | ID | VBUS > > + * ------------------------------------ > > + * [1] DEVICE | H | H > > + * [2] NONE | H | L > > + * [3] HOST | L | H > > + * [4] HOST | L | L > > + * > > + * In case we have only one of these signals: > > + * - VBUS only - we want to distinguish between [1] and [2], so ID is > > +always 1 > > + * - ID only - we want to distinguish between [1] and [4], so VBUS = ID > > +*/ static void usb_conn_detect_cable(struct work_struct *work) { > > + struct usb_conn_info *info; > > + enum usb_role role; > > + int id, vbus, ret; > > + > > + info = container_of(to_delayed_work(work), > > + struct usb_conn_info, dw_det); > > + > > + /* check ID and VBUS */ > > + id = info->id_gpiod ? > > + gpiod_get_value_cansleep(info->id_gpiod) : 1; > > + vbus = info->vbus_gpiod ? > > + gpiod_get_value_cansleep(info->vbus_gpiod) : id; > > + > > + if (!id) > > + role = USB_ROLE_HOST; > > + else if (vbus) > > + role = USB_ROLE_DEVICE; > > + else > > + role = USB_ROLE_NONE; > > + > > + dev_dbg(info->dev, "role %d/%d, gpios: id %d, vbus %d\n", > > + info->last_role, role, id, vbus); > > + > > + if (info->last_role == role) { > > + dev_warn(info->dev, "repeated role: %d\n", role); > > + return; > > + } > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + ret = usb_role_switch_set_role(info->role_sw, role); > > + if (ret) > > + dev_err(info->dev, "failed to set role: %d\n", ret); > > + > > + if (role == USB_ROLE_HOST) { > > + ret = regulator_enable(info->vbus); > > + if (ret) > > + dev_err(info->dev, "enable vbus regulator failed\n"); > > + } > > + > > + info->last_role = role; > > + > > + dev_dbg(info->dev, "vbus regulator is %s\n", > > + regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); } > > + > > +static void usb_conn_queue_dwork(struct usb_conn_info *info, > > + unsigned long delay) > > +{ > > + queue_delayed_work(system_power_efficient_wq, &info- > > >dw_det, delay); } > > + > > +static irqreturn_t usb_conn_isr(int irq, void *dev_id) { > > + struct usb_conn_info *info = dev_id; > > + > > + usb_conn_queue_dwork(info, info->debounce_jiffies); > > + > > + return IRQ_HANDLED; > > +} > > + > > +static int usb_conn_probe(struct platform_device *pdev) { > > + struct device *dev = &pdev->dev; > > + struct device_node *np = dev->of_node; > > + struct device_node *parent; > > + struct device_node *child; > > + struct usb_conn_info *info; > > + int ret = 0; > > + > > + if (!np) > > + return -EINVAL; > > + > > + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); > > + if (!info) > > + return -ENOMEM; > > + > > + info->dev = dev; > > + > > + child = of_get_child_by_name(np, "connector"); > > + if (!child) { > > + dev_err(dev, "failed to find connector node\n"); > > + return -ENODEV; > > + } > > + > > + info->id_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "id-gpios", 0, GPIOD_IN, "idpin"); > > + if (IS_ERR(info->id_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->id_gpiod); > > + } > > + > > + info->vbus_gpiod = devm_gpiod_get_from_of_node( > > + dev, child, "vbus-gpios", 0, GPIOD_IN, > > + "vbuspin"); > > + if (IS_ERR(info->vbus_gpiod)) { > > + of_node_put(child); > > + return PTR_ERR(info->vbus_gpiod); > > + } > > + > > + if (!info->id_gpiod && !info->vbus_gpiod) { > > + dev_err(dev, "failed to get gpios\n"); > > + return -ENODEV; > > + } > > + > > + of_node_put(child); > > + > > + if (info->id_gpiod) > > + ret = gpiod_set_debounce(info->id_gpiod, > > USB_GPIO_DEB_US); > > + if (!ret && info->vbus_gpiod) > > + ret = gpiod_set_debounce(info->vbus_gpiod, > > USB_GPIO_DEB_US); > > + if (ret < 0) > > + info->debounce_jiffies = > > msecs_to_jiffies(USB_GPIO_DEB_MS); > > + > > + INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); > > + > > + info->vbus = devm_regulator_get(dev, "vbus"); > > + if (IS_ERR(info->vbus)) { > > + dev_err(dev, "failed to get vbus\n"); > > + return PTR_ERR(info->vbus); > > + } > > + > > + child = of_graph_get_endpoint_by_regs(np, -1, 0); > > + parent = of_graph_get_remote_port_parent(child); > > + info->role_sw = > > fwnode_usb_role_switch_get(of_fwnode_handle(parent)); > > + of_node_put(child); > > + of_node_put(parent); > > + if (IS_ERR(info->role_sw)) { > > + dev_err(dev, "failed to get role switch\n"); > > + return PTR_ERR(info->role_sw); > > + } > > + > > + if (info->id_gpiod) { > > + info->id_irq = gpiod_to_irq(info->id_gpiod); > > + if (info->id_irq < 0) { > > + dev_err(dev, "failed to get ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? Good catch, will fix it. Thanks > > + return info->id_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->id_irq, NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request ID IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + if (info->vbus_gpiod) { > > + info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); > > + if (info->vbus_irq < 0) { > > + dev_err(dev, "failed to get VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); > > + return info->vbus_irq; > > + } > > + > > + ret = devm_request_threaded_irq(dev, info->vbus_irq, > > NULL, > > + usb_conn_isr, > > USB_CONN_IRQF, > > + pdev->name, info); > > + if (ret < 0) { > > + dev_err(dev, "failed to request VBUS IRQ\n"); > May be usb_role_switch_put(info->role_sw); ?? > > + return ret; > > + } > > + } > > + > > + platform_set_drvdata(pdev, info); > > + > > + /* Perform initial detection */ > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static int usb_conn_remove(struct platform_device *pdev) { > > + struct usb_conn_info *info = platform_get_drvdata(pdev); > > + > > + cancel_delayed_work_sync(&info->dw_det); > > + > > + if (info->last_role == USB_ROLE_HOST) > > + regulator_disable(info->vbus); > > + > > + usb_role_switch_put(info->role_sw); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_suspend(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + if (info->id_gpiod) > > + disable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + disable_irq(info->vbus_irq); > > + > > + pinctrl_pm_select_sleep_state(dev); > > + > > + return 0; > > +} > > + > > +static int __maybe_unused usb_conn_resume(struct device *dev) { > > + struct usb_conn_info *info = dev_get_drvdata(dev); > > + > > + pinctrl_pm_select_default_state(dev); > > + > > + if (info->id_gpiod) > > + enable_irq(info->id_irq); > > + if (info->vbus_gpiod) > > + enable_irq(info->vbus_irq); > > + > > + usb_conn_queue_dwork(info, 0); > > + > > + return 0; > > +} > > + > > +static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, > > + usb_conn_suspend, usb_conn_resume); > > + > > +#define DEV_PMS_OPS (IS_ENABLED(CONFIG_PM_SLEEP) ? > > &usb_conn_pm_ops : > > +NULL) > > + > > +static const struct of_device_id usb_conn_dt_match[] = { > > + { .compatible = "linux,typeb-conn-gpio", }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(of, usb_conn_dt_match); > > + > > +static struct platform_driver usb_conn_driver = { > > + .probe = usb_conn_probe, > > + .remove = usb_conn_remove, > > + .driver = { > > + .name = "typeb-conn-gpio", > > + .pm = DEV_PMS_OPS, > > + .of_match_table = usb_conn_dt_match, > > + }, > > +}; > > + > > +module_platform_driver(usb_conn_driver); > > + > > +MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); > > +MODULE_DESCRIPTION("USB Type-B GPIO connector driver"); > > +MODULE_LICENSE("GPL v2"); > > -- > > 2.21.0 > ^ permalink raw reply [flat|nested] 69+ messages in thread
* [PATCH v4 6/6] usb: mtu3: register a USB Role Switch for dual role mode 2019-04-26 6:47 ` Chunfeng Yun (?) (?) @ 2019-04-26 6:47 ` Chunfeng Yun -1 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Because extcon is not allowed for new bindings, and the dual role switch is supported by USB Role Switch, especially for Type-C drivers, so register a USB Role Switch to support the new way Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. assign fwnode member of usb_role_switch struct suggested by Heikki v3 changes: 1. select USB_ROLE_SWITCH in Kconfig suggested by Heikki 2. rename ssusb_mode_manual_switch() to ssusb_mode_switch() v2 no change --- drivers/usb/mtu3/Kconfig | 1 + drivers/usb/mtu3/mtu3.h | 5 ++++ drivers/usb/mtu3/mtu3_debugfs.c | 4 +-- drivers/usb/mtu3/mtu3_dr.c | 48 ++++++++++++++++++++++++++++++++- drivers/usb/mtu3/mtu3_dr.h | 6 ++--- drivers/usb/mtu3/mtu3_plat.c | 3 ++- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig index bcc23486c4ed..88e3db7b3016 100644 --- a/drivers/usb/mtu3/Kconfig +++ b/drivers/usb/mtu3/Kconfig @@ -43,6 +43,7 @@ config USB_MTU3_DUAL_ROLE bool "Dual Role mode" depends on ((USB=y || USB=USB_MTU3) && (USB_GADGET=y || USB_GADGET=USB_MTU3)) depends on (EXTCON=y || EXTCON=USB_MTU3) + select USB_ROLE_SWITCH help This is the default mode of working of MTU3 controller where both host and gadget features are enabled. diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 76ecf12fdf62..6087be236a35 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -199,6 +199,9 @@ struct mtu3_gpd_ring { * @id_nb : notifier for iddig(idpin) detection * @id_work : work of iddig detection notifier * @id_event : event of iddig detecion notifier +* @role_sw : use USB Role Switch to support dual-role switch, can't use +* extcon at the same time, and extcon is deprecated. +* @role_sw_used : true when the USB Role Switch is used. * @is_u3_drd: whether port0 supports usb3.0 dual-role device or not * @manual_drd_enabled: it's true when supports dual-role device by debugfs * to switch host/device modes depending on user input. @@ -212,6 +215,8 @@ struct otg_switch_mtk { struct notifier_block id_nb; struct work_struct id_work; unsigned long id_event; + struct usb_role_switch *role_sw; + bool role_sw_used; bool is_u3_drd; bool manual_drd_enabled; }; diff --git a/drivers/usb/mtu3/mtu3_debugfs.c b/drivers/usb/mtu3/mtu3_debugfs.c index 62c57ddc554e..c96e5dab0a48 100644 --- a/drivers/usb/mtu3/mtu3_debugfs.c +++ b/drivers/usb/mtu3/mtu3_debugfs.c @@ -453,9 +453,9 @@ static ssize_t ssusb_mode_write(struct file *file, const char __user *ubuf, return -EFAULT; if (!strncmp(buf, "host", 4) && !ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 1); + ssusb_mode_switch(ssusb, 1); } else if (!strncmp(buf, "device", 6) && ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 0); + ssusb_mode_switch(ssusb, 0); } else { dev_err(ssusb->dev, "wrong or duplicated setting\n"); return -EINVAL; diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 5fcb71af875a..08e18448e8b8 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -7,6 +7,8 @@ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> */ +#include <linux/usb/role.h> + #include "mtu3.h" #include "mtu3_dr.h" #include "mtu3_debug.h" @@ -280,7 +282,7 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) * This is useful in special cases, such as uses TYPE-A receptacle but also * wants to support dual-role mode. */ -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -318,6 +320,47 @@ void ssusb_set_force_mode(struct ssusb_mtk *ssusb, mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); } +static int ssusb_role_sw_set(struct device *dev, enum usb_role role) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + bool to_host = false; + + if (role == USB_ROLE_HOST) + to_host = true; + + if (to_host ^ ssusb->is_host) + ssusb_mode_switch(ssusb, to_host); + + return 0; +} + +static enum usb_role ssusb_role_sw_get(struct device *dev) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + enum usb_role role; + + role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; + + return role; +} + +static int ssusb_role_sw_register(struct otg_switch_mtk *otg_sx) +{ + struct usb_role_switch_desc role_sx_desc = { 0 }; + struct ssusb_mtk *ssusb = + container_of(otg_sx, struct ssusb_mtk, otg_switch); + + if (!otg_sx->role_sw_used) + return 0; + + role_sx_desc.set = ssusb_role_sw_set; + role_sx_desc.get = ssusb_role_sw_get; + role_sx_desc.fwnode = dev_fwnode(ssusb->dev); + otg_sx->role_sw = usb_role_switch_register(ssusb->dev, &role_sx_desc); + + return PTR_ERR_OR_ZERO(otg_sx->role_sw); +} + int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -328,6 +371,8 @@ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) if (otg_sx->manual_drd_enabled) ssusb_dr_debugfs_init(ssusb); + else if (otg_sx->role_sw_used) + ret = ssusb_role_sw_register(otg_sx); else ret = ssusb_extcon_register(otg_sx); @@ -340,4 +385,5 @@ void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) cancel_work_sync(&otg_sx->id_work); cancel_work_sync(&otg_sx->vbus_work); + usb_role_switch_unregister(otg_sx->role_sw); } diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h index ba6fe357ce29..5e58c4dbd54a 100644 --- a/drivers/usb/mtu3/mtu3_dr.h +++ b/drivers/usb/mtu3/mtu3_dr.h @@ -71,7 +71,7 @@ static inline void ssusb_gadget_exit(struct ssusb_mtk *ssusb) #if IS_ENABLED(CONFIG_USB_MTU3_DUAL_ROLE) int ssusb_otg_switch_init(struct ssusb_mtk *ssusb); void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb); -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host); +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host); int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on); void ssusb_set_force_mode(struct ssusb_mtk *ssusb, enum mtu3_dr_force_mode mode); @@ -86,8 +86,8 @@ static inline int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) static inline void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) {} -static inline void -ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) {} +static inline void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) +{} static inline int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on) { diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index fd0f6c5dfbc1..9c256ea3cdf5 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -299,8 +299,9 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd"); otg_sx->manual_drd_enabled = of_property_read_bool(node, "enable-manual-drd"); + otg_sx->role_sw_used = of_property_read_bool(node, "usb-role-switch"); - if (of_property_read_bool(node, "extcon")) { + if (!otg_sx->role_sw_used && of_property_read_bool(node, "extcon")) { otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0); if (IS_ERR(otg_sx->edev)) { dev_err(ssusb->dev, "couldn't get extcon device\n"); -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 6/6] usb: mtu3: register a USB Role Switch for dual role mode @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, devicetree, Hans de Goede, Badhri Jagan Sridharan, Linus Walleij, linux-usb, linux-kernel, Biju Das, Matthias Brugger, Andy Shevchenko, linux-mediatek, Min Guo, Chunfeng Yun, Adam Thomson, linux-arm-kernel, Li Jun Because extcon is not allowed for new bindings, and the dual role switch is supported by USB Role Switch, especially for Type-C drivers, so register a USB Role Switch to support the new way Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. assign fwnode member of usb_role_switch struct suggested by Heikki v3 changes: 1. select USB_ROLE_SWITCH in Kconfig suggested by Heikki 2. rename ssusb_mode_manual_switch() to ssusb_mode_switch() v2 no change --- drivers/usb/mtu3/Kconfig | 1 + drivers/usb/mtu3/mtu3.h | 5 ++++ drivers/usb/mtu3/mtu3_debugfs.c | 4 +-- drivers/usb/mtu3/mtu3_dr.c | 48 ++++++++++++++++++++++++++++++++- drivers/usb/mtu3/mtu3_dr.h | 6 ++--- drivers/usb/mtu3/mtu3_plat.c | 3 ++- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig index bcc23486c4ed..88e3db7b3016 100644 --- a/drivers/usb/mtu3/Kconfig +++ b/drivers/usb/mtu3/Kconfig @@ -43,6 +43,7 @@ config USB_MTU3_DUAL_ROLE bool "Dual Role mode" depends on ((USB=y || USB=USB_MTU3) && (USB_GADGET=y || USB_GADGET=USB_MTU3)) depends on (EXTCON=y || EXTCON=USB_MTU3) + select USB_ROLE_SWITCH help This is the default mode of working of MTU3 controller where both host and gadget features are enabled. diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 76ecf12fdf62..6087be236a35 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -199,6 +199,9 @@ struct mtu3_gpd_ring { * @id_nb : notifier for iddig(idpin) detection * @id_work : work of iddig detection notifier * @id_event : event of iddig detecion notifier +* @role_sw : use USB Role Switch to support dual-role switch, can't use +* extcon at the same time, and extcon is deprecated. +* @role_sw_used : true when the USB Role Switch is used. * @is_u3_drd: whether port0 supports usb3.0 dual-role device or not * @manual_drd_enabled: it's true when supports dual-role device by debugfs * to switch host/device modes depending on user input. @@ -212,6 +215,8 @@ struct otg_switch_mtk { struct notifier_block id_nb; struct work_struct id_work; unsigned long id_event; + struct usb_role_switch *role_sw; + bool role_sw_used; bool is_u3_drd; bool manual_drd_enabled; }; diff --git a/drivers/usb/mtu3/mtu3_debugfs.c b/drivers/usb/mtu3/mtu3_debugfs.c index 62c57ddc554e..c96e5dab0a48 100644 --- a/drivers/usb/mtu3/mtu3_debugfs.c +++ b/drivers/usb/mtu3/mtu3_debugfs.c @@ -453,9 +453,9 @@ static ssize_t ssusb_mode_write(struct file *file, const char __user *ubuf, return -EFAULT; if (!strncmp(buf, "host", 4) && !ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 1); + ssusb_mode_switch(ssusb, 1); } else if (!strncmp(buf, "device", 6) && ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 0); + ssusb_mode_switch(ssusb, 0); } else { dev_err(ssusb->dev, "wrong or duplicated setting\n"); return -EINVAL; diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 5fcb71af875a..08e18448e8b8 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -7,6 +7,8 @@ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> */ +#include <linux/usb/role.h> + #include "mtu3.h" #include "mtu3_dr.h" #include "mtu3_debug.h" @@ -280,7 +282,7 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) * This is useful in special cases, such as uses TYPE-A receptacle but also * wants to support dual-role mode. */ -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -318,6 +320,47 @@ void ssusb_set_force_mode(struct ssusb_mtk *ssusb, mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); } +static int ssusb_role_sw_set(struct device *dev, enum usb_role role) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + bool to_host = false; + + if (role == USB_ROLE_HOST) + to_host = true; + + if (to_host ^ ssusb->is_host) + ssusb_mode_switch(ssusb, to_host); + + return 0; +} + +static enum usb_role ssusb_role_sw_get(struct device *dev) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + enum usb_role role; + + role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; + + return role; +} + +static int ssusb_role_sw_register(struct otg_switch_mtk *otg_sx) +{ + struct usb_role_switch_desc role_sx_desc = { 0 }; + struct ssusb_mtk *ssusb = + container_of(otg_sx, struct ssusb_mtk, otg_switch); + + if (!otg_sx->role_sw_used) + return 0; + + role_sx_desc.set = ssusb_role_sw_set; + role_sx_desc.get = ssusb_role_sw_get; + role_sx_desc.fwnode = dev_fwnode(ssusb->dev); + otg_sx->role_sw = usb_role_switch_register(ssusb->dev, &role_sx_desc); + + return PTR_ERR_OR_ZERO(otg_sx->role_sw); +} + int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -328,6 +371,8 @@ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) if (otg_sx->manual_drd_enabled) ssusb_dr_debugfs_init(ssusb); + else if (otg_sx->role_sw_used) + ret = ssusb_role_sw_register(otg_sx); else ret = ssusb_extcon_register(otg_sx); @@ -340,4 +385,5 @@ void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) cancel_work_sync(&otg_sx->id_work); cancel_work_sync(&otg_sx->vbus_work); + usb_role_switch_unregister(otg_sx->role_sw); } diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h index ba6fe357ce29..5e58c4dbd54a 100644 --- a/drivers/usb/mtu3/mtu3_dr.h +++ b/drivers/usb/mtu3/mtu3_dr.h @@ -71,7 +71,7 @@ static inline void ssusb_gadget_exit(struct ssusb_mtk *ssusb) #if IS_ENABLED(CONFIG_USB_MTU3_DUAL_ROLE) int ssusb_otg_switch_init(struct ssusb_mtk *ssusb); void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb); -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host); +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host); int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on); void ssusb_set_force_mode(struct ssusb_mtk *ssusb, enum mtu3_dr_force_mode mode); @@ -86,8 +86,8 @@ static inline int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) static inline void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) {} -static inline void -ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) {} +static inline void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) +{} static inline int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on) { diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index fd0f6c5dfbc1..9c256ea3cdf5 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -299,8 +299,9 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd"); otg_sx->manual_drd_enabled = of_property_read_bool(node, "enable-manual-drd"); + otg_sx->role_sw_used = of_property_read_bool(node, "usb-role-switch"); - if (of_property_read_bool(node, "extcon")) { + if (!otg_sx->role_sw_used && of_property_read_bool(node, "extcon")) { otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0); if (IS_ERR(otg_sx->edev)) { dev_err(ssusb->dev, "couldn't get extcon device\n"); -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [v4,6/6] usb: mtu3: register a USB Role Switch for dual role mode @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Because extcon is not allowed for new bindings, and the dual role switch is supported by USB Role Switch, especially for Type-C drivers, so register a USB Role Switch to support the new way Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. assign fwnode member of usb_role_switch struct suggested by Heikki v3 changes: 1. select USB_ROLE_SWITCH in Kconfig suggested by Heikki 2. rename ssusb_mode_manual_switch() to ssusb_mode_switch() v2 no change --- drivers/usb/mtu3/Kconfig | 1 + drivers/usb/mtu3/mtu3.h | 5 ++++ drivers/usb/mtu3/mtu3_debugfs.c | 4 +-- drivers/usb/mtu3/mtu3_dr.c | 48 ++++++++++++++++++++++++++++++++- drivers/usb/mtu3/mtu3_dr.h | 6 ++--- drivers/usb/mtu3/mtu3_plat.c | 3 ++- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig index bcc23486c4ed..88e3db7b3016 100644 --- a/drivers/usb/mtu3/Kconfig +++ b/drivers/usb/mtu3/Kconfig @@ -43,6 +43,7 @@ config USB_MTU3_DUAL_ROLE bool "Dual Role mode" depends on ((USB=y || USB=USB_MTU3) && (USB_GADGET=y || USB_GADGET=USB_MTU3)) depends on (EXTCON=y || EXTCON=USB_MTU3) + select USB_ROLE_SWITCH help This is the default mode of working of MTU3 controller where both host and gadget features are enabled. diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 76ecf12fdf62..6087be236a35 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -199,6 +199,9 @@ struct mtu3_gpd_ring { * @id_nb : notifier for iddig(idpin) detection * @id_work : work of iddig detection notifier * @id_event : event of iddig detecion notifier +* @role_sw : use USB Role Switch to support dual-role switch, can't use +* extcon at the same time, and extcon is deprecated. +* @role_sw_used : true when the USB Role Switch is used. * @is_u3_drd: whether port0 supports usb3.0 dual-role device or not * @manual_drd_enabled: it's true when supports dual-role device by debugfs * to switch host/device modes depending on user input. @@ -212,6 +215,8 @@ struct otg_switch_mtk { struct notifier_block id_nb; struct work_struct id_work; unsigned long id_event; + struct usb_role_switch *role_sw; + bool role_sw_used; bool is_u3_drd; bool manual_drd_enabled; }; diff --git a/drivers/usb/mtu3/mtu3_debugfs.c b/drivers/usb/mtu3/mtu3_debugfs.c index 62c57ddc554e..c96e5dab0a48 100644 --- a/drivers/usb/mtu3/mtu3_debugfs.c +++ b/drivers/usb/mtu3/mtu3_debugfs.c @@ -453,9 +453,9 @@ static ssize_t ssusb_mode_write(struct file *file, const char __user *ubuf, return -EFAULT; if (!strncmp(buf, "host", 4) && !ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 1); + ssusb_mode_switch(ssusb, 1); } else if (!strncmp(buf, "device", 6) && ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 0); + ssusb_mode_switch(ssusb, 0); } else { dev_err(ssusb->dev, "wrong or duplicated setting\n"); return -EINVAL; diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 5fcb71af875a..08e18448e8b8 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -7,6 +7,8 @@ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> */ +#include <linux/usb/role.h> + #include "mtu3.h" #include "mtu3_dr.h" #include "mtu3_debug.h" @@ -280,7 +282,7 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) * This is useful in special cases, such as uses TYPE-A receptacle but also * wants to support dual-role mode. */ -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -318,6 +320,47 @@ void ssusb_set_force_mode(struct ssusb_mtk *ssusb, mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); } +static int ssusb_role_sw_set(struct device *dev, enum usb_role role) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + bool to_host = false; + + if (role == USB_ROLE_HOST) + to_host = true; + + if (to_host ^ ssusb->is_host) + ssusb_mode_switch(ssusb, to_host); + + return 0; +} + +static enum usb_role ssusb_role_sw_get(struct device *dev) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + enum usb_role role; + + role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; + + return role; +} + +static int ssusb_role_sw_register(struct otg_switch_mtk *otg_sx) +{ + struct usb_role_switch_desc role_sx_desc = { 0 }; + struct ssusb_mtk *ssusb = + container_of(otg_sx, struct ssusb_mtk, otg_switch); + + if (!otg_sx->role_sw_used) + return 0; + + role_sx_desc.set = ssusb_role_sw_set; + role_sx_desc.get = ssusb_role_sw_get; + role_sx_desc.fwnode = dev_fwnode(ssusb->dev); + otg_sx->role_sw = usb_role_switch_register(ssusb->dev, &role_sx_desc); + + return PTR_ERR_OR_ZERO(otg_sx->role_sw); +} + int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -328,6 +371,8 @@ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) if (otg_sx->manual_drd_enabled) ssusb_dr_debugfs_init(ssusb); + else if (otg_sx->role_sw_used) + ret = ssusb_role_sw_register(otg_sx); else ret = ssusb_extcon_register(otg_sx); @@ -340,4 +385,5 @@ void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) cancel_work_sync(&otg_sx->id_work); cancel_work_sync(&otg_sx->vbus_work); + usb_role_switch_unregister(otg_sx->role_sw); } diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h index ba6fe357ce29..5e58c4dbd54a 100644 --- a/drivers/usb/mtu3/mtu3_dr.h +++ b/drivers/usb/mtu3/mtu3_dr.h @@ -71,7 +71,7 @@ static inline void ssusb_gadget_exit(struct ssusb_mtk *ssusb) #if IS_ENABLED(CONFIG_USB_MTU3_DUAL_ROLE) int ssusb_otg_switch_init(struct ssusb_mtk *ssusb); void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb); -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host); +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host); int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on); void ssusb_set_force_mode(struct ssusb_mtk *ssusb, enum mtu3_dr_force_mode mode); @@ -86,8 +86,8 @@ static inline int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) static inline void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) {} -static inline void -ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) {} +static inline void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) +{} static inline int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on) { diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index fd0f6c5dfbc1..9c256ea3cdf5 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -299,8 +299,9 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd"); otg_sx->manual_drd_enabled = of_property_read_bool(node, "enable-manual-drd"); + otg_sx->role_sw_used = of_property_read_bool(node, "usb-role-switch"); - if (of_property_read_bool(node, "extcon")) { + if (!otg_sx->role_sw_used && of_property_read_bool(node, "extcon")) { otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0); if (IS_ERR(otg_sx->edev)) { dev_err(ssusb->dev, "couldn't get extcon device\n"); ^ permalink raw reply related [flat|nested] 69+ messages in thread
* [PATCH v4 6/6] usb: mtu3: register a USB Role Switch for dual role mode @ 2019-04-26 6:47 ` Chunfeng Yun 0 siblings, 0 replies; 69+ messages in thread From: Chunfeng Yun @ 2019-04-26 6:47 UTC (permalink / raw) To: Rob Herring, Greg Kroah-Hartman, Heikki Krogerus Cc: Mark Rutland, Chunfeng Yun, Matthias Brugger, Adam Thomson, Li Jun, Badhri Jagan Sridharan, Hans de Goede, Andy Shevchenko, Min Guo, devicetree, linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek, Biju Das, Linus Walleij Because extcon is not allowed for new bindings, and the dual role switch is supported by USB Role Switch, especially for Type-C drivers, so register a USB Role Switch to support the new way Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> --- v4 changes: 1. assign fwnode member of usb_role_switch struct suggested by Heikki v3 changes: 1. select USB_ROLE_SWITCH in Kconfig suggested by Heikki 2. rename ssusb_mode_manual_switch() to ssusb_mode_switch() v2 no change --- drivers/usb/mtu3/Kconfig | 1 + drivers/usb/mtu3/mtu3.h | 5 ++++ drivers/usb/mtu3/mtu3_debugfs.c | 4 +-- drivers/usb/mtu3/mtu3_dr.c | 48 ++++++++++++++++++++++++++++++++- drivers/usb/mtu3/mtu3_dr.h | 6 ++--- drivers/usb/mtu3/mtu3_plat.c | 3 ++- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig index bcc23486c4ed..88e3db7b3016 100644 --- a/drivers/usb/mtu3/Kconfig +++ b/drivers/usb/mtu3/Kconfig @@ -43,6 +43,7 @@ config USB_MTU3_DUAL_ROLE bool "Dual Role mode" depends on ((USB=y || USB=USB_MTU3) && (USB_GADGET=y || USB_GADGET=USB_MTU3)) depends on (EXTCON=y || EXTCON=USB_MTU3) + select USB_ROLE_SWITCH help This is the default mode of working of MTU3 controller where both host and gadget features are enabled. diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 76ecf12fdf62..6087be236a35 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -199,6 +199,9 @@ struct mtu3_gpd_ring { * @id_nb : notifier for iddig(idpin) detection * @id_work : work of iddig detection notifier * @id_event : event of iddig detecion notifier +* @role_sw : use USB Role Switch to support dual-role switch, can't use +* extcon at the same time, and extcon is deprecated. +* @role_sw_used : true when the USB Role Switch is used. * @is_u3_drd: whether port0 supports usb3.0 dual-role device or not * @manual_drd_enabled: it's true when supports dual-role device by debugfs * to switch host/device modes depending on user input. @@ -212,6 +215,8 @@ struct otg_switch_mtk { struct notifier_block id_nb; struct work_struct id_work; unsigned long id_event; + struct usb_role_switch *role_sw; + bool role_sw_used; bool is_u3_drd; bool manual_drd_enabled; }; diff --git a/drivers/usb/mtu3/mtu3_debugfs.c b/drivers/usb/mtu3/mtu3_debugfs.c index 62c57ddc554e..c96e5dab0a48 100644 --- a/drivers/usb/mtu3/mtu3_debugfs.c +++ b/drivers/usb/mtu3/mtu3_debugfs.c @@ -453,9 +453,9 @@ static ssize_t ssusb_mode_write(struct file *file, const char __user *ubuf, return -EFAULT; if (!strncmp(buf, "host", 4) && !ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 1); + ssusb_mode_switch(ssusb, 1); } else if (!strncmp(buf, "device", 6) && ssusb->is_host) { - ssusb_mode_manual_switch(ssusb, 0); + ssusb_mode_switch(ssusb, 0); } else { dev_err(ssusb->dev, "wrong or duplicated setting\n"); return -EINVAL; diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 5fcb71af875a..08e18448e8b8 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -7,6 +7,8 @@ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> */ +#include <linux/usb/role.h> + #include "mtu3.h" #include "mtu3_dr.h" #include "mtu3_debug.h" @@ -280,7 +282,7 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) * This is useful in special cases, such as uses TYPE-A receptacle but also * wants to support dual-role mode. */ -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -318,6 +320,47 @@ void ssusb_set_force_mode(struct ssusb_mtk *ssusb, mtu3_writel(ssusb->ippc_base, SSUSB_U2_CTRL(0), value); } +static int ssusb_role_sw_set(struct device *dev, enum usb_role role) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + bool to_host = false; + + if (role == USB_ROLE_HOST) + to_host = true; + + if (to_host ^ ssusb->is_host) + ssusb_mode_switch(ssusb, to_host); + + return 0; +} + +static enum usb_role ssusb_role_sw_get(struct device *dev) +{ + struct ssusb_mtk *ssusb = dev_get_drvdata(dev); + enum usb_role role; + + role = ssusb->is_host ? USB_ROLE_HOST : USB_ROLE_DEVICE; + + return role; +} + +static int ssusb_role_sw_register(struct otg_switch_mtk *otg_sx) +{ + struct usb_role_switch_desc role_sx_desc = { 0 }; + struct ssusb_mtk *ssusb = + container_of(otg_sx, struct ssusb_mtk, otg_switch); + + if (!otg_sx->role_sw_used) + return 0; + + role_sx_desc.set = ssusb_role_sw_set; + role_sx_desc.get = ssusb_role_sw_get; + role_sx_desc.fwnode = dev_fwnode(ssusb->dev); + otg_sx->role_sw = usb_role_switch_register(ssusb->dev, &role_sx_desc); + + return PTR_ERR_OR_ZERO(otg_sx->role_sw); +} + int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; @@ -328,6 +371,8 @@ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) if (otg_sx->manual_drd_enabled) ssusb_dr_debugfs_init(ssusb); + else if (otg_sx->role_sw_used) + ret = ssusb_role_sw_register(otg_sx); else ret = ssusb_extcon_register(otg_sx); @@ -340,4 +385,5 @@ void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) cancel_work_sync(&otg_sx->id_work); cancel_work_sync(&otg_sx->vbus_work); + usb_role_switch_unregister(otg_sx->role_sw); } diff --git a/drivers/usb/mtu3/mtu3_dr.h b/drivers/usb/mtu3/mtu3_dr.h index ba6fe357ce29..5e58c4dbd54a 100644 --- a/drivers/usb/mtu3/mtu3_dr.h +++ b/drivers/usb/mtu3/mtu3_dr.h @@ -71,7 +71,7 @@ static inline void ssusb_gadget_exit(struct ssusb_mtk *ssusb) #if IS_ENABLED(CONFIG_USB_MTU3_DUAL_ROLE) int ssusb_otg_switch_init(struct ssusb_mtk *ssusb); void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb); -void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host); +void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host); int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on); void ssusb_set_force_mode(struct ssusb_mtk *ssusb, enum mtu3_dr_force_mode mode); @@ -86,8 +86,8 @@ static inline int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) static inline void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) {} -static inline void -ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) {} +static inline void ssusb_mode_switch(struct ssusb_mtk *ssusb, int to_host) +{} static inline int ssusb_set_vbus(struct otg_switch_mtk *otg_sx, int is_on) { diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index fd0f6c5dfbc1..9c256ea3cdf5 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -299,8 +299,9 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd"); otg_sx->manual_drd_enabled = of_property_read_bool(node, "enable-manual-drd"); + otg_sx->role_sw_used = of_property_read_bool(node, "usb-role-switch"); - if (of_property_read_bool(node, "extcon")) { + if (!otg_sx->role_sw_used && of_property_read_bool(node, "extcon")) { otg_sx->edev = extcon_get_edev_by_phandle(ssusb->dev, 0); if (IS_ERR(otg_sx->edev)) { dev_err(ssusb->dev, "couldn't get extcon device\n"); -- 2.21.0 ^ permalink raw reply related [flat|nested] 69+ messages in thread
end of thread, other threads:[~2019-04-30 6:58 UTC | newest] Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-04-26 6:47 [v4 PATCH 0/6] add USB Type-B GPIO connector driver Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 1/6] dt-bindings: connector: add optional properties for Type-B Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` [v4,1/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 1/6] " Chunfeng Yun 2019-04-26 13:19 ` Rob Herring 2019-04-26 13:19 ` Rob Herring 2019-04-26 13:19 ` [v4,1/6] " Rob Herring 2019-04-26 13:19 ` [PATCH v4 1/6] " Rob Herring 2019-04-26 6:47 ` [PATCH v4 2/6] dt-bindings: usb: add binding for Type-B GPIO connector driver Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` [v4,2/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 2/6] " Chunfeng Yun 2019-04-26 20:45 ` Rob Herring 2019-04-26 20:45 ` Rob Herring 2019-04-26 20:45 ` [v4,2/6] " Rob Herring 2019-04-28 1:50 ` [PATCH v4 2/6] " Chunfeng Yun 2019-04-28 1:50 ` Chunfeng Yun 2019-04-28 1:50 ` [v4,2/6] " Chunfeng Yun 2019-04-28 1:50 ` [PATCH v4 2/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 3/6] dt-bindings: usb: mtu3: add properties about USB Role Switch Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` [v4,3/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 3/6] " Chunfeng Yun 2019-04-26 20:49 ` Rob Herring 2019-04-26 20:49 ` Rob Herring 2019-04-26 20:49 ` [v4,3/6] " Rob Herring 2019-04-28 12:16 ` [PATCH v4 3/6] " Chunfeng Yun 2019-04-28 12:16 ` Chunfeng Yun 2019-04-28 12:16 ` [v4,3/6] " Chunfeng Yun 2019-04-28 12:16 ` [PATCH v4 3/6] " Chunfeng Yun 2019-04-29 16:25 ` Rob Herring 2019-04-29 16:25 ` Rob Herring 2019-04-29 16:25 ` [v4,3/6] " Rob Herring 2019-04-29 16:25 ` [PATCH v4 3/6] " Rob Herring 2019-04-30 6:57 ` Chunfeng Yun 2019-04-30 6:57 ` Chunfeng Yun 2019-04-30 6:57 ` [v4,3/6] " Chunfeng Yun 2019-04-30 6:57 ` [PATCH v4 3/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 4/6] usb: roles: add API to get usb_role_switch by node Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` [v4,4/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 4/6] " Chunfeng Yun 2019-04-26 7:02 ` Biju Das 2019-04-26 7:02 ` Biju Das 2019-04-26 7:02 ` [v4,4/6] " Biju Das 2019-04-26 7:02 ` [PATCH v4 4/6] " Biju Das 2019-04-26 7:16 ` Chunfeng Yun 2019-04-26 7:16 ` Chunfeng Yun 2019-04-26 7:16 ` [v4,4/6] " Chunfeng Yun 2019-04-26 7:16 ` [PATCH v4 4/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 5/6] usb: roles: add USB Type-B GPIO connector driver Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` [v4,5/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 5/6] " Chunfeng Yun 2019-04-26 9:22 ` Biju Das 2019-04-26 9:22 ` Biju Das 2019-04-26 9:22 ` [v4,5/6] " Biju Das 2019-04-26 9:22 ` [PATCH v4 5/6] " Biju Das 2019-04-28 9:26 ` Chunfeng Yun 2019-04-28 9:26 ` Chunfeng Yun 2019-04-28 9:26 ` [v4,5/6] " Chunfeng Yun 2019-04-28 9:26 ` [PATCH v4 5/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 6/6] usb: mtu3: register a USB Role Switch for dual role mode Chunfeng Yun 2019-04-26 6:47 ` Chunfeng Yun 2019-04-26 6:47 ` [v4,6/6] " Chunfeng Yun 2019-04-26 6:47 ` [PATCH v4 6/6] " Chunfeng Yun
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.