Skip to content

Commit 6e0f306

Browse files
committed
Merge tag 'usb-serial-5.5-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-next
Johan writes: USB-serial updates for 5.5-rc1 Here are the USB-serial updates for 5.5-rc1, including: - support for a new class of pl2303 devices - improved divisor calculations for ch341 - fixes for a remote-wakeup bug in the moschip drivers - improved device-type handling in mos7840 - various cleanups of mos7840 Included are also some new device ids. All have been in linux-next with no reported issues. Signed-off-by: Johan Hovold <johan@kernel.org> * tag 'usb-serial-5.5-rc1' of https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial: USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P USB: serial: option: add support for Foxconn T77W968 LTE modules USB: serial: mos7840: drop port open flag USB: serial: mos7840: drop read-urb check USB: serial: mos7840: drop port driver data accessors USB: serial: mos7840: drop serial struct accessor USB: serial: mos7840: drop paranoid serial checks USB: serial: mos7840: drop paranoid port checks USB: serial: mos7840: drop redundant urb context check USB: serial: mos7840: rip out broken interrupt handling USB: serial: mos7840: fix probe error handling USB: serial: mos7840: document MCS7810 detection hack USB: serial: mos7840: clean up device-type handling USB: serial: mos7840: fix remote wakeup USB: serial: mos7720: fix remote wakeup USB: serial: option: add support for DW5821e with eSIM support USB: serial: mos7840: add USB ID to support Moxa UPort 2210 USB: serial: ch341: reimplement line-speed handling USB: serial: pl2303: add support for PL2303HXN
2 parents e47ff01 + c1a1f27 commit 6e0f306

File tree

8 files changed

+300
-710
lines changed

8 files changed

+300
-710
lines changed

drivers/usb/serial/ch341.c

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,6 @@
4848
#define CH341_BIT_DCD 0x08
4949
#define CH341_BITS_MODEM_STAT 0x0f /* all bits */
5050

51-
/*******************************/
52-
/* baudrate calculation factor */
53-
/*******************************/
54-
#define CH341_BAUDBASE_FACTOR 1532620800
55-
#define CH341_BAUDBASE_DIVMAX 3
56-
5751
/* Break support - the information used to implement this was gleaned from
5852
* the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato.
5953
*/
@@ -144,37 +138,96 @@ static int ch341_control_in(struct usb_device *dev,
144138
return 0;
145139
}
146140

141+
#define CH341_CLKRATE 48000000
142+
#define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact)))
143+
#define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512))
144+
145+
static const speed_t ch341_min_rates[] = {
146+
CH341_MIN_RATE(0),
147+
CH341_MIN_RATE(1),
148+
CH341_MIN_RATE(2),
149+
CH341_MIN_RATE(3),
150+
};
151+
152+
/*
153+
* The device line speed is given by the following equation:
154+
*
155+
* baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where
156+
*
157+
* 0 <= ps <= 3,
158+
* 0 <= fact <= 1,
159+
* 2 <= div <= 256 if fact = 0, or
160+
* 9 <= div <= 256 if fact = 1
161+
*/
162+
static int ch341_get_divisor(speed_t speed)
163+
{
164+
unsigned int fact, div, clk_div;
165+
int ps;
166+
167+
/*
168+
* Clamp to supported range, this makes the (ps < 0) and (div < 2)
169+
* sanity checks below redundant.
170+
*/
171+
speed = clamp(speed, 46U, 3000000U);
172+
173+
/*
174+
* Start with highest possible base clock (fact = 1) that will give a
175+
* divisor strictly less than 512.
176+
*/
177+
fact = 1;
178+
for (ps = 3; ps >= 0; ps--) {
179+
if (speed > ch341_min_rates[ps])
180+
break;
181+
}
182+
183+
if (ps < 0)
184+
return -EINVAL;
185+
186+
/* Determine corresponding divisor, rounding down. */
187+
clk_div = CH341_CLK_DIV(ps, fact);
188+
div = CH341_CLKRATE / (clk_div * speed);
189+
190+
/* Halve base clock (fact = 0) if required. */
191+
if (div < 9 || div > 255) {
192+
div /= 2;
193+
clk_div *= 2;
194+
fact = 0;
195+
}
196+
197+
if (div < 2)
198+
return -EINVAL;
199+
200+
/*
201+
* Pick next divisor if resulting rate is closer to the requested one,
202+
* scale up to avoid rounding errors on low rates.
203+
*/
204+
if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >=
205+
16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1)))
206+
div++;
207+
208+
return (0x100 - div) << 8 | fact << 2 | ps;
209+
}
210+
147211
static int ch341_set_baudrate_lcr(struct usb_device *dev,
148212
struct ch341_private *priv, u8 lcr)
149213
{
150-
short a;
214+
int val;
151215
int r;
152-
unsigned long factor;
153-
short divisor;
154216

155217
if (!priv->baud_rate)
156218
return -EINVAL;
157-
factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);
158-
divisor = CH341_BAUDBASE_DIVMAX;
159-
160-
while ((factor > 0xfff0) && divisor) {
161-
factor >>= 3;
162-
divisor--;
163-
}
164219

165-
if (factor > 0xfff0)
220+
val = ch341_get_divisor(priv->baud_rate);
221+
if (val < 0)
166222
return -EINVAL;
167223

168-
factor = 0x10000 - factor;
169-
a = (factor & 0xff00) | divisor;
170-
171224
/*
172225
* CH341A buffers data until a full endpoint-size packet (32 bytes)
173226
* has been received unless bit 7 is set.
174227
*/
175-
a |= BIT(7);
228+
val |= BIT(7);
176229

177-
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a);
230+
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, val);
178231
if (r)
179232
return r;
180233

drivers/usb/serial/ftdi_sio.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,9 @@ static const struct usb_device_id id_table_combined[] = {
10331033
/* Sienna devices */
10341034
{ USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) },
10351035
{ USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) },
1036+
/* U-Blox devices */
1037+
{ USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) },
1038+
{ USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) },
10361039
{ } /* Terminating entry */
10371040
};
10381041

drivers/usb/serial/ftdi_sio_ids.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,3 +1558,10 @@
15581558
*/
15591559
#define UNJO_VID 0x22B7
15601560
#define UNJO_ISODEBUG_V1_PID 0x150D
1561+
1562+
/*
1563+
* U-Blox products (http://www.u-blox.com).
1564+
*/
1565+
#define UBLOX_VID 0x1546
1566+
#define UBLOX_C099F9P_ZED_PID 0x0502
1567+
#define UBLOX_C099F9P_ODIN_PID 0x0503

drivers/usb/serial/mos7720.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,10 +1833,6 @@ static int mos7720_startup(struct usb_serial *serial)
18331833
product = le16_to_cpu(serial->dev->descriptor.idProduct);
18341834
dev = serial->dev;
18351835

1836-
/* setting configuration feature to one */
1837-
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
1838-
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
1839-
18401836
if (product == MOSCHIP_DEVICE_ID_7715) {
18411837
struct urb *urb = serial->port[0]->interrupt_in_urb;
18421838

0 commit comments

Comments
 (0)