OpenNuvoton / NUC970_Linux_Kernel

Linux Kernel Source Code for NUC970 Series Microprocessor
Other
68 stars 69 forks source link

SPI clock bug: Can't set two speed on the same bus with different chipselect. #35

Closed qianfan-Zhao closed 5 years ago

qianfan-Zhao commented 5 years ago

I had connected two device on the same spi bus and they use different chipselect.

One is MODE0 and another is MODE3.

spi1: spi1@b8006300 {
    status = "okay";
    #address-cells = <1>;
    #size-cells = <0>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_spi1_cs0_cs1>;
    sleep = <3>;

    spidev0@0 {
        compatible = "rohm,dh2228fv";
        spi-max-frequency = <3000000>;
        reg = <0>;
        spi-cpha;
    };

    spidev1@1 {
        compatible = "rohm,dh2228fv";
        spi-max-frequency = <10000000>;
        reg = <1>;
        spi-cpol;
        spi-cpha;
    };
};

Write 1K random data from the spi bus and dump them by using logic analysis:

dd if=/dev/urandom of=/dev/spidev0.1 bs=1K count=1; dd if=/dev/urandom of=/dev/spidev0.0 bs=1K count=1

The datas come first is in MODE3 and speed is 9.52MHz, after that is MODE0 and speed is 9.52MHz (should be 3MHz).

qianfan-Zhao commented 5 years ago

Resolution:

diff --git a/drivers/spi/spi-nuc970-p0.c b/drivers/spi/spi-nuc970-p0.c
index 531c8281ec6..8dbc875c376 100644
--- a/drivers/spi/spi-nuc970-p0.c
+++ b/drivers/spi/spi-nuc970-p0.c
@@ -445,6 +445,7 @@ static int nuc970_spi0_setupxfer(struct spi_device *spi,
    if (ret)
        return ret;

+   nuc970_set_divider(hw);
    nuc970_spi0_setup_txbitlen(hw, hw->pdata->txbitlen);
    nuc970_tx_edge(hw, hw->pdata->txneg);
    nuc970_rx_edge(hw, hw->pdata->rxneg);
diff --git a/drivers/spi/spi-nuc970-p1.c b/drivers/spi/spi-nuc970-p1.c
index 9885dbb6c6c..47a0dfddbb7 100644
--- a/drivers/spi/spi-nuc970-p1.c
+++ b/drivers/spi/spi-nuc970-p1.c
@@ -445,6 +445,7 @@ static int nuc970_spi1_setupxfer(struct spi_device *spi,
    if (ret)
        return ret;

+   nuc970_set_divider(hw);
    nuc970_spi1_setup_txbitlen(hw, hw->pdata->txbitlen);
    nuc970_tx_edge(hw, hw->pdata->txneg);
    nuc970_rx_edge(hw, hw->pdata->rxneg);
yachen commented 5 years ago

Fixed in 329f50237a85e801f39814c7392269504dd94efe, thanks.