diff options
author | Igor Grinberg <grinberg@compulab.co.il> | 2010-10-10 17:59:18 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 10:22:10 -0700 |
commit | a9138192d0e716c3e9714b3fe03543d93ebbad9f (patch) | |
tree | 9846352e032cf59df136953f1fb36d27839af9b1 /drivers | |
parent | c6f694af8318a526c639306d9d07ee33cb7c168a (diff) |
USB: otg/ulpi: improve ulpi phy detection.
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/otg/ulpi.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c index ccc81950822..e0d2a5c504c 100644 --- a/drivers/usb/otg/ulpi.c +++ b/drivers/usb/otg/ulpi.c @@ -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) |