return status;
}
+bool tegra_usb_phy_apple_1000ma_charger_detected(struct tegra_usb_phy *phy)
+{
+ bool status = 0;
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+ if (phy->ops && phy->ops->apple_charger_1000ma_detect)
+ status = phy->ops->apple_charger_1000ma_detect(phy);
+
+ return status;
+}
+
+bool tegra_usb_phy_apple_2000ma_charger_detected(struct tegra_usb_phy *phy)
+{
+ bool status = 0;
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+ if (phy->ops && phy->ops->apple_charger_2000ma_detect)
+ status = phy->ops->apple_charger_2000ma_detect(phy);
+
+ return status;
+}
+
+bool tegra_usb_phy_apple_500ma_charger_detected(struct tegra_usb_phy *phy)
+{
+ bool status = 0;
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+ if (phy->ops && phy->ops->apple_charger_500ma_detect)
+ status = phy->ops->apple_charger_500ma_detect(phy);
+
+ return status;
+}
+
bool tegra_usb_phy_hw_accessible(struct tegra_usb_phy *phy)
{
if (!phy->hw_accessible)
#define UHSIC_PHY_ENABLE (1 << 19)
#define USB_PHY_VBUS_WAKEUP_ID 0x408
+#define DIV_DET_EN (1 << 31)
#define VDCD_DET_STS (1 << 26)
#define VDCD_DET_CHG_DET (1 << 25)
+#define VOP_DIV2P7_DET (1 << 23)
+#define VOP_DIV2P0_DET (1 << 22)
+#define VON_DIV2P7_DET (1 << 15)
+#define VON_DIV2P0_DET (1 << 14)
#define VDAT_DET_INT_EN (1 << 16)
#define VDAT_DET_CHG_DET (1 << 17)
#define VDAT_DET_STS (1 << 18)
return ret;
}
+static bool utmi_phy_apple_charger_1000ma_detect(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ bool ret;
+ void __iomem *base = phy->regs;
+ unsigned long org_flags;
+
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+ ret = false;
+
+ org_flags = utmi_phy_set_dp_dm_pull_up_down(phy,
+ FORCE_PULLUP_DP | FORCE_PULLUP_DM |
+ DISABLE_PULLDN_DP | DISABLE_PULLDN_DM);
+ usleep_range(20000, 30000);
+ utmi_phy_set_dp_dm_pull_up_down(phy,
+ DISABLE_PULLUP_DP | DISABLE_PULLUP_DM |
+ DISABLE_PULLDN_DP | DISABLE_PULLDN_DM);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ val |= DIV_DET_EN;
+ writel(val, base + USB_PHY_VBUS_WAKEUP_ID);
+
+ usleep_range(10000, 20000);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ val &= ~DIV_DET_EN;
+ writel(val, base + USB_PHY_VBUS_WAKEUP_ID);
+
+ if ((val & VOP_DIV2P0_DET) && (val & VON_DIV2P7_DET))
+ ret = true;
+
+ utmi_phy_set_dp_dm_pull_up_down(phy, org_flags);
+
+ return ret;
+}
+
+static bool utmi_phy_apple_charger_2000ma_detect(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ bool ret;
+ void __iomem *base = phy->regs;
+ unsigned long org_flags;
+
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+ ret = false;
+
+ org_flags = utmi_phy_set_dp_dm_pull_up_down(phy,
+ FORCE_PULLUP_DP | FORCE_PULLUP_DM |
+ DISABLE_PULLDN_DP | DISABLE_PULLDN_DM);
+ usleep_range(20000, 30000);
+ utmi_phy_set_dp_dm_pull_up_down(phy,
+ DISABLE_PULLUP_DP | DISABLE_PULLUP_DM |
+ DISABLE_PULLDN_DP | DISABLE_PULLDN_DM);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ val |= DIV_DET_EN;
+ writel(val, base + USB_PHY_VBUS_WAKEUP_ID);
+
+ usleep_range(10000, 20000);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ val &= ~DIV_DET_EN;
+ writel(val, base + USB_PHY_VBUS_WAKEUP_ID);
+
+ if ((val & VOP_DIV2P7_DET) && (val & VON_DIV2P0_DET))
+ ret = true;
+
+ utmi_phy_set_dp_dm_pull_up_down(phy, org_flags);
+
+ return ret;
+}
+
+static bool utmi_phy_apple_charger_500ma_detect(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ bool ret;
+ void __iomem *base = phy->regs;
+ unsigned long org_flags;
+
+ DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+ ret = false;
+
+ org_flags = utmi_phy_set_dp_dm_pull_up_down(phy,
+ FORCE_PULLUP_DP | FORCE_PULLUP_DM |
+ DISABLE_PULLDN_DP | DISABLE_PULLDN_DM);
+ usleep_range(20000, 30000);
+ utmi_phy_set_dp_dm_pull_up_down(phy,
+ DISABLE_PULLUP_DP | DISABLE_PULLUP_DM |
+ DISABLE_PULLDN_DP | DISABLE_PULLDN_DM);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ val |= DIV_DET_EN;
+ writel(val, base + USB_PHY_VBUS_WAKEUP_ID);
+
+ usleep_range(10000, 20000);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ val &= ~DIV_DET_EN;
+ writel(val, base + USB_PHY_VBUS_WAKEUP_ID);
+
+ if ((val & VOP_DIV2P0_DET) && (val & VON_DIV2P0_DET))
+ ret = true;
+
+ utmi_phy_set_dp_dm_pull_up_down(phy, org_flags);
+
+ return ret;
+}
+
static bool uhsic_phy_remotewake_detected(struct tegra_usb_phy *phy)
{
void __iomem *base = phy->regs;
.resume = utmi_phy_resume,
.charger_detect = utmi_phy_charger_detect,
.nv_charger_detect = utmi_phy_nv_charger_detect,
+ .apple_charger_1000ma_detect = utmi_phy_apple_charger_1000ma_detect,
+ .apple_charger_2000ma_detect = utmi_phy_apple_charger_2000ma_detect,
+ .apple_charger_500ma_detect = utmi_phy_apple_charger_500ma_detect,
.pmc_disable = utmi_phy_pmc_disable,
};
/*
- * Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2011 NVIDIA Corporation.
+ * Copyright (c) 2010 Google, Inc.
+ * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
*/
bool tegra_usb_phy_nv_charger_detected(struct tegra_usb_phy *phy);
+/**
+ * Indicates whether apple 1A charger is connected or not
+ * if apple 1A charger is detected then returns true else false
+ */
+bool tegra_usb_phy_apple_1000ma_charger_detected(struct tegra_usb_phy *phy);
+
+/**
+ * Indicates whether apple 2A charger is connected or not
+ * if apple 2A charger is detected then returns true else false
+ */
+bool tegra_usb_phy_apple_2000ma_charger_detected(struct tegra_usb_phy *phy);
+
+/**
+ * Indicates whether apple 0.5A charger is connected or not
+ * if apple 0.5A charger is detected then returns true else false
+ */
+bool tegra_usb_phy_apple_500ma_charger_detected(struct tegra_usb_phy *phy);
+
/**
* Indicates whether phy resumed due to the pmc remote/hotplug wake event
* or not, returns true if remote/hotplug wake is detected.