From: Johan Hovold <johan@kernel.org>
To: Tony Chung <tony467913@gmail.com>
Cc: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
linux-usb@vger.kernel.org
Subject: Re: [PATCH 3/3] driver: usb: serial: mos7840: add more baudrate options
Date: Tue, 11 Feb 2025 14:08:10 +0100 [thread overview]
Message-ID: <Z6tLuiw7eK5s4Agq@hovoldconsulting.com> (raw)
In-Reply-To: <20241024100901.69883-4-tony467913@gmail.com>
On Thu, Oct 24, 2024 at 06:09:05PM +0800, Tony Chung wrote:
> Adds more baud rate options using 96M/30M/External clock sources.
> To use these clock sources,
> set through Clk_Select_Reg1 and Clk_Select_Reg2.
>
> Signed-off-by: Tony Chung <tony467913@gmail.com>
> ---
> drivers/usb/serial/mos7840.c | 156 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 155 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
> index acc16737b..70ee4a638 100644
> --- a/drivers/usb/serial/mos7840.c
> +++ b/drivers/usb/serial/mos7840.c
> @@ -1169,6 +1169,37 @@ static int mos7840_calc_baud_rate_divisor(struct usb_serial_port *port,
> *divisor = 0x01; // DLM=0, DLL=0x01
> *clk_sel_val = 0x60; // clock source=24M
>
> + /* below are using 96M or 30M clock source
> + * will determine the clock source later
> + * in function mos7840_send_cmd_write_baud_rate
> + */
Block comment style, also try to follow style of driver and capitalise
"Below".
That said, this one should not be needed after you add proper
abstractions for this. For example, instead of returning a raw
clk_sel_val you return an enum which you handle in the caller.
> + } else if (baudRate == 6000000) {
> + *divisor = 0x01; // DLM=0, DLL=0x01
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 96M
> + } else if (baudRate == 2000000) {
> + *divisor = 0x03; // DLM=0, DLL=0x03
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 96M
The above looks useful.
> + } else if (baudRate == 403200) {
> + *divisor = 0x0f; // DLM=0, DLL=0x0f
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 96M
> + } else if (baudRate == 225000) {
> + *divisor = 0x1b; // DLM=0, DLL=0x1b
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 96M
> + } else if (baudRate == 153600) {
> + *divisor = 0x27; // DLM=0, DLL=0x27
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 96M
But why would anyone use these?
> + } else if (baudRate == 10000) {
> + *divisor = 0xbb; // DLM=0, DLL=0xbb
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 30M
> + } else if (baudRate == 125000) {
> + *divisor = 0x0f; // DLM=0, DLL=0x0f
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 30M
> + } else if (baudRate == 625000) {
> + *divisor = 0x03; // DLM=0, DLL=0x03
> + *clk_sel_val = 0x80; // DUMMY val, clock source = 30M
Or these?
In any case, these would probably also need to go in a lookup table.
> +
> +
> } else if (baudRate <= 115200) {
> *divisor = 115200 / baudRate;
> *clk_sel_val = 0x0;
> @@ -1246,11 +1277,134 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
>
> }
>
> - if (1) { /* baudRate <= 115200) */
> + if (1) {
Probably a good time to get rid of this in a preparatory patch to reduce
the indentation.
> clk_sel_val = 0x0;
> Data = 0x0;
> status = mos7840_calc_baud_rate_divisor(port, baudRate, &divisor,
> &clk_sel_val);
> + if (status < 0) {
> + dev_dbg(&port->dev, "%s failed in set_serial_baud\n", __func__);
> + return -1;
> + }
Ok, here you add the error handling. But as I mentioned it's better to
fix the caller so that it does not pass in a speed that too high for the
driver. Just keep the old rate and update the termios to reflect that
that requested rate was rejected.
> +
> + /* Write clk_sel_val to SP_Reg or Clk_Select_Reg*/
Space before */
> + // check clk_sel_val before setting the clk_sel_val
No c99 comments, please.
> + if (clk_sel_val == 0x80) {
> + // clk_sel_val is DUMMY value -> Write the corresponding value to Clk_Select_Reg
Odd indentation.
> + // 0x01:30M, 0x02:96M, 0x05:External Clock
Ok, so here's the comment I asked for earlier. That should probably go
above the clock register defines, and/or with defines for these
constants added as well.
> + if (baudRate == 125000 || baudRate == 625000 || baudRate == 10000) {
> + clk_sel_val = 0x01;
> + } else if (baudRate == 153600 || baudRate == 225000 || baudRate == 403200 ||
> + baudRate == 2000000 || baudRate == 6000000) {
> + clk_sel_val = 0x02;
> + } else {
> + clk_sel_val = 0x05; // externel clk for custom case.
> + }
This needs to be cleaned up using a lookup table and a clk_sel enum.
If there are product that would benefit from using the external clock
input, this would need to be handled on a per-device basis so that we
know its frequency.
> + // needs to set clock source through
> + // Clk_Select_Reg1(offset 0x13) & Clk_Select_Reg2(offset 0x14)
> + // Clk_Select_Reg1 for port1,2 Clk_Select_Reg2 for port3,4
> + if (mos7840_port->port_num <= 2) {
> + status = mos7840_get_reg_sync(port, CLOCK_SELECT_REG1, &Data);
> + if (status < 0) {
> + dev_dbg(&port->dev, "reading Clk_Select_Reg failed in set_serial_baud\n");
Looks like the driver is currently using dev_dbg() for errors, but this
should most likely be dev_err() throughout. No need to say in which
function it fails, just
failed to read clock select register: %d\n
or similar should do.
> + return -1;
> + }
> + if (mos7840_port->port_num == 1) {
> + Data = (Data & 0xf8) | clk_sel_val;
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG1, Data);
> + } else if (mos7840_port->port_num == 2) {
> + Data = (Data & 0xc7) | (clk_sel_val<<3);
Spaces around binary operator throughout.
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG1, Data);
> + }
> + if (status < 0) {
> + dev_dbg(&port->dev, "setting Clk_Select_Reg failed\n");
> + return -1;
> + }
> + } else if (mos7840_port->port_num <= 4) {
> + status = mos7840_get_reg_sync(port, CLOCK_SELECT_REG2, &Data);
> + if (status < 0) {
> + dev_dbg(&port->dev, "reading Clk_Select_Reg failed in set_serial_baud\n");
> + return -1;
> + }
> + if (mos7840_port->port_num == 3) {
> + Data = (Data & 0xf8) | clk_sel_val;
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG2, Data);
> + } else if (mos7840_port->port_num == 4) {
> + Data = (Data & 0xc7) | (clk_sel_val<<3);
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG2, Data);
> + }
> + if (status < 0) {
> + dev_dbg(&port->dev, "setting Clk_Select_Reg failed\n");
> + return -1;
> + }
> + }
The above needs to be cleaned up and abstracted better too. It's hardly
readable currently and the patterns looks too similar to be repeated
like this (i.e. a helper function may be the right choice).
> + } else {
> + // clk_sel_val is not DUMMY value -> Write the corresponding value to SP_Reg
> +
> + /* First, needs to write default value to
> + * Clk_Select_Reg1(offset 0x13) & Clk_Select_Reg2(offset 0x14)
> + * Clk_Select_Reg1 for port1,2 Clk_Select_Reg2 for port3,4
> + */
> + if (mos7840_port->port_num <= 2) {
> + status = mos7840_get_reg_sync(port, CLOCK_SELECT_REG1, &Data);
> + if (status < 0) {
> + dev_dbg(&port->dev, "reading Clk_Select_Reg failed in set_serial_baud\n");
> + return -1;
> + }
> + if (mos7840_port->port_num == 1) {
> + Data = (Data & 0xf8) | 0x00;
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG1, Data);
> + } else if (mos7840_port->port_num == 2) {
> + Data = (Data & 0xc7) | (0x00<<3);
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG1, Data);
> + }
> + if (status < 0) {
> + dev_dbg(&port->dev, "setting Clk_Select_Reg failed\n");
> + return -1;
> + }
> + } else if (mos7840_port->port_num <= 4) {
> + status = mos7840_get_reg_sync(port, CLOCK_SELECT_REG2, &Data);
> + if (status < 0) {
> + dev_dbg(&port->dev, "reading Clk_Select_Reg failed in set_serial_baud\n");
> + return -1;
> + }
> + if (mos7840_port->port_num == 3) {
> + Data = (Data & 0xf8) | 0x00;
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG2, Data);
> + } else if (mos7840_port->port_num == 4) {
> + Data = (Data & 0xc7) | (0x00<<3);
> + status =
> + mos7840_set_reg_sync(port, CLOCK_SELECT_REG2, Data);
> + }
> + if (status < 0) {
> + dev_dbg(&port->dev, "setting Clk_Select_Reg failed\n");
> + return -1;
> + }
> + }
This is the same code as above, just writing the default value. This
obviously needs to be refactored.
> + // select clock source by writing clk_sel_val to SPx_Reg
> + status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
> + &Data);
> + if (status < 0) {
> + dev_dbg(&port->dev, "reading spreg failed in set_serial_baud\n");
> + return -1;
> + }
> + Data = (Data & 0x8f) | clk_sel_val;
> + status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset,
> + Data);
> + if (status < 0) {
> + dev_dbg(&port->dev, "Writing spreg failed in set_serial_baud\n");
> + return -1;
> + }
> + }
Johan
next prev parent reply other threads:[~2025-02-11 13:08 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-24 10:08 [PATCH 0/3] drivers: usb: serial: mos7840: Improved baud rate support Tony Chung
2024-10-24 10:09 ` [PATCH 1/3] drivers: usb: serial: mos7840: Add defines for clock select register offset Tony Chung
2025-02-11 9:44 ` Johan Hovold
2024-10-24 10:09 ` [PATCH 2/3] drivers: usb: serial: mos7840: added optimized register setups for common baudrates Tony Chung
2025-02-11 10:16 ` Johan Hovold
2024-10-24 10:09 ` [PATCH 3/3] driver: usb: serial: mos7840: add more baudrate options Tony Chung
2025-02-11 13:08 ` Johan Hovold [this message]
2025-02-11 9:41 ` [PATCH 0/3] drivers: usb: serial: mos7840: Improved baud rate support Johan Hovold
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z6tLuiw7eK5s4Agq@hovoldconsulting.com \
--to=johan@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=tony467913@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox