Search code examples
linuxlinux-device-driveracpi

How should I2C drivers be matched in ACPI with HID PRP0001


I am trying to instantiate this sensor in ACPI using device specific data, i.e., with Name (_DSD, ...) and with a compatible string, e.g., with the following ASL excerpt:

Device (TOF1) {
    Name (_HID, "PRP0001")
    Name (_DDN, "STMicroelectronics VL53L0X laser rangefinder")
    Name (_CRS, ResourceTemplate () {
        I2cSerialBus (
            0x29,
            ControllerInitiated,
            I2C_SPEED,
            AddressingMode7Bit,
            "\\_SB.PCI0.I2C1.MUX2.CH01",
            0x00,
            ResourceConsumer,,)
    })
    Name (_DSD, Package () {
        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
        Package () {
            Package () {"compatible", "st,vl53l0x"},
        }
    })
}

I was under the impression that if I specify my devices as I have in the above ASL, I would not need to modify the driver (e.g., by adding an ACPI match tables) and could match the device using the existing OF match table in the driver. However, this only seems partly true. The sensor fails to probe due to this check in the kernel in i2c-core-base.c:

if (!driver->id_table &&
    !i2c_acpi_match_device(dev->driver->acpi_match_table, client) &&
    !i2c_of_match_device(dev->driver->of_match_table, client))
    return -ENODEV;

My interpretation of this statement is that the device driver must either have (i) an ID table or (ii) a matching ACPI ID table or (iii) a matching OF ID table. The VL53L0X does not have an ID table nor a ACPI match table, so I am relying on matching using the OF table.

Now, there are two things that I am confused about here. Firstly, I can printk(KERN_ERR "%s", dev->driver->driver.name) and see that I am indeed already looking at the correct driver, so why exactly are we checking if the driver matches again?

Secondly, if i2c_of_match_device(dev->driver->of_match_table, client) is failing to match, what exactly was matched in the first place that resulted in being able to printk(KERN_ERR "%s", dev->driver->driver.name) and see the correct name of the driver?


Solution

  • Not really an answer to the question above, but one hack/work around for this problem is to just add the ID table to the driver.

    static const struct i2c_device_id vl53l0x_id[] = {
        { "vl53l0x", 0 },
        { }
    };
    MODULE_DEVICE_TABLE(i2c, vl53l0x_id);
    
    static struct i2c_driver vl53l0x_driver = {
        .driver = {
            .name = "vl53l0x-i2c",
            .of_match_table = st_vl53l0x_dt_match,
        },
        .probe_new = vl53l0x_probe,
        .id_table = vl53l0x_id,
    };
    module_i2c_driver(vl53l0x_driver);
    

    This results in the check in the question being skipped over. This isn't a great solution since the I2C ID table is not passed to probe_new, however, it does work for this driver since there is no further configuration to be done.

    It seems however that matching i2c devices like this is being deprecated as per the comments and patches around the introduction of probe_new.