Hi,
We have a MAX3107 we are using for RS485 and we have an external crystal.
The relevant parts of our drive tree overlay is:
...
...
uart_clk: xtal_max14830 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <3686400>;
};
...
...
uart2: max3107@0 {
compatible = "maxim,max3107";
reg = <0>;
clocks = <&uart_clk>;
clock-names = "xtal";
...
...
};
uart3: max3107@1 {
compatible = "maxim,max3107";
reg = <1>;
clocks = <&uart_clk>;
clock-names = "xtal";
...
...
When we use the driver as it comes, it appears and we can do what we
like with it's GPIOs, but it doesn't send or receive.
The only thing we see wrong in dmesg is "clock is not stable yet". So we
figured our problem was related to the clock.
Looking on a scope, nothing is transmitted when we try sending something
from Linux.
At line 579, in max310x_set_ref_clk, there is the line.
clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT;
The chip's datasheet (p43) states:
Bit 4: ClockEnSet the ClockEn bit high to enable an external clocking
(crystal or clock generator at XIN). Set the ClockEn bit to 0 to disable
clocking
Bit 1: CrystalEnSet the CrystalEn bit high to enable the crystal
oscillator. When using an external clock source at XIN, CrystalEn must
be set low.
So it sounds like with an external crystal, you also need bit 4,
MAX310X_CLKSRC_EXTCLK_BIT.
So shouldn't that line read:
clksrc = MAX310X_CLKSRC_EXTCLK_BIT | (xtal ? MAX310X_CLKSRC_CRYST_BIT : 0);
When we do that, we don't see "clock is not stable yet" in dmesg and our
data transmits.
Patch attached.
Regards,
Joe
commit 028b9a3692f27da5e5524489e834ba3bb477ff63
Author: Joe Burmeister <joe.burmeister@xxxxxxxxxxxxx>
Date: Mon Apr 1 12:03:51 2019 +0100
Fix external crystal register setup.
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 3db48fcd6068..73a144be3e2c 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -576,7 +576,7 @@ static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
}
/* Configure clock source */
- clksrc = xtal ? MAX310X_CLKSRC_CRYST_BIT : MAX310X_CLKSRC_EXTCLK_BIT;
+ clksrc = MAX310X_CLKSRC_EXTCLK_BIT | (xtal ? MAX310X_CLKSRC_CRYST_BIT : 0);
/* Configure PLL */
if (pllcfg) {