* [PATCH v2 0/9] usb/dwc3 / phy/tusb1210: Add TUSB1211 charger detection
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
Hi All,
Here is v2 of the patchs-series to add support for USB charger-type
(SDP/DCP) detection using a tusb1210 phy connected to a dwc3 controller.
Changes in v2:
[PATCH v2 9/9] phy: ti: tusb1210: Add charger detection:
- Add an online attribute to the registered power_supply class device,
otherwise upower thinks it is an extra system battery
- Add tusb1210_remove_charger_detect() function to properly unregister
the tusb->psy_nb notifier and to cancel tusb->chg_det_work
v1 cover-letter:
Some Android x86 tablets with a Bay Trail (BYT) SoC (with DWC3 UDC)
and a Crystal Cove PMIC, which does not support charger-detection,
rely on a TUSB1211 phy for charger-detection.
This series adds support for this, it starts with some dwc3 bug-fixes
for issues hit while developing this, as well as adding support to
the dwc3 code to set a special property checked by the tusb1210 driver
to signal that it needs to enable charger-detection.
The 2nd half of the series does some refactoring / fixes to the
tusb1210 driver and adds the charger-detection support.
Regards,
Hans
Hans de Goede (8):
usb: dwc3: pci: Add "snps,dis_u2_susphy_quirk" for Intel Bay Trail
usb: dwc3: pci: Fix Bay Trail phy GPIO mappings
usb: dwc3: pci: Set the swnode from inside dwc3_pci_quirks()
usb: dwc3: pci: Set "linux,phy_charger_detect" property on some Bay
Trail boards
usb: dwc3: pci: Also apply Bay Trail GPIO mappings to ulpi-device
phy: ti: tusb1210: Improve ulpi_read()/_write() error checking
phy: ti: tusb1210: Drop tusb->vendor_specific2 != 0 check from
tusb1210_power_on()
phy: ti: tusb1210: Add a delay between power-on and restoring the
phy-parameters
Stephan Gerhold (1):
phy: ti: tusb1210: Add charger detection
drivers/phy/ti/phy-tusb1210.c | 439 ++++++++++++++++++++++++++++++++--
drivers/usb/dwc3/dwc3-pci.c | 60 ++++-
2 files changed, 467 insertions(+), 32 deletions(-)
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v2 1/9] usb: dwc3: pci: Add "snps,dis_u2_susphy_quirk" for Intel Bay Trail
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy, Serge Semin
Commit e0082698b689 ("usb: dwc3: ulpi: conditionally resume ULPI PHY")
fixed an issue where ULPI transfers would timeout if any requests where
send to the phy sometime after init, giving it enough time to auto-suspend.
Commit e5f4ca3fce90 ("usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend
regression") changed the behavior to instead of clearing the
DWC3_GUSB2PHYCFG_SUSPHY bit, add an extra sleep when it is set.
But on Bay Trail devices, when phy_set_mode() gets called during init,
this leads to errors like these:
[ 28.451522] tusb1210 dwc3.ulpi: error -110 writing val 0x01 to reg 0x0a
[ 28.464089] tusb1210 dwc3.ulpi: error -110 writing val 0x01 to reg 0x0a
Add "snps,dis_u2_susphy_quirk" to the settings for Bay Trail devices to
fix this. This restores the old behavior for Bay Trail devices, since
previously the DWC3_GUSB2PHYCFG_SUSPHY bit would get cleared on the first
ulpi_read/_write() and then was never set again.
Fixes: e5f4ca3fce90 ("usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend regression")
Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 7ff8fc8f79a9..022341aef400 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -119,6 +119,13 @@ static const struct property_entry dwc3_pci_intel_properties[] = {
{}
};
+static const struct property_entry dwc3_pci_intel_byt_properties[] = {
+ PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
+ PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+ PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
+ {}
+};
+
static const struct property_entry dwc3_pci_mrfld_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
@@ -161,6 +168,10 @@ static const struct software_node dwc3_pci_intel_swnode = {
.properties = dwc3_pci_intel_properties,
};
+static const struct software_node dwc3_pci_intel_byt_swnode = {
+ .properties = dwc3_pci_intel_byt_properties,
+};
+
static const struct software_node dwc3_pci_intel_mrfld_swnode = {
.properties = dwc3_pci_mrfld_properties,
};
@@ -344,7 +355,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
(kernel_ulong_t) &dwc3_pci_intel_swnode, },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BYT),
- (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+ (kernel_ulong_t) &dwc3_pci_intel_byt_swnode, },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD),
(kernel_ulong_t) &dwc3_pci_intel_mrfld_swnode, },
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 1/9] usb: dwc3: pci: Add "snps, dis_u2_susphy_quirk" for Intel Bay Trail
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy, Serge Semin
Commit e0082698b689 ("usb: dwc3: ulpi: conditionally resume ULPI PHY")
fixed an issue where ULPI transfers would timeout if any requests where
send to the phy sometime after init, giving it enough time to auto-suspend.
Commit e5f4ca3fce90 ("usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend
regression") changed the behavior to instead of clearing the
DWC3_GUSB2PHYCFG_SUSPHY bit, add an extra sleep when it is set.
But on Bay Trail devices, when phy_set_mode() gets called during init,
this leads to errors like these:
[ 28.451522] tusb1210 dwc3.ulpi: error -110 writing val 0x01 to reg 0x0a
[ 28.464089] tusb1210 dwc3.ulpi: error -110 writing val 0x01 to reg 0x0a
Add "snps,dis_u2_susphy_quirk" to the settings for Bay Trail devices to
fix this. This restores the old behavior for Bay Trail devices, since
previously the DWC3_GUSB2PHYCFG_SUSPHY bit would get cleared on the first
ulpi_read/_write() and then was never set again.
Fixes: e5f4ca3fce90 ("usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend regression")
Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 7ff8fc8f79a9..022341aef400 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -119,6 +119,13 @@ static const struct property_entry dwc3_pci_intel_properties[] = {
{}
};
+static const struct property_entry dwc3_pci_intel_byt_properties[] = {
+ PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
+ PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+ PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
+ {}
+};
+
static const struct property_entry dwc3_pci_mrfld_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
@@ -161,6 +168,10 @@ static const struct software_node dwc3_pci_intel_swnode = {
.properties = dwc3_pci_intel_properties,
};
+static const struct software_node dwc3_pci_intel_byt_swnode = {
+ .properties = dwc3_pci_intel_byt_properties,
+};
+
static const struct software_node dwc3_pci_intel_mrfld_swnode = {
.properties = dwc3_pci_mrfld_properties,
};
@@ -344,7 +355,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
(kernel_ulong_t) &dwc3_pci_intel_swnode, },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BYT),
- (kernel_ulong_t) &dwc3_pci_intel_swnode, },
+ (kernel_ulong_t) &dwc3_pci_intel_byt_swnode, },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD),
(kernel_ulong_t) &dwc3_pci_intel_mrfld_swnode, },
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 2/9] usb: dwc3: pci: Fix Bay Trail phy GPIO mappings
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
When the Bay Trail phy GPIO mappings where added cs and reset were swapped,
this did not cause any issues sofar, because sofar they were always driven
high/low at the same time.
Note the new mapping has been verified both in /sys/kernel/debug/gpio
output on Android factory images on multiple devices, as well as in
the schematics for some devices.
Fixes: 5741022cbdf3 ("usb: dwc3: pci: Add GPIO lookup table on platforms without ACPI GPIO resources")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 022341aef400..1ecedbb1684c 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -85,8 +85,8 @@ static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
static struct gpiod_lookup_table platform_bytcr_gpios = {
.dev_id = "0000:00:16.0",
.table = {
- GPIO_LOOKUP("INT33FC:00", 54, "reset", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("INT33FC:02", 14, "cs", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("INT33FC:00", 54, "cs", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("INT33FC:02", 14, "reset", GPIO_ACTIVE_HIGH),
{}
},
};
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 2/9] usb: dwc3: pci: Fix Bay Trail phy GPIO mappings
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
When the Bay Trail phy GPIO mappings where added cs and reset were swapped,
this did not cause any issues sofar, because sofar they were always driven
high/low at the same time.
Note the new mapping has been verified both in /sys/kernel/debug/gpio
output on Android factory images on multiple devices, as well as in
the schematics for some devices.
Fixes: 5741022cbdf3 ("usb: dwc3: pci: Add GPIO lookup table on platforms without ACPI GPIO resources")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 022341aef400..1ecedbb1684c 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -85,8 +85,8 @@ static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
static struct gpiod_lookup_table platform_bytcr_gpios = {
.dev_id = "0000:00:16.0",
.table = {
- GPIO_LOOKUP("INT33FC:00", 54, "reset", GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP("INT33FC:02", 14, "cs", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("INT33FC:00", 54, "cs", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("INT33FC:02", 14, "reset", GPIO_ACTIVE_HIGH),
{}
},
};
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 3/9] usb: dwc3: pci: Set the swnode from inside dwc3_pci_quirks()
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
The quirk handling may need to set some different properties
which means using a different swnode, move the setting of the swnode
to inside dwc3_pci_quirks() so that the quirk handling can choose
a different swnode.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 1ecedbb1684c..40a3a1b114e9 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -184,7 +184,8 @@ static const struct software_node dwc3_pci_amd_mr_swnode = {
.properties = dwc3_pci_mr_properties,
};
-static int dwc3_pci_quirks(struct dwc3_pci *dwc)
+static int dwc3_pci_quirks(struct dwc3_pci *dwc,
+ const struct software_node *swnode)
{
struct pci_dev *pdev = dwc->pci;
@@ -241,7 +242,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
}
}
- return 0;
+ return device_add_software_node(&dwc->dwc3->dev, swnode);
}
#ifdef CONFIG_PM
@@ -306,11 +307,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
dwc->dwc3->dev.parent = dev;
ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev));
- ret = device_add_software_node(&dwc->dwc3->dev, (void *)id->driver_data);
- if (ret < 0)
- goto err;
-
- ret = dwc3_pci_quirks(dwc);
+ ret = dwc3_pci_quirks(dwc, (void *)id->driver_data);
if (ret)
goto err;
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 3/9] usb: dwc3: pci: Set the swnode from inside dwc3_pci_quirks()
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
The quirk handling may need to set some different properties
which means using a different swnode, move the setting of the swnode
to inside dwc3_pci_quirks() so that the quirk handling can choose
a different swnode.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 1ecedbb1684c..40a3a1b114e9 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -184,7 +184,8 @@ static const struct software_node dwc3_pci_amd_mr_swnode = {
.properties = dwc3_pci_mr_properties,
};
-static int dwc3_pci_quirks(struct dwc3_pci *dwc)
+static int dwc3_pci_quirks(struct dwc3_pci *dwc,
+ const struct software_node *swnode)
{
struct pci_dev *pdev = dwc->pci;
@@ -241,7 +242,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
}
}
- return 0;
+ return device_add_software_node(&dwc->dwc3->dev, swnode);
}
#ifdef CONFIG_PM
@@ -306,11 +307,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
dwc->dwc3->dev.parent = dev;
ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev));
- ret = device_add_software_node(&dwc->dwc3->dev, (void *)id->driver_data);
- if (ret < 0)
- goto err;
-
- ret = dwc3_pci_quirks(dwc);
+ ret = dwc3_pci_quirks(dwc, (void *)id->driver_data);
if (ret)
goto err;
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 4/9] usb: dwc3: pci: Set "linux,phy_charger_detect" property on some Bay Trail boards
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
Some Android x86 tablets with a Bay Trail (BYT) SoC and a Crystal Cove
PMIC, which does not support charger-detection, rely on the TUSB1211 phy
for charger-detection.
Windows tablets with the same SoC + PMIC often use an extra chip for
charger-detection like the FSA831A. But since on Android tablets
the designers already need to add a TUSB1211 phy to support device/gadget
mode the phy is used to do charger-detection instead.
These Android x86 tablets can be identified by the unique combination of
a Bay Trail SoC (already checked for by PCI-ids) + a Crystal Cove PMIC +
not using the standard ACPI battery and ac drivers. Where as on Windows
tablets the standard ACPI battery and ac drivers will be used on BYT
boards with a Crystal Cove PMIC.
Set a special kernel-internal (so not part of the dt-bindings)
"linux,phy_charger_detect" property on these boards, which tells the
tusb1210 driver to enable charger-detection.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 40a3a1b114e9..8deccf0aa5e7 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -126,6 +126,14 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = {
{}
};
+static const struct property_entry dwc3_pci_intel_phy_charger_detect_properties[] = {
+ PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
+ PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+ PROPERTY_ENTRY_BOOL("linux,phy_charger_detect"),
+ PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
+ {}
+};
+
static const struct property_entry dwc3_pci_mrfld_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
@@ -172,6 +180,10 @@ static const struct software_node dwc3_pci_intel_byt_swnode = {
.properties = dwc3_pci_intel_byt_properties,
};
+static const struct software_node dwc3_pci_intel_phy_charger_detect_swnode = {
+ .properties = dwc3_pci_intel_phy_charger_detect_properties,
+};
+
static const struct software_node dwc3_pci_intel_mrfld_swnode = {
.properties = dwc3_pci_mrfld_properties,
};
@@ -239,6 +251,18 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
gpiod_put(gpio);
usleep_range(10000, 11000);
}
+
+ /*
+ * Some Android tablets with a Crystal Cove PMIC
+ * (INT33FD), rely on the TUSB1211 phy for charger
+ * detection. These can be identified by them _not_
+ * using the standard ACPI battery and ac drivers.
+ */
+ if (acpi_dev_present("INT33FD", "1", 2) &&
+ acpi_quirk_skip_acpi_ac_and_battery()) {
+ dev_info(&pdev->dev, "Using TUSB1211 phy for charger detection\n");
+ swnode = &dwc3_pci_intel_phy_charger_detect_swnode;
+ }
}
}
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 4/9] usb: dwc3: pci: Set "linux, phy_charger_detect" property on some Bay Trail boards
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
Some Android x86 tablets with a Bay Trail (BYT) SoC and a Crystal Cove
PMIC, which does not support charger-detection, rely on the TUSB1211 phy
for charger-detection.
Windows tablets with the same SoC + PMIC often use an extra chip for
charger-detection like the FSA831A. But since on Android tablets
the designers already need to add a TUSB1211 phy to support device/gadget
mode the phy is used to do charger-detection instead.
These Android x86 tablets can be identified by the unique combination of
a Bay Trail SoC (already checked for by PCI-ids) + a Crystal Cove PMIC +
not using the standard ACPI battery and ac drivers. Where as on Windows
tablets the standard ACPI battery and ac drivers will be used on BYT
boards with a Crystal Cove PMIC.
Set a special kernel-internal (so not part of the dt-bindings)
"linux,phy_charger_detect" property on these boards, which tells the
tusb1210 driver to enable charger-detection.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 40a3a1b114e9..8deccf0aa5e7 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -126,6 +126,14 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = {
{}
};
+static const struct property_entry dwc3_pci_intel_phy_charger_detect_properties[] = {
+ PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
+ PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+ PROPERTY_ENTRY_BOOL("linux,phy_charger_detect"),
+ PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
+ {}
+};
+
static const struct property_entry dwc3_pci_mrfld_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
@@ -172,6 +180,10 @@ static const struct software_node dwc3_pci_intel_byt_swnode = {
.properties = dwc3_pci_intel_byt_properties,
};
+static const struct software_node dwc3_pci_intel_phy_charger_detect_swnode = {
+ .properties = dwc3_pci_intel_phy_charger_detect_properties,
+};
+
static const struct software_node dwc3_pci_intel_mrfld_swnode = {
.properties = dwc3_pci_mrfld_properties,
};
@@ -239,6 +251,18 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
gpiod_put(gpio);
usleep_range(10000, 11000);
}
+
+ /*
+ * Some Android tablets with a Crystal Cove PMIC
+ * (INT33FD), rely on the TUSB1211 phy for charger
+ * detection. These can be identified by them _not_
+ * using the standard ACPI battery and ac drivers.
+ */
+ if (acpi_dev_present("INT33FD", "1", 2) &&
+ acpi_quirk_skip_acpi_ac_and_battery()) {
+ dev_info(&pdev->dev, "Using TUSB1211 phy for charger detection\n");
+ swnode = &dwc3_pci_intel_phy_charger_detect_swnode;
+ }
}
}
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 5/9] usb: dwc3: pci: Also apply Bay Trail GPIO mappings to ulpi-device
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
In order for the phy driver to be able to actually get and control
the cs and reset GPIOs the dev_id member of the gpiod_lookup table must
be set to point to the dev_name() of the ulpi-device instantiated by
dwc3_ulpi_init().
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 8deccf0aa5e7..fdcf552a6365 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -252,6 +252,14 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
usleep_range(10000, 11000);
}
+ /*
+ * Make the pdev name predictable (only 1 DWC3 on BYT)
+ * and patch the phy dev-name into the lookup table so
+ * that the phy-driver can get the GPIOs.
+ */
+ dwc->dwc3->id = PLATFORM_DEVID_NONE;
+ platform_bytcr_gpios.dev_id = "dwc3.ulpi";
+
/*
* Some Android tablets with a Crystal Cove PMIC
* (INT33FD), rely on the TUSB1211 phy for charger
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 5/9] usb: dwc3: pci: Also apply Bay Trail GPIO mappings to ulpi-device
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
In order for the phy driver to be able to actually get and control
the cs and reset GPIOs the dev_id member of the gpiod_lookup table must
be set to point to the dev_name() of the ulpi-device instantiated by
dwc3_ulpi_init().
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/dwc3/dwc3-pci.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 8deccf0aa5e7..fdcf552a6365 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -252,6 +252,14 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc,
usleep_range(10000, 11000);
}
+ /*
+ * Make the pdev name predictable (only 1 DWC3 on BYT)
+ * and patch the phy dev-name into the lookup table so
+ * that the phy-driver can get the GPIOs.
+ */
+ dwc->dwc3->id = PLATFORM_DEVID_NONE;
+ platform_bytcr_gpios.dev_id = "dwc3.ulpi";
+
/*
* Some Android tablets with a Crystal Cove PMIC
* (INT33FD), rely on the TUSB1211 phy for charger
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 6/9] phy: ti: tusb1210: Improve ulpi_read()/_write() error checking
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
ulpi_read() and ulpi_write() calls can fail. Add wrapper functions to log
errors when this happens and add error checking to the read + write of
the phy parameters from the TUSB1210_VENDOR_SPECIFIC2 register.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/phy/ti/phy-tusb1210.c | 62 +++++++++++++++++++++++++++--------
1 file changed, 48 insertions(+), 14 deletions(-)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index 15c1c79e5c29..bf7793afdc84 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -26,6 +26,33 @@ struct tusb1210 {
u8 vendor_specific2;
};
+static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)
+{
+ int ret;
+
+ ret = ulpi_write(tusb->ulpi, reg, val);
+ if (ret)
+ dev_err(&tusb->ulpi->dev, "error %d writing val 0x%02x to reg 0x%02x\n",
+ ret, val, reg);
+
+ return ret;
+}
+
+static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val)
+{
+ int ret;
+
+ ret = ulpi_read(tusb->ulpi, reg);
+ if (ret >= 0) {
+ *val = ret;
+ ret = 0;
+ } else {
+ dev_err(&tusb->ulpi->dev, "error %d reading reg 0x%02x\n", ret, reg);
+ }
+
+ return ret;
+}
+
static int tusb1210_power_on(struct phy *phy)
{
struct tusb1210 *tusb = phy_get_drvdata(phy);
@@ -35,8 +62,8 @@ static int tusb1210_power_on(struct phy *phy)
/* Restore the optional eye diagram optimization value */
if (tusb->vendor_specific2)
- ulpi_write(tusb->ulpi, TUSB1210_VENDOR_SPECIFIC2,
- tusb->vendor_specific2);
+ return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
+ tusb->vendor_specific2);
return 0;
}
@@ -55,33 +82,34 @@ static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct tusb1210 *tusb = phy_get_drvdata(phy);
int ret;
+ u8 reg;
- ret = ulpi_read(tusb->ulpi, ULPI_OTG_CTRL);
+ ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, ®);
if (ret < 0)
return ret;
switch (mode) {
case PHY_MODE_USB_HOST:
- ret |= (ULPI_OTG_CTRL_DRVVBUS_EXT
+ reg |= (ULPI_OTG_CTRL_DRVVBUS_EXT
| ULPI_OTG_CTRL_ID_PULLUP
| ULPI_OTG_CTRL_DP_PULLDOWN
| ULPI_OTG_CTRL_DM_PULLDOWN);
- ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
- ret |= ULPI_OTG_CTRL_DRVVBUS;
+ tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
+ reg |= ULPI_OTG_CTRL_DRVVBUS;
break;
case PHY_MODE_USB_DEVICE:
- ret &= ~(ULPI_OTG_CTRL_DRVVBUS
+ reg &= ~(ULPI_OTG_CTRL_DRVVBUS
| ULPI_OTG_CTRL_DP_PULLDOWN
| ULPI_OTG_CTRL_DM_PULLDOWN);
- ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
- ret &= ~ULPI_OTG_CTRL_DRVVBUS_EXT;
+ tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
+ reg &= ~ULPI_OTG_CTRL_DRVVBUS_EXT;
break;
default:
/* nothing */
return 0;
}
- return ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
+ return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
}
static const struct phy_ops phy_ops = {
@@ -95,11 +123,14 @@ static int tusb1210_probe(struct ulpi *ulpi)
{
struct tusb1210 *tusb;
u8 val, reg;
+ int ret;
tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL);
if (!tusb)
return -ENOMEM;
+ tusb->ulpi = ulpi;
+
tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(tusb->gpio_reset))
@@ -119,7 +150,9 @@ static int tusb1210_probe(struct ulpi *ulpi)
* diagram optimization and DP/DM swap.
*/
- reg = ulpi_read(ulpi, TUSB1210_VENDOR_SPECIFIC2);
+ ret = tusb1210_ulpi_read(tusb, TUSB1210_VENDOR_SPECIFIC2, ®);
+ if (ret)
+ return ret;
/* High speed output drive strength configuration */
if (!device_property_read_u8(&ulpi->dev, "ihstx", &val))
@@ -133,15 +166,16 @@ static int tusb1210_probe(struct ulpi *ulpi)
if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val))
u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK);
- ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg);
+ ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg);
+ if (ret)
+ return ret;
+
tusb->vendor_specific2 = reg;
tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
if (IS_ERR(tusb->phy))
return PTR_ERR(tusb->phy);
- tusb->ulpi = ulpi;
-
phy_set_drvdata(tusb->phy, tusb);
ulpi_set_drvdata(ulpi, tusb);
return 0;
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 6/9] phy: ti: tusb1210: Improve ulpi_read()/_write() error checking
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
ulpi_read() and ulpi_write() calls can fail. Add wrapper functions to log
errors when this happens and add error checking to the read + write of
the phy parameters from the TUSB1210_VENDOR_SPECIFIC2 register.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/phy/ti/phy-tusb1210.c | 62 +++++++++++++++++++++++++++--------
1 file changed, 48 insertions(+), 14 deletions(-)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index 15c1c79e5c29..bf7793afdc84 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -26,6 +26,33 @@ struct tusb1210 {
u8 vendor_specific2;
};
+static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)
+{
+ int ret;
+
+ ret = ulpi_write(tusb->ulpi, reg, val);
+ if (ret)
+ dev_err(&tusb->ulpi->dev, "error %d writing val 0x%02x to reg 0x%02x\n",
+ ret, val, reg);
+
+ return ret;
+}
+
+static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val)
+{
+ int ret;
+
+ ret = ulpi_read(tusb->ulpi, reg);
+ if (ret >= 0) {
+ *val = ret;
+ ret = 0;
+ } else {
+ dev_err(&tusb->ulpi->dev, "error %d reading reg 0x%02x\n", ret, reg);
+ }
+
+ return ret;
+}
+
static int tusb1210_power_on(struct phy *phy)
{
struct tusb1210 *tusb = phy_get_drvdata(phy);
@@ -35,8 +62,8 @@ static int tusb1210_power_on(struct phy *phy)
/* Restore the optional eye diagram optimization value */
if (tusb->vendor_specific2)
- ulpi_write(tusb->ulpi, TUSB1210_VENDOR_SPECIFIC2,
- tusb->vendor_specific2);
+ return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
+ tusb->vendor_specific2);
return 0;
}
@@ -55,33 +82,34 @@ static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
struct tusb1210 *tusb = phy_get_drvdata(phy);
int ret;
+ u8 reg;
- ret = ulpi_read(tusb->ulpi, ULPI_OTG_CTRL);
+ ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, ®);
if (ret < 0)
return ret;
switch (mode) {
case PHY_MODE_USB_HOST:
- ret |= (ULPI_OTG_CTRL_DRVVBUS_EXT
+ reg |= (ULPI_OTG_CTRL_DRVVBUS_EXT
| ULPI_OTG_CTRL_ID_PULLUP
| ULPI_OTG_CTRL_DP_PULLDOWN
| ULPI_OTG_CTRL_DM_PULLDOWN);
- ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
- ret |= ULPI_OTG_CTRL_DRVVBUS;
+ tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
+ reg |= ULPI_OTG_CTRL_DRVVBUS;
break;
case PHY_MODE_USB_DEVICE:
- ret &= ~(ULPI_OTG_CTRL_DRVVBUS
+ reg &= ~(ULPI_OTG_CTRL_DRVVBUS
| ULPI_OTG_CTRL_DP_PULLDOWN
| ULPI_OTG_CTRL_DM_PULLDOWN);
- ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
- ret &= ~ULPI_OTG_CTRL_DRVVBUS_EXT;
+ tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
+ reg &= ~ULPI_OTG_CTRL_DRVVBUS_EXT;
break;
default:
/* nothing */
return 0;
}
- return ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
+ return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
}
static const struct phy_ops phy_ops = {
@@ -95,11 +123,14 @@ static int tusb1210_probe(struct ulpi *ulpi)
{
struct tusb1210 *tusb;
u8 val, reg;
+ int ret;
tusb = devm_kzalloc(&ulpi->dev, sizeof(*tusb), GFP_KERNEL);
if (!tusb)
return -ENOMEM;
+ tusb->ulpi = ulpi;
+
tusb->gpio_reset = devm_gpiod_get_optional(&ulpi->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(tusb->gpio_reset))
@@ -119,7 +150,9 @@ static int tusb1210_probe(struct ulpi *ulpi)
* diagram optimization and DP/DM swap.
*/
- reg = ulpi_read(ulpi, TUSB1210_VENDOR_SPECIFIC2);
+ ret = tusb1210_ulpi_read(tusb, TUSB1210_VENDOR_SPECIFIC2, ®);
+ if (ret)
+ return ret;
/* High speed output drive strength configuration */
if (!device_property_read_u8(&ulpi->dev, "ihstx", &val))
@@ -133,15 +166,16 @@ static int tusb1210_probe(struct ulpi *ulpi)
if (!device_property_read_u8(&ulpi->dev, "datapolarity", &val))
u8p_replace_bits(®, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK);
- ulpi_write(ulpi, TUSB1210_VENDOR_SPECIFIC2, reg);
+ ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg);
+ if (ret)
+ return ret;
+
tusb->vendor_specific2 = reg;
tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
if (IS_ERR(tusb->phy))
return PTR_ERR(tusb->phy);
- tusb->ulpi = ulpi;
-
phy_set_drvdata(tusb->phy, tusb);
ulpi_set_drvdata(ulpi, tusb);
return 0;
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 7/9] phy: ti: tusb1210: Drop tusb->vendor_specific2 != 0 check from tusb1210_power_on()
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
Since commit eb445a15fa69 ("phy: tusb1210: use bitmasks to set
VENDOR_SPECIFIC2") tusb->vendor_specific2 always contains a valid value
so there no need to check that it is set.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/phy/ti/phy-tusb1210.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index bf7793afdc84..04baed24469f 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -61,11 +61,8 @@ static int tusb1210_power_on(struct phy *phy)
gpiod_set_value_cansleep(tusb->gpio_cs, 1);
/* Restore the optional eye diagram optimization value */
- if (tusb->vendor_specific2)
- return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
- tusb->vendor_specific2);
-
- return 0;
+ return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
+ tusb->vendor_specific2);
}
static int tusb1210_power_off(struct phy *phy)
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 7/9] phy: ti: tusb1210: Drop tusb->vendor_specific2 != 0 check from tusb1210_power_on()
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
Since commit eb445a15fa69 ("phy: tusb1210: use bitmasks to set
VENDOR_SPECIFIC2") tusb->vendor_specific2 always contains a valid value
so there no need to check that it is set.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/phy/ti/phy-tusb1210.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index bf7793afdc84..04baed24469f 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -61,11 +61,8 @@ static int tusb1210_power_on(struct phy *phy)
gpiod_set_value_cansleep(tusb->gpio_cs, 1);
/* Restore the optional eye diagram optimization value */
- if (tusb->vendor_specific2)
- return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
- tusb->vendor_specific2);
-
- return 0;
+ return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
+ tusb->vendor_specific2);
}
static int tusb1210_power_off(struct phy *phy)
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] phy: ti: tusb1210: Add a delay between power-on and restoring the phy-parameters
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
Now that we actually log errors on ulpi_write failures it becomes clear
that the ulpi_write() restoring the phy-parameters on power-on is failing
after a suspend/resume add a short delay after driving the cs line high
to fix this.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/phy/ti/phy-tusb1210.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index 04baed24469f..9ef4c5f79b75 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -8,6 +8,7 @@
*/
#include <linux/module.h>
#include <linux/bitfield.h>
+#include <linux/delay.h>
#include <linux/ulpi/driver.h>
#include <linux/ulpi/regs.h>
#include <linux/gpio/consumer.h>
@@ -18,6 +19,8 @@
#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4)
#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6)
+#define TUSB1210_RESET_TIME_MS 30
+
struct tusb1210 {
struct ulpi *ulpi;
struct phy *phy;
@@ -60,6 +63,8 @@ static int tusb1210_power_on(struct phy *phy)
gpiod_set_value_cansleep(tusb->gpio_reset, 1);
gpiod_set_value_cansleep(tusb->gpio_cs, 1);
+ msleep(TUSB1210_RESET_TIME_MS);
+
/* Restore the optional eye diagram optimization value */
return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
tusb->vendor_specific2);
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 8/9] phy: ti: tusb1210: Add a delay between power-on and restoring the phy-parameters
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
Now that we actually log errors on ulpi_write failures it becomes clear
that the ulpi_write() restoring the phy-parameters on power-on is failing
after a suspend/resume add a short delay after driving the cs line high
to fix this.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/phy/ti/phy-tusb1210.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index 04baed24469f..9ef4c5f79b75 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -8,6 +8,7 @@
*/
#include <linux/module.h>
#include <linux/bitfield.h>
+#include <linux/delay.h>
#include <linux/ulpi/driver.h>
#include <linux/ulpi/regs.h>
#include <linux/gpio/consumer.h>
@@ -18,6 +19,8 @@
#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4)
#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6)
+#define TUSB1210_RESET_TIME_MS 30
+
struct tusb1210 {
struct ulpi *ulpi;
struct phy *phy;
@@ -60,6 +63,8 @@ static int tusb1210_power_on(struct phy *phy)
gpiod_set_value_cansleep(tusb->gpio_reset, 1);
gpiod_set_value_cansleep(tusb->gpio_cs, 1);
+ msleep(TUSB1210_RESET_TIME_MS);
+
/* Restore the optional eye diagram optimization value */
return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
tusb->vendor_specific2);
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 9/9] phy: ti: tusb1210: Add charger detection
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-13 13:05 ` Hans de Goede
-1 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
From: Stephan Gerhold <stephan@gerhold.net>
Some Android x86 tablets with a Bay Trail (BYT) SoC and a Crystal Cove
PMIC, which does not support charger-detection, rely on a TUSB1211
phy for charger-detection.
Add support for charger detection on TUSB1211 phy-s and export
the information about the detected charger through the standard
power_supply class interface. power_supply class charger IC drivers
like the bq24190_charger.c driver will then pick this up and set
their input_current_limit based on this.
Note the "linux,phy_charger_detect" property used to enable this is
a special kernel-internal (so not part of the dt-bindings) property
used by dwc3 platform code to indicate that the phy needs to do
charger-detection.
Changes by Hans de Goede:
- Use "linux,phy_charger_detect" property to enable charger-detect
- Switch from a linear flow to a state-machine, with retries on
ulpi communication errors
- Use SW_CONTROL bit to disable the FSM when detection is finished
- Do a phy-reset on disconnect to work around the phy often refusing
ulpi_read()/_write() commands after a disconnect
- Use power_supply_reg_notifier() for Vbus monitoring
- Export the detection result through a power_supply class device
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Co-developed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
- Add an online attribute to the registered power_supply class device,
otherwise upower thinks it is an extra system battery
- Add tusb1210_remove_charger_detect() function to properly unregister
the tusb->psy_nb notifier and to cancel tusb->chg_det_work
---
drivers/phy/ti/phy-tusb1210.c | 377 +++++++++++++++++++++++++++++++++-
1 file changed, 370 insertions(+), 7 deletions(-)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index 9ef4c5f79b75..a0cdbcadf09e 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -13,20 +13,59 @@
#include <linux/ulpi/regs.h>
#include <linux/gpio/consumer.h>
#include <linux/phy/ulpi_phy.h>
-
-#define TUSB1210_VENDOR_SPECIFIC2 0x80
-#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK GENMASK(3, 0)
-#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4)
-#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6)
-
-#define TUSB1210_RESET_TIME_MS 30
+#include <linux/power_supply.h>
+#include <linux/workqueue.h>
+
+#define TUSB1211_POWER_CONTROL 0x3d
+#define TUSB1211_POWER_CONTROL_SET 0x3e
+#define TUSB1211_POWER_CONTROL_CLEAR 0x3f
+#define TUSB1211_POWER_CONTROL_SW_CONTROL BIT(0)
+#define TUSB1211_POWER_CONTROL_DET_COMP BIT(1)
+#define TUSB1211_POWER_CONTROL_DP_VSRC_EN BIT(6)
+
+#define TUSB1210_VENDOR_SPECIFIC2 0x80
+#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK GENMASK(3, 0)
+#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4)
+#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6)
+
+#define TUSB1211_VENDOR_SPECIFIC3 0x85
+#define TUSB1211_VENDOR_SPECIFIC3_SET 0x86
+#define TUSB1211_VENDOR_SPECIFIC3_CLEAR 0x87
+#define TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET BIT(4)
+#define TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN BIT(6)
+
+#define TUSB1210_RESET_TIME_MS 50
+
+#define TUSB1210_CHG_DET_MAX_RETRIES 5
+
+/* TUSB1210 charger detection work states */
+enum tusb1210_chg_det_state {
+ TUSB1210_CHG_DET_CONNECTING,
+ TUSB1210_CHG_DET_START_DET,
+ TUSB1210_CHG_DET_READ_DET,
+ TUSB1210_CHG_DET_FINISH_DET,
+ TUSB1210_CHG_DET_CONNECTED,
+ TUSB1210_CHG_DET_DISCONNECTING,
+ TUSB1210_CHG_DET_DISCONNECTING_DONE,
+ TUSB1210_CHG_DET_DISCONNECTED,
+};
struct tusb1210 {
struct ulpi *ulpi;
struct phy *phy;
struct gpio_desc *gpio_reset;
struct gpio_desc *gpio_cs;
+ u8 otg_ctrl;
u8 vendor_specific2;
+#ifdef CONFIG_POWER_SUPPLY
+ enum power_supply_usb_type chg_type;
+ enum tusb1210_chg_det_state chg_det_state;
+ int chg_det_retries;
+ struct delayed_work chg_det_work;
+ struct notifier_block psy_nb;
+ struct power_supply *psy;
+ struct power_supply *charger;
+#endif
};
static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)
@@ -111,9 +150,330 @@ static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
return 0;
}
+ tusb->otg_ctrl = reg;
return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
}
+#ifdef CONFIG_POWER_SUPPLY
+const char * const tusb1210_chg_det_states[] = {
+ "CHG_DET_CONNECTING",
+ "CHG_DET_START_DET",
+ "CHG_DET_READ_DET",
+ "CHG_DET_FINISH_DET",
+ "CHG_DET_CONNECTED",
+ "CHG_DET_DISCONNECTING",
+ "CHG_DET_DISCONNECTING_DONE",
+ "CHG_DET_DISCONNECTED",
+};
+
+static void tusb1210_reset(struct tusb1210 *tusb)
+{
+ gpiod_set_value_cansleep(tusb->gpio_reset, 0);
+ usleep_range(200, 500);
+ gpiod_set_value_cansleep(tusb->gpio_reset, 1);
+}
+
+static void tusb1210_chg_det_set_type(struct tusb1210 *tusb,
+ enum power_supply_usb_type type)
+{
+ dev_dbg(&tusb->ulpi->dev, "charger type: %d\n", type);
+ tusb->chg_type = type;
+ tusb->chg_det_retries = 0;
+ power_supply_changed(tusb->psy);
+}
+
+static void tusb1210_chg_det_set_state(struct tusb1210 *tusb,
+ enum tusb1210_chg_det_state new_state,
+ int delay_ms)
+{
+ if (delay_ms)
+ dev_dbg(&tusb->ulpi->dev, "chg_det new state %s in %d ms\n",
+ tusb1210_chg_det_states[new_state], delay_ms);
+
+ tusb->chg_det_state = new_state;
+ mod_delayed_work(system_long_wq, &tusb->chg_det_work,
+ msecs_to_jiffies(delay_ms));
+}
+
+static void tusb1210_chg_det_handle_ulpi_error(struct tusb1210 *tusb)
+{
+ tusb1210_reset(tusb);
+ if (tusb->chg_det_retries < TUSB1210_CHG_DET_MAX_RETRIES) {
+ tusb->chg_det_retries++;
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET,
+ TUSB1210_RESET_TIME_MS);
+ } else {
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET,
+ TUSB1210_RESET_TIME_MS);
+ }
+}
+
+/*
+ * Boards using a TUSB121x for charger-detection have 3 power_supply class devs:
+ *
+ * tusb1211-charger-detect(1) -> charger -> fuel-gauge
+ *
+ * To determine if an USB charger is connected to the board, the online prop of
+ * the charger psy needs to be read. Since the tusb1211-charger-detect psy is
+ * the start of the supplier -> supplied-to chain, power_supply_am_i_supplied()
+ * cannot be used here.
+ *
+ * Instead, below is a list of the power_supply names of known chargers for
+ * these boards and the charger psy is looked up by name from this list.
+ *
+ * (1) modelling the external USB charger
+ */
+static const char * const tusb1210_chargers[] = {
+ "bq24190-charger",
+};
+
+static bool tusb1210_get_online(struct tusb1210 *tusb)
+{
+ union power_supply_propval val;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tusb1210_chargers) && !tusb->charger; i++)
+ tusb->charger = power_supply_get_by_name(tusb1210_chargers[i]);
+
+ if (!tusb->charger)
+ return false;
+
+ if (power_supply_get_property(tusb->charger, POWER_SUPPLY_PROP_ONLINE, &val))
+ return false;
+
+ return val.intval;
+}
+
+static void tusb1210_chg_det_work(struct work_struct *work)
+{
+ struct tusb1210 *tusb = container_of(work, struct tusb1210, chg_det_work.work);
+ bool vbus_present = tusb1210_get_online(tusb);
+ int ret;
+ u8 val;
+
+ dev_dbg(&tusb->ulpi->dev, "chg_det state %s vbus_present %d\n",
+ tusb1210_chg_det_states[tusb->chg_det_state], vbus_present);
+
+ switch (tusb->chg_det_state) {
+ case TUSB1210_CHG_DET_CONNECTING:
+ tusb->chg_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;
+ tusb->chg_det_retries = 0;
+ /* Power on USB controller for ulpi_read()/_write() */
+ ret = pm_runtime_resume_and_get(tusb->ulpi->dev.parent);
+ if (ret < 0) {
+ dev_err(&tusb->ulpi->dev, "error %d runtime-resuming\n", ret);
+ /* Should never happen, skip charger detection */
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);
+ return;
+ }
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET, 0);
+ break;
+ case TUSB1210_CHG_DET_START_DET:
+ /*
+ * Use the builtin charger detection FSM to keep things simple.
+ * This only detects DCP / SDP. This is good enough for the few
+ * boards which actually rely on the phy for charger detection.
+ */
+ mutex_lock(&tusb->phy->mutex);
+ ret = tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_SET,
+ TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET);
+ mutex_unlock(&tusb->phy->mutex);
+ if (ret) {
+ tusb1210_chg_det_handle_ulpi_error(tusb);
+ break;
+ }
+
+ /* Wait 400 ms for the charger detection FSM to finish */
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_READ_DET, 400);
+ break;
+ case TUSB1210_CHG_DET_READ_DET:
+ mutex_lock(&tusb->phy->mutex);
+ ret = tusb1210_ulpi_read(tusb, TUSB1211_POWER_CONTROL, &val);
+ mutex_unlock(&tusb->phy->mutex);
+ if (ret) {
+ tusb1210_chg_det_handle_ulpi_error(tusb);
+ break;
+ }
+
+ if (val & TUSB1211_POWER_CONTROL_DET_COMP)
+ tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_DCP);
+ else
+ tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_SDP);
+
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET, 0);
+ break;
+ case TUSB1210_CHG_DET_FINISH_DET:
+ mutex_lock(&tusb->phy->mutex);
+
+ /* Set SW_CONTROL to stop the charger-det FSM */
+ ret = tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_SET,
+ TUSB1211_POWER_CONTROL_SW_CONTROL);
+
+ /* Clear DP_VSRC_EN which may have been enabled by the charger-det FSM */
+ ret |= tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_CLEAR,
+ TUSB1211_POWER_CONTROL_DP_VSRC_EN);
+
+ /* Clear CHGD_IDP_SRC_EN (may have been enabled by the charger-det FSM) */
+ ret |= tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_CLEAR,
+ TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN);
+
+ /* If any of the above fails reset the phy */
+ if (ret) {
+ tusb1210_reset(tusb);
+ msleep(TUSB1210_RESET_TIME_MS);
+ }
+
+ /* Restore phy-parameters and OTG_CTRL register */
+ tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, tusb->otg_ctrl);
+ tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
+ tusb->vendor_specific2);
+
+ mutex_unlock(&tusb->phy->mutex);
+
+ pm_runtime_put(tusb->ulpi->dev.parent);
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);
+ break;
+ case TUSB1210_CHG_DET_CONNECTED:
+ if (!vbus_present)
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING, 0);
+ break;
+ case TUSB1210_CHG_DET_DISCONNECTING:
+ /*
+ * The phy seems to take approx. 600ms longer then the charger
+ * chip (which is used to get vbus_present) to determine Vbus
+ * session end. Wait 800ms to ensure the phy has detected and
+ * signalled Vbus session end.
+ */
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING_DONE, 800);
+ break;
+ case TUSB1210_CHG_DET_DISCONNECTING_DONE:
+ /*
+ * The phy often stops reacting to ulpi_read()/_write requests
+ * after a Vbus-session end. Reset it to work around this.
+ */
+ tusb1210_reset(tusb);
+ tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_UNKNOWN);
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTED, 0);
+ break;
+ case TUSB1210_CHG_DET_DISCONNECTED:
+ if (vbus_present)
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTING, 0);
+ break;
+ }
+}
+
+static int tusb1210_psy_notifier(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct tusb1210 *tusb = container_of(nb, struct tusb1210, psy_nb);
+ struct power_supply *psy = ptr;
+
+ if (psy != tusb->psy && psy->desc->type == POWER_SUPPLY_TYPE_USB)
+ queue_delayed_work(system_long_wq, &tusb->chg_det_work, 0);
+
+ return NOTIFY_OK;
+}
+
+static int tusb1210_psy_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct tusb1210 *tusb = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = tusb1210_get_online(tusb);
+ break;
+ case POWER_SUPPLY_PROP_USB_TYPE:
+ val->intval = tusb->chg_type;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ if (tusb->chg_type == POWER_SUPPLY_USB_TYPE_DCP)
+ val->intval = 2000000;
+ else
+ val->intval = 500000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const enum power_supply_usb_type tusb1210_psy_usb_types[] = {
+ POWER_SUPPLY_USB_TYPE_SDP,
+ POWER_SUPPLY_USB_TYPE_DCP,
+ POWER_SUPPLY_USB_TYPE_UNKNOWN,
+};
+
+static const enum power_supply_property tusb1210_psy_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_USB_TYPE,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
+};
+
+static const struct power_supply_desc tusb1210_psy_desc = {
+ .name = "tusb1211-charger-detect",
+ .type = POWER_SUPPLY_TYPE_USB,
+ .usb_types = tusb1210_psy_usb_types,
+ .num_usb_types = ARRAY_SIZE(tusb1210_psy_usb_types),
+ .properties = tusb1210_psy_props,
+ .num_properties = ARRAY_SIZE(tusb1210_psy_props),
+ .get_property = tusb1210_psy_get_prop,
+};
+
+/* Setup charger detection if requested, on errors continue without chg-det */
+static void tusb1210_probe_charger_detect(struct tusb1210 *tusb)
+{
+ struct power_supply_config psy_cfg = { .drv_data = tusb };
+ struct device *dev = &tusb->ulpi->dev;
+ int ret;
+
+ if (!device_property_read_bool(dev->parent, "linux,phy_charger_detect"))
+ return;
+
+ if (tusb->ulpi->id.product != 0x1508) {
+ dev_err(dev, "error charger detection is only supported on the TUSB1211\n");
+ return;
+ }
+
+ ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &tusb->otg_ctrl);
+ if (ret)
+ return;
+
+ tusb->psy = power_supply_register(dev, &tusb1210_psy_desc, &psy_cfg);
+ if (IS_ERR(tusb->psy))
+ return;
+
+ /*
+ * Delay initial run by 2 seconds to allow the charger driver,
+ * which is used to determine vbus_present, to load.
+ */
+ tusb->chg_det_state = TUSB1210_CHG_DET_DISCONNECTED;
+ INIT_DELAYED_WORK(&tusb->chg_det_work, tusb1210_chg_det_work);
+ queue_delayed_work(system_long_wq, &tusb->chg_det_work, 2 * HZ);
+
+ tusb->psy_nb.notifier_call = tusb1210_psy_notifier;
+ power_supply_reg_notifier(&tusb->psy_nb);
+}
+
+static void tusb1210_remove_charger_detect(struct tusb1210 *tusb)
+{
+
+ if (!IS_ERR_OR_NULL(tusb->psy)) {
+ power_supply_unreg_notifier(&tusb->psy_nb);
+ cancel_delayed_work_sync(&tusb->chg_det_work);
+ power_supply_unregister(tusb->psy);
+ }
+
+ if (tusb->charger)
+ power_supply_put(tusb->charger);
+}
+#else
+static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) { }
+static void tusb1210_remove_charger_detect(struct tusb1210 *tusb) { }
+#endif
+
static const struct phy_ops phy_ops = {
.power_on = tusb1210_power_on,
.power_off = tusb1210_power_off,
@@ -174,6 +534,8 @@ static int tusb1210_probe(struct ulpi *ulpi)
tusb->vendor_specific2 = reg;
+ tusb1210_probe_charger_detect(tusb);
+
tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
if (IS_ERR(tusb->phy))
return PTR_ERR(tusb->phy);
@@ -188,6 +550,7 @@ static void tusb1210_remove(struct ulpi *ulpi)
struct tusb1210 *tusb = ulpi_get_drvdata(ulpi);
ulpi_phy_destroy(ulpi, tusb->phy);
+ tusb1210_remove_charger_detect(tusb);
}
#define TI_VENDOR_ID 0x0451
--
2.33.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v2 9/9] phy: ti: tusb1210: Add charger detection
@ 2022-02-13 13:05 ` Hans de Goede
0 siblings, 0 replies; 24+ messages in thread
From: Hans de Goede @ 2022-02-13 13:05 UTC (permalink / raw)
To: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I, Vinod Koul
Cc: Hans de Goede, Stephan Gerhold, linux-usb, linux-phy
From: Stephan Gerhold <stephan@gerhold.net>
Some Android x86 tablets with a Bay Trail (BYT) SoC and a Crystal Cove
PMIC, which does not support charger-detection, rely on a TUSB1211
phy for charger-detection.
Add support for charger detection on TUSB1211 phy-s and export
the information about the detected charger through the standard
power_supply class interface. power_supply class charger IC drivers
like the bq24190_charger.c driver will then pick this up and set
their input_current_limit based on this.
Note the "linux,phy_charger_detect" property used to enable this is
a special kernel-internal (so not part of the dt-bindings) property
used by dwc3 platform code to indicate that the phy needs to do
charger-detection.
Changes by Hans de Goede:
- Use "linux,phy_charger_detect" property to enable charger-detect
- Switch from a linear flow to a state-machine, with retries on
ulpi communication errors
- Use SW_CONTROL bit to disable the FSM when detection is finished
- Do a phy-reset on disconnect to work around the phy often refusing
ulpi_read()/_write() commands after a disconnect
- Use power_supply_reg_notifier() for Vbus monitoring
- Export the detection result through a power_supply class device
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Co-developed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
- Add an online attribute to the registered power_supply class device,
otherwise upower thinks it is an extra system battery
- Add tusb1210_remove_charger_detect() function to properly unregister
the tusb->psy_nb notifier and to cancel tusb->chg_det_work
---
drivers/phy/ti/phy-tusb1210.c | 377 +++++++++++++++++++++++++++++++++-
1 file changed, 370 insertions(+), 7 deletions(-)
diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
index 9ef4c5f79b75..a0cdbcadf09e 100644
--- a/drivers/phy/ti/phy-tusb1210.c
+++ b/drivers/phy/ti/phy-tusb1210.c
@@ -13,20 +13,59 @@
#include <linux/ulpi/regs.h>
#include <linux/gpio/consumer.h>
#include <linux/phy/ulpi_phy.h>
-
-#define TUSB1210_VENDOR_SPECIFIC2 0x80
-#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK GENMASK(3, 0)
-#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4)
-#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6)
-
-#define TUSB1210_RESET_TIME_MS 30
+#include <linux/power_supply.h>
+#include <linux/workqueue.h>
+
+#define TUSB1211_POWER_CONTROL 0x3d
+#define TUSB1211_POWER_CONTROL_SET 0x3e
+#define TUSB1211_POWER_CONTROL_CLEAR 0x3f
+#define TUSB1211_POWER_CONTROL_SW_CONTROL BIT(0)
+#define TUSB1211_POWER_CONTROL_DET_COMP BIT(1)
+#define TUSB1211_POWER_CONTROL_DP_VSRC_EN BIT(6)
+
+#define TUSB1210_VENDOR_SPECIFIC2 0x80
+#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK GENMASK(3, 0)
+#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK GENMASK(5, 4)
+#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK BIT(6)
+
+#define TUSB1211_VENDOR_SPECIFIC3 0x85
+#define TUSB1211_VENDOR_SPECIFIC3_SET 0x86
+#define TUSB1211_VENDOR_SPECIFIC3_CLEAR 0x87
+#define TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET BIT(4)
+#define TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN BIT(6)
+
+#define TUSB1210_RESET_TIME_MS 50
+
+#define TUSB1210_CHG_DET_MAX_RETRIES 5
+
+/* TUSB1210 charger detection work states */
+enum tusb1210_chg_det_state {
+ TUSB1210_CHG_DET_CONNECTING,
+ TUSB1210_CHG_DET_START_DET,
+ TUSB1210_CHG_DET_READ_DET,
+ TUSB1210_CHG_DET_FINISH_DET,
+ TUSB1210_CHG_DET_CONNECTED,
+ TUSB1210_CHG_DET_DISCONNECTING,
+ TUSB1210_CHG_DET_DISCONNECTING_DONE,
+ TUSB1210_CHG_DET_DISCONNECTED,
+};
struct tusb1210 {
struct ulpi *ulpi;
struct phy *phy;
struct gpio_desc *gpio_reset;
struct gpio_desc *gpio_cs;
+ u8 otg_ctrl;
u8 vendor_specific2;
+#ifdef CONFIG_POWER_SUPPLY
+ enum power_supply_usb_type chg_type;
+ enum tusb1210_chg_det_state chg_det_state;
+ int chg_det_retries;
+ struct delayed_work chg_det_work;
+ struct notifier_block psy_nb;
+ struct power_supply *psy;
+ struct power_supply *charger;
+#endif
};
static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)
@@ -111,9 +150,330 @@ static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
return 0;
}
+ tusb->otg_ctrl = reg;
return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
}
+#ifdef CONFIG_POWER_SUPPLY
+const char * const tusb1210_chg_det_states[] = {
+ "CHG_DET_CONNECTING",
+ "CHG_DET_START_DET",
+ "CHG_DET_READ_DET",
+ "CHG_DET_FINISH_DET",
+ "CHG_DET_CONNECTED",
+ "CHG_DET_DISCONNECTING",
+ "CHG_DET_DISCONNECTING_DONE",
+ "CHG_DET_DISCONNECTED",
+};
+
+static void tusb1210_reset(struct tusb1210 *tusb)
+{
+ gpiod_set_value_cansleep(tusb->gpio_reset, 0);
+ usleep_range(200, 500);
+ gpiod_set_value_cansleep(tusb->gpio_reset, 1);
+}
+
+static void tusb1210_chg_det_set_type(struct tusb1210 *tusb,
+ enum power_supply_usb_type type)
+{
+ dev_dbg(&tusb->ulpi->dev, "charger type: %d\n", type);
+ tusb->chg_type = type;
+ tusb->chg_det_retries = 0;
+ power_supply_changed(tusb->psy);
+}
+
+static void tusb1210_chg_det_set_state(struct tusb1210 *tusb,
+ enum tusb1210_chg_det_state new_state,
+ int delay_ms)
+{
+ if (delay_ms)
+ dev_dbg(&tusb->ulpi->dev, "chg_det new state %s in %d ms\n",
+ tusb1210_chg_det_states[new_state], delay_ms);
+
+ tusb->chg_det_state = new_state;
+ mod_delayed_work(system_long_wq, &tusb->chg_det_work,
+ msecs_to_jiffies(delay_ms));
+}
+
+static void tusb1210_chg_det_handle_ulpi_error(struct tusb1210 *tusb)
+{
+ tusb1210_reset(tusb);
+ if (tusb->chg_det_retries < TUSB1210_CHG_DET_MAX_RETRIES) {
+ tusb->chg_det_retries++;
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET,
+ TUSB1210_RESET_TIME_MS);
+ } else {
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET,
+ TUSB1210_RESET_TIME_MS);
+ }
+}
+
+/*
+ * Boards using a TUSB121x for charger-detection have 3 power_supply class devs:
+ *
+ * tusb1211-charger-detect(1) -> charger -> fuel-gauge
+ *
+ * To determine if an USB charger is connected to the board, the online prop of
+ * the charger psy needs to be read. Since the tusb1211-charger-detect psy is
+ * the start of the supplier -> supplied-to chain, power_supply_am_i_supplied()
+ * cannot be used here.
+ *
+ * Instead, below is a list of the power_supply names of known chargers for
+ * these boards and the charger psy is looked up by name from this list.
+ *
+ * (1) modelling the external USB charger
+ */
+static const char * const tusb1210_chargers[] = {
+ "bq24190-charger",
+};
+
+static bool tusb1210_get_online(struct tusb1210 *tusb)
+{
+ union power_supply_propval val;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tusb1210_chargers) && !tusb->charger; i++)
+ tusb->charger = power_supply_get_by_name(tusb1210_chargers[i]);
+
+ if (!tusb->charger)
+ return false;
+
+ if (power_supply_get_property(tusb->charger, POWER_SUPPLY_PROP_ONLINE, &val))
+ return false;
+
+ return val.intval;
+}
+
+static void tusb1210_chg_det_work(struct work_struct *work)
+{
+ struct tusb1210 *tusb = container_of(work, struct tusb1210, chg_det_work.work);
+ bool vbus_present = tusb1210_get_online(tusb);
+ int ret;
+ u8 val;
+
+ dev_dbg(&tusb->ulpi->dev, "chg_det state %s vbus_present %d\n",
+ tusb1210_chg_det_states[tusb->chg_det_state], vbus_present);
+
+ switch (tusb->chg_det_state) {
+ case TUSB1210_CHG_DET_CONNECTING:
+ tusb->chg_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;
+ tusb->chg_det_retries = 0;
+ /* Power on USB controller for ulpi_read()/_write() */
+ ret = pm_runtime_resume_and_get(tusb->ulpi->dev.parent);
+ if (ret < 0) {
+ dev_err(&tusb->ulpi->dev, "error %d runtime-resuming\n", ret);
+ /* Should never happen, skip charger detection */
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);
+ return;
+ }
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET, 0);
+ break;
+ case TUSB1210_CHG_DET_START_DET:
+ /*
+ * Use the builtin charger detection FSM to keep things simple.
+ * This only detects DCP / SDP. This is good enough for the few
+ * boards which actually rely on the phy for charger detection.
+ */
+ mutex_lock(&tusb->phy->mutex);
+ ret = tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_SET,
+ TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET);
+ mutex_unlock(&tusb->phy->mutex);
+ if (ret) {
+ tusb1210_chg_det_handle_ulpi_error(tusb);
+ break;
+ }
+
+ /* Wait 400 ms for the charger detection FSM to finish */
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_READ_DET, 400);
+ break;
+ case TUSB1210_CHG_DET_READ_DET:
+ mutex_lock(&tusb->phy->mutex);
+ ret = tusb1210_ulpi_read(tusb, TUSB1211_POWER_CONTROL, &val);
+ mutex_unlock(&tusb->phy->mutex);
+ if (ret) {
+ tusb1210_chg_det_handle_ulpi_error(tusb);
+ break;
+ }
+
+ if (val & TUSB1211_POWER_CONTROL_DET_COMP)
+ tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_DCP);
+ else
+ tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_SDP);
+
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET, 0);
+ break;
+ case TUSB1210_CHG_DET_FINISH_DET:
+ mutex_lock(&tusb->phy->mutex);
+
+ /* Set SW_CONTROL to stop the charger-det FSM */
+ ret = tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_SET,
+ TUSB1211_POWER_CONTROL_SW_CONTROL);
+
+ /* Clear DP_VSRC_EN which may have been enabled by the charger-det FSM */
+ ret |= tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_CLEAR,
+ TUSB1211_POWER_CONTROL_DP_VSRC_EN);
+
+ /* Clear CHGD_IDP_SRC_EN (may have been enabled by the charger-det FSM) */
+ ret |= tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_CLEAR,
+ TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN);
+
+ /* If any of the above fails reset the phy */
+ if (ret) {
+ tusb1210_reset(tusb);
+ msleep(TUSB1210_RESET_TIME_MS);
+ }
+
+ /* Restore phy-parameters and OTG_CTRL register */
+ tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, tusb->otg_ctrl);
+ tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
+ tusb->vendor_specific2);
+
+ mutex_unlock(&tusb->phy->mutex);
+
+ pm_runtime_put(tusb->ulpi->dev.parent);
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);
+ break;
+ case TUSB1210_CHG_DET_CONNECTED:
+ if (!vbus_present)
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING, 0);
+ break;
+ case TUSB1210_CHG_DET_DISCONNECTING:
+ /*
+ * The phy seems to take approx. 600ms longer then the charger
+ * chip (which is used to get vbus_present) to determine Vbus
+ * session end. Wait 800ms to ensure the phy has detected and
+ * signalled Vbus session end.
+ */
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING_DONE, 800);
+ break;
+ case TUSB1210_CHG_DET_DISCONNECTING_DONE:
+ /*
+ * The phy often stops reacting to ulpi_read()/_write requests
+ * after a Vbus-session end. Reset it to work around this.
+ */
+ tusb1210_reset(tusb);
+ tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_UNKNOWN);
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTED, 0);
+ break;
+ case TUSB1210_CHG_DET_DISCONNECTED:
+ if (vbus_present)
+ tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTING, 0);
+ break;
+ }
+}
+
+static int tusb1210_psy_notifier(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct tusb1210 *tusb = container_of(nb, struct tusb1210, psy_nb);
+ struct power_supply *psy = ptr;
+
+ if (psy != tusb->psy && psy->desc->type == POWER_SUPPLY_TYPE_USB)
+ queue_delayed_work(system_long_wq, &tusb->chg_det_work, 0);
+
+ return NOTIFY_OK;
+}
+
+static int tusb1210_psy_get_prop(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct tusb1210 *tusb = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = tusb1210_get_online(tusb);
+ break;
+ case POWER_SUPPLY_PROP_USB_TYPE:
+ val->intval = tusb->chg_type;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ if (tusb->chg_type == POWER_SUPPLY_USB_TYPE_DCP)
+ val->intval = 2000000;
+ else
+ val->intval = 500000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const enum power_supply_usb_type tusb1210_psy_usb_types[] = {
+ POWER_SUPPLY_USB_TYPE_SDP,
+ POWER_SUPPLY_USB_TYPE_DCP,
+ POWER_SUPPLY_USB_TYPE_UNKNOWN,
+};
+
+static const enum power_supply_property tusb1210_psy_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_USB_TYPE,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
+};
+
+static const struct power_supply_desc tusb1210_psy_desc = {
+ .name = "tusb1211-charger-detect",
+ .type = POWER_SUPPLY_TYPE_USB,
+ .usb_types = tusb1210_psy_usb_types,
+ .num_usb_types = ARRAY_SIZE(tusb1210_psy_usb_types),
+ .properties = tusb1210_psy_props,
+ .num_properties = ARRAY_SIZE(tusb1210_psy_props),
+ .get_property = tusb1210_psy_get_prop,
+};
+
+/* Setup charger detection if requested, on errors continue without chg-det */
+static void tusb1210_probe_charger_detect(struct tusb1210 *tusb)
+{
+ struct power_supply_config psy_cfg = { .drv_data = tusb };
+ struct device *dev = &tusb->ulpi->dev;
+ int ret;
+
+ if (!device_property_read_bool(dev->parent, "linux,phy_charger_detect"))
+ return;
+
+ if (tusb->ulpi->id.product != 0x1508) {
+ dev_err(dev, "error charger detection is only supported on the TUSB1211\n");
+ return;
+ }
+
+ ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &tusb->otg_ctrl);
+ if (ret)
+ return;
+
+ tusb->psy = power_supply_register(dev, &tusb1210_psy_desc, &psy_cfg);
+ if (IS_ERR(tusb->psy))
+ return;
+
+ /*
+ * Delay initial run by 2 seconds to allow the charger driver,
+ * which is used to determine vbus_present, to load.
+ */
+ tusb->chg_det_state = TUSB1210_CHG_DET_DISCONNECTED;
+ INIT_DELAYED_WORK(&tusb->chg_det_work, tusb1210_chg_det_work);
+ queue_delayed_work(system_long_wq, &tusb->chg_det_work, 2 * HZ);
+
+ tusb->psy_nb.notifier_call = tusb1210_psy_notifier;
+ power_supply_reg_notifier(&tusb->psy_nb);
+}
+
+static void tusb1210_remove_charger_detect(struct tusb1210 *tusb)
+{
+
+ if (!IS_ERR_OR_NULL(tusb->psy)) {
+ power_supply_unreg_notifier(&tusb->psy_nb);
+ cancel_delayed_work_sync(&tusb->chg_det_work);
+ power_supply_unregister(tusb->psy);
+ }
+
+ if (tusb->charger)
+ power_supply_put(tusb->charger);
+}
+#else
+static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) { }
+static void tusb1210_remove_charger_detect(struct tusb1210 *tusb) { }
+#endif
+
static const struct phy_ops phy_ops = {
.power_on = tusb1210_power_on,
.power_off = tusb1210_power_off,
@@ -174,6 +534,8 @@ static int tusb1210_probe(struct ulpi *ulpi)
tusb->vendor_specific2 = reg;
+ tusb1210_probe_charger_detect(tusb);
+
tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
if (IS_ERR(tusb->phy))
return PTR_ERR(tusb->phy);
@@ -188,6 +550,7 @@ static void tusb1210_remove(struct ulpi *ulpi)
struct tusb1210 *tusb = ulpi_get_drvdata(ulpi);
ulpi_phy_destroy(ulpi, tusb->phy);
+ tusb1210_remove_charger_detect(tusb);
}
#define TI_VENDOR_ID 0x0451
--
2.33.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/9] usb/dwc3 / phy/tusb1210: Add TUSB1211 charger detection
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-17 15:31 ` Greg Kroah-Hartman
-1 siblings, 0 replies; 24+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-17 15:31 UTC (permalink / raw)
To: Hans de Goede
Cc: Felipe Balbi, Kishon Vijay Abraham I, Vinod Koul,
Stephan Gerhold, linux-usb, linux-phy
On Sun, Feb 13, 2022 at 02:05:15PM +0100, Hans de Goede wrote:
> Hi All,
>
> Here is v2 of the patchs-series to add support for USB charger-type
> (SDP/DCP) detection using a tusb1210 phy connected to a dwc3 controller.
>
> Changes in v2:
> [PATCH v2 9/9] phy: ti: tusb1210: Add charger detection:
> - Add an online attribute to the registered power_supply class device,
> otherwise upower thinks it is an extra system battery
> - Add tusb1210_remove_charger_detect() function to properly unregister
> the tusb->psy_nb notifier and to cancel tusb->chg_det_work
>
> v1 cover-letter:
>
> Some Android x86 tablets with a Bay Trail (BYT) SoC (with DWC3 UDC)
> and a Crystal Cove PMIC, which does not support charger-detection,
> rely on a TUSB1211 phy for charger-detection.
>
> This series adds support for this, it starts with some dwc3 bug-fixes
> for issues hit while developing this, as well as adding support to
> the dwc3 code to set a special property checked by the tusb1210 driver
> to signal that it needs to enable charger-detection.
>
> The 2nd half of the series does some refactoring / fixes to the
> tusb1210 driver and adds the charger-detection support.
The first 4 are all in my usb trees now, thanks.
greg k-h
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/9] usb/dwc3 / phy/tusb1210: Add TUSB1211 charger detection
@ 2022-02-17 15:31 ` Greg Kroah-Hartman
0 siblings, 0 replies; 24+ messages in thread
From: Greg Kroah-Hartman @ 2022-02-17 15:31 UTC (permalink / raw)
To: Hans de Goede
Cc: Felipe Balbi, Kishon Vijay Abraham I, Vinod Koul,
Stephan Gerhold, linux-usb, linux-phy
On Sun, Feb 13, 2022 at 02:05:15PM +0100, Hans de Goede wrote:
> Hi All,
>
> Here is v2 of the patchs-series to add support for USB charger-type
> (SDP/DCP) detection using a tusb1210 phy connected to a dwc3 controller.
>
> Changes in v2:
> [PATCH v2 9/9] phy: ti: tusb1210: Add charger detection:
> - Add an online attribute to the registered power_supply class device,
> otherwise upower thinks it is an extra system battery
> - Add tusb1210_remove_charger_detect() function to properly unregister
> the tusb->psy_nb notifier and to cancel tusb->chg_det_work
>
> v1 cover-letter:
>
> Some Android x86 tablets with a Bay Trail (BYT) SoC (with DWC3 UDC)
> and a Crystal Cove PMIC, which does not support charger-detection,
> rely on a TUSB1211 phy for charger-detection.
>
> This series adds support for this, it starts with some dwc3 bug-fixes
> for issues hit while developing this, as well as adding support to
> the dwc3 code to set a special property checked by the tusb1210 driver
> to signal that it needs to enable charger-detection.
>
> The 2nd half of the series does some refactoring / fixes to the
> tusb1210 driver and adds the charger-detection support.
The first 4 are all in my usb trees now, thanks.
greg k-h
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/9] usb/dwc3 / phy/tusb1210: Add TUSB1211 charger detection
2022-02-13 13:05 ` Hans de Goede
@ 2022-02-25 8:58 ` Vinod Koul
-1 siblings, 0 replies; 24+ messages in thread
From: Vinod Koul @ 2022-02-25 8:58 UTC (permalink / raw)
To: Hans de Goede
Cc: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I,
Stephan Gerhold, linux-usb, linux-phy
On 13-02-22, 14:05, Hans de Goede wrote:
> Hi All,
>
> Here is v2 of the patchs-series to add support for USB charger-type
> (SDP/DCP) detection using a tusb1210 phy connected to a dwc3 controller.
>
> Changes in v2:
> [PATCH v2 9/9] phy: ti: tusb1210: Add charger detection:
> - Add an online attribute to the registered power_supply class device,
> otherwise upower thinks it is an extra system battery
> - Add tusb1210_remove_charger_detect() function to properly unregister
> the tusb->psy_nb notifier and to cancel tusb->chg_det_work
>
> v1 cover-letter:
>
> Some Android x86 tablets with a Bay Trail (BYT) SoC (with DWC3 UDC)
> and a Crystal Cove PMIC, which does not support charger-detection,
> rely on a TUSB1211 phy for charger-detection.
>
> This series adds support for this, it starts with some dwc3 bug-fixes
> for issues hit while developing this, as well as adding support to
> the dwc3 code to set a special property checked by the tusb1210 driver
> to signal that it needs to enable charger-detection.
>
> The 2nd half of the series does some refactoring / fixes to the
> tusb1210 driver and adds the charger-detection support.
Applied phy patches to phy-next, thanks
--
~Vinod
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v2 0/9] usb/dwc3 / phy/tusb1210: Add TUSB1211 charger detection
@ 2022-02-25 8:58 ` Vinod Koul
0 siblings, 0 replies; 24+ messages in thread
From: Vinod Koul @ 2022-02-25 8:58 UTC (permalink / raw)
To: Hans de Goede
Cc: Felipe Balbi, Greg Kroah-Hartman, Kishon Vijay Abraham I,
Stephan Gerhold, linux-usb, linux-phy
On 13-02-22, 14:05, Hans de Goede wrote:
> Hi All,
>
> Here is v2 of the patchs-series to add support for USB charger-type
> (SDP/DCP) detection using a tusb1210 phy connected to a dwc3 controller.
>
> Changes in v2:
> [PATCH v2 9/9] phy: ti: tusb1210: Add charger detection:
> - Add an online attribute to the registered power_supply class device,
> otherwise upower thinks it is an extra system battery
> - Add tusb1210_remove_charger_detect() function to properly unregister
> the tusb->psy_nb notifier and to cancel tusb->chg_det_work
>
> v1 cover-letter:
>
> Some Android x86 tablets with a Bay Trail (BYT) SoC (with DWC3 UDC)
> and a Crystal Cove PMIC, which does not support charger-detection,
> rely on a TUSB1211 phy for charger-detection.
>
> This series adds support for this, it starts with some dwc3 bug-fixes
> for issues hit while developing this, as well as adding support to
> the dwc3 code to set a special property checked by the tusb1210 driver
> to signal that it needs to enable charger-detection.
>
> The 2nd half of the series does some refactoring / fixes to the
> tusb1210 driver and adds the charger-detection support.
Applied phy patches to phy-next, thanks
--
~Vinod
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 24+ messages in thread