All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] USB: serial: ftdi_sio: only bind FT232H if UART mode is enabled
@ 2017-07-13 16:25 Anatolij Gustschin
  2017-07-19  9:03 ` Johan Hovold
  0 siblings, 1 reply; 4+ messages in thread
From: Anatolij Gustschin @ 2017-07-13 16:25 UTC (permalink / raw)
  To: Johan Hovold, linux-usb; +Cc: linux-kernel, Greg Kroah-Hartman

On FT232H the interface mode can be configured in the EEPROM,
and the async UART mode is configured by default. The chip is
also in async UART mode if no EEPROM is connected.

Check the EEPROM configuration and do not bind as serial device
when different interface mode is programmed in the EEPROM.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
 drivers/usb/serial/ftdi_sio.c | 62 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/usb/serial/ftdi_sio.h | 12 +++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 1cec037..624ce8f 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -92,6 +92,7 @@ static int   ftdi_stmclite_probe(struct usb_serial *serial);
 static int   ftdi_8u2232c_probe(struct usb_serial *serial);
 static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
 static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
+static int   ftdi_ft232h_probe(struct usb_serial *serial);
 
 static const struct ftdi_sio_quirk ftdi_jtag_quirk = {
 	.probe	= ftdi_jtag_probe,
@@ -117,6 +118,10 @@ static const struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
 	.probe	= ftdi_8u2232c_probe,
 };
 
+static const struct ftdi_sio_quirk ftdi_ft232h_quirk = {
+	.probe	= ftdi_ft232h_probe,
+};
+
 /*
  * The 8U232AM has the same API as the sio except for:
  * - it can support MUCH higher baudrates; up to:
@@ -173,7 +178,8 @@ static const struct usb_device_id id_table_combined[] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) ,
 		.driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk },
 	{ USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
-	{ USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_232H_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_ft232h_quirk },
 	{ USB_DEVICE(FTDI_VID, FTDI_FTX_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
@@ -1905,6 +1911,60 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
 }
 
 /*
+ * Check this amount of FT232H EEPROM bytes. If all are 0xff,
+ * we assume that the EEPROM is erased or is not populated.
+ * Then, async. UART is the default interface mode.
+ */
+#define EEPROM_CHK_BUF_SZ	6
+
+static inline bool ftdi_sio_chk_erased(const void *buf, int size)
+{
+	const unsigned char *data = buf;
+	unsigned int i;
+
+	for (i = 0; i < size; i++)
+		if (data[i] != 0xff)
+			return false;
+	return true;
+}
+
+static int ftdi_ft232h_probe(struct usb_serial *serial)
+{
+	struct usb_device *udev = serial->dev;
+	unsigned char *buf;
+	unsigned int i;
+	int ret;
+
+	buf = kmalloc(EEPROM_CHK_BUF_SZ, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	/* Try to read the configured interface mode in EEPROM */
+	for (i = 0; i < EEPROM_CHK_BUF_SZ / 2; i++) {
+		ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+				      FTDI_SIO_READ_EEPROM_REQUEST,
+				      FTDI_SIO_READ_EEPROM_REQUEST_TYPE,
+				      0, i, buf + i * 2, 2,
+				      USB_CTRL_GET_TIMEOUT);
+		if (ret < 0) {
+			dev_err(&udev->dev, "reading EEPROM failed: %d\n", ret);
+			goto out;
+		}
+	}
+
+	ret = 0;
+	if (ftdi_sio_chk_erased(buf, EEPROM_CHK_BUF_SZ))
+		goto out;
+
+	/* Lower nibble contains interface mode bits, if zero -> UART mode */
+	if (buf[0] & 0x0f)
+		ret = -ENODEV; /* No UART, don't bind! */
+out:
+	kfree(buf);
+	return ret;
+}
+
+/*
  * First two ports on JTAG adaptors using an FT4232 such as STMicroelectronics's
  * ST Micro Connect Lite are reserved for JTAG or other non-UART interfaces and
  * can be accessed from userspace.
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index bbcc13df..82d56cb 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -432,6 +432,18 @@ enum ftdi_sio_baudrate {
  *         1 = active
  */
 
+/*
+ *  BmRequestType:   1100 0000b
+ *  bRequest:        FTDI_SIO_READ_EEPROM_REQUEST
+ *  wValue:          0
+ *  wIndex:          Address of word to read
+ *  wLength:         2
+ *  Data:            return a word of data from EEPROM
+ *                   at address in wIndex
+ */
+#define FTDI_SIO_READ_EEPROM_REQUEST_TYPE \
+	(USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN)
+#define FTDI_SIO_READ_EEPROM_REQUEST	0x90
 
 
 /* Descriptors returned by the device
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] USB: serial: ftdi_sio: only bind FT232H if UART mode is enabled
  2017-07-13 16:25 [PATCH] USB: serial: ftdi_sio: only bind FT232H if UART mode is enabled Anatolij Gustschin
@ 2017-07-19  9:03 ` Johan Hovold
  2017-07-19 11:23   ` Anatolij Gustschin
  0 siblings, 1 reply; 4+ messages in thread
From: Johan Hovold @ 2017-07-19  9:03 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: Johan Hovold, linux-usb, linux-kernel, Greg Kroah-Hartman

On Thu, Jul 13, 2017 at 06:25:25PM +0200, Anatolij Gustschin wrote:
> On FT232H the interface mode can be configured in the EEPROM,
> and the async UART mode is configured by default. The chip is
> also in async UART mode if no EEPROM is connected.
> 
> Check the EEPROM configuration and do not bind as serial device
> when different interface mode is programmed in the EEPROM.

Thanks for the patch. As you may have inferred from my reply to your MFD
series, this won't be needed for a while still however.

Also note that some people already use asynchronous FIFO mode using this
driver (also mentioned in the datasheets as an option) so only binding
in UART mode would be too restrictive.

Thanks,
Johan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] USB: serial: ftdi_sio: only bind FT232H if UART mode is enabled
  2017-07-19  9:03 ` Johan Hovold
