This introduces the `uart_mode` sysfs attribute as seen in the `io_ti`
USB serial driver, allowing this USB serial interface to be switched
between RS-232, 2-wire RS-485 and 4-wire RS-485.
/sys/class/tty/ttyUSB${num}/device/uart takes a single integer:
0: RS-232 mode (default for RS-232-compatible dongles)
1: RS-485 2w mode (default for RS-485-only dongles)
2: RS-485 4w mode / RS-422 mode
Write this *before* opening your serial device.
This has been successfully tested on a Moxa UPort 1150 in 4-wire RS-485
mode.
Signed-off-by: Stuart Longland <[email protected]>
---
drivers/usb/serial/ti_usb_3410_5052.c | 48 +++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c
b/drivers/usb/serial/ti_usb_3410_5052.c
index 8fc3854e5e69..fb30d7ff32d7 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -514,6 +514,46 @@ MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
module_usb_serial_driver(serial_drivers, ti_id_table_combined);
+/* Sysfs Attributes */
+
+static ssize_t uart_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_serial_port *port = to_usb_serial_port(dev);
+ struct ti_port *tport = usb_get_serial_port_data(port);
+
+ return sprintf(buf, "%d\n", tport->tp_uart_mode);
+}
+
+static ssize_t uart_mode_store(struct device *dev,
+ struct device_attribute *attr, const char *valbuf, size_t count)
+{
+ struct usb_serial_port *port = to_usb_serial_port(dev);
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ unsigned int v = simple_strtoul(valbuf, NULL, 0);
+
+ dev_dbg(dev, "%s: setting uart_mode = %d\n", __func__, v);
+
+ if (v < 256)
+ tport->tp_uart_mode = v;
+ else
+ dev_err(dev, "%s - uart_mode %d is invalid\n", __func__, v);
+
+ return count;
+}
+static DEVICE_ATTR_RW(uart_mode);
+
+static int ti_create_sysfs_attrs(struct usb_serial_port *port)
+{
+ return device_create_file(&port->dev, &dev_attr_uart_mode);
+}
+
+static int ti_remove_sysfs_attrs(struct usb_serial_port *port)
+{
+ device_remove_file(&port->dev, &dev_attr_uart_mode);
+ return 0;
+}
+
static int ti_startup(struct usb_serial *serial)
{
struct ti_device *tdev;
@@ -607,6 +647,7 @@ static void ti_release(struct usb_serial *serial)
static int ti_port_probe(struct usb_serial_port *port)
{
struct ti_port *tport;
+ int status;
tport = kzalloc(sizeof(*tport), GFP_KERNEL);
if (!tport)
@@ -628,6 +669,12 @@ static int ti_port_probe(struct usb_serial_port *port)
usb_set_serial_port_data(port, tport);
+ status = ti_create_sysfs_attrs(port);
+ if (status) {
+ kfree(tport);
+ return status;
+ }
+
port->port.drain_delay = 3;
return 0;
@@ -638,6 +685,7 @@ static int ti_port_remove(struct usb_serial_port *port)
struct ti_port *tport;
tport = usb_get_serial_port_data(port);
+ ti_remove_sysfs_attrs(port);
kfree(tport);
return 0;
--
2.13.0
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html