summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorPhilip Rakity <prakity@nvidia.com>2014-03-26 11:40:25 +0530
committerRiham Haidar <rhaidar@nvidia.com>2014-04-28 15:20:52 -0700
commit2174623265342629ebc3d47c2faccf8ac6b791e7 (patch)
tree4b0e592a000fdc8fac6192e281974594f1fcd6be /drivers/usb/gadget
parent90492410f75ac5a236242265345dc15a8278b987 (diff)
usb: gadget: tegra:fix delay in charging icon in UI
Moving CDP charger detection to early phase and also setting charger current to Non-standard before QC2.0 charger detection to fix delay in charging icon in UI. Bug 1424733 Bug 1458999 (cherry picked from commit 4f0e5756869074d27d808eab2225459c6daec5fb) (cherry picked from commit 57b2e6af46175c3f8992bc29e7ec1a778f9002f1) Change-Id: I0db19bf633b0d76d687d64e5599ccf41ef469876 Reviewed-on: http://git-master/r/384598 Reviewed-on: http://git-master/r/396042 Signed-off-by: Rakesh Bodla <rbodla@nvidia.com> Signed-off-by: Philip Rakity <prakity@nvidia.com> Reviewed-on: http://git-master/r/401889 Reviewed-by: Riham Haidar <rhaidar@nvidia.com> Tested-by: Riham Haidar <rhaidar@nvidia.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/tegra_udc.c94
-rw-r--r--drivers/usb/gadget/tegra_udc.h2
2 files changed, 33 insertions, 63 deletions
diff --git a/drivers/usb/gadget/tegra_udc.c b/drivers/usb/gadget/tegra_udc.c
index 7d1c0e6b5305..2f40ea5afdf6 100644
--- a/drivers/usb/gadget/tegra_udc.c
+++ b/drivers/usb/gadget/tegra_udc.c
@@ -1482,51 +1482,6 @@ static int tegra_usb_set_charging_current(struct tegra_udc *udc)
return ret;
}
-static void tegra_detect_charging_type_is_cdp_or_dcp(struct tegra_udc *udc)
-{
- u32 portsc;
- u32 temp;
- unsigned long flags;
-
- /* use spinlock to prevent kernel preemption here */
- spin_lock_irqsave(&udc->lock, flags);
- if (udc->support_pmu_vbus) {
- temp = udc_readl(udc, VBUS_SENSOR_REG_OFFSET);
- temp |= (USB_SYS_VBUS_A_VLD_SW_VALUE |
- USB_SYS_VBUS_A_VLD_SW_EN |
- USB_SYS_VBUS_ASESSION_VLD_SW_VALUE |
- USB_SYS_VBUS_ASESSION_VLD_SW_EN);
- udc_writel(udc, temp, VBUS_SENSOR_REG_OFFSET);
- }
-
- /* set controller to run which cause D+ pull high */
- temp = udc_readl(udc, USB_CMD_REG_OFFSET);
- temp |= USB_CMD_RUN_STOP;
- udc_writel(udc, temp, USB_CMD_REG_OFFSET);
-
- udelay(10);
-
- /* use D+ and D- status to check it is CDP or DCP */
- portsc = udc_readl(udc, PORTSCX_REG_OFFSET);
- portsc &= PORTSCX_LINE_STATUS_BITS;
- if (portsc == PORTSCX_LINE_STATUS_BITS)
- tegra_udc_set_charger_type(udc, CONNECT_TYPE_DCP);
- else if (portsc == PORTSCX_LINE_STATUS_DP_BIT)
- tegra_udc_set_charger_type(udc, CONNECT_TYPE_CDP);
- else
- /*
- * If it take more 100mS between D+ pull high and read
- * Line Status, host might initiate the RESET, then we
- * see both line status as 0 (SE0). This really should
- * not happen as we disabled the kernel preemption
- * before reaching here.
- * Bug can be raised here but it is also safe to assume
- * as CDP.
- */
- tegra_udc_set_charger_type(udc, CONNECT_TYPE_CDP);
- spin_unlock_irqrestore(&udc->lock, flags);
-}
-
static int tegra_detect_cable_type(struct tegra_udc *udc)
{
if (!udc->charging_supported) {
@@ -1535,11 +1490,29 @@ static int tegra_detect_cable_type(struct tegra_udc *udc)
}
if (tegra_usb_phy_charger_detected(udc->phy)) {
- if (tegra_usb_phy_qc2_charger_detected(udc->phy,
- udc->qc2_voltage))
- tegra_udc_set_charger_type(udc, CONNECT_TYPE_DCP_QC2);
- else
- tegra_detect_charging_type_is_cdp_or_dcp(udc);
+ if (tegra_usb_phy_cdp_charger_detected(udc->phy))
+ tegra_udc_set_charger_type(udc, CONNECT_TYPE_CDP);
+ else if (udc->qc2_voltage) {
+ /* Must be DCP -- figure out if Quick Charge 2 or DCP.
+ * Initially set low current since QC2 will reset to
+ * 5V if current is too high when it changes to higher
+ * voltage during detection. So setting to non-standard
+ * which sets for low current. Also, setting current
+ * early allows the charging icon to show up on UI.
+ */
+ tegra_udc_set_charger_type(udc,
+ CONNECT_TYPE_NON_STANDARD_CHARGER);
+ tegra_usb_set_charging_current(udc);
+
+ if (tegra_usb_phy_qc2_charger_detected(udc->phy,
+ udc->qc2_voltage))
+ tegra_udc_set_charger_type(udc,
+ CONNECT_TYPE_DCP_QC2);
+ else
+ tegra_udc_set_charger_type(udc,
+ CONNECT_TYPE_DCP);
+ } else
+ tegra_udc_set_charger_type(udc, CONNECT_TYPE_DCP);
}
#if !defined(CONFIG_ARCH_TEGRA_11x_SOC) && !defined(CONFIG_ARCH_TEGRA_14x_SOC)
else if (tegra_usb_phy_apple_500ma_charger_detected(udc->phy))
@@ -2874,6 +2847,15 @@ static int __init tegra_udc_probe(struct platform_device *pdev)
udc->fence_read = true;
udc->charging_supported = pdata->u_data.dev.charging_supported;
+ udc->qc2_voltage = pdata->qc2_voltage;
+
+ udc->qc2_current_limit =
+ pdata->u_data.dev.qc2_current_limit_ma * 1000;
+
+ DBG("%s: QC2 voltage = %d, current = %d\n",
+ __func__,
+ udc->qc2_voltage_limit,
+ udc->qc2_current_limit);
if (pdata->u_data.dev.dcp_current_limit_ma)
udc->dcp_current_limit =
@@ -2881,13 +2863,6 @@ static int __init tegra_udc_probe(struct platform_device *pdev)
else
udc->dcp_current_limit =
USB_CHARGING_DCP_CURRENT_LIMIT_UA;
-
- if (pdata->u_data.dev.qc2_current_limit_ma)
- udc->qc2_current_limit =
- pdata->u_data.dev.qc2_current_limit_ma * 1000;
- else
- udc->qc2_current_limit =
- USB_CHARGING_DCP_CURRENT_LIMIT_UA;
} else {
dev_err(&pdev->dev, "failed to get platform_data\n");
err = -ENODATA;
@@ -3008,11 +2983,6 @@ static int __init tegra_udc_probe(struct platform_device *pdev)
"usb_bat_chg regulator not registered:"
" USB charging will not be enabled\n");
udc->vbus_reg = NULL;
- } else {
- udc->qc2_voltage = pdata->qc2_voltage;
- DBG("%s: qc2_v(i) = %d, qc2_v(o) = %d\n",
- __func__,
- pdata->qc2_voltage, udc->qc2_voltage);
}
if (pdata->port_otg)
diff --git a/drivers/usb/gadget/tegra_udc.h b/drivers/usb/gadget/tegra_udc.h
index 9f437dac9608..44d0a08fa8e2 100644
--- a/drivers/usb/gadget/tegra_udc.h
+++ b/drivers/usb/gadget/tegra_udc.h
@@ -451,6 +451,7 @@ struct tegra_udc {
enum tegra_connect_type connect_type;
enum tegra_connect_type prev_connect_type;
enum tegra_connect_type connect_type_lp0;
+ enum tegra_usb_qc2_voltage qc2_voltage;
void __iomem *regs;
size_t ep_qh_size; /* size after alignment adjustment*/
dma_addr_t ep_qh_dma; /* dma address of QH */
@@ -477,7 +478,6 @@ struct tegra_udc {
bool fence_read;
bool vbus_in_lp0;
bool charging_supported;
- enum tegra_usb_qc2_voltage qc2_voltage;
#ifdef CONFIG_EXTCON
struct extcon_dev *edev;
struct extcon_dev *vbus_extcon_dev;