summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorRakesh Bodla <rbodla@nvidia.com>2011-07-22 11:50:40 +0530
committerManish Tuteja <mtuteja@nvidia.com>2011-07-25 02:31:34 -0700
commit69c083d495e1f187654c5a1bcd58569e54bf985b (patch)
tree1fb3f0f943f6ffa03d2e9aee77703c965ac1a088 /arch
parentbe13b88a2cb2f898d02d266041e1f2ae0a9b259b (diff)
tegra: usb: phy: USB charger detection support
USB PHY related charger detection logic is implemented. Bug 819334 Change-Id: Ica7e66509d52d787cc5c25434b45534176bc8dc7 Reviewed-on: http://git-master/r/42298 Reviewed-by: Rakesh Bodla <rbodla@nvidia.com> Tested-by: Rakesh Bodla <rbodla@nvidia.com> Reviewed-by: Hanumanth Venkateswa Moganty <vmoganty@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h2
-rw-r--r--arch/arm/mach-tegra/usb_phy.c54
2 files changed, 56 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
index 0ff8f5545d31..609134c4ff82 100644
--- a/arch/arm/mach-tegra/include/mach/usb_phy.h
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -126,6 +126,8 @@ int tegra_usb_phy_bus_idle(struct tegra_usb_phy *phy);
bool tegra_usb_phy_is_device_connected(struct tegra_usb_phy *phy);
+bool tegra_usb_phy_charger_detect(struct tegra_usb_phy *phy);
+
int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size);
#endif /* __MACH_USB_PHY_H */
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index ee17dffc3d8c..0dc14abc3fa4 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -76,6 +76,11 @@
#define USB_SUSP_SET (1 << 14)
#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
+#define USB_PHY_VBUS_WAKEUP_ID 0x408
+#define VDAT_DET_INT_EN (1 << 16)
+#define VDAT_DET_CHG_DET (1 << 17)
+#define VDAT_DET_STS (1 << 18)
+
#define USB1_LEGACY_CTRL 0x410
#define USB1_NO_LEGACY_MODE (1 << 0)
#define USB1_VBUS_SENSE_CTL_MASK (3 << 1)
@@ -163,6 +168,8 @@
#define UTMIP_BAT_CHRG_CFG0 0x830
#define UTMIP_PD_CHRG (1 << 0)
+#define UTMIP_ON_SINK_EN (1 << 2)
+#define UTMIP_OP_SRC_EN (1 << 3)
#define UTMIP_SPARE_CFG0 0x834
#define FUSE_SETUP_SEL (1 << 3)
@@ -225,6 +232,10 @@
#define UHSIC_SPARE_CFG0 0x82c
+/* These values (in milli second) are taken from the battery charging spec */
+#define TDP_SRC_ON_MS 100
+#define TDPSRC_CON_MS 40
+
static DEFINE_SPINLOCK(utmip_pad_lock);
static int utmip_pad_count;
@@ -1464,6 +1475,49 @@ bool tegra_usb_phy_is_device_connected(struct tegra_usb_phy *phy)
return true;
}
+bool tegra_usb_phy_charger_detect(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+ bool status;
+
+ if (phy_is_ulpi(phy)) {
+ /* Charger detection is not there for ULPI
+ * return Charger not available */
+ return false;
+ }
+
+ /* Enable charger detection logic */
+ val = readl(base + UTMIP_BAT_CHRG_CFG0);
+ val |= UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN;
+ writel(val, base + UTMIP_BAT_CHRG_CFG0);
+
+ /* Source should be on for 100 ms as per USB charging spec */
+ msleep(TDP_SRC_ON_MS);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ /* If charger is not connected disable the interrupt */
+ val &= ~VDAT_DET_INT_EN;
+ val |= VDAT_DET_CHG_DET;
+ writel(val,base + USB_PHY_VBUS_WAKEUP_ID);
+
+ val = readl(base + USB_PHY_VBUS_WAKEUP_ID);
+ if (val & VDAT_DET_STS)
+ status = true;
+ else
+ status = false;
+
+ /* Disable charger detection logic */
+ val = readl(base + UTMIP_BAT_CHRG_CFG0);
+ val &= ~(UTMIP_OP_SRC_EN | UTMIP_ON_SINK_EN);
+ writel(val, base + UTMIP_BAT_CHRG_CFG0);
+
+ /* Delay of 40 ms before we pull the D+ as per battery charger spec */
+ msleep(TDPSRC_CON_MS);
+
+ return status;
+}
+
int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size)
{
if (pdata) {