summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSakethram Bommisetti <sakethram.bommisetti@stericsson.com>2011-09-08 14:39:13 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:07 +0200
commitbfa8fffa3cd7da098ee89a6498897d03459d0c5b (patch)
tree67a66564816f0afa205e15dfc03b8cd8ffc2a01b
parent29390773a3081c76e16f9958a6ddb38b58febb09 (diff)
ux500:USB:Boot time detection
Enabling the phy during the booting of kernel if usb is connected. ST-Ericsson ID: NA ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: NA Change-Id: Ic750bf42dbfc9bfb60cc9930e9ea9aa1f58cf8ff Signed-off-by: Sakethram Bommisetti <sakethram.bommisetti@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30436 Reviewed-by: Praveena NADAHALLY <praveen.nadahally@stericsson.com>
-rw-r--r--drivers/usb/otg/ab8500-usb.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c
index 2b67433fa6c..b6ec661c9aa 100644
--- a/drivers/usb/otg/ab8500-usb.c
+++ b/drivers/usb/otg/ab8500-usb.c
@@ -41,6 +41,10 @@
#define AB8500_USB_LINE_STAT_REG 0x80
#define AB8500_USB_PHY_CTRL_REG 0x8A
#define AB8500_VBUS_CTRL_REG 0x82
+#define AB8500_IT_SOURCE2_REG 0x01
+#define AB8500_IT_SOURCE20_REG 0x13
+#define AB8500_SRC_INT_USB_HOST 0x04
+#define AB8500_SRC_INT_USB_DEVICE 0x80
#define AB8500_BIT_OTG_STAT_ID (1 << 0)
#define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0)
@@ -448,6 +452,84 @@ static int ab8500_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
return 0;
}
+/**
+ * ab8500_usb_boot_detect : detect the USB cable during boot time.
+ * @device: value for device.
+ *
+ * This function is used to detect the USB cable during boot time.
+ */
+static int ab8500_usb_boot_detect(struct ab8500_usb *ab)
+{
+ int err;
+ struct device *device = ab->dev;
+ u8 usb_status = 0;
+ u8 val = 0;
+
+ /* Disabling PHY before selective enable or disable */
+ abx500_mask_and_set_register_interruptible(ab->dev,
+ AB8500_USB,
+ AB8500_USB_PHY_CTRL_REG,
+ AB8500_BIT_PHY_CTRL_DEVICE_EN,
+ AB8500_BIT_PHY_CTRL_DEVICE_EN);
+
+ udelay(100);
+
+ abx500_mask_and_set_register_interruptible(ab->dev,
+ AB8500_USB,
+ AB8500_USB_PHY_CTRL_REG,
+ AB8500_BIT_PHY_CTRL_DEVICE_EN,
+ 0);
+
+ abx500_mask_and_set_register_interruptible(ab->dev,
+ AB8500_USB,
+ AB8500_USB_PHY_CTRL_REG,
+ AB8500_BIT_PHY_CTRL_HOST_EN,
+ AB8500_BIT_PHY_CTRL_HOST_EN);
+
+ udelay(100);
+
+ abx500_mask_and_set_register_interruptible(ab->dev,
+ AB8500_USB,
+ AB8500_USB_PHY_CTRL_REG,
+ AB8500_BIT_PHY_CTRL_HOST_EN,
+ 0);
+
+
+ err = abx500_get_register_interruptible(device,
+ AB8500_INTERRUPT, AB8500_IT_SOURCE20_REG,
+ &usb_status);
+ if (err < 0) {
+ dev_err(device, "Read IT 20 failed\n");
+ return err;
+ }
+
+ if (usb_status & AB8500_SRC_INT_USB_HOST)
+ ab8500_usb_host_phy_en(ab);
+
+
+ err = abx500_get_register_interruptible(device,
+ AB8500_INTERRUPT, AB8500_IT_SOURCE2_REG,
+ &usb_status);
+ if (err < 0) {
+ dev_err(device, "Read IT 2 failed\n");
+ return err;
+ }
+
+ if (usb_status & AB8500_SRC_INT_USB_DEVICE) {
+ /* Check if it is a dedicated charger */
+ (void)abx500_get_register_interruptible(device,
+ AB8500_USB, AB8500_USB_LINE_STAT_REG, &val);
+
+ val = (val >> 3) & 0x0F;
+
+ if (val == USB_LINK_DEDICATED_CHG)
+ ab->mode = USB_DEDICATED_CHG;
+ else
+ ab8500_usb_peri_phy_en(ab);
+ }
+
+ return 0;
+}
static void ab8500_usb_regulator_put(struct ab8500_usb *ab)
{
@@ -710,6 +792,10 @@ static int __devinit ab8500_usb_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "revision 0x%2x driver initialized\n", ab->rev);
+ err = ab8500_usb_boot_detect(ab);
+ if (err < 0)
+ goto fail3;
+
return 0;
fail3:
ab8500_usb_irq_free(ab);