@ 2017-07-19 11:23   ` Anatolij Gustschin
  2017-07-25 11:43     ` Johan Hovold
  0 siblings, 1 reply; 4+ messages in thread
From: Anatolij Gustschin @ 2017-07-19 11:23 UTC (permalink / raw)
  To: Johan Hovold; +Cc: linux-usb, linux-kernel, Greg Kroah-Hartman

On Wed, 19 Jul 2017 11:03:11 +0200
Johan Hovold johan@kernel.org wrote:

>On Thu, Jul 13, 2017 at 06:25:25PM +0200, Anatolij Gustschin wrote:
>> On FT232H the interface mode can be configured in the EEPROM,
>> and the async UART mode is configured by default. The chip is
>> also in async UART mode if no EEPROM is connected.
>> 
>> Check the EEPROM configuration and do not bind as serial device
>> when different interface mode is programmed in the EEPROM.  
>
>Thanks for the patch. As you may have inferred from my reply to your MFD
>series, this won't be needed for a while still however.
>
>Also note that some people already use asynchronous FIFO mode using this
>driver (also mentioned in the datasheets as an option) so only binding
>in UART mode would be too restrictive.

You probably mean asynchronous bitbang mode, not asynchronous FIFO
mode? This bitbang mode can always be set by sending a chip command
(mentioned as software configured in the datasheets)
Could you please point to code in this driver used for non-UART modes?
I don't see such code by a quick glance. There are some quirks for
various JTAG adapters to skip binding as serial port (the ftdi_sio
driver is not used in JTAG operation modes then). Or do people use
usual serial interface to send data in bitbang modes?

Async and sync FIFO (FT245) modes however can only be configured via
EEPROM settings, at least for FT232H.

Thanks,
Anatolij

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] USB: serial: ftdi_sio: only bind FT232H if UART mode is enabled
  2017-07-19 11:23   ` Anatolij Gustschin
@ 2017-07-25 11:43     ` Johan Hovold
  0 siblings, 0 replies; 4+ messages in thread
From: Johan Hovold @ 2017-07-25 11:43 UTC (permalink / raw)
  To: Anatolij Gustschin
  Cc: Johan Hovold, linux-usb, linux-kernel, Greg Kroah-Hartman

On Wed, Jul 19, 2017 at 01:23:27PM +0200, Anatolij Gustschin wrote:
> On Wed, 19 Jul 2017 11:03:11 +0200
> Johan Hovold johan@kernel.org wrote:
> 
> >On Thu, Jul 13, 2017 at 06:25:25PM +0200, Anatolij Gustschin wrote:
> >> On FT232H the interface mode can be configured in the EEPROM,
> >> and the async UART mode is configured by default. The chip is
> >> also in async UART mode if no EEPROM is connected.
> >> 
> >> Check the EEPROM configuration and do not bind as serial device
> >> when different interface mode is programmed in the EEPROM.  
> >
> >Thanks for the patch. As you may have inferred from my reply to your MFD
> >series, this won't be needed for a while still however.
> >
> >Also note that some people already use asynchronous FIFO mode using this
> >driver (also mentioned in the datasheets as an option) so only binding
> >in UART mode would be too restrictive.
> 
> You probably mean asynchronous bitbang mode, not asynchronous FIFO
> mode?

No, I really meant asynchronous FIFO mode. And as mentioned in the data
sheets that can be used with the normal serial (VCP) drivers on both
Linux and that other OS.

> This bitbang mode can always be set by sending a chip command
> (mentioned as software configured in the datasheets)
> Could you please point to code in this driver used for non-UART modes?
> I don't see such code by a quick glance. There are some quirks for
> various JTAG adapters to skip binding as serial port (the ftdi_sio
> driver is not used in JTAG operation modes then). Or do people use
> usual serial interface to send data in bitbang modes?

Exactly.

> Async and sync FIFO (FT245) modes however can only be configured via
> EEPROM settings, at least for FT232H.

Right.

Thanks,
Johan

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-07-25 11:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-13 16:25 [PATCH] USB: serial: ftdi_sio: only bind FT232H if UART mode is enabled Anatolij Gustschin
2017-07-19  9:03 ` Johan Hovold
2017-07-19 11:23   ` Anatolij Gustschin
2017-07-25 11:43     ` Johan Hovold

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.