From: Li Jun <jun.li@nxp.com> To: heikki.krogerus@linux.intel.com, robh+dt@kernel.org, shawnguo@kernel.org Cc: gregkh@linuxfoundation.org, linux@roeck-us.net, linux-usb@vger.kernel.org, linux-imx@nxp.com, jun.li@nxp.com, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 3/4] usb: typec: add typec orientation switch support via mux controller Date: Wed, 19 May 2021 15:14:49 +0800 [thread overview] Message-ID: <1621408490-23811-4-git-send-email-jun.li@nxp.com> (raw) In-Reply-To: <1621408490-23811-1-git-send-email-jun.li@nxp.com> Some dedicated mux block can use existing mux controller as a mux provider, typec port as a consumer to select channel for orientation switch, this can be an alternate way to current typec_switch interface. Signed-off-by: Li Jun <jun.li@nxp.com> --- drivers/usb/typec/class.c | 26 +++++++++++++++++++++++++- drivers/usb/typec/class.h | 2 ++ drivers/usb/typec/mux.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/usb/typec_mux.h | 4 ++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index a29bf2c32233..1bb0275e6204 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1601,6 +1601,7 @@ static void typec_release(struct device *dev) ida_simple_remove(&typec_index_ida, port->id); ida_destroy(&port->mode_ids); typec_switch_put(port->sw); + typec_mux_control_switch_put(port->mux_control_switch); typec_mux_put(port->mux); kfree(port->cap); kfree(port); @@ -1816,6 +1817,13 @@ int typec_set_orientation(struct typec_port *port, if (ret) return ret; + if (!port->sw) { + ret = typec_mux_control_switch_set(port->mux_control_switch, + port->mux_control_switch_states[orientation]); + if (ret) + return ret; + } + port->orientation = orientation; sysfs_notify(&port->dev.kobj, NULL, "orientation"); kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); @@ -1991,7 +1999,7 @@ struct typec_port *typec_register_port(struct device *parent, const struct typec_capability *cap) { struct typec_port *port; - int ret; + int ret = 0; int id; port = kzalloc(sizeof(*port), GFP_KERNEL); @@ -2068,6 +2076,22 @@ struct typec_port *typec_register_port(struct device *parent, return ERR_PTR(ret); } + if (!port->sw) { + /* Try to get typec switch via general mux controller */ + port->mux_control_switch = typec_mux_control_switch_get(&port->dev); + if (IS_ERR(port->mux_control_switch)) + ret = PTR_ERR(port->mux_control_switch); + else if (port->mux_control_switch) + ret = device_property_read_u32_array(&port->dev, + "mux-control-switch-states", + port->mux_control_switch_states, + 3); + if (ret) { + put_device(&port->dev); + return ERR_PTR(ret); + } + } + port->mux = typec_mux_get(&port->dev, NULL); if (IS_ERR(port->mux)) { ret = PTR_ERR(port->mux); diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index aef03eb7e152..15dad2621c83 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -50,6 +50,8 @@ struct typec_port { enum typec_orientation orientation; struct typec_switch *sw; + struct mux_control *mux_control_switch; + int mux_control_switch_states[3]; struct typec_mux *mux; const struct typec_capability *cap; diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 9da22ae3006c..6c5c4f07286d 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -11,6 +11,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/mux/consumer.h> #include <linux/property.h> #include <linux/slab.h> @@ -176,6 +177,39 @@ void *typec_switch_get_drvdata(struct typec_switch *sw) } EXPORT_SYMBOL_GPL(typec_switch_get_drvdata); +struct mux_control *typec_mux_control_switch_get(struct device *dev) +{ + if (!device_property_present(dev, "mux-control-names")) + return NULL; + + return mux_control_get(dev, "typec-orientation-switch"); +} +EXPORT_SYMBOL_GPL(typec_mux_control_switch_get); + +int typec_mux_control_switch_set(struct mux_control *mc_sw, int state) +{ + int ret; + + if (!mc_sw) + return 0; + + ret = mux_control_deselect(mc_sw); + if (ret) + return ret; + + return mux_control_select(mc_sw, state); +} +EXPORT_SYMBOL_GPL(typec_mux_control_switch_set); + +void typec_mux_control_switch_put(struct mux_control *mc_sw) +{ + if (!mc_sw) + return; + + return mux_control_put(mc_sw); +} +EXPORT_SYMBOL_GPL(typec_mux_control_switch_put); + /* ------------------------------------------------------------------------- */ static int mux_fwnode_match(struct device *dev, const void *fwnode) diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h index a9d9957933dc..e0933e205b80 100644 --- a/include/linux/usb/typec_mux.h +++ b/include/linux/usb/typec_mux.h @@ -27,6 +27,10 @@ void typec_switch_put(struct typec_switch *sw); int typec_switch_set(struct typec_switch *sw, enum typec_orientation orientation); +struct mux_control *typec_mux_control_switch_get(struct device *dev); +int typec_mux_control_switch_set(struct mux_control *mc_sw, int state); +void typec_mux_control_switch_put(struct mux_control *mc_sw); + static inline struct typec_switch *typec_switch_get(struct device *dev) { return fwnode_typec_switch_get(dev_fwnode(dev)); -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Li Jun <jun.li@nxp.com> To: heikki.krogerus@linux.intel.com, robh+dt@kernel.org, shawnguo@kernel.org Cc: gregkh@linuxfoundation.org, linux@roeck-us.net, linux-usb@vger.kernel.org, linux-imx@nxp.com, jun.li@nxp.com, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 3/4] usb: typec: add typec orientation switch support via mux controller Date: Wed, 19 May 2021 15:14:49 +0800 [thread overview] Message-ID: <1621408490-23811-4-git-send-email-jun.li@nxp.com> (raw) In-Reply-To: <1621408490-23811-1-git-send-email-jun.li@nxp.com> Some dedicated mux block can use existing mux controller as a mux provider, typec port as a consumer to select channel for orientation switch, this can be an alternate way to current typec_switch interface. Signed-off-by: Li Jun <jun.li@nxp.com> --- drivers/usb/typec/class.c | 26 +++++++++++++++++++++++++- drivers/usb/typec/class.h | 2 ++ drivers/usb/typec/mux.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/usb/typec_mux.h | 4 ++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index a29bf2c32233..1bb0275e6204 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1601,6 +1601,7 @@ static void typec_release(struct device *dev) ida_simple_remove(&typec_index_ida, port->id); ida_destroy(&port->mode_ids); typec_switch_put(port->sw); + typec_mux_control_switch_put(port->mux_control_switch); typec_mux_put(port->mux); kfree(port->cap); kfree(port); @@ -1816,6 +1817,13 @@ int typec_set_orientation(struct typec_port *port, if (ret) return ret; + if (!port->sw) { + ret = typec_mux_control_switch_set(port->mux_control_switch, + port->mux_control_switch_states[orientation]); + if (ret) + return ret; + } + port->orientation = orientation; sysfs_notify(&port->dev.kobj, NULL, "orientation"); kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); @@ -1991,7 +1999,7 @@ struct typec_port *typec_register_port(struct device *parent, const struct typec_capability *cap) { struct typec_port *port; - int ret; + int ret = 0; int id; port = kzalloc(sizeof(*port), GFP_KERNEL); @@ -2068,6 +2076,22 @@ struct typec_port *typec_register_port(struct device *parent, return ERR_PTR(ret); } + if (!port->sw) { + /* Try to get typec switch via general mux controller */ + port->mux_control_switch = typec_mux_control_switch_get(&port->dev); + if (IS_ERR(port->mux_control_switch)) + ret = PTR_ERR(port->mux_control_switch); + else if (port->mux_control_switch) + ret = device_property_read_u32_array(&port->dev, + "mux-control-switch-states", + port->mux_control_switch_states, + 3); + if (ret) { + put_device(&port->dev); + return ERR_PTR(ret); + } + } + port->mux = typec_mux_get(&port->dev, NULL); if (IS_ERR(port->mux)) { ret = PTR_ERR(port->mux); diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index aef03eb7e152..15dad2621c83 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -50,6 +50,8 @@ struct typec_port { enum typec_orientation orientation; struct typec_switch *sw; + struct mux_control *mux_control_switch; + int mux_control_switch_states[3]; struct typec_mux *mux; const struct typec_capability *cap; diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 9da22ae3006c..6c5c4f07286d 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -11,6 +11,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/mux/consumer.h> #include <linux/property.h> #include <linux/slab.h> @@ -176,6 +177,39 @@ void *typec_switch_get_drvdata(struct typec_switch *sw) } EXPORT_SYMBOL_GPL(typec_switch_get_drvdata); +struct mux_control *typec_mux_control_switch_get(struct device *dev) +{ + if (!device_property_present(dev, "mux-control-names")) + return NULL; + + return mux_control_get(dev, "typec-orientation-switch"); +} +EXPORT_SYMBOL_GPL(typec_mux_control_switch_get); + +int typec_mux_control_switch_set(struct mux_control *mc_sw, int state) +{ + int ret; + + if (!mc_sw) + return 0; + + ret = mux_control_deselect(mc_sw); + if (ret) + return ret; + + return mux_control_select(mc_sw, state); +} +EXPORT_SYMBOL_GPL(typec_mux_control_switch_set); + +void typec_mux_control_switch_put(struct mux_control *mc_sw) +{ + if (!mc_sw) + return; + + return mux_control_put(mc_sw); +} +EXPORT_SYMBOL_GPL(typec_mux_control_switch_put); + /* ------------------------------------------------------------------------- */ static int mux_fwnode_match(struct device *dev, const void *fwnode) diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h index a9d9957933dc..e0933e205b80 100644 --- a/include/linux/usb/typec_mux.h +++ b/include/linux/usb/typec_mux.h @@ -27,6 +27,10 @@ void typec_switch_put(struct typec_switch *sw); int typec_switch_set(struct typec_switch *sw, enum typec_orientation orientation); +struct mux_control *typec_mux_control_switch_get(struct device *dev); +int typec_mux_control_switch_set(struct mux_control *mc_sw, int state); +void typec_mux_control_switch_put(struct mux_control *mc_sw); + static inline struct typec_switch *typec_switch_get(struct device *dev) { return fwnode_typec_switch_get(dev_fwnode(dev)); -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-05-19 7:32 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-05-19 7:14 [PATCH 0/4] typec switch via mux controller Li Jun 2021-05-19 7:14 ` Li Jun 2021-05-19 7:14 ` [PATCH 1/4] dt-bindings: connector: Add typec orientation switch properties Li Jun 2021-05-19 7:14 ` Li Jun 2021-05-21 1:30 ` Rob Herring 2021-05-21 1:30 ` Rob Herring 2021-05-25 11:48 ` Jun Li 2021-05-25 11:48 ` Jun Li 2021-05-19 7:14 ` [PATCH 2/4] usb: typec: use typec cap fwnode's of_node for typec port Li Jun 2021-05-19 7:14 ` Li Jun 2021-05-20 12:38 ` Heikki Krogerus 2021-05-20 12:38 ` Heikki Krogerus 2021-05-19 7:14 ` Li Jun [this message] 2021-05-19 7:14 ` [PATCH 3/4] usb: typec: add typec orientation switch support via mux controller Li Jun 2021-05-20 12:33 ` Heikki Krogerus 2021-05-20 12:33 ` Heikki Krogerus 2021-05-21 8:37 ` Heikki Krogerus 2021-05-21 8:37 ` Heikki Krogerus 2021-05-25 11:46 ` Jun Li 2021-05-25 11:46 ` Jun Li 2021-05-26 9:16 ` Heikki Krogerus 2021-05-26 9:16 ` Heikki Krogerus 2021-05-31 11:58 ` Jun Li 2021-05-31 11:58 ` Jun Li 2021-05-21 13:02 ` Jun Li 2021-05-21 13:02 ` Jun Li 2021-05-19 7:14 ` [PATCH 4/4] arm64: dts: imx8mp-evk: enable usb0 with typec connector Li Jun 2021-05-19 7:14 ` Li Jun
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1621408490-23811-4-git-send-email-jun.li@nxp.com \ --to=jun.li@nxp.com \ --cc=devicetree@vger.kernel.org \ --cc=gregkh@linuxfoundation.org \ --cc=heikki.krogerus@linux.intel.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-imx@nxp.com \ --cc=linux-usb@vger.kernel.org \ --cc=linux@roeck-us.net \ --cc=robh+dt@kernel.org \ --cc=shawnguo@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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.