Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Arm drivers: are device tree descriptions required for every device?



I apologise for the length of this post but it does highlight some
anomalies in device detection.

I have struggled to understand the attachment of devices on buses such
as i2c and spi on arm soc's.

I understand the need to have an fdt entry so the kernel knows where
i2c or spi bus are located so it can address them. Taking for example a
Raspberry Pi zero there are two physically accessible i2c buses 
i2c@7e205000 and i2c@7e804000) and one spi bus at spi@7e204000. With
these entries in the fdt the kernel correctly attaches i2c1, i2c2 and
spi0. (Note there is also an extra i2c0 bus but this is inaccessible,
cannot be used and I have omitted it the examples below)

The fun starts when you add physical devices to these busses. If I
attach two bme280 sensors, both with base address 0x76, to i2c1 and
i2c2 then adding an appropriate line into /etc/modules.conf they are
automagically detected with a standard GENERIC kernel:

[   1.0000000] NetBSD 10.0_BETA (RPI) #0: Fri Mar 24 15:44:06 GMT 2023
...
[   1.0000000] bsciic1 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic1: interrupting on icu irq 53
[   1.0000000] iic1 at bsciic1: I2C bus
[   1.0000000] bsciic2 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic2: interrupting on icu irq 53
[   1.0000000] iic2 at bsciic2: I2C bus
...
Loading modules.
[   3.1312420] bmx280thp0 at iic1 addr 0x76
[   3.1713100] bmx280thp0: Bosch Sensortec BME280, Chip ID: 0x60
[   3.2027150] bmx280thp1 at iic2 addr 0x76
[   3.2427840] bmx280thp1: Bosch Sensortec BME280, Chip ID: 0x60

rpi# envstat
                 Current  CritMax  WarnMax  WarnMin  CritMin  Unit
[bmx280thp0]
  temperature:    19.560                                      degC
     pressure:   978.300                                       hPa
     humidity:    45.404                                       %rH
[bmx280thp1]
  temperature:    19.610                                      degC
     pressure:   978.680                                       hPa
     humidity:    45.103                                       %rH
[vcmbox0]
  temperature:    33.628   85.000                             degC

OK, so a module attach works fine and correctly finds the devices at
the known base address of 0x76 or 0x77.
What about configuring a kernel which explicitly has the devices listed
in the config so we don't have to use modules?  Add a line to the RPI
config:

bmx280thp* at iic? addr 0x76

Reboot with the new kernel and note:

[   1.0000000] NetBSD 10.0_BETA (RPI_SPI_I2C) #3: Sun Apr  2 22:24:21
BST 2023
...
[   1.0000000] bsciic1 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic1: interrupting on icu irq 53
[   1.0000000] iic1 at bsciic1: I2C bus
[   1.0000000] bsciic2 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic2: interrupting on icu irq 53
[   1.0000000] iic2 at bsciic2: I2C bus

No sensors found...

rpi# envstat
                 Current  CritMax  WarnMax  WarnMin  CritMin  Unit
[vcmbox0]
  temperature:    35.780   85.000                             degC

So that doesn't work!

However Brad Spenser <brad%anduin.elder.org@localhost> who wrote the
driver and has been very helpful suggested adding an overlay dtbo to
list the devices explicitly:

/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2835";

        fragment@1 {
                target-path = "/soc/i2c@7e205000";

                __overlay__ {
                        status = "okay";
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;
                        clock-frequency = <0x61a80>;

                        bmx280thp@76 {
                                compatible = "bosch,bmx280";
                                reg = <0x76>;
                        };

                };
        };

        fragment@2 {
                target-path = "/soc/i2c@7e804000";

                __overlay__ {
                        status = "okay";
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;
                        clock-frequency = <0x61a80>;

                        bmx280thp@76 {
                                compatible = "bosch,bmx280";
                                reg = <0x76>;
                        };

                };
        };
};

adding this to the boot config results in:

[   1.0000000] bsciic1 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic1: interrupting on icu irq 53
[   1.0000000] iic1 at bsciic1: I2C bus
[   1.0000000] bmx280thp0 at iic1 addr 0x76
[   1.0000000] bmx280thp0: Bosch Sensortec BME280, Chip ID: 0x60

[   1.0000000] bsciic2 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic2: interrupting on icu irq 53
[   1.0000000] iic2 at bsciic2: I2C bus
[   1.0000000] bmx280thp1 at iic2 addr 0x76
[   1.0000000] bmx280thp1: Failed to reset chip: 5
[   1.0000000] bmx280thp1: Bosch Sensortec BME280, Chip ID: 0x60
...

rpi# envstat
                 Current  CritMax  WarnMax  WarnMin  CritMin  Unit
[bmx280thp0]
  temperature:    19.930                                      degC
     pressure:   977.320                                       hPa
     humidity:    44.551                                       %rH
[bmx280thp1]
  temperature:    19.990                                      degC
     pressure:   977.630                                       hPa
     humidity:    44.610                                       %rH
[vcmbox0]
  temperature:    35.780   85.000                             degC

So that works now. Let's keep the same config but pull one of the
chips:

[     1.000000] iic1 at bsciic1: I2C bus
[     1.000000] bmx280thp0 at iic1 addr 0x76
[     1.000000] bmx280thp0: Bosch Sensortec BME280, Chip ID: 0x60
[     1.000000] bsciic2 at simplebus1: Broadcom Serial Controller
[     1.000000] bsciic2: interrupting on icu irq 53
[     1.000000] iic2 at bsciic2: I2C bus
[     1.000000] bmx280thp1 at iic2 addr 0x76
[     1.000000] bmx280thp1: autoconfiguration error: Failed to reset
chip: 5
[     1.000000] bmx280thp1: autoconfiguration error: Unable to setup
device

Well I guess that's expected, but it's a bit noisy! Certainly if you
used the module attach then there would be just one entry and no error
message.

So it would appear that module attach just works and probes the devices
OK, but using a static config needs extra work to explicitly list the
devices in the fdt hardware config. This doesn't seem right as its
duplicating info unnecessarily.

Just a final note - if you use a GENERIC kernel with the overlay loaded
then:

[   1.0000000] bsciic1 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic1: interrupting on icu irq 53
[   1.0000000] iic1 at bsciic1: I2C bus
[   1.0000000] bmx280thp (bosch,bmx280) at iic1 addr 0x76 not
configured
[   1.0000000] bsciic2 at simplebus1: Broadcom Serial Controller
[   1.0000000] bsciic2: interrupting on icu irq 53
[   1.0000000] iic2 at bsciic2: I2C bus
[   1.0000000] bmx280thp (bosch,bmx280) at iic2 addr 0x76 not
configured

this is not unexpected!

I think the moral of this story is there is some inconsistency here. I
understand the need for the fdt to list the physical buses together
with their attachment point, but it should not be necessary to list
the individual devices you ae going to put on the bus via an overlay.
The kernel config should have entries for any devices you want to use
together with their base address and they should be enumerated at boot
time.

Brad noted that spi attached devices don't work with the bme280x
modules - you need to specify the entry in the kernel config - I have
still to test this properly...

one final thing to note is that i2cscan (which is the subject of at
least one PR) is still broken, reporting multiple non-existent devices!

Dave


Home | Main Index | Thread Index | Old Index