1 year ago

#354015

test-img

kwisatz

Writing a device tree (dts) overlay for an enc28j60 chip on the amlogic meson g12a platform

I need to write a .dts overlay file to use a Microchip enc28j60 on a Radxa Zero, which is an Amlogic Meson G12A platform via SPI. The kernel I'm using is 5.10 from radxa.

Starting from having absolutely no idea what I was doing, I have ended up with the following overlay:

/dts-v1/;
/plugin/;

#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>

&spicc1 {
    // spicc1 defined in meson-g12-common.dtsi

    // See meson-g12a-spi-spidev.dts
    pinctrl-0 = <&spicc1_pins &spicc1_ss0_pins>;
    pinctrl-names = "default";
    // handled by `param_spidev_spi_bus` and meson-fixup.scr-cmd for the spi-spidev overlay
    status = "okay";

    #address-cells = <1>;
    #size-cells = <0>;

    eth1: enc28j60@0 {
        compatible = "microchip,enc28j60";
        reg = <0>;  /* for spi, this defines the chipselect */
        /**
         * gpio_int has interrupts-cells = <2>
         *
         * How does this distinguish between e.g. GPIOAO_4 on the first chip and GPIOZ_4 on the second ?!
         */
        interrupt-parent = <&gpio_intc>;
        interrupts = <GPIOX_8 IRQ_TYPE_EDGE_FALLING>;

        // causes "enc28j60 spi1.0: there is not valid maps for state default"
        pinctrl-0 = <&enc28j60_int_pin>;
        pinctrl-names = "default";

        spi-max-frequency = <12000000>;
        status = "okay";
        debug = <1>;
    };
};

// See meson-g12-common.dtsi
// I think what happens here is that we define this pin as the interrupt pin (something must
// tell the chip that we want this pin to receive interrupts) and then "interrupts" in &eth1
// actually uses it
&periphs_pinctrl {
    enc28j60_int_pin: enc28j60_int_pin@0 {
        amlogic,pins = <&gpio GPIOX_8>;
        amlogic,function = <0>; /* in */
        amlogic,pull = <IRQ_TYPE_NONE>;
    };
};

// Not entirely sure this is correct, but I haven't found any other way to do this
// and this compiles
/ {
    __overrides__ {
        irq   = <&eth1>, "interrupts:0", <&enc28j60_int_pin>, "brcm,pins:0";
        speed = <&eth1>, "spi-max-frequency:0";
    };
};

The result of my efforts, unfortunately is still a non-functioning enc28j60 driver:

[    3.882872] enc28j60 spi1.0: there is not valid maps for state default
[    3.884022] enc28j60 spi1.0: Ethernet driver 1.02 loaded
[    3.896540] enc28j60 spi1.0: chip not found
[    3.896686] enc28j60: probe of spi1.0 failed with error -5

I have documented the entire process and progress (or lack thereof) on the Radxa Community Forums.

What I would need to progress are either information (but I'll gladly accept answers to all of the questions ;)):

  1. How to put the kernel and driver into debug mode so that I can see more detailed information than what dmesg is outputting above.
  2. How to verify what I am trying to do with the interrupt pin is correct and making sense. (I have found similar examples for other platforms [tegra, brcm], but for the meson chips, pinctrl seems to be entirely done as part of the kernel driver code, not as a device tree).

embedded

embedded-linux

spi

device-tree

soc

0 Answers

Your Answer

Accepted video resources