I2C Support on the Balloon Board
Introduction
The I2C bus is a simple 2-wire serial bus developed by Philips (see [Philips Semiconductors website | http://www.semiconductors.philips.com/markets/mms/protocols/i2c/]).
There is no dedicated I2C hardware on the Balloon. However, two of the GPIO (General-Purpose I/O) lines on the board have been designated as I2C_DATA and I2C_CLOCK on the Balloon circuit diagrams and support for driving these lines as if they were an I2C master is provided in the Linux distributions available from http://husaberg.toby-churchill.com/.
GPIO Lines
GPIO 11 is used for the SDA line (Serial DAta) and GPIO 20 is used for SCL (Serial CLock). These appear on the Samtek ExpansionConnector at E4 and E22 repectively.
I2C Support Under Linux
Support for driving I2C bus masters is provided by the Linux 2.4 kernel. The Linux 2.6 kernel also has support reading the state of various devices that might be attached to the bus, and displaying them in /proc/bus/i2c.
I2C support is split between several modules:
- i2c-core.o
- Provides most generic I2C functionality
- i2c-proc.o
- Provides entries in /proc/bus/i2c for each I2C bus
- i2c-dev.o
- Provides user-space accesible device files for each bus in /dev
There are also modules that talk to specific hardware. These are split into algorithms and adapters. An Algorithm modules provides the code necessary for a specific type of hardware to produce I2C protocol compatible messages, and an Adapter modules knows how to talk to a specific peice of hardware.
On the Balloon Board the two modules used are:
- i2c-algo-bit.o
The bit-bashing algoroitm
- l3-bit-sa1100.o
- Manipulates the GPIO lines on the Balloon
The i2c-algo-bit.o module contains code that allows any two available wires to used as an I2C bus. The only Balloon-specific code is in l3-bit-sa1100.o. This provides get and set function for the SDA and SCL GPIO lines, and registers itself as an adapter provider with i2c-algo-bit.o.
Problems
Most of the code for I2C support is in the <kernel>/drivers/i2c directory, but the Balloon-specific code - l3-bit-sa1100.c is in the <kernel>/drivers/l3 directory. This file actually provides a combined l3 and I2C adapter, but only if I2C support is compiled into the kernel statically. This is because the I2C-specific code is wrapped in a #ifdef CONFIG_I2C_BIT_SA1100_GPIO / #endif block.
With the 2.4.25-vrs2-tcl1 kernel, L3 support must built into the kernel statically, rather than as a module.
There is also a bug in the code (now fixed in the 2.4.25-vrs2-tcl1 distribution but still in 2.6.8.1-tcl1 and in CVS at time of writing):
static void i2c_setscl(void *data, int state)
{
struct bit_data *bits = data;
unsigned long flags;
local_irq_save(flags);
#if defined(CONFIG_SA1100_BALLOON)
if (state)
balloon_in_dir(BALLOON_I2C_''DATA'');
else {
balloon_clear(BALLOON_I2C_''DATA'');%%%
balloon_out_dir(BALLOON_I2C_''DATA'');
}
#else
if (state)
GPDR &= ~bits->scl;
else {
GPCR = bits->scl;%%%
GPDR |= bits->scl;
}
#endif
local_irq_restore(flags);
}
The above function is to set SCL - the I2C clock line, but (on the Balloon) this function sets the data line. The references to BALLOON_I2C_DATA need to be changed to BALLOON_I2C_CLOCK.
