Michael_Y
Michael_Y

Reputation: 43

How do I add a proper description of the spi bus in DTS?

I have a project, where there is a main board with CPU and a daughter board with two e-metering chips, connected to main board with SPI bus. CPU acts as a controller for this bus, it runs on Linux, ARM architecture.

I've been tasked to write a driver (builtin kernel module) for this daughter board, but I have very limited practical experience with SPI linux drivers. This picture shows how my architecture looks. The issue is that different CPU gpios act as Chipselect for each e-meter chip, other "wires" are shared. GPIOS cannot be changed, they are depicted as they are present in schematics.

In Linux spi API, struct spi_device has a cs_gpio field, but no other fields describing miso/mosi/rst and other gpios, so I guess I have to add a proper description of the spi bus in DTS. The question is how to do it correctly? Unfortunately, I can't find a proper dts description, or full description of it's fields I may need. The fact that there are two chips makes it even harder :(

Note, that each chip measurements should be written in different sysfs attributes, as they measure electricity from different power lines. This should be implemented in a single driver, so it can't be instantiated twice for each chip, it should run for both of them, not like in this post answers.

I started by implementing a simple spi driver, but I have no idea what values should be in struct spi_board_info chip_select and bus_num fields, and in struct spi_device there is only cs_gpio field, and no fields for describing mosi/miso/rst/sck lines (gpios).

To sum this up, can you please guide me how to write a dts for my daughter board and spi bus, or tell how to instantiate in a driver / dts that spi bus wires are controlled by the exact gpios?

Upvotes: 1

Views: 368

Answers (1)

Michael_Y
Michael_Y

Reputation: 43

So thanks to @IanAbbott I found out about spi-gpio driver in Linux (src), and device tree binding description here.

So this is a proper device tree:

spi-gpio {
    compatible = "spi-gpio";
    #address-cells = <0x1>;
    ranges;
    status = "okay";

    sck-gpios   = <&pio 4 9 GPIO_ACTIVE_HIGH>;  // PE9
    mosi-gpios  = <&pio 4 6 GPIO_ACTIVE_HIGH>;  // PE6
    miso-gpios  = <&pio 4 8 GPIO_ACTIVE_HIGH>;  // PE8
    cs-gpios    = <&pio 4 4 GPIO_ACTIVE_HIGH>,  // PE4
                  <&pio 4 17 GPIO_ACTIVE_HIGH>; // PE17
    num-chipselects = <2>;

    /* Clients */
    m90e32@0 {
        reg = <0>;
        compatible = "atmel,m90e32";
        spi-max-frequency = <950000>;
    };

    m90e32@1 {
        reg = <1>;
        compatible = "atmel,m90e32";
        spi-max-frequency = <950000>;
    };
};

The idea is to use spi-gpio driver to communicate with e-meter chips, it can be done via spidev in userspace or in a different kernel module. More info in my other question.

Upvotes: 0

Related Questions