I’ll post updates to this comment as I make progress (or not).
March 23rd
I’ve been reading through multiple other examples as well as through meson-g12a-radxa-zero.dts
and I can’t really figure out what needs to go where. None of the terms used make any sense to me, nor do the values.
There are not enough examples of other peripherals for the radxa using SPI for me to infer what needs to go where unfortunately.
How does one get an understanding of this? How would I know which values even exist for e.g. interrupt-parent
? What do 25
and 0x2
mean in the context of interrupts
and is that something Raspberry-Pi specific or not? I.e. I would think that the value that should go there would be something related to GPIOC_7
since that’s the pin on the radxa board that leads to the INT
pin on the enc28j60
board.
I’ll take a step back and try to learn the basics on device trees, etc. Still help would be appreciated since I’m under some time pressure and any help will save me some sleep and hair.
But of course, it would be preferable to get the kernel build to include it in its build somehow…
Got that figured out from Thomas’ video. The path to the file goes into arch/ar4/boot/dts/amlogic/overlay/Makefile
.
March 24th
Noon
Have watched more of Thomas Petazzoni’s talks… I have now switched from the fragment
-based syntax for overlays to the &reference
-based one as recommended by this Google guide for Android.
The resulting dts
file now looks like this:
/dts-v1/;
/plugin/;
&spicc1 {
#address-cells = <1>;
#size-cells = <0>;
eth1: enc28j60@0 {
compatible = "microchip,enc28j60";
reg = <0>; /* for spi, this defines the chipselect */
interrupt-parent = <&gpio_intc>;
interrupts = <25 0x2>; /* gpio_int has #interrupts-cell = <2>, falling edge */
spi-max-frequency = <12000000>;
status = "okay";
};
};
I have also read through the dtsi
file common to all meson platforms (arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
), learning in the process that gpio_intc
is an interrupt-controller
on cbus: bus@ffd00000
.
spicc1_pins
however are defined below apb: bus@ff600000
> periphs: bus@34400
> periphs_pinctrl
> gpio
.
In any case, this heavily simplified dtbo
results in the following dmesg
output:
[ 3.877628] enc28j60 spi1.0: Ethernet driver 1.02 loaded
[ 3.883065] enc28j60 spi1.0: chip not found
[ 3.884736] enc28j60: probe of spi1.0 failed with error -5
Afternoon
I believe this to be the correct interrupt configuration for my case (having wired the enc28j60
to SPI_B (pins 19, 21, 23, 25 and pin 22 as INT
)):
/dts-v1/;
/plugin/;
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
&spicc1 {
#address-cells = <1>;
#size-cells = <0>;
eth1: enc28j60@0 {
compatible = "microchip,enc28j60";
reg = <0>; /* for spi, this defines the chipselect */
interrupt-parent = <&gpio_intc>;
/* gpio_int has interrupts-cell = <2>, falling edge */
interrupts = <GPIOC_7 IRQ_TYPE_EDGE_FALLING>; // GPIOC_7
spi-max-frequency = <12000000>;
status = "okay";
};
};
Nothing has changed about the output of dmesg
for far, but I believe I am missing the pinctrl-0
stuff.
March 25th, 5pm
The dts has evolved a bit since I have changed the interrupt pin from pin 22 (GPIOC_7
) to pin 28 (GPIOAO_2
) given that pin 22 in an open drain
as @linuxlion wrote. The file now looks like this:
/dts-v1/;
/plugin/;
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
&spicc1 {
#address-cells = <1>;
#size-cells = <0>;
eth1: enc28j60@0 {
compatible = "microchip,enc28j60";
reg = <0>; /* for spi, this defines the chipselect */
interrupt-parent = <&gpio_intc>;
/**
* gpio_int has interrupts-cells = <2>
* Pin#22 (GPIOC_7) and Pin#36 (GPIOH_8) are open drain pins.
* This means for input they need to connected to either GND or VCC (floating state is undefined),
* for output they will need external pull up
*/
// interrupts = <GPIOC_7 IRQ_TYPE_EDGE_FALLING>; // <48, 2>
interrupts = <GPIOAO_2 IRQ_TYPE_EDGE_FALLING>; // <2, 2>
pinctrl-names = "default";
//pinctrl-0 = <&spicc1_pins &spicc1_ss0_pins>;
pinctrl-0 = <&enc28j60_pins>;
spi-max-frequency = <12000000>;
status = "okay";
};
};
// Targetting gpio, which is a node of periphs (periphs_pinctrl)
&gpio {
enc28j60_pins: enc28j60_pins@0 {
amlogic,pins = <GPIOAO_2>;
amlogic,function = <0>; /* in */
amlogic,pull = <IRQ_TYPE_NONE>;
};
};
The status however is still the same as yesterday morning:
[ 3.932714] enc28j60 spi1.0: Ethernet driver 1.02 loaded
[ 3.955366] enc28j60 spi1.0: chip not found
[ 3.955544] enc28j60: probe of spi1.0 failed with error -5
March 25th, 7pm
I have found some mistakes in the dts
and I have finally managed to at least get pinctrl
to what I need. The dts
now looks like this:
/dts-v1/;
/plugin/;
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
&spicc1 {
// See meson-g12a-spi-spidev.dts
pinctrl-0 = <&spicc1_pins &spicc1_ss0_pins>;
pinctrl-names = "default";
status = "okay";
// spicc1 defined in meson-g12-common.dtsi
#address-cells = <1>;
#size-cells = <0>;
eth1: enc28j60@0 {
compatible = "microchip,enc28j60";
reg = <0>; /* for spi, this defines the chipselect */
interrupt-parent = <&gpio_intc>;
/**
* gpio_int has interrupts-cells = <2>
* Pin#22 (GPIOC_7) and Pin#36 (GPIOH_8) are open drain pins.
* This means for input they need to connected to either GND or VCC (floating state is undefined),
* for output they will need external pull up.
How does this distinguish between e.g. GPIOAO_4 on the first chip and GPIOZ_4 on the second ?!
*/
// interrupts = <GPIOC_7 IRQ_TYPE_EDGE_FALLING>; // <48, 2>
// interrupts = <GPIOAO_2 IRQ_TYPE_EDGE_FALLING>; // <2, 2>
interrupts = <GPIOAO_4 IRQ_TYPE_EDGE_FALLING>; // <4, 2>
pinctrl-0 = <&enc28j60_pins>;
pinctrl-names = "default";
spi-max-frequency = <12000000>;
status = "okay";
};
};
// See meson-g12-common.dtsi
&periphs_pinctrl {
enc28j60_pins: enc28j60_pins@0 {
amlogic,pins = <GPIOAO_4>;
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__ {
int_pin = <ð1>, "interrupts:0",
<&enc28j60_pins>, "brcm,pins:0";
speed = <ð1>, "spi-max-frequency:0";
};
};
The state of the enc28j60 is almost unchanged, except for the fact that it now states that some default state is not properly mapped (I assume this refers to pinctrl-0
on the enc28j6@0
node):
[ 3.901038] enc28j60 spi1.0: there is not valid maps for state default
[ 3.902188] enc28j60 spi1.0: Ethernet driver 1.02 loaded
[ 3.947474] enc28j60 spi1.0: chip not found
[ 3.947564] enc28j60: probe of spi1.0 failed with error -5
And, as mentioned before, pinctrl
handles now feature:
[…]
device: ffd15000.spi current state: default
state: default
type: MUX_GROUP controller pinctrl-meson group: spi1_mosi (262) function: spi1 (4)
type: CONFIGS_GROUP controller pinctrl-meson group spi1_mosi (262)config 000fa00a
type: MUX_GROUP controller pinctrl-meson group: spi1_miso (263) function: spi1 (4)
type: CONFIGS_GROUP controller pinctrl-meson group spi1_miso (263)config 000fa00a
type: MUX_GROUP controller pinctrl-meson group: spi1_clk (265) function: spi1 (4)
type: CONFIGS_GROUP controller pinctrl-meson group spi1_clk (265)config 000fa00a
type: MUX_GROUP controller pinctrl-meson group: spi1_ss0 (264) function: spi1 (4)
type: CONFIGS_GROUP controller pinctrl-meson group spi1_ss0 (264)config 00000001
[…]
March 25th, 8:30pm
No progress. Just for fun, I connected a second enc28j60
to SPI-A
with the exact same result:
[ 3.892814] enc28j60 spi0.0: Ethernet driver 1.02 loaded
[ 3.902207] enc28j60 spi0.0: chip not found
[ 3.902642] enc28j60: probe of spi0.0 failed with error -5
[ 3.906838] enc28j60 spi1.0: Ethernet driver 1.02 loaded
[ 3.925501] enc28j60 spi1.0: chip not found
[ 3.925591] enc28j60: probe of spi1.0 failed with error -5