From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Li Jun <jun.li@nxp.com>
Cc: robh+dt@kernel.org, shawnguo@kernel.org,
gregkh@linuxfoundation.org, linux@roeck-us.net,
linux-usb@vger.kernel.org, linux-imx@nxp.com,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 3/4] usb: typec: add typec orientation switch support via mux controller
Date: Fri, 21 May 2021 11:37:47 +0300 [thread overview]
Message-ID: <YKdxW8SFntFYcyv+@kuha.fi.intel.com> (raw)
In-Reply-To: <YKZXHG7BSSZssiBg@kuha.fi.intel.com>
[-- Attachment #1: Type: text/plain, Size: 764 bytes --]
Hi,
On Thu, May 20, 2021 at 03:33:36PM +0300, Heikki Krogerus wrote:
> Why not just do that inside fwnode_typec_switch_get() and handle the
> whole thing in drivers/usb/typec/mux.c (or in its own file if you
> prefer)?
>
> You'll just need to register a "wrapper" Type-C switch object for the
> OF mux controller, but that should not be a problem. That way you
> don't need to export any new functions, touch this file or anything
> else.
I wrote a bit of code just to see how that would look. I'm attaching
you the hack I made. I guess something like that would not be too bad.
A wrapper is probable always a bit clumsy, but I'm not sure that in
this case it's a huge problem. Of course if there are any better
ideas, let's here them :-)
thanks,
--
heikki
[-- Attachment #2: 0001-usb-typec-mux-Add-wrapper-for-OF-mux-controllers-tha.patch --]
[-- Type: text/plain, Size: 5213 bytes --]
From bdd63f82788fe95e056ed85ece939e41cfb862ad Mon Sep 17 00:00:00 2001
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Date: Fri, 21 May 2021 10:42:23 +0300
Subject: [PATCH] usb: typec: mux: Add wrapper for OF mux controllers that
handle orientation
Interim. Experiment only.
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
drivers/usb/typec/Makefile | 1 +
drivers/usb/typec/mux.c | 13 +++--
drivers/usb/typec/mux.h | 15 ++++++
drivers/usb/typec/of_mux.c | 97 ++++++++++++++++++++++++++++++++++++++
4 files changed, 122 insertions(+), 4 deletions(-)
create mode 100644 drivers/usb/typec/of_mux.c
diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index a0adb8947a301..d85231b2fe10b 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_TYPEC) += typec.o
typec-y := class.o mux.o bus.o port-mapper.o
+typec-$(MULTIPLEXER) += of_mux.o
obj-$(CONFIG_TYPEC) += altmodes/
obj-$(CONFIG_TYPEC_TCPM) += tcpm/
obj-$(CONFIG_TYPEC_UCSI) += ucsi/
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c
index 9da22ae3006c9..282622276d97b 100644
--- a/drivers/usb/typec/mux.c
+++ b/drivers/usb/typec/mux.c
@@ -63,6 +63,9 @@ struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode)
sw = fwnode_connection_find_match(fwnode, "orientation-switch", NULL,
typec_switch_match);
+ if (!sw)
+ sw = of_switch_register(fwnode);
+
if (!IS_ERR_OR_NULL(sw))
WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
@@ -78,10 +81,12 @@ EXPORT_SYMBOL_GPL(fwnode_typec_switch_get);
*/
void typec_switch_put(struct typec_switch *sw)
{
- if (!IS_ERR_OR_NULL(sw)) {
- module_put(sw->dev.parent->driver->owner);
- put_device(&sw->dev);
- }
+ if (IS_ERR_OR_NULL(sw))
+ return;
+
+ module_put(sw->dev.parent->driver->owner);
+ of_switch_unregister(sw);
+ put_device(&sw->dev);
}
EXPORT_SYMBOL_GPL(typec_switch_put);
diff --git a/drivers/usb/typec/mux.h b/drivers/usb/typec/mux.h
index 4fd9426ee44f6..c99caab766313 100644
--- a/drivers/usb/typec/mux.h
+++ b/drivers/usb/typec/mux.h
@@ -5,8 +5,11 @@
#include <linux/usb/typec_mux.h>
+struct of_switch;
+
struct typec_switch {
struct device dev;
+ struct of_switch *osw;
typec_switch_set_fn_t set;
};
@@ -18,4 +21,16 @@ struct typec_mux {
#define to_typec_switch(_dev_) container_of(_dev_, struct typec_switch, dev)
#define to_typec_mux(_dev_) container_of(_dev_, struct typec_mux, dev)
+#ifdef CONFIG_MULTIPLEXER
+struct typec_switch *of_switch_register(struct fwnode_handle *fwnode);
+void of_switch_unregister(struct typec_switch *sw);
+#else
+static inline struct typec_switch *of_switch_register(struct fwnode_handle *fwnode)
+{
+ return NULL;
+}
+
+static inline void of_switch_unregister(struct typec_switch *sw) { }
+#endif /* MULTIPLEXER */
+
#endif /* __USB_TYPEC_MUX__ */
diff --git a/drivers/usb/typec/of_mux.c b/drivers/usb/typec/of_mux.c
new file mode 100644
index 0000000000000..48686a92331d7
--- /dev/null
+++ b/drivers/usb/typec/of_mux.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Wrapper for mux controllers handling orientation
+ *
+ * Copyright (C) 2021 Intel Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/mux/consumer.h>
+#include <linux/usb/typec_mux.h>
+
+#include "mux.h"
+
+struct of_switch {
+ struct mux_control *mc;
+ unsigned int state[3];
+};
+
+static int of_switch_set(struct typec_switch *sw, enum typec_orientation orientation)
+{
+ int ret;
+
+ /* Checking has the switch been unregistered - just not released yet */
+ if (!sw->osw)
+ return -ENODEV;
+
+ ret = mux_control_deselect(sw->osw->mc);
+ if (ret)
+ return ret;
+
+ return mux_control_select(sw->osw->mc, sw->osw->state[orientation]);
+}
+
+struct typec_switch *of_switch_register(struct fwnode_handle *fwnode)
+{
+ struct typec_switch_desc desc;
+ struct typec_switch *sw;
+ struct mux_control *mc;
+ unsigned int state[3];
+ struct of_switch *osw;
+ int ret;
+
+ if (!fwnode_property_present(fwnode, "mux-control-names"))
+ return NULL;
+
+ ret = fwnode_property_read_u32_array(fwnode, "mux-control-switch-states",
+ state, 3);
+ if (ret)
+ return ERR_PTR(ret);
+
+ desc.fwnode = fwnode;
+ desc.set = of_switch_set;
+ desc.name = fwnode_get_name(fwnode);
+ desc.drvdata = NULL;
+
+ sw = typec_switch_register(NULL, &desc);
+ if (IS_ERR(sw))
+ return sw;
+
+ sw->dev.of_node = to_of_node(fwnode);
+
+ mc = mux_control_get(&sw->dev, "typec-orientation-switch");
+ if (IS_ERR_OR_NULL(mc)) {
+ typec_switch_unregister(sw);
+ if (IS_ERR(mc))
+ return ERR_CAST(mc);
+ return ERR_PTR(-ENODEV);
+ }
+
+ osw = kzalloc(sizeof(osw), GFP_KERNEL);
+ if (!osw) {
+ typec_switch_unregister(sw);
+ mux_control_put(mc);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ memcpy(osw->state, state, sizeof(unsigned int) * 3);
+ osw->mc = mc;
+ sw->osw = osw;
+
+ return sw;
+}
+
+void of_switch_unregister(struct typec_switch *sw)
+{
+ struct of_switch *osw = sw->osw;
+
+ if (!osw)
+ return;
+
+ sw->osw = NULL;
+ typec_switch_unregister(sw);
+ mux_control_put(osw->mc);
+ kfree(osw);
+}
--
2.30.2
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
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-21 8:39 UTC|newest]
Thread overview: 14+ 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 ` [PATCH 1/4] dt-bindings: connector: Add typec orientation switch properties Li Jun
2021-05-21 1:30 ` Rob Herring
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-20 12:38 ` Heikki Krogerus
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-21 8:37 ` Heikki Krogerus [this message]
2021-05-25 11:46 ` Jun Li
2021-05-26 9:16 ` Heikki Krogerus
2021-05-31 11:58 ` 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
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=YKdxW8SFntFYcyv+@kuha.fi.intel.com \
--to=heikki.krogerus@linux.intel.com \
--cc=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=jun.li@nxp.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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).