I2C Bit Banging Driver for LinkIt Smart 7688

I2C peripheral in LinkIt Smart 7688 works most of the cases. But it has some issues with devices that respond with NACK frequently. In such cases, you can replace the kernel driver that utilises internal I2C peripheral with a bitbanging driver that emulates I2C using GPIOs.

LinkIt Smart 7688 has most of the GPIOs allocated for peripherals such as I2C, SPI, UARTs. So let’s switch the ports allocated to I2C to GPIOs first. This can be done by directly manipulating the corresponding multiplexer.

Linux DEVMEN (/dev/mem) virtual driver allows this manipulation by exposing memory mapped port control registers. Run make menuconfig and select: Global build settings > Kernel build options > /dev/mem virtual device support.

This will create a /dev/mem driver at the target machine. You can write a simple script or you can use omega2-ctrl utility to control the multiplexers. Usage of the utility can be found here. What you want to is to set the GPIO4 pin and GPIO5 pin under the control of GPIO logic.

# omega2-ctrl gpiomux set i2c gpio

Nex, you need a set of drivers for the bitbanging of I2C. Run make menuconfig and select followings under Kernel modules > I2C support >

  • kmod-i2c-core
  • kmod-i2c-algo-bit
  • kmod-i2c-gpio
  • kmod-i2c-gpio-custom

Due to the dependencies, you choose the last one then all the others should follow. You can install them as separate kernel modules or you can select all the modules to be included in the kernel except the last one. You have to specify the GPIO pins for the I2C bitbanging by manually calling insmod

# insmod i2c-gpio-custom bus0=0,5,4

Note that actual driver (/dev/i2c-0) won’t be populated until the above driver is loaded. After that you can use i2cdetect command to check if it is actually working.