Received: by 10.223.164.202 with SMTP id h10csp1606861wrb; Thu, 16 Nov 2017 00:52:50 -0800 (PST) X-Google-Smtp-Source: AGs4zMbId72KMBiVHCiIZLTyqA3igHUF3lZH3mUBFHNhRpzExosllZDrFLPhnPCRa0t+UZhFp051 X-Received: by 10.101.75.204 with SMTP id p12mr981749pgr.61.1510822370474; Thu, 16 Nov 2017 00:52:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510822370; cv=none; d=google.com; s=arc-20160816; b=r56Zln2IvTWMqueHALQBHH1fMxXN8tpuB/8lZkrizlHDq3DFwuBDMPWontLvZLAmgZ iU0/8EbMa5cTUn7oXBRoepPdstvuaG2U59E1vDiJaj3SUhqBf4SFeHnI+XMPFS/GqKAJ umnA5zIkjoUgmh87AS/Xl/EJBE5+lq7mM4m4TGHnrQFiAepXzFi9Vg6xEXeFBWHa8VJR ZCuc+ziunYXQVxvKV3Hh9Xz5wCWOJz/TizKsqHbwdFVAE22CQ4AojPvxloaRJXs2PrfP psrvJ7yO7khd6X+/cKP4j6hzgjYpd5P8DvNFfx7LravhUWkbmR0BOrcAU0beDQfbija+ Zfvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=MbQpFHkLqq43LWaYSWmqxKN2erCw2jxCd0qJ0x7MkuQ=; b=xiY1rb8m3phAFd4ykBC08+a9l/4ypR1AmMOhLVgaoZW9ZXQazViqD86DWO2M0ayv63 1wieyk56bckNZmrTDWm0fs++ZJ72nX3f5pjilc794NPpn9nQhoz6lmG8BZnQ3HqWNAOe 8uFdE9abjf+BBQoOPniHV9fdVM0T5DEEm3Bejcr2SHMRWEDvOP0MNIBm6SMNekJ9VmLC +HKP7KKWdSnjT1GNgR+QKmiyMAa6n/KowRI9BtZ34j86i3imPNoqBKzg0UfNfLT1Wrh0 YnJ1wuRgs2DIJhE7M5L3j+uHDrZpy6qvsHiqrWKa0x1hMnizqYkKMbIJTwxg7Acs3MpW VvPw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=K0cj/AyT; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l91si520179plb.647.2017.11.16.00.52.38; Thu, 16 Nov 2017 00:52:50 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=K0cj/AyT; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759025AbdKPHq1 (ORCPT + 91 others); Thu, 16 Nov 2017 02:46:27 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:46800 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750867AbdKPHqV (ORCPT ); Thu, 16 Nov 2017 02:46:21 -0500 Received: by mail-pf0-f193.google.com with SMTP id i15so8720028pfa.3; Wed, 15 Nov 2017 23:46:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=MbQpFHkLqq43LWaYSWmqxKN2erCw2jxCd0qJ0x7MkuQ=; b=K0cj/AyTshLRRb6hPjC0kVy+wsaoAkt+xwDickm9QEWjyoP0MRzhG+fnveIxSxNeVr Em83DUfiW8CE+0IDAvJ9lLUoheIbQwi1Wx5tO3DKj+MgtLiPvdTHtiqEHI8Ynvu/XqHA JWuvPxQhpsa06bbxiSLSYPObWIRbTWcVZOCGjufVrcLC3z6XyW0wWAFJ5+1fddPqnHjB +rQUNfPXgZ0/QP3EVuHRnqGYgugGJTSvu/MxLgz7VN8gYjGrmHSHenro7AMtNnMGJe5c r3ZPmxKo3KGrqqqV4/s9ggl5ypYVNp+39LzeNAAF4d4Qq2o/PZ7S4dvRDjs+gP2cLrUn dsnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=MbQpFHkLqq43LWaYSWmqxKN2erCw2jxCd0qJ0x7MkuQ=; b=DaTXlJIYNRk0pT3z4Js88A0zG/QTRCeU3GXNzZ/BEanG/n7kklziQurkCO4TESn+z2 XOoq8ADxrmzbNsYGalVITc7P6CQlZ7B9wZicdErOi+6pMdYI3Iwa2CLztYc/WfTWmkIQ DbkfaFYAMjGhVtfWKf7FxK8A55pMEC15dRc2dL3FiPIs4UXevFCZNTusAXTnYnkKFchG VR9B+ElZR6gC8UhDMXruM36QbiNdGXpYro+9j9mYgkNbAGrcEz/5WmzlUzY6dNh6yjCv gCPiYujPd9GrPiBdTS204AsmqEDu1KT6TfswtngwR0wwhkoNvbI9rvV4Dh+TgptCVPQF duMg== X-Gm-Message-State: AJaThX7MAgTUg0cyDVtBgjrM5Bq0H91MmTcUrxqU6odRcLEA3GBPWwdn n9mWFGMByZdRVUjiVmzn8D8= X-Received: by 10.98.8.67 with SMTP id c64mr935951pfd.50.1510818381025; Wed, 15 Nov 2017 23:46:21 -0800 (PST) Received: from localhost (59-120-186-245.HINET-IP.hinet.net. [59.120.186.245]) by smtp.gmail.com with ESMTPSA id o84sm1550155pfa.46.2017.11.15.23.46.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Nov 2017 23:46:20 -0800 (PST) From: "Ji-Ze Hong (Peter Hong)" X-Google-Original-From: "Ji-Ze Hong (Peter Hong)" To: johan@kernel.org Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, "Ji-Ze Hong (Peter Hong)" Subject: [PATCH V1 1/4] usb: serial: f81534: add high baud rate support Date: Thu, 16 Nov 2017 15:46:06 +0800 Message-Id: <1510818369-10323-1-git-send-email-hpeter+linux_kernel@gmail.com> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The F81532/534 had 4 clocksource 1.846/18.46/14.77/24MHz and baud rates can be up to 1.5Mbits with 24MHz. F81532/534 Clock register (offset +08h) Bit0: UART Enable (always on) Bit2-1: Clock source selector 00: 1.846MHz. 01: 18.46MHz. 10: 24MHz. 11: 14.77MHz. Signed-off-by: Ji-Ze Hong (Peter Hong) --- drivers/usb/serial/f81534.c | 84 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index cb8214860192..76c676ef5f0d 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -45,6 +45,7 @@ #define F81534_MODEM_CONTROL_REG (0x04 + F81534_UART_BASE_ADDRESS) #define F81534_LINE_STATUS_REG (0x05 + F81534_UART_BASE_ADDRESS) #define F81534_MODEM_STATUS_REG (0x06 + F81534_UART_BASE_ADDRESS) +#define F81534_CLOCK_REG (0x08 + F81534_UART_BASE_ADDRESS) #define F81534_CONFIG1_REG (0x09 + F81534_UART_BASE_ADDRESS) #define F81534_DEF_CONF_ADDRESS_START 0x3000 @@ -61,7 +62,7 @@ /* Default URB timeout for USB operations */ #define F81534_USB_MAX_RETRY 10 -#define F81534_USB_TIMEOUT 1000 +#define F81534_USB_TIMEOUT 2000 #define F81534_SET_GET_REGISTER 0xA0 #define F81534_NUM_PORT 4 @@ -100,7 +101,6 @@ #define F81534_CMD_READ 0x03 #define F81534_DEFAULT_BAUD_RATE 9600 -#define F81534_MAX_BAUDRATE 115200 #define F81534_PORT_CONF_DISABLE_PORT BIT(3) #define F81534_PORT_CONF_NOT_EXIST_PORT BIT(7) @@ -110,6 +110,22 @@ #define F81534_1X_RXTRIGGER 0xc3 #define F81534_8X_RXTRIGGER 0xcf +/* + * F81532/534 Clock registers (offset +08h) + * + * Bit0: UART Enable (always on) + * Bit2-1: Clock source selector + * 00: 1.846MHz. + * 01: 18.46MHz. + * 10: 24MHz. + * 11: 14.77MHz. + */ + +#define F81534_CLK_1_846_MHZ BIT(0) +#define F81534_CLK_18_46_MHZ (BIT(0) | BIT(1)) +#define F81534_CLK_24_MHZ (BIT(0) | BIT(2)) +#define F81534_CLK_14_77_MHZ (BIT(0) | BIT(1) | BIT(2)) + static const struct usb_device_id f81534_id_table[] = { { USB_DEVICE(FINTEK_VENDOR_ID_1, FINTEK_DEVICE_ID) }, { USB_DEVICE(FINTEK_VENDOR_ID_2, FINTEK_DEVICE_ID) }, @@ -133,6 +149,7 @@ struct f81534_port_private { struct usb_serial_port *port; unsigned long tx_empty; spinlock_t msr_lock; + u32 baud_base; u8 shadow_mcr; u8 shadow_lcr; u8 shadow_msr; @@ -464,13 +481,51 @@ static u32 f81534_calc_baud_divisor(u32 baudrate, u32 clockrate) return DIV_ROUND_CLOSEST(clockrate, baudrate); } -static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate, - u8 lcr) +static int f81534_set_port_config(struct usb_serial_port *port, + struct tty_struct *tty, u32 baudrate, u32 old_baudrate, u8 lcr) { struct f81534_port_private *port_priv = usb_get_serial_port_data(port); u32 divisor; int status; + int idx; u8 value; + static u32 const baudrate_table[] = {115200, 921600, 1152000, + 1500000}; + static u8 const clock_table[] = {F81534_CLK_1_846_MHZ, + F81534_CLK_14_77_MHZ, F81534_CLK_18_46_MHZ, + F81534_CLK_24_MHZ}; + + do { + for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) { + if (baudrate <= baudrate_table[idx] && + baudrate_table[idx] % baudrate == 0) + break; + } + + /* Found acceptable baud rate */ + if (idx != ARRAY_SIZE(baudrate_table)) + break; + + if (baudrate == old_baudrate && + old_baudrate != F81534_DEFAULT_BAUD_RATE) + old_baudrate = F81534_DEFAULT_BAUD_RATE; + + dev_warn(&port->dev, + "baudrate: %d not supported, change to: %d\n", + baudrate, old_baudrate); + + baudrate = old_baudrate; + tty_encode_baud_rate(tty, baudrate, baudrate); + + } while (1); + + port_priv->baud_base = baudrate_table[idx]; + status = f81534_set_port_register(port, F81534_CLOCK_REG, + clock_table[idx]); + if (status) { + dev_err(&port->dev, "CLOCK_REG setting failed\n"); + return status; + } if (baudrate <= 1200) value = F81534_1X_RXTRIGGER; /* 128 FIFO & TL: 1x */ @@ -486,7 +541,7 @@ static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate, if (baudrate <= 1200) value = UART_FCR_TRIGGER_1 | UART_FCR_ENABLE_FIFO; /* TL: 1 */ else - value = UART_FCR_R_TRIG_11 | UART_FCR_ENABLE_FIFO; /* TL: 14 */ + value = UART_FCR_TRIGGER_8 | UART_FCR_ENABLE_FIFO; /* TL: 8 */ status = f81534_set_port_register(port, F81534_FIFO_CONTROL_REG, value); @@ -495,7 +550,7 @@ static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate, return status; } - divisor = f81534_calc_baud_divisor(baudrate, F81534_MAX_BAUDRATE); + divisor = f81534_calc_baud_divisor(baudrate, baudrate_table[idx]); mutex_lock(&port_priv->lcr_mutex); @@ -745,6 +800,7 @@ static void f81534_set_termios(struct tty_struct *tty, u8 new_lcr = 0; int status; u32 baud; + u32 old_baud; if (C_BAUD(tty) == B0) f81534_update_mctrl(port, 0, TIOCM_DTR | TIOCM_RTS); @@ -784,18 +840,14 @@ static void f81534_set_termios(struct tty_struct *tty, if (!baud) return; - if (baud > F81534_MAX_BAUDRATE) { - if (old_termios) - baud = tty_termios_baud_rate(old_termios); - else - baud = F81534_DEFAULT_BAUD_RATE; - - tty_encode_baud_rate(tty, baud, baud); - } + if (old_termios) + old_baud = tty_termios_baud_rate(old_termios); + else + old_baud = F81534_DEFAULT_BAUD_RATE; dev_dbg(&port->dev, "%s: baud: %d\n", __func__, baud); - status = f81534_set_port_config(port, baud, new_lcr); + status = f81534_set_port_config(port, tty, baud, old_baud, new_lcr); if (status < 0) { dev_err(&port->dev, "%s: set port config failed: %d\n", __func__, status); @@ -951,7 +1003,7 @@ static int f81534_get_serial_info(struct usb_serial_port *port, tmp.type = PORT_16550A; tmp.port = port->port_number; tmp.line = port->minor; - tmp.baud_base = F81534_MAX_BAUDRATE; + tmp.baud_base = port_priv->baud_base; if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) return -EFAULT; -- 2.7.4 From 1584245773921340306@xxx Thu Nov 16 17:48:25 +0000 2017 X-GM-THRID: 1582686746258533661 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread