Re: [PATCH] ulpi: add i.MX25 & 35 internal PHY ID

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 Hi,

On 10/05/10 07:42, Daniel Mack wrote:
> On Mon, Oct 04, 2010 at 05:15:35PM +0200, Igor Grinberg wrote:
>>  On 10/04/10 16:54, Sergei Shtylyov wrote:
>>> Hello.
>>>
>>> Eric Bénard wrote:
>>>
>>>> without this patch, the initialization of the OTG port in host mode
>>>> fails with :
>>>> ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
>>>> mxc-ehci mxc-ehci.0: initializing i.MX USB Controller
>>>> ULPI transceiver vendor/product ID 0x0000/0x0000
>>>> ULPI ID does not match any known transceiver.
>>>> mxc-ehci mxc-ehci.0: unable to init transceiver, probably missing
>>>> Signed-off-by: Eric Bénard <eric@xxxxxxxxxx>
>>>> ---
>>>>  drivers/usb/otg/ulpi.c |    5 ++++-
>>>>  1 files changed, 4 insertions(+), 1 deletions(-)
>>>    You should have CC'ed linux-usb@xxxxxxxxxxxxxxxx
>>>
>>>> diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
>>>> index ccc8195..e802e44 100644
>>>> --- a/drivers/usb/otg/ulpi.c
>>>> +++ b/drivers/usb/otg/ulpi.c
>>>> @@ -34,7 +34,10 @@
>>>>  /* ULPI hardcoded IDs, used for probing */
>>>>  static unsigned int ulpi_ids[] = {
>>>>      ULPI_ID(0x04cc, 0x1504),    /* NXP ISP1504 */
>>>> -    ULPI_ID(0x0424, 0x0006),        /* SMSC USB3319 */
>>>> +    ULPI_ID(0x0424, 0x0006),    /* SMSC USB3319 */
>>>> +#if (defined(CONFIG_ARCH_MX25) || defined(CONFIG_ARCH_MX35))
>>>> +    ULPI_ID(0x0000, 0x0000),    /* i.MX25 & i.MX35 internal PHY */
>>>> +#endif
>>>    I don't know why this table is at all used in the first place. IMO, checking for the vendor/device ID serves no purpose...
>> Well, it was there in first place, when Daniel merged this.
>> May be it was taken from Sascha.
>> I think its purpose to check if there is a ulpi transceiver out there,
>> although, ulpi defines a special scratch register for testing purposes.
> Correct, its primary purpose was to see whether the ULPI low-level
> communication works at all, and to bail out when it doesn't.
>
> I wasn't aware of that scratch register. If we don't need that table any
> more, feel free to drop it.

This driver is still in development stage and is not fully functional,
so I'd like to keep the table and ID info printing, but I really don't like
trivial IDs, like that of Eric.

How about something like the attached patch?

Eric, can you test if it works for you?

If it's good, I can send a prettier version of it for review and merging.

-- 
Regards,
Igor.

diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
index ccc8195..059d9ac 100644
--- a/drivers/usb/otg/ulpi.c
+++ b/drivers/usb/otg/ulpi.c
@@ -29,12 +29,23 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
 
+
+struct ulpi_info {
+	unsigned int	id;
+	char		*name;
+};
+
 #define ULPI_ID(vendor, product) (((vendor) << 16) | (product))
+#define ULPI_INFO(_id, _name)		\
+	{				\
+		.id	= (_id),	\
+		.name	= (_name),	\
+	}
 
 /* ULPI hardcoded IDs, used for probing */
-static unsigned int ulpi_ids[] = {
-	ULPI_ID(0x04cc, 0x1504),	/* NXP ISP1504 */
-	ULPI_ID(0x0424, 0x0006),        /* SMSC USB3319 */
+static struct ulpi_info ulpi_ids[] = {
+	ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"),
+	ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB3319"),
 };
 
 static int ulpi_set_otg_flags(struct otg_transceiver *otg)
@@ -137,6 +148,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;
@@ -153,12 +190,19 @@ static int ulpi_init(struct otg_transceiver *otg)
 
 	pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid);
 
-	for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++)
-		if (ulpi_ids[i] == ULPI_ID(vid, pid))
-			return ulpi_set_flags(otg);
+	for (i = 0; i < ARRAY_SIZE(ulpi_ids); i++) {
+		if (ulpi_ids[i].id == ULPI_ID(vid, pid)) {
+			pr_info("Found %s ULPI transceiver.\n",
+				ulpi_ids[i].name);
+			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)

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux