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.

  • Have you actually compiled and tried to use i2c-gpio.ko? It seems to build pretty easily. – goldilocks Oct 31 '15 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. – Alistair Buxton Oct 31 '15 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 '15 at 17:40
  • Yeah you're right, it's not in the default modules on raspbian. One more thing I need to sort out. – Alistair Buxton Oct 31 '15 at 17:44
  • Okay I have rebuilt the kernel with the module. As I expected it does absolutely nothing when loaded. – Alistair Buxton Oct 31 '15 at 20:48
up vote 4 down vote accepted

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.
  • 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 '15 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. – Alistair Buxton Nov 1 '15 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. – RandomInsano Aug 28 '16 at 5:39

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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