Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: serial: mos7840: clean up register handling

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>

authored by

JackyChou and committed by
Johan Hovold
e8603076 6abd8371

+16 -32
+16 -32
drivers/usb/serial/mos7840.c
··· 298 298 val = val & 0x00ff; 299 299 /* For the UART control registers, the application number need 300 300 to be Or'ed */ 301 - if (port->serial->num_ports == 4) { 301 + if (port->serial->num_ports == 2 && port->port_number != 0) 302 + val |= ((__u16)port->port_number + 2) << 8; 303 + else 302 304 val |= ((__u16)port->port_number + 1) << 8; 303 - } else { 304 - if (port->port_number == 0) { 305 - val |= ((__u16)port->port_number + 1) << 8; 306 - } else { 307 - val |= ((__u16)port->port_number + 2) << 8; 308 - } 309 - } 310 305 dev_dbg(&port->dev, "%s application number is %x\n", __func__, val); 311 306 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, 312 307 MCS_WR_RTYPE, val, reg, NULL, 0, ··· 327 332 return -ENOMEM; 328 333 329 334 /* Wval is same as application number */ 330 - if (port->serial->num_ports == 4) { 335 + if (port->serial->num_ports == 2 && port->port_number != 0) 336 + Wval = ((__u16)port->port_number + 2) << 8; 337 + else 331 338 Wval = ((__u16)port->port_number + 1) << 8; 332 - } else { 333 - if (port->port_number == 0) { 334 - Wval = ((__u16)port->port_number + 1) << 8; 335 - } else { 336 - Wval = ((__u16)port->port_number + 2) << 8; 337 - } 338 - } 339 339 dev_dbg(&port->dev, "%s application number is %x\n", __func__, Wval); 340 340 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ, 341 341 MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH, ··· 2117 2127 mos7840_port->SpRegOffset = 0x0; 2118 2128 mos7840_port->ControlRegOffset = 0x1; 2119 2129 mos7840_port->DcrRegOffset = 0x4; 2120 - } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) { 2121 - mos7840_port->SpRegOffset = 0x8; 2122 - mos7840_port->ControlRegOffset = 0x9; 2123 - mos7840_port->DcrRegOffset = 0x16; 2124 - } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) { 2125 - mos7840_port->SpRegOffset = 0xa; 2126 - mos7840_port->ControlRegOffset = 0xb; 2127 - mos7840_port->DcrRegOffset = 0x19; 2128 - } else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) { 2129 - mos7840_port->SpRegOffset = 0xa; 2130 - mos7840_port->ControlRegOffset = 0xb; 2131 - mos7840_port->DcrRegOffset = 0x19; 2132 - } else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) { 2133 - mos7840_port->SpRegOffset = 0xc; 2134 - mos7840_port->ControlRegOffset = 0xd; 2135 - mos7840_port->DcrRegOffset = 0x1c; 2130 + } else { 2131 + u8 phy_num = mos7840_port->port_num; 2132 + 2133 + /* Port 2 in the 2-port case uses registers of port 3 */ 2134 + if (serial->num_ports == 2) 2135 + phy_num = 3; 2136 + 2137 + mos7840_port->SpRegOffset = 0x8 + 2 * (phy_num - 2); 2138 + mos7840_port->ControlRegOffset = 0x9 + 2 * (phy_num - 2); 2139 + mos7840_port->DcrRegOffset = 0x16 + 3 * (phy_num - 2); 2136 2140 } 2137 2141 mos7840_dump_serial_port(port, mos7840_port); 2138 2142 mos7840_set_port_private(port, mos7840_port);