Skip to content
Advertisement

Linux loading i2c drivers

I have linux 4.4 on my board. I also have two i2c devices with their driver. When I connect first device to board – i see in dmesg that _probe function called. When I don’t connect any device to board – in dmesg i don’t see _probe function. When I connect second device – in dmesg i don’t see _probe function. But I want to see it. If I use i2cdetect tool i see correct device addresses. Field .detect in driver don’t used. I want to see _probe function in dmesg with second device or without devices.

How linux check connected i2c devices and how it choose will driver load or not?

This my device tree:

    i2c@546c0000 {
        #address-cells = <0x1>;
        #size-cells = <0x0>;
        compatible = "nvidia,tegra210-vii2c";
        reg = <0x0 0x546c0000 0x0 0x34000>;
        iommus = <0x52 0x12>;
        interrupts = <0x0 0x11 0x4>;
        scl-gpio = <0x7b 0x92 0x0>;
        sda-gpio = <0x7b 0x93 0x0>;
        status = "okay";
        clocks = <0x41 0xd0 0x41 0x51 0x41 0x1c>;
        clock-names = "vii2c", "i2cslow", "host1x";
        resets = <0x41 0xd0>;
        reset-names = "vii2c";
        clock-frequency = <0x61a80>;
        bus-pullup-supply = <0x69>;
        avdd_dsi_csi-supply = <0x67>;
        linux,phandle = <0xe0>;
        phandle = <0xe0>;

        newname_c@30 {
            compatible = "nvidia,newname";
            reg = <0x30>;
            devnode = "video0";
            physical_w = "3.674";
            physical_h = "2.738";
            vertical-flip = "true";
            avdd-reg = "vana";
            iovdd-reg = "vif";
            clocks = <0x41 0x117>;
            clock-names = "clk_out_3";
            clock-frequency = <0x16e3600>;
            mclk = "clk_out_3";
            reset-gpios = <0x7b 0x94 0x0>;
            pwdn-gpios = <0x7b 0x97 0x0>;
            vana-supply = <0x94>;
            vif-supply = <0x93>;
            status = "okay";
            linux,phandle = <0xe1>;
            phandle = <0xe1>;

Advertisement

Answer

During he boot process, when the kernel parses the device tree and reaches your device node, it will look for any driver with an of_match_table whose one of the compatible entries match your node’s compatible property. Each matched driver will be loaded, its probe function will be run and given a suitable struct i2c_client structure as parameter, according to (and containing) elements you specified in your node (I skipped the details). So to answer to your question, Linux (the I2C core actually) does not check any connected i2c device. The corresponding device driver does (in the probe function generally, usually by reading a register whose value is known in advance). This is why you have to declare your device in advance. Have a look here for details on devices and drivers matching, as well as module auto-loading.

First, try to make sure the support of your driver has been enabled in the kernel config using the below command:

zcat /proc/config.gz | grep <your_driver_kconfig_option>

You should see something ending with =y or =m. Now, back to your issue, there are several reasons why this may not work:

  • Your driver is not built or not installed (if built as module)
  • The driver does not have this compatible entry in its of_match_table. You can try a match with the driver’s name (the compatible value of your node should be the same as i2c_driver.driver.mame element in the driver code). This is not clean but may help.

PS: If the /proc/config.gz file does not exist, run modprobe configs command first.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement