Good evening,
I have MFRC522 card reader. It works well with generic spidev
kernel-level driver and high-level python driver. However, as I wanted to learn device trees in linux, I tried to bind kernel-level driver for this chip I found on the internet to this SPI interface in DT.
The driver I want to use -- https://github.com/ks0n/mfrc522-linux
Here's the fragment of the original DT (decompiled /boot/bcm2708-rpi-zero-w.dtb):
spi@7e204000 {
compatible = "brcm,bcm2835-spi";
reg = < 0x7e204000 0x200 >;
interrupts = < 0x02 0x16 >;
clocks = < 0x08 0x14 >;
#address-cells = < 0x01 >;
#size-cells = < 0x00 >;
status = "disabled";
dmas = < 0x09 0x06 0x09 0x07 >;
dma-names = "tx\0rx";
pinctrl-names = "default";
pinctrl-0 = < 0x0c 0x0d >;
cs-gpios = < 0x07 0x08 0x01 0x07 0x07 0x01 >;
phandle = < 0x1e >;
spidev@0 {
compatible = "spidev";
reg = < 0x00 >;
#address-cells = < 0x01 >;
#size-cells = < 0x00 >;
spi-max-frequency = < 0x7735940 >;
phandle = < 0x5e >;
};
spidev@1 {
compatible = "spidev";
reg = < 0x01 >;
#address-cells = < 0x01 >;
#size-cells = < 0x00 >;
spi-max-frequency = < 0x7735940 >;
phandle = < 0x5f >;
};
};
Comment: status property is changed from "disabled" to "enabled" in rpi's /boot/config.txt
Here's this same fragment of my modified DT:
spi@7e204000 {
compatible = "brcm,bcm2835-spi";
reg = < 0x7e204000 0x200 >;
interrupts = < 0x02 0x16 >;
clocks = < 0x08 0x14 >;
#address-cells = < 0x01 >;
#size-cells = < 0x00 >;
status = "disabled";
dmas = < 0x0b 0x06 0x0b 0x07 >;
dma-names = "tx\0rx";
pinctrl-names = "default";
pinctrl-0 = < 0x0e 0x0f >;
cs-gpios = < 0x07 0x08 0x01 0x07 0x07 0x01 >;
phandle = < 0x22 >;
mfrc522@0 {
compatible = "mfrc522";
reg = < 0x00 >;
#address-cells = < 0x01 >;
#size-cells = < 0x00 >;
spi-max-frequency = < 0xf4240 >;
phandle = < 0x63 >;
};
spidev@1 {
compatible = "spidev";
reg = < 0x01 >;
#address-cells = < 0x01 >;
#size-cells = < 0x00 >;
spi-max-frequency = < 0x7735940 >;
phandle = < 0x64 >;
};
};
This is taken from generic example DT in mfrc522-linux
driver's repository -- https://github.com/ks0n/mfrc522-linux/blob/master/bcm2710-rpi-3-b-plus_mfrc522.dts
As you can see, the only things changed are max-frequency and assigned driver. spidev
driver worked with same configuration of this node, also I was able to read and write RFID cards using python high level driver.
So I think rest of the parameters should also work with mfrc522-linux
driver.
But this driver fails on probe. It fails with this message:
[ 1177.295068] mfrc522: loading out-of-tree module taints kernel.
[ 1177.296085] MFRC522 init
[ 1177.302900] [MFRC522] SPI Probed
[ 1177.311715] [MFRC522] this chip is not an MFRC522: 0x12
[ 1177.311764] mfrc522: probe of spi0.0 failed with error 1
Looking into the code I see that the driver is reading register 0x37 on mfrc522_spi.c:29. And it expects 0x90 or 0x91 (mfrc522_module.c:181).
It seems to be the correct behaviour. In the datasheet (https://pdf1.alldatasheet.com/datasheet-pdf/view/227840/NXP/RC522.html , point 9.2.4.8 VersionReg) I can see that the correct value of this register is either 90h or 91h.
But when I read value of this register on my system it's 12h. I changed the code of this driver to read this register's value a couple of times -- it's 12h each time.
I changed the driver to print some additional usefull values. Here's the output:
[ 1177.295068] mfrc522: loading out-of-tree module taints kernel.
[ 1177.296085] MFRC522 init
[ 1177.302900] [MFRC522] SPI Probed
[ 1177.311276] [MFRC522-ll] MFRC522 raw version 18
[ 1177.311415] [MFRC522-ll] MFRC522 AutoTestReg 64
[ 1177.311511] [MFRC522-ll] MFRC522 TCounterValReg high 0
[ 1177.311606] [MFRC522-ll] MFRC522 TModeReg 0
[ 1177.311700] [MFRC522-ll] MFRC522 TCounterValReg low 0
[ 1177.311715] [MFRC522] this chip is not an MFRC522: 0x12
[ 1177.311764] mfrc522: probe of spi0.0 failed with error 1
The other values seem to be correct (they agree with the datasheet). But I don't know why the value of version register is 12h on my system. Maybe the DT is misconfigured?