Commit 6e0f3060 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'usb-serial-5.5-rc1' of...

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: default avatarJohan 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
parents e47ff01b c1a1f273
Loading
Loading
Loading
Loading
+75 −22
Original line number Diff line number Diff line
@@ -48,12 +48,6 @@
#define CH341_BIT_DCD 0x08
#define CH341_BITS_MODEM_STAT 0x0f /* all bits */

/*******************************/
/* baudrate calculation factor */
/*******************************/
#define CH341_BAUDBASE_FACTOR 1532620800
#define CH341_BAUDBASE_DIVMAX 3

/* Break support - the information used to implement this was gleaned from
 * the Net/FreeBSD uchcom.c driver by Takanori Watanabe.  Domo arigato.
 */
@@ -144,37 +138,96 @@ static int ch341_control_in(struct usb_device *dev,
	return 0;
}

#define CH341_CLKRATE		48000000
#define CH341_CLK_DIV(ps, fact)	(1 << (12 - 3 * (ps) - (fact)))
#define CH341_MIN_RATE(ps)	(CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512))

static const speed_t ch341_min_rates[] = {
	CH341_MIN_RATE(0),
	CH341_MIN_RATE(1),
	CH341_MIN_RATE(2),
	CH341_MIN_RATE(3),
};

/*
 * The device line speed is given by the following equation:
 *
 *	baudrate = 48000000 / (2^(12 - 3 * ps - fact) * div), where
 *
 *		0 <= ps <= 3,
 *		0 <= fact <= 1,
 *		2 <= div <= 256 if fact = 0, or
 *		9 <= div <= 256 if fact = 1
 */
static int ch341_get_divisor(speed_t speed)
{
	unsigned int fact, div, clk_div;
	int ps;

	/*
	 * Clamp to supported range, this makes the (ps < 0) and (div < 2)
	 * sanity checks below redundant.
	 */
	speed = clamp(speed, 46U, 3000000U);

	/*
	 * Start with highest possible base clock (fact = 1) that will give a
	 * divisor strictly less than 512.
	 */
	fact = 1;
	for (ps = 3; ps >= 0; ps--) {
		if (speed > ch341_min_rates[ps])
			break;
	}

	if (ps < 0)
		return -EINVAL;

	/* Determine corresponding divisor, rounding down. */
	clk_div = CH341_CLK_DIV(ps, fact);
	div = CH341_CLKRATE / (clk_div * speed);

	/* Halve base clock (fact = 0) if required. */
	if (div < 9 || div > 255) {
		div /= 2;
		clk_div *= 2;
		fact = 0;
	}

	if (div < 2)
		return -EINVAL;

	/*
	 * Pick next divisor if resulting rate is closer to the requested one,
	 * scale up to avoid rounding errors on low rates.
	 */
	if (16 * CH341_CLKRATE / (clk_div * div) - 16 * speed >=
			16 * speed - 16 * CH341_CLKRATE / (clk_div * (div + 1)))
		div++;

	return (0x100 - div) << 8 | fact << 2 | ps;
}

static int ch341_set_baudrate_lcr(struct usb_device *dev,
				  struct ch341_private *priv, u8 lcr)
{
	short a;
	int val;
	int r;
	unsigned long factor;
	short divisor;

	if (!priv->baud_rate)
		return -EINVAL;
	factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);
	divisor = CH341_BAUDBASE_DIVMAX;

	while ((factor > 0xfff0) && divisor) {
		factor >>= 3;
		divisor--;
	}

	if (factor > 0xfff0)
	val = ch341_get_divisor(priv->baud_rate);
	if (val < 0)
		return -EINVAL;

	factor = 0x10000 - factor;
	a = (factor & 0xff00) | divisor;

	/*
	 * CH341A buffers data until a full endpoint-size packet (32 bytes)
	 * has been received unless bit 7 is set.
	 */
	a |= BIT(7);
	val |= BIT(7);

	r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a);
	r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, val);
	if (r)
		return r;

+3 −0
Original line number Diff line number Diff line
@@ -1033,6 +1033,9 @@ static const struct usb_device_id id_table_combined[] = {
	/* Sienna devices */
	{ USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) },
	{ USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) },
	/* U-Blox devices */
	{ USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) },
	{ USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) },
	{ }					/* Terminating entry */
};

+7 −0
Original line number Diff line number Diff line
@@ -1558,3 +1558,10 @@
 */
#define UNJO_VID			0x22B7
#define UNJO_ISODEBUG_V1_PID		0x150D

/*
 * U-Blox products (http://www.u-blox.com).
 */
#define UBLOX_VID			0x1546
#define UBLOX_C099F9P_ZED_PID		0x0502
#define UBLOX_C099F9P_ODIN_PID		0x0503
+0 −4
Original line number Diff line number Diff line
@@ -1833,10 +1833,6 @@ static int mos7720_startup(struct usb_serial *serial)
	product = le16_to_cpu(serial->dev->descriptor.idProduct);
	dev = serial->dev;

	/* setting configuration feature to one */
	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
			(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);

	if (product == MOSCHIP_DEVICE_ID_7715) {
		struct urb *urb = serial->port[0]->interrupt_in_urb;

Loading