* [PATCH v3 0/4] phy: cpcap-usb: improve charger detection and export cable state
@ 2026-07-05 10:11 Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Ivaylo Dimitrov @ 2026-07-05 10:11 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
Roger Quadros, Tony Lindgren, Linus Walleij, Bartosz Golaszewski
Cc: linux-phy, devicetree, linux-kernel, linux-omap, linux-gpio,
Ivaylo Dimitrov
The Motorola CPCAP USB PHY contains the hardware state machine used for
USB cable detection. Besides distinguishing USB peripheral and host
connections, it can also detect dedicated charging ports (DCP).
This series updates the Device Tree binding and corresponding mapphone
Device Tree to use the charger detection interrupt, adds DCP detection
support to the CPCAP USB PHY and finally exports the detected cable state
through the Extcon framework.
The existing driver already interprets the CPCAP USB detection state
machine to determine the attached cable type. This series extends that
logic to distinguish DCP connections and exposes the detected cable state
through Extcon using a standard kernel interface. It also makes the idle
UART mode optional, allowing the PHY to remain in its default USB
detection configuration unless UART support is explicitly requested.
The series has been tested on Motorola Droid 4 hardware.
Changes in v3:
- Drop "phy: cpcap-usb: Prevent line glitches from triggering sysrq"
- Fix DT schema interrupts order
- Fix boot cable detection
Changes in v2:
- add chrg_det interrupt instead of replacing se1
- Fix remove() race by cancelling detect_work before hardware teardown
- Restore SysRq state on all error paths
- Introduce CPCAP_UNKNOWN initial mode
- Snapshot enable_uart module parameter
Ivaylo Dimitrov (4):
dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt
ARM: dts: ti: cpcap-mapphone: use charger detection interrupt for
CPCAP USB PHY
phy: cpcap-usb: add DCP detection and make UART idle mode optional
phy: cpcap-usb: add extcon support
.../bindings/phy/motorola,cpcap-usb-phy.yaml | 6 +-
.../dts/ti/omap/motorola-cpcap-mapphone.dtsi | 6 +-
drivers/phy/motorola/phy-cpcap-usb.c | 320 +++++++++++++++---
3 files changed, 279 insertions(+), 53 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt
2026-07-05 10:11 [PATCH v3 0/4] phy: cpcap-usb: improve charger detection and export cable state Ivaylo Dimitrov
@ 2026-07-05 10:11 ` Ivaylo Dimitrov
2026-07-05 10:19 ` sashiko-bot
2026-07-06 17:14 ` Conor Dooley
2026-07-05 10:11 ` [PATCH v3 2/4] ARM: dts: ti: cpcap-mapphone: use charger detection interrupt for CPCAP USB PHY Ivaylo Dimitrov
` (2 subsequent siblings)
3 siblings, 2 replies; 10+ messages in thread
From: Ivaylo Dimitrov @ 2026-07-05 10:11 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
Roger Quadros, Tony Lindgren, Linus Walleij, Bartosz Golaszewski
Cc: linux-phy, devicetree, linux-kernel, linux-omap, linux-gpio,
Ivaylo Dimitrov
The CPCAP USB PHY driver uses the CPCAP charger detection interrupt
for DCP detection.
Update the binding and example DTS to use the corresponding
"chrg_det" interrupt name.
Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
---
.../devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
index 0febd04a61f4..523a8f8480d0 100644
--- a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
@@ -30,6 +30,7 @@ properties:
- description: se1 interrupt
- description: dm interrupt
- description: dp interrupt
+ - description: charger detection interrupt
interrupt-names:
description: Interrupt names
@@ -43,6 +44,7 @@ properties:
- const: se1
- const: dm
- const: dp
+ - const: chrg_det
io-channels:
description: IIO ADC channels used by the USB PHY
@@ -91,10 +93,10 @@ examples:
interrupts-extended = <
&cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0
&cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0
- &cpcap 48 1
+ &cpcap 48 1 &cpcap 13 0
>;
interrupt-names = "id_ground", "id_float", "se0conn", "vbusvld",
- "sessvld", "sessend", "se1", "dm", "dp";
+ "sessvld", "sessend", "se1", "dm", "dp", "chrg_det";
io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
io-channel-names = "vbus", "id";
vusb-supply = <&vusb>;
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 2/4] ARM: dts: ti: cpcap-mapphone: use charger detection interrupt for CPCAP USB PHY
2026-07-05 10:11 [PATCH v3 0/4] phy: cpcap-usb: improve charger detection and export cable state Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
@ 2026-07-05 10:11 ` Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 3/4] phy: cpcap-usb: add DCP detection and make UART idle mode optional Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 4/4] phy: cpcap-usb: add extcon support Ivaylo Dimitrov
3 siblings, 0 replies; 10+ messages in thread
From: Ivaylo Dimitrov @ 2026-07-05 10:11 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
Roger Quadros, Tony Lindgren, Linus Walleij, Bartosz Golaszewski
Cc: linux-phy, devicetree, linux-kernel, linux-omap, linux-gpio,
Ivaylo Dimitrov
Update the CPCAP USB PHY interrupt mapping to use the charger
detection interrupt and corresponding "chrg_det" interrupt name.
This matches the driver and binding updates for DCP detection.
Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
---
arch/arm/boot/dts/ti/omap/motorola-cpcap-mapphone.dtsi | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/ti/omap/motorola-cpcap-mapphone.dtsi b/arch/arm/boot/dts/ti/omap/motorola-cpcap-mapphone.dtsi
index 6b1195c2a768..51a858021541 100644
--- a/arch/arm/boot/dts/ti/omap/motorola-cpcap-mapphone.dtsi
+++ b/arch/arm/boot/dts/ti/omap/motorola-cpcap-mapphone.dtsi
@@ -125,11 +125,13 @@ cpcap_usb2_phy: phy {
interrupts-extended =
<&cpcap 15 0>, <&cpcap 14 0>, <&cpcap 28 0>,
<&cpcap 19 0>, <&cpcap 18 0>, <&cpcap 17 0>,
- <&cpcap 16 0>, <&cpcap 49 0>, <&cpcap 48 0>;
+ <&cpcap 16 0>, <&cpcap 49 0>, <&cpcap 48 0>,
+ <&cpcap 13 0>;
interrupt-names =
"id_ground", "id_float", "se0conn",
"vbusvld", "sessvld", "sessend",
- "se1", "dm", "dp";
+ "se1", "dm", "dp",
+ "chrg_det";
mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,
<&gpio1 0 GPIO_ACTIVE_HIGH>;
io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 3/4] phy: cpcap-usb: add DCP detection and make UART idle mode optional
2026-07-05 10:11 [PATCH v3 0/4] phy: cpcap-usb: improve charger detection and export cable state Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 2/4] ARM: dts: ti: cpcap-mapphone: use charger detection interrupt for CPCAP USB PHY Ivaylo Dimitrov
@ 2026-07-05 10:11 ` Ivaylo Dimitrov
2026-07-05 10:24 ` sashiko-bot
2026-07-05 10:11 ` [PATCH v3 4/4] phy: cpcap-usb: add extcon support Ivaylo Dimitrov
3 siblings, 1 reply; 10+ messages in thread
From: Ivaylo Dimitrov @ 2026-07-05 10:11 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
Roger Quadros, Tony Lindgren, Linus Walleij, Bartosz Golaszewski
Cc: linux-phy, devicetree, linux-kernel, linux-omap, linux-gpio,
Ivaylo Dimitrov
Handle DCP separately from USB host connections based on CPCAP charger
detection status.
Make the existing idle UART mode optional via the "enable_uart" module
parameter. When disabled, the PHY remains in its USB/charger detection
configuration while idle. This reduces power usage in idle by 25mW.
Also initialize the PHY into the baseline configuration required for
reliable charger detection during probe.
Fix possible race where HW setup in cpcap_usb_phy_remove() can be run
in parallel with cpcap_usb_detect().
Note: Enabling UART idle mode increases idle power consumption.
Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
---
drivers/phy/motorola/phy-cpcap-usb.c | 251 +++++++++++++++++++++------
1 file changed, 202 insertions(+), 49 deletions(-)
diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
index 7cb020dd3423..78bb1773e537 100644
--- a/drivers/phy/motorola/phy-cpcap-usb.c
+++ b/drivers/phy/motorola/phy-cpcap-usb.c
@@ -110,6 +110,15 @@ enum cpcap_gpio_mode {
CPCAP_OTG_DM_DP,
};
+enum cpcap_mode {
+ CPCAP_UNKNOWN,
+ CPCAP_IDLE,
+ CPCAP_CHARGER,
+ CPCAP_USB,
+ CPCAP_USB_HOST,
+ CPCAP_DOCK,
+};
+
struct cpcap_phy_ddata {
struct regmap *reg;
struct device *dev;
@@ -124,10 +133,13 @@ struct cpcap_phy_ddata {
struct iio_channel *id;
struct regulator *vusb;
atomic_t active;
- unsigned int vbus_provider:1;
- unsigned int docked:1;
+ enum cpcap_mode mode;
};
+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)");
static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
{
int error, value = 0;
@@ -175,6 +187,7 @@ static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
s->id_ground = val & BIT(15);
s->id_float = val & BIT(14);
+ s->chrg_det = val & BIT(13);
s->vbusov = val & BIT(11);
error = regmap_read(ddata->reg, CPCAP_REG_INTS2, &val);
@@ -196,8 +209,9 @@ static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
return 0;
}
-static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata);
+static int cpcap_usb_set_idle_mode(struct cpcap_phy_ddata *ddata);
static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata);
+static int cpcap_usb_set_dcp_mode(struct cpcap_phy_ddata *ddata);
static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
enum musb_vbus_id_status status)
@@ -228,7 +242,7 @@ static void cpcap_usb_detect(struct work_struct *work)
vbus = cpcap_usb_vbus_valid(ddata);
/* We need to kick the VBUS as USB A-host */
- if (s.id_ground && ddata->vbus_provider) {
+ if (s.id_ground && ddata->mode == CPCAP_USB_HOST) {
dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n");
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
@@ -243,7 +257,7 @@ static void cpcap_usb_detect(struct work_struct *work)
return;
}
- if (vbus && s.id_ground && ddata->docked) {
+ if (vbus && s.id_ground && ddata->mode == CPCAP_DOCK) {
dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n");
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
@@ -252,15 +266,14 @@ static void cpcap_usb_detect(struct work_struct *work)
}
/* No VBUS needed with docks */
- if (vbus && s.id_ground && !ddata->vbus_provider) {
+ if (vbus && s.id_ground && ddata->mode != CPCAP_USB_HOST) {
dev_dbg(ddata->dev, "connected to a dock\n");
- ddata->docked = true;
-
error = cpcap_usb_set_usb_mode(ddata);
if (error)
goto out_err;
+ ddata->mode = CPCAP_DOCK;
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
/*
@@ -274,17 +287,13 @@ static void cpcap_usb_detect(struct work_struct *work)
return;
}
- if (s.id_ground && !ddata->docked) {
+ if (s.id_ground && ddata->mode != CPCAP_DOCK) {
dev_dbg(ddata->dev, "id ground, USB host mode\n");
- ddata->vbus_provider = true;
-
error = cpcap_usb_set_usb_mode(ddata);
if (error)
goto out_err;
- cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
-
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
CPCAP_BIT_VBUSSTBY_EN |
CPCAP_BIT_VBUSEN_SPI,
@@ -292,38 +301,63 @@ static void cpcap_usb_detect(struct work_struct *work)
if (error)
goto out_err;
+ ddata->mode = CPCAP_USB_HOST;
+ cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
+
return;
}
- error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
- CPCAP_BIT_VBUSSTBY_EN |
- CPCAP_BIT_VBUSEN_SPI, 0);
- if (error)
- goto out_err;
-
vbus = cpcap_usb_vbus_valid(ddata);
- /* Otherwise assume we're connected to a USB host */
- if (vbus) {
- dev_dbg(ddata->dev, "connected to USB host\n");
- error = cpcap_usb_set_usb_mode(ddata);
+ /* Check if we're connected to a USB host */
+ if (vbus && ddata->mode != CPCAP_USB_HOST) {
+ enum cpcap_mode new_mode;
+
+ if (!s.chrg_det || !s.sessvld ||
+ !(ddata->mode == CPCAP_IDLE ||
+ ddata->mode == CPCAP_UNKNOWN))
+ return;
+
+ if (s.se1)
+ new_mode = CPCAP_CHARGER;
+ else if (!s.dm && !s.dp)
+ new_mode = CPCAP_USB;
+ else
+ return;
+
+ dev_dbg(ddata->dev, "connected to %s\n",
+ s.se1 ? "DCP" : "USB host");
+
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
+ CPCAP_BIT_VBUSSTBY_EN |
+ CPCAP_BIT_VBUSEN_SPI, 0);
if (error)
goto out_err;
- cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);
+
+ if (new_mode == CPCAP_CHARGER)
+ error = cpcap_usb_set_dcp_mode(ddata);
+ else
+ error = cpcap_usb_set_usb_mode(ddata);
+
+ if (error)
+ goto out_err;
+
+ ddata->mode = new_mode;
+ if (ddata->mode == CPCAP_USB)
+ cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);
return;
}
- ddata->vbus_provider = false;
- ddata->docked = false;
- cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
+ if (ddata->mode == CPCAP_IDLE)
+ return;
- /* Default to debug UART mode */
- error = cpcap_usb_set_uart_mode(ddata);
+ error = cpcap_usb_set_idle_mode(ddata);
if (error)
goto out_err;
- dev_dbg(ddata->dev, "set UART mode\n");
+ ddata->mode = CPCAP_IDLE;
+ cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
return;
@@ -373,7 +407,7 @@ static const char * const cpcap_phy_irqs[] = {
"id_ground", "id_float",
/* REG_INT1 */
- "se0conn", "vbusvld", "sessvld", "sessend", "se1",
+ "se0conn", "vbusvld", "sessvld", "sessend", "chrg_det",
/* REG_INT_3 */
"dm", "dp",
@@ -411,43 +445,69 @@ static int cpcap_usb_gpio_set_mode(struct cpcap_phy_ddata *ddata,
return 0;
}
-static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
+static int cpcap_usb_set_idle_mode(struct cpcap_phy_ddata *ddata)
{
int error;
+ unsigned int val;
+ bool enable_uart = cpcap_enable_uart;
/* Disable lines to prevent glitches from waking up mdm6600 */
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
if (error)
goto out_err;
- if (ddata->pins_uart) {
- error = pinctrl_select_state(ddata->pins, ddata->pins_uart);
+ if (enable_uart && ddata->pins_uart) {
+ error = pinctrl_select_state(ddata->pins, ddata->pins_uart);
+ if (error)
+ goto out_err;
+ } else if (!enable_uart && ddata->pins_ulpi) {
+ error = pinctrl_select_state(ddata->pins, ddata->pins_ulpi);
if (error)
goto out_err;
}
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
+ CPCAP_BIT_DP150KPU |
+ CPCAP_BIT_DP1K5PU |
+ CPCAP_BIT_DM1K5PU |
+ CPCAP_BIT_DPPD |
+ CPCAP_BIT_DMPD |
CPCAP_BIT_VBUSPD,
+ CPCAP_BIT_DP150KPU |
CPCAP_BIT_VBUSPD);
if (error)
goto out_err;
- error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
- 0xffff, CPCAP_BIT_UARTMUX0 |
- CPCAP_BIT_EMUMODE0);
+ val = CPCAP_BIT_USBSUSPEND;
+
+ if (enable_uart)
+ val |= (CPCAP_BIT_UARTMUX0 | CPCAP_BIT_EMUMODE0);
+
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2, 0xffff, val);
if (error)
goto out_err;
- error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff,
- CPCAP_BIT_IDPU_SPI);
+ val = CPCAP_BIT_VBUSSTBY_EN |
+ CPCAP_BIT_VBUSPD_SPI |
+ CPCAP_BIT_DMPD_SPI |
+ CPCAP_BIT_DPPD_SPI |
+ CPCAP_BIT_PU_SPI |
+ CPCAP_BIT_IDPU_SPI |
+ CPCAP_BIT_ULPI_SPI_SEL;
+
+ if (!enable_uart)
+ val |= CPCAP_BIT_SUSPEND_SPI;
+
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff, val);
if (error)
goto out_err;
- /* Enable UART mode */
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
if (error)
goto out_err;
+ dev_dbg(ddata->dev, "set %s mode\n", enable_uart ? "UART" : "IDLE");
+
return 0;
out_err:
@@ -508,6 +568,42 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
return error;
}
+static int cpcap_usb_set_dcp_mode(struct cpcap_phy_ddata *ddata)
+{
+ int error = 0;
+
+ /* Disable lines to prevent glitches from waking up mdm6600 */
+ error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
+ if (error)
+ return error;
+
+ if (ddata->pins_ulpi) {
+ error = pinctrl_select_state(ddata->pins, ddata->pins_ulpi);
+ if (error) {
+ dev_err(ddata->dev, "could not set usb mode: %i\n",
+ error);
+
+ return error;
+ }
+ }
+
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
+ CPCAP_BIT_SUSPEND_SPI, 0);
+ if (error)
+ goto out_err;
+
+ error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
+ if (error)
+ goto out_err;
+
+ return 0;
+
+out_err:
+ dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
+
+ return error;
+}
+
static int cpcap_usb_init_optional_pins(struct cpcap_phy_ddata *ddata)
{
ddata->pins = devm_pinctrl_get(ddata->dev);
@@ -537,9 +633,6 @@ static int cpcap_usb_init_optional_pins(struct cpcap_phy_ddata *ddata)
ddata->pins_uart = NULL;
}
- if (ddata->pins_uart)
- return pinctrl_select_state(ddata->pins, ddata->pins_uart);
-
return 0;
}
@@ -592,6 +685,65 @@ static int cpcap_usb_init_iio(struct cpcap_phy_ddata *ddata)
return error;
}
+static int cpcap_usb_init_usb(struct cpcap_phy_ddata *ddata)
+{
+ struct cpcap_usb_ints_state s;
+ int error;
+ int mask;
+
+ error = cpcap_phy_get_ints_state(ddata, &s);
+ if (error)
+ return error;
+
+ error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
+ if (error)
+ return error;
+
+ if (ddata->pins_ulpi) {
+ error = pinctrl_select_state(ddata->pins, ddata->pins_ulpi);
+ if (error)
+ return error;
+ }
+
+ /*
+ * Do not touch DM/DP PD as this will break charger detection if charger
+ * is connected before we detect it.
+ */
+ if (s.se1) {
+ mask = CPCAP_BIT_VBUSEN_SPI | CPCAP_BIT_VBUSPU_SPI |
+ CPCAP_BIT_SUSPEND_SPI | CPCAP_BIT_ULPI_SPI_SEL;
+ } else {
+ mask = CPCAP_BIT_VBUSEN_SPI | CPCAP_BIT_VBUSPU_SPI |
+ CPCAP_BIT_DMPD_SPI | CPCAP_BIT_DPPD_SPI |
+ CPCAP_BIT_SUSPEND_SPI | CPCAP_BIT_PU_SPI |
+ CPCAP_BIT_ULPI_SPI_SEL;
+ }
+
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, mask,
+ CPCAP_BIT_ULPI_SPI_SEL);
+ if (error)
+ return error;
+
+ /*
+ * Configure safe DP/DM termination state.
+ *
+ * Vendor kernel uses:
+ * DP150KPU = enabled
+ * all USB pullups/pulldowns = disabled
+ */
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
+ CPCAP_BIT_DP150KPU |
+ CPCAP_BIT_DP1K5PU |
+ CPCAP_BIT_DM1K5PU |
+ CPCAP_BIT_DPPD |
+ CPCAP_BIT_DMPD,
+ CPCAP_BIT_DP150KPU);
+ if (error)
+ return error;
+
+ return cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
+}
+
#ifdef CONFIG_OF
static const struct of_device_id cpcap_usb_phy_id_table[] = {
{
@@ -625,6 +777,7 @@ static int cpcap_usb_phy_probe(struct platform_device *pdev)
if (!otg)
return -ENOMEM;
+ ddata->mode = CPCAP_UNKNOWN;
ddata->dev = &pdev->dev;
ddata->phy.dev = ddata->dev;
ddata->phy.label = "cpcap_usb_phy";
@@ -669,6 +822,10 @@ static int cpcap_usb_phy_probe(struct platform_device *pdev)
if (error)
goto out_reg_disable;
+ error = cpcap_usb_init_usb(ddata);
+ if (error)
+ goto out_reg_disable;
+
error = cpcap_usb_init_interrupts(pdev, ddata);
if (error)
goto out_reg_disable;
@@ -688,17 +845,13 @@ static int cpcap_usb_phy_probe(struct platform_device *pdev)
static void cpcap_usb_phy_remove(struct platform_device *pdev)
{
struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev);
- int error;
atomic_set(&ddata->active, 0);
- error = cpcap_usb_set_uart_mode(ddata);
- if (error)
- dev_err(ddata->dev, "could not set UART mode\n");
-
+ cancel_delayed_work_sync(&ddata->detect_work);
+ cpcap_usb_set_idle_mode(ddata);
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
usb_remove_phy(&ddata->phy);
- cancel_delayed_work_sync(&ddata->detect_work);
regulator_disable(ddata->vusb);
}
--
2.39.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 4/4] phy: cpcap-usb: add extcon support
2026-07-05 10:11 [PATCH v3 0/4] phy: cpcap-usb: improve charger detection and export cable state Ivaylo Dimitrov
` (2 preceding siblings ...)
2026-07-05 10:11 ` [PATCH v3 3/4] phy: cpcap-usb: add DCP detection and make UART idle mode optional Ivaylo Dimitrov
@ 2026-07-05 10:11 ` Ivaylo Dimitrov
2026-07-05 10:25 ` sashiko-bot
3 siblings, 1 reply; 10+ messages in thread
From: Ivaylo Dimitrov @ 2026-07-05 10:11 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
Roger Quadros, Tony Lindgren, Linus Walleij, Bartosz Golaszewski
Cc: linux-phy, devicetree, linux-kernel, linux-omap, linux-gpio,
Ivaylo Dimitrov
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 78bb1773e537..ba36d110df41 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;
@@ -134,12 +136,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;
}
@@ -346,6 +401,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;
}
@@ -358,6 +415,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;
@@ -777,7 +835,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
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt
2026-07-05 10:11 ` [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
@ 2026-07-05 10:19 ` sashiko-bot
2026-07-06 17:14 ` Conor Dooley
1 sibling, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-05 10:19 UTC (permalink / raw)
To: Ivaylo Dimitrov
Cc: vkoul, devicetree, robh, conor+dt, olteanv, linux-phy,
neil.armstrong
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] Adding a new interrupt to the items list without specifying `minItems` breaks backward compatibility for existing device trees.
--
commit 7e8931dde2ba82b58d38efd0314e63d294e5301f
Author: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt
This commit updates the motorola,cpcap-usb-phy binding by appending a new
charger detection interrupt for DCP detection and updating the example.
> diff --git a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> index dd345cbd0a0b4..7488c46cc6193 100644
> --- a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> @@ -30,6 +30,7 @@ properties:
> - description: se1 interrupt
> - description: dm interrupt
> - description: dp interrupt
> + - description: charger detection interrupt
>
> interrupt-names:
> description: Interrupt names
> @@ -43,6 +44,7 @@ properties:
> - const: se1
> - const: dm
> - const: dp
> + - const: chrg_det
[Severity: Critical]
Does appending these items implicitly change the required number of interrupts
from 9 to 10?
In dt-schema, defining an items list implicitly sets both minItems and maxItems
to the length of the list unless explicitly overridden. By appending the 10th
item to interrupts and interrupt-names without adding a minItems: 9 fallback,
it appears schema validation will strictly mandate exactly 10 interrupts.
Is this a regression that will cause existing device trees with 9 interrupts
to fail validation?
If the driver is updated to unconditionally require this new interrupt, could
this also cause the driver to fail to probe on hardware using older device
trees?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260705101105.1798069-1-ivo.g.dimitrov.75@gmail.com?part=1
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 3/4] phy: cpcap-usb: add DCP detection and make UART idle mode optional
2026-07-05 10:11 ` [PATCH v3 3/4] phy: cpcap-usb: add DCP detection and make UART idle mode optional Ivaylo Dimitrov
@ 2026-07-05 10:24 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-05 10:24 UTC (permalink / raw)
To: Ivaylo Dimitrov
Cc: vkoul, neil.armstrong, conor+dt, olteanv, devicetree, linux-phy,
robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] CPCAP_BIT_USBSUSPEND is left enabled when transitioning from idle mode to USB mode, permanently suspending the USB transceiver.
Pre-existing issues:
- [High] A Time-of-Check to Time-of-Use (TOCTOU) race condition between the threaded IRQ handler and `remove()` leads to a use-after-free of `ddata`.
--
commit a337f1a3972ec0ccd4a231f2afbec0cfcdfd64fc
Author: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
phy: cpcap-usb: add DCP detection and make UART idle mode optional
Handle DCP separately from USB host connections based on CPCAP charger
detection status. Make the existing idle UART mode optional via the
"enable_uart" module parameter. Initialize the PHY into the baseline
configuration required for reliable charger detection during probe.
> diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
> index 7cb020dd3423c..78bb1773e5379 100644
> --- a/drivers/phy/motorola/phy-cpcap-usb.c
> +++ b/drivers/phy/motorola/phy-cpcap-usb.c
[ ... ]
> - error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
> - 0xffff, CPCAP_BIT_UARTMUX0 |
> - CPCAP_BIT_EMUMODE0);
> + val = CPCAP_BIT_USBSUSPEND;
> +
> + if (enable_uart)
> + val |= (CPCAP_BIT_UARTMUX0 | CPCAP_BIT_EMUMODE0);
> +
> + error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2, 0xffff, val);
[Severity: High]
Could this permanently suspend the USB transceiver? When unplugging a USB
cable, cpcap_usb_set_idle_mode() runs and sets CPCAP_BIT_USBSUSPEND.
However, when re-plugging the cable, cpcap_usb_set_usb_mode() is called,
which only masks CPCAP_BIT_USBXCVREN when updating CPCAP_REG_USBC2:
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
CPCAP_BIT_USBXCVREN,
CPCAP_BIT_USBXCVREN);
Since it doesn't clear the CPCAP_BIT_USBSUSPEND bit, will the transceiver
remain suspended and break subsequent data communication?
[ ... ]
> @@ -688,17 +845,13 @@ static int cpcap_usb_phy_probe(struct platform_device *pdev)
> static void cpcap_usb_phy_remove(struct platform_device *pdev)
> {
> struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev);
> - int error;
>
> atomic_set(&ddata->active, 0);
> - error = cpcap_usb_set_uart_mode(ddata);
> - if (error)
> - dev_err(ddata->dev, "could not set UART mode\n");
> -
> + cancel_delayed_work_sync(&ddata->detect_work);
[Severity: High]
This isn't a bug introduced by this patch, but does this sequence leave a
window for a use-after-free on ddata?
Because the IRQ is devm-managed, it remains active until the devres phase
after remove() returns. If cpcap_phy_irq_thread() is preempted right after
checking ddata->active but before scheduling the work:
if (!atomic_read(&ddata->active))
return IRQ_NONE;
/* preempted here */
schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
And cpcap_usb_phy_remove() runs to completion, ddata will be freed. When
the IRQ thread resumes, it will queue the work again, causing the delayed
work to execute and access the freed ddata.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260705101105.1798069-1-ivo.g.dimitrov.75@gmail.com?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 4/4] phy: cpcap-usb: add extcon support
2026-07-05 10:11 ` [PATCH v3 4/4] phy: cpcap-usb: add extcon support Ivaylo Dimitrov
@ 2026-07-05 10:25 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-05 10:25 UTC (permalink / raw)
To: Ivaylo Dimitrov
Cc: linux-phy, conor+dt, devicetree, neil.armstrong, olteanv, vkoul,
robh
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] Missing reset of extcon state on driver removal, leading to stale connection states for consumers.
Pre-existing issues:
- [High] Pre-existing UAF race condition during device removal between the IRQ thread and remove() leading to delayed work executing after device data is freed.
--
commit a6baa41684450d481944fb6077e8db95e4f80e2e
Author: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
phy: cpcap-usb: add extcon support
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.
> diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
> index 78bb1773e5379..ba36d110df419 100644
> --- a/drivers/phy/motorola/phy-cpcap-usb.c
> +++ b/drivers/phy/motorola/phy-cpcap-usb.c
[ ... ]
> @@ -777,7 +835,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;
> +
[Severity: Medium]
When the module is removed or unbound, devres will automatically unregister
the extcon device. However, since there are no corresponding updates to
cpcap_usb_phy_remove() in phy-cpcap-usb.c, the extcon cable states are not
explicitly reset to EXTCON_NONE before the device goes away.
Will consumers of this extcon device (e.g. charger drivers) retain stale
connection states because of missed disconnect notifications during removal?
> ddata->mode = CPCAP_UNKNOWN;
> + ddata->cable = EXTCON_NONE;
> ddata->dev = &pdev->dev;
> ddata->phy.dev = ddata->dev;
> ddata->phy.label = "cpcap_usb_phy";
[Severity: High]
This isn't a bug introduced by this patch, but is there a pre-existing
use-after-free race condition during device removal between
cpcap_phy_irq_thread() and cpcap_usb_phy_remove() in phy-cpcap-usb.c?
Looking at cpcap_usb_phy_remove(), it cancels the work:
cpcap_usb_phy_remove() {
...
atomic_set(&ddata->active, 0);
cancel_delayed_work_sync(&ddata->detect_work);
...
}
However, if cpcap_phy_irq_thread() is preempted right after checking the
active flag:
cpcap_phy_irq_thread() {
...
if (!atomic_read(&ddata->active))
return IRQ_NONE;
/* preempted here */
schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
...
}
Could this sequence occur during unbind/removal:
1. IRQ thread reads active == 1, gets preempted.
2. cpcap_usb_phy_remove() sets active = 0, calls cancel_delayed_work_sync()
(which does nothing since the work isn't queued yet).
3. Devres frees the IRQ, waiting for the IRQ thread to finish.
4. IRQ thread resumes and queues the delayed work.
5. Devres frees the ddata structure.
6. The delayed work timer expires and accesses the freed memory?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260705101105.1798069-1-ivo.g.dimitrov.75@gmail.com?part=4
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt
2026-07-05 10:11 ` [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
2026-07-05 10:19 ` sashiko-bot
@ 2026-07-06 17:14 ` Conor Dooley
2026-07-06 21:25 ` Ivaylo Dimitrov
1 sibling, 1 reply; 10+ messages in thread
From: Conor Dooley @ 2026-07-06 17:14 UTC (permalink / raw)
To: Ivaylo Dimitrov
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
Roger Quadros, Tony Lindgren, Linus Walleij, Bartosz Golaszewski,
linux-phy, devicetree, linux-kernel, linux-omap, linux-gpio
[-- Attachment #1: Type: text/plain, Size: 2329 bytes --]
On Sun, Jul 05, 2026 at 01:11:02PM +0300, Ivaylo Dimitrov wrote:
> The CPCAP USB PHY driver uses the CPCAP charger detection interrupt
> for DCP detection.
This is not currently true, the driver does not look for this interrupt
at the time of this patch.
> Update the binding and example DTS to use the corresponding
> "chrg_det" interrupt name.
Sounds to me like this new interrupt is optional, since until now it has
not been needed? The patch however makes it mandatory. I think your
driver patch also makes it mandatory, which will break older
devicetrees.
What makes this ABI break okay?
Thanks,
Conor.
>
> Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
> ---
> .../devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> index 0febd04a61f4..523a8f8480d0 100644
> --- a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> @@ -30,6 +30,7 @@ properties:
> - description: se1 interrupt
> - description: dm interrupt
> - description: dp interrupt
> + - description: charger detection interrupt
>
> interrupt-names:
> description: Interrupt names
> @@ -43,6 +44,7 @@ properties:
> - const: se1
> - const: dm
> - const: dp
> + - const: chrg_det
>
> io-channels:
> description: IIO ADC channels used by the USB PHY
> @@ -91,10 +93,10 @@ examples:
> interrupts-extended = <
> &cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0
> &cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0
> - &cpcap 48 1
> + &cpcap 48 1 &cpcap 13 0
> >;
> interrupt-names = "id_ground", "id_float", "se0conn", "vbusvld",
> - "sessvld", "sessend", "se1", "dm", "dp";
> + "sessvld", "sessend", "se1", "dm", "dp", "chrg_det";
> io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
> io-channel-names = "vbus", "id";
> vusb-supply = <&vusb>;
> --
> 2.39.5
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt
2026-07-06 17:14 ` Conor Dooley
@ 2026-07-06 21:25 ` Ivaylo Dimitrov
0 siblings, 0 replies; 10+ messages in thread
From: Ivaylo Dimitrov @ 2026-07-06 21:25 UTC (permalink / raw)
To: Conor Dooley
Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Aaro Koskinen, Andreas Kemnade, Kevin Hilman,
Roger Quadros, Tony Lindgren, Linus Walleij, Bartosz Golaszewski,
linux-phy, devicetree, linux-kernel, linux-omap, linux-gpio
Hi,
On 6.07.26 г. 20:14 ч., Conor Dooley wrote:
> On Sun, Jul 05, 2026 at 01:11:02PM +0300, Ivaylo Dimitrov wrote:
>> The CPCAP USB PHY driver uses the CPCAP charger detection interrupt
>> for DCP detection.
>
> This is not currently true, the driver does not look for this interrupt
> at the time of this patch.
>
Right, this is bad wording caused by the fact that initially the driver
patch came before the binding patch.
>> Update the binding and example DTS to use the corresponding
>> "chrg_det" interrupt name.
>
> Sounds to me like this new interrupt is optional, since until now it has
> not been needed? The patch however makes it mandatory. I think your
> driver patch also makes it mandatory, which will break older
> devicetrees.
>
Oh, it is indeed not needed for proper DCP/SDP detection, after some
experiments I was able to teach the driver to do proper detection by
using current interrupts only.
> What makes this ABI break okay?
>
Will send new series with schema/DT patches dropped.
Thanks and regards,
Ivo
> Thanks,
> Conor.
>
>>
>> Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
>> ---
>> .../devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
>> index 0febd04a61f4..523a8f8480d0 100644
>> --- a/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
>> +++ b/Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
>> @@ -30,6 +30,7 @@ properties:
>> - description: se1 interrupt
>> - description: dm interrupt
>> - description: dp interrupt
>> + - description: charger detection interrupt
>>
>> interrupt-names:
>> description: Interrupt names
>> @@ -43,6 +44,7 @@ properties:
>> - const: se1
>> - const: dm
>> - const: dp
>> + - const: chrg_det
>>
>> io-channels:
>> description: IIO ADC channels used by the USB PHY
>> @@ -91,10 +93,10 @@ examples:
>> interrupts-extended = <
>> &cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0
>> &cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0
>> - &cpcap 48 1
>> + &cpcap 48 1 &cpcap 13 0
>> >;
>> interrupt-names = "id_ground", "id_float", "se0conn", "vbusvld",
>> - "sessvld", "sessend", "se1", "dm", "dp";
>> + "sessvld", "sessend", "se1", "dm", "dp", "chrg_det";
>> io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
>> io-channel-names = "vbus", "id";
>> vusb-supply = <&vusb>;
>> --
>> 2.39.5
>>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-07-06 21:26 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-05 10:11 [PATCH v3 0/4] phy: cpcap-usb: improve charger detection and export cable state Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 1/4] dt-bindings: phy: motorola,cpcap-usb: add chrg_det interrupt Ivaylo Dimitrov
2026-07-05 10:19 ` sashiko-bot
2026-07-06 17:14 ` Conor Dooley
2026-07-06 21:25 ` Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 2/4] ARM: dts: ti: cpcap-mapphone: use charger detection interrupt for CPCAP USB PHY Ivaylo Dimitrov
2026-07-05 10:11 ` [PATCH v3 3/4] phy: cpcap-usb: add DCP detection and make UART idle mode optional Ivaylo Dimitrov
2026-07-05 10:24 ` sashiko-bot
2026-07-05 10:11 ` [PATCH v3 4/4] phy: cpcap-usb: add extcon support Ivaylo Dimitrov
2026-07-05 10:25 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox