USB: otg/ulpi: improve ulpi phy detection.
authorIgor Grinberg <grinberg@compulab.co.il>
Sun, 10 Oct 2010 15:59:18 +0000 (17:59 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 22 Oct 2010 17:22:10 +0000 (10:22 -0700)
Improve ulpi phy detection by utilizing the "scratch" register.
Allow unknown ulpi phy work without the need to hard-code the id.

Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/otg/ulpi.c

index ccc81950822b25e9550b3947863630516f4b2d54..e0d2a5c504cc97457685f71c28f01ab3bc80c648 100644 (file)
@@ -137,6 +137,32 @@ static int ulpi_set_flags(struct otg_transceiver *otg)
        return ulpi_set_fc_flags(otg);
 }
 
+static int ulpi_check_integrity(struct otg_transceiver *otg)
+{
+       int ret, i;
+       unsigned int val = 0x55;
+
+       for (i = 0; i < 2; i++) {
+               ret = otg_io_write(otg, val, ULPI_SCRATCH);
+               if (ret < 0)
+                       return ret;
+
+               ret = otg_io_read(otg, ULPI_SCRATCH);
+               if (ret < 0)
+                       return ret;
+
+               if (ret != val) {
+                       pr_err("ULPI integrity check: failed!");
+                       return -ENODEV;
+               }
+               val = val << 1;
+       }
+
+       pr_info("ULPI integrity check: passed.\n");
+
+       return 0;
+}
+
 static int ulpi_init(struct otg_transceiver *otg)
 {
        int i, vid, pid, ret;
@@ -155,10 +181,13 @@ static int ulpi_init(struct otg_transceiver *otg)
 
        for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++)
                if (ulpi_ids[i] == ULPI_ID(vid, pid))
-                       return ulpi_set_flags(otg);
+                       break;
+
+       ret = ulpi_check_integrity(otg);
+       if (ret)
+               return ret;
 
-       pr_err("ULPI ID does not match any known transceiver.\n");
-       return -ENODEV;
+       return ulpi_set_flags(otg);
 }
 
 static int ulpi_set_host(struct otg_transceiver *otg, struct usb_bus *host)