3

I would like to use the i2c_gpio software i2c kernel module because the broadcom hardware i2c does not support I2C_M_NOSTART. How do I do this?

I think that in order to do it I need to take the device tree config for i2c_gpio and turn it into a device tree fragment, then compile and load it. But I don't know how to rewrite the config as a fragment. Perhaps there is another, easier way.

5
  • Have you actually compiled and tried to use i2c-gpio.ko? It seems to build pretty easily.
    – goldilocks
    Oct 31, 2015 at 16:39
  • i2c-gpio is already built in the standard kernel modules. My question is how do you make it work? Loading it won't do anything without a configuration. Oct 31, 2015 at 17:24
  • Are you sure? It's not set in bcmrpi_defconfig, which is usually identical to the one spit out via proc from this kernel. Try modprobe configs; gunzip -c /proc/config.gz | grep I2C_GPIO. You probably get # CONFIG_I2C_GPIO is not set. Not that that helps much with using it, but you are one step closer. Or further away, lol.
    – goldilocks
    Oct 31, 2015 at 17:40
  • Yeah you're right, it's not in the default modules on raspbian. One more thing I need to sort out. Oct 31, 2015 at 17:44
  • Okay I have rebuilt the kernel with the module. As I expected it does absolutely nothing when loaded. Oct 31, 2015 at 20:48

1 Answer 1

5

As of June 2016 Raspbian already has the necessary modifications. You only need to enable the overlay in config.txt (step 6 onwards).

I finally got this working as follows:

  1. Rebuild the kernel with i2c_gpio module. You must edit the bcm2708_defconfig or bcmrpi_defconfig and add the line CONFIG_I2C_GPIO=m before running the make defconfig.
  2. Install kernel and modules using mkknlimg for device tree support as described in the kernel building docs.
  3. Convert the example i2c_gpio config to a device tree fragment as follows:

    // Overlay for i2c_gpio bitbanging host bus.
    /dts-v1/;
    /plugin/;
    
    / {
            compatible = "brcm,bcm2708";
    
            fragment@0 {
                    target-path = "/";
                    __overlay__ {
                            i2c_gpio: i2c@0 {
                                    compatible = "i2c-gpio";
                                    gpios = <&gpio 23 0 /* sda */
                                             &gpio 24 0 /* scl */
                                            >;
                                    i2c-gpio,delay-us = <2>; /* ~100 kHz */
                                    #address-cells = <1>;
                                    #size-cells = <0>;
                            };
                    };
            };
            __overrides__ {
                    i2c_gpio_sda = <&i2c_gpio>,"gpios:4";
                    i2c_gpio_scl = <&i2c_gpio>,"gpios:16";
                    i2c_gpio_delay_us = <&i2c_gpio>,"i2c-gpio,delay-us:0";
            };
    };
    
    • This will default to using gpio 23 and 24 for software i2c.
    • delay-us should be 2 for 100kHz operation.
    • The following lines should be removed because they will prevent the driver from working on Raspberry Pi: i2c-gpio,sda-open-drain; i2c-gpio,scl-open-drain;
  4. Build the device tree blob with dtc -@ -I dts -O dtb -o i2c-gpio.dtb i2c-gpio.dts

  5. Copy the blob to /boot/overlays/

  6. Add a line in /boot/config.txt dtoverlay=i2c-gpio

    If you want to use different pins, put dtoverlay=i2c-gpio,i2c_gpio_sda=<pin>,i2c_gpio_scl=<pin> instead. You can also change the rate with i2c_gpio_delay_us=<usecs>.

  7. Reboot.
  8. modprobe i2c-dev and you now should have /dev/i2c-3 in addition to any others you previously configured.
3
  • 1
    Good job. Could you edit your answer to clarify which line is the "open drain" one? As a matter of record you should be able to achieve the same I2C commands with my abyz.co.uk/rpi/pigpio/cif.html#bbI2CZip function.
    – joan
    Nov 1, 2015 at 9:48
  • Updated. I didn't know pigpio had that feature. I'm already using piscope and I2C_sniffer.py to watch the bus activity. It looks like I will need a user space implementation anyway because even i2c-gpio can't quite work with the buggy i2c device I am trying to control. Nov 1, 2015 at 19:21
  • It looks like Raspbian circa August 2016 has all of the tough work done as "i2c-gpio" is installed already. Steps 6-8 are really all that seem to be needed. Aug 28, 2016 at 5:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.