USB: serial: mos7840: clean up register handling
authorJackyChou <jackychou@asix.com.tw>
Fri, 30 Nov 2018 06:31:21 +0000 (14:31 +0800)
committerJohan Hovold <johan@kernel.org>
Wed, 5 Dec 2018 05:58:30 +0000 (06:58 +0100)
In the read/write function, set port 2 independently in the 2-port case.

When setting the offset of port registers, the offset between port 1 and
other ports is different, so port 1 is set independently.
Then in the rest of ports, the port 2 between 2-ports case and 4-ports case
is different, so port 2 in 2-ports case is set independently.

Specifically, port 2 in the 2-port case maps to the registers used by
port 3 in the 4-port case.

Signed-off-by: JackyChou <jackychou@asix.com.tw>
[ johan: simplify register-offset handling at port probe, add a comment
         and amend commit message ]
Signed-off-by: Johan Hovold <johan@kernel.org>
drivers/usb/serial/mos7840.c

index bfbf75b36349e86bf4d01064f7d7233c4bde7bdd..4159d319538868f76f5a42d8e311228867d611ed 100644 (file)
@@ -298,15 +298,10 @@ static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg,
        val = val & 0x00ff;
        /* For the UART control registers, the application number need
           to be Or'ed */
-       if (port->serial->num_ports == 4) {
+       if (port->serial->num_ports == 2 && port->port_number != 0)
+               val |= ((__u16)port->port_number + 2) << 8;
+       else
                val |= ((__u16)port->port_number + 1) << 8;
-       } else {
-               if (port->port_number == 0) {
-                       val |= ((__u16)port->port_number + 1) << 8;
-               } else {
-                       val |= ((__u16)port->port_number + 2) << 8;
-               }
-       }
        dev_dbg(&port->dev, "%s application number is %x\n", __func__, val);
        return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
                               MCS_WR_RTYPE, val, reg, NULL, 0,
@@ -332,15 +327,10 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
                return -ENOMEM;
 
        /* Wval  is same as application number */
-       if (port->serial->num_ports == 4) {
+       if (port->serial->num_ports == 2 && port->port_number != 0)
+               Wval = ((__u16)port->port_number + 2) << 8;
+       else
                Wval = ((__u16)port->port_number + 1) << 8;
-       } else {
-               if (port->port_number == 0) {
-                       Wval = ((__u16)port->port_number + 1) << 8;
-               } else {
-                       Wval = ((__u16)port->port_number + 2) << 8;
-               }
-       }
        dev_dbg(&port->dev, "%s application number is %x\n", __func__, Wval);
        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
                              MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
@@ -2127,22 +2117,16 @@ static int mos7840_port_probe(struct usb_serial_port *port)
                mos7840_port->SpRegOffset = 0x0;
                mos7840_port->ControlRegOffset = 0x1;
                mos7840_port->DcrRegOffset = 0x4;
-       } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) {
-               mos7840_port->SpRegOffset = 0x8;
-               mos7840_port->ControlRegOffset = 0x9;
-               mos7840_port->DcrRegOffset = 0x16;
-       } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) {
-               mos7840_port->SpRegOffset = 0xa;
-               mos7840_port->ControlRegOffset = 0xb;
-               mos7840_port->DcrRegOffset = 0x19;
-       } else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) {
-               mos7840_port->SpRegOffset = 0xa;
-               mos7840_port->ControlRegOffset = 0xb;
-               mos7840_port->DcrRegOffset = 0x19;
-       } else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) {
-               mos7840_port->SpRegOffset = 0xc;
-               mos7840_port->ControlRegOffset = 0xd;
-               mos7840_port->DcrRegOffset = 0x1c;
+       } else {
+               u8 phy_num = mos7840_port->port_num;
+
+               /* Port 2 in the 2-port case uses registers of port 3 */
+               if (serial->num_ports == 2)
+                       phy_num = 3;
+
+               mos7840_port->SpRegOffset = 0x8 + 2 * (phy_num - 2);
+               mos7840_port->ControlRegOffset = 0x9 + 2 * (phy_num - 2);
+               mos7840_port->DcrRegOffset = 0x16 + 3 * (phy_num - 2);
        }
        mos7840_dump_serial_port(port, mos7840_port);
        mos7840_set_port_private(port, mos7840_port);