This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3352: McSPI chip-select issue

Part Number: AM3352

Tool/software: Linux

Hi Sir 

We used TI SDK 2.02 for development and want to use SPI interface with two CS pins.

attachment is the device tree

  1 spi0_pins: pinmux_spi0 {
  2     pinctrl-single,pins = <
  3         0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */
  4         0x15C (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
  5         0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */
  6         0x158 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
  7         0x160 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs1.spi0_cs1 */
  8     >;
  9 };
10
11
12 /* SPI Busses */
13 &spi0 {
14     status = "okay";
15     pinctrl-names = "default";
16     pinctrl-0 = <&spi0_pins>;
17
18     m25p80@0 {
19         compatible = "mx25l6405d";
20         spi-max-frequency = <40000000>;
21
22         reg = <0>;
23         spi-cpol;
24         spi-cpha;
25         #address-cells = <1>;
26         #size-cells = <1>;
27
28         /* reg : The partition's offset and size within the mtd bank. */
29         partitions@0 {
30             label = "MLO";
31             reg = <0x0 0x80000>;
32         };
33
34         partitions@1 {
35             label = "U-Boot";
36             reg = <0x80000 0x100000>;
37         };
38
39         partitions@2 {
40             label = "U-Boot Env";
41             reg = <0x180000 0x20000>;
42         };
43
44     };
45
46     tpm_spi_tis@1{
47         compatible = "infineon,slb9670";
48         reg = <1>;  /* CE1 */
49         spi-max-frequency = <500000>;
50     };
51
52 };

we found some issues while using SPI interface. 

a. chip select 0 -> connect to device A

b. chip select 1 -> connect to device B

when we want to read the device ID of device B 

               1. CS1 will active low while sending data ->  ok 

               2. CS0 is always low  -> NG

Do you have any suggestion about this issue and thanks for your help.

BR

Yimin

  1 spi0_pins: pinmux_spi0 {
  2     pinctrl-single,pins = <
  3         0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */
  4         0x15C (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
  5         0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */
  6         0x158 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
  7         0x160 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs1.spi0_cs1 */
  8     >;
  9 };
10
11
12 /* SPI Busses */
13 &spi0 {
14     status = "okay";
15     pinctrl-names = "default";
16     pinctrl-0 = <&spi0_pins>;
17
18     m25p80@0 {
19         compatible = "mx25l6405d";
20         spi-max-frequency = <40000000>;
21
22         reg = <0>;
23         spi-cpol;
24         spi-cpha;
25         #address-cells = <1>;
26         #size-cells = <1>;
27
28         /* reg : The partition's offset and size within the mtd bank. */
29         partitions@0 {
30             label = "MLO";
31             reg = <0x0 0x80000>;
32         };
33
34         partitions@1 {
35             label = "U-Boot";
36             reg = <0x80000 0x100000>;
37         };
38
39         partitions@2 {
40             label = "U-Boot Env";
41             reg = <0x180000 0x20000>;
42         };
43
44     };
45
46     tpm_spi_tis@1{
47         compatible = "infineon,slb9670";
48         reg = <1>;  /* CE1 */
49         spi-max-frequency = <500000>;
50     };
51

52 };

  • Hi Sir

    it is workaround for uboot.

    BTW, we found this issue in kernel section.

    Do you have any suggestion ?

    thanks

    BR
    Yimin
  • Have you tried using the same approach: setting the EPOL bit in the chconf registers after a reset.
  • Hi SIr

    thanks for your reply.

    Could you offer the example code of kernel to us for reference ?

    BR
    Yimin
  • Yimin,

    Here is a patch that I have applied to our Linux kernel to address this issue. It is for linux-processor-sdk-3.14. It requires that all SPI chip-selects on a SPI bus must all be active-low polarity.

    I hope that it also works for you.

    Configure all SPI chip-selects to active-low in the Linux SPI driver for
    Sitara.
    
    When the SPI peripheral is reset, all SPI chip-selects on the bus become
    configured as active-high. When a SPI device is first accessed, its specific
    chip-select polarity will be properly configured, but the other chip-selects
    on the same bus may not have been configured yet. If these other chip-selects
    are actually active-low, the SPI access can cause multiple active-low
    chip-select signals to be asserted.
    
    To eliminate this issue, configure _all_ chip-selects on the bus as active-low
    when the SPI peripheral is configured as a master. The limitation is that no
    active-high chip-slects can be supported - _all_ SPI devices must use the
    active-low chip-select polarity.
    
    NOTE: This change requires that _all_ devices on the SPI bus _must_ use
    active-low chip-select polarity. Active-high chip-selects are no longer
    supported.
    
    
    --- a/drivers/spi/spi-omap2-mcspi.c	2016-01-06 09:52:40.742535425 -0800
    +++ b/drivers/spi/spi-omap2-mcspi.c	2016-01-07 16:19:24.148534128 -0800
    @@ -257,6 +257,8 @@ static void omap2_mcspi_set_master_mode(
     	struct omap2_mcspi	*mcspi = spi_master_get_devdata(master);
     	struct omap2_mcspi_regs	*ctx = &mcspi->ctx;
     	u32 l;
    +	int i;
    +	u32 chconf;
     
     	/*
     	 * Setup when switching from (reset default) slave mode
    @@ -268,6 +270,19 @@ static void omap2_mcspi_set_master_mode(
     	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
     
     	ctx->modulctrl = l;
    +
    +	/*
    +	 * Configure all chip-selects on this bus to active-low
    +	 *
    +	 * NOTE: This requires that _all_ devices on the SPI bus _must_ use
    +	 * active-low chip-selects. Active-high chip-selects are not supported!
    +	 */
    +	for (i = 0; i < master->num_chipselect; i++)
    +	{
    +		chconf = mcspi_read_reg(master, OMAP2_MCSPI_CHCONF0 + (i * 0x14));
    +		chconf |= OMAP2_MCSPI_CHCONF_EPOL;
    +		mcspi_write_reg(master, OMAP2_MCSPI_CHCONF0 + (i * 0x14), chconf);
    +	}
     }
     
     static void omap2_mcspi_set_fifo(const struct spi_device *spi,
    @@ -976,7 +991,8 @@ static int omap2_mcspi_setup(struct spi_
     		cs->base = mcspi->base + spi->chip_select * 0x14;
     		cs->phys = mcspi->phys + spi->chip_select * 0x14;
     		cs->mode = 0;
    -		cs->chconf0 = 0;
    +		/* Configure chip-select as active-low */
    +		cs->chconf0 = OMAP2_MCSPI_CHCONF_EPOL;
     		spi->controller_state = cs;
     		/* Link this to context save list */
     		list_add_tail(&cs->node, &ctx->cs);
    

  • Hi Sir

    thanks for you help.

    BTW, we also found some patches in kernel 4.4 for spi-omap2-mcspi.c which can fixed this issue.

    BR
    Yimin