From: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
To: Vinod Koul <vkoul@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Aaro Koskinen <aaro.koskinen@iki.fi>,
Andreas Kemnade <andreas@kemnade.info>,
Kevin Hilman <khilman@baylibre.com>,
Roger Quadros <rogerq@kernel.org>,
Tony Lindgren <tony@atomide.com>,
Linus Walleij <linusw@kernel.org>,
Bartosz Golaszewski <brgl@kernel.org>,
--cc=linux-phy@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
linux-gpio@vger.kernel.org
Cc: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
Subject: [PATCH v4 4/6] phy: cpcap-usb: add extcon support
Date: Sat, 11 Jul 2026 19:47:52 +0300 [thread overview]
Message-ID: <20260711164754.185565-5-ivo.g.dimitrov.75@gmail.com> (raw)
In-Reply-To: <20260711164754.185565-1-ivo.g.dimitrov.75@gmail.com>
Register an Extcon device and report the detected cable state.
The driver already determines the type of cable attached during USB cable
detection. Export the detected state through the Extcon framework so
other drivers can consume it using a standard kernel interface.
Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
---
drivers/phy/motorola/phy-cpcap-usb.c | 69 ++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
index d4eb8086b600..8f9bea1d8a21 100644
--- a/drivers/phy/motorola/phy-cpcap-usb.c
+++ b/drivers/phy/motorola/phy-cpcap-usb.c
@@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/extcon-provider.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -123,6 +124,7 @@ struct cpcap_phy_ddata {
struct regmap *reg;
struct device *dev;
struct usb_phy phy;
+ struct extcon_dev *edev;
struct delayed_work detect_work;
struct pinctrl *pins;
struct pinctrl_state *pins_ulpi;
@@ -135,12 +137,23 @@ struct cpcap_phy_ddata {
struct regulator *vusb;
atomic_t active;
enum cpcap_mode mode;
+ int cable;
};
static bool cpcap_enable_uart;
module_param_named(enable_uart, cpcap_enable_uart, bool, 0644);
MODULE_PARM_DESC(enable_uart,
"Enable UART on the USB connector while idle (increases power consumption)");
+
+/* List of detectable cables */
+static const unsigned int cpcap_extcon_cables[] = {
+ EXTCON_USB,
+ EXTCON_USB_HOST,
+ EXTCON_CHG_USB_SDP,
+ EXTCON_CHG_USB_DCP,
+ EXTCON_NONE,
+};
+
static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
{
int error, value = 0;
@@ -226,6 +239,46 @@ static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
__func__, error);
}
+static void cpcap_usb_set_extcon(struct cpcap_phy_ddata *ddata)
+{
+ int cable;
+
+ switch (ddata->mode) {
+ case CPCAP_CHARGER:
+ cable = EXTCON_CHG_USB_DCP;
+ break;
+ case CPCAP_USB:
+ cable = EXTCON_CHG_USB_SDP;
+ break;
+ case CPCAP_USB_HOST:
+ case CPCAP_DOCK:
+ cable = EXTCON_USB_HOST;
+ break;
+ case CPCAP_IDLE:
+ cable = EXTCON_NONE;
+ break;
+ case CPCAP_UNKNOWN:
+ dev_warn_once(ddata->dev, "called with unknown PHY mode\n");
+ return;
+ }
+
+ if (cable == ddata->cable)
+ return;
+
+ if (ddata->cable == EXTCON_CHG_USB_SDP)
+ extcon_set_state_sync(ddata->edev, EXTCON_USB, false);
+ else if (cable == EXTCON_CHG_USB_SDP)
+ extcon_set_state_sync(ddata->edev, EXTCON_USB, true);
+
+ if (ddata->cable != EXTCON_NONE)
+ extcon_set_state_sync(ddata->edev, ddata->cable, false);
+
+ if (cable != EXTCON_NONE)
+ extcon_set_state_sync(ddata->edev, cable, true);
+
+ ddata->cable = cable;
+}
+
static void cpcap_usb_detect(struct work_struct *work)
{
struct cpcap_phy_ddata *ddata;
@@ -275,6 +328,7 @@ static void cpcap_usb_detect(struct work_struct *work)
ddata->mode = CPCAP_DOCK;
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
+ cpcap_usb_set_extcon(ddata);
/*
* Force check state again after musb has reoriented,
@@ -303,6 +357,7 @@ static void cpcap_usb_detect(struct work_struct *work)
ddata->mode = CPCAP_USB_HOST;
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
+ cpcap_usb_set_extcon(ddata);
return;
}
@@ -341,6 +396,8 @@ static void cpcap_usb_detect(struct work_struct *work)
if (ddata->mode == CPCAP_USB)
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);
+ cpcap_usb_set_extcon(ddata);
+
return;
}
@@ -359,6 +416,7 @@ static void cpcap_usb_detect(struct work_struct *work)
ddata->mode = CPCAP_IDLE;
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
+ cpcap_usb_set_extcon(ddata);
return;
@@ -781,7 +839,18 @@ static int cpcap_usb_phy_probe(struct platform_device *pdev)
if (!otg)
return -ENOMEM;
+ ddata->edev = devm_extcon_dev_allocate(&pdev->dev, cpcap_extcon_cables);
+ if (IS_ERR(ddata->edev)) {
+ return dev_err_probe(&pdev->dev, PTR_ERR(ddata->edev),
+ "failed to allocate extcon device\n");
+ }
+
+ error = devm_extcon_dev_register(&pdev->dev, ddata->edev);
+ if (error < 0)
+ return error;
+
ddata->mode = CPCAP_UNKNOWN;
+ ddata->cable = EXTCON_NONE;
ddata->dev = &pdev->dev;
ddata->phy.dev = ddata->dev;
ddata->phy.label = "cpcap_usb_phy";
--
2.39.5
next prev parent reply other threads:[~2026-07-11 16:48 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-11 16:47 [PATCH v4 0/6] phy: cpcap-usb: improve charger detection and export cable state Ivaylo Dimitrov
2026-07-11 16:47 ` [PATCH v4 1/6] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
2026-07-11 16:47 ` [PATCH v4 2/6] dt-bindings: phy: motorola,cpcap-usb-phy: add optional safe pinctrl state Ivaylo Dimitrov
2026-07-11 17:00 ` sashiko-bot
2026-07-11 16:47 ` [PATCH v4 3/6] phy: cpcap-usb: add DCP detection and make UART idle mode optional Ivaylo Dimitrov
2026-07-11 17:06 ` sashiko-bot
2026-07-11 16:47 ` Ivaylo Dimitrov [this message]
2026-07-11 17:14 ` [PATCH v4 4/6] phy: cpcap-usb: add extcon support sashiko-bot
2026-07-11 16:47 ` [PATCH v4 5/6] ARM: dts: ti: cpcap-mapphone: add charger detection interrupt for CPCAP USB PHY Ivaylo Dimitrov
2026-07-11 16:47 ` [PATCH v4 6/6] ARM: dts: ti: cpcap-mapphone: add USB safe pinctrl state Ivaylo Dimitrov
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=20260711164754.185565-5-ivo.g.dimitrov.75@gmail.com \
--to=ivo.g.dimitrov.75@gmail.com \
--cc=--cc=linux-phy@lists.infradead.org \
--cc=aaro.koskinen@iki.fi \
--cc=andreas@kemnade.info \
--cc=brgl@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=khilman@baylibre.com \
--cc=krzk+dt@kernel.org \
--cc=linusw@kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=robh@kernel.org \
--cc=rogerq@kernel.org \
--cc=tony@atomide.com \
--cc=vkoul@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