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/]).
Balloon3
The pxa270 includes two I2C buses. One of these is used for power management on the board. The other is brought out for user control via the samtec and
It is exposed on the CUED IO board on the 9-pin D connection, and is taken to the PCF8574 to provide 8 channels of digital IO. A handy user-space library is provided to use it to drive things.
The i2C address space is fixed by soldered links so you need to avoid clashes with other devices when adding a new one. The address space is detailed [/hardware/300/balloon3_i2c_address_map.pdf | in this chart]
Balloon 2
There is no dedicated I2C hardware on the Balloon 2. 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://balloonboard.org/files/balloon2/205g/]
Hardware
Balloon2 GPIOs
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.
http://www.balloonboard.org/hardware/205/con/samtek.jpg
Software
I2C Support Under Linux
Support for driving I2C bus masters is provided in 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 balloon3 you should load:
- i2c-pxa
- Provides board-specific support and brings in core modules
- i2c-dev
- Provides /dev filesystem entries so you can read/write devices
If you want to talk to the pcf8754 in a convenient way you need to:
modprobe pcf8574
which will provide /sys/bus/i2c/device/0-0038/write (and corresponding read) files where you can read or write the status of all 8 IO lines.
On the Balloon2 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.
Using i2c
You can use i2c at a very level, or use device-specific drivers and interact with them at a higher level. The combination of multiple modules, 2 different buses, 2 different address nomenclatures and the ability to interact at the bus level via /dev or via a device driver via /sys allows for plenty of confusion. Hopefully the below will help.
i2cdump in the i2c-tools package (or in lm-sensors package on lenny-vintage distros) is handy for examing the bus at a low level and seeing what hardware is present.
i2c addressing is confusing because it is 8-bit but the bottom bit is the r/w bit so addresses can be written with/without this bit. The [/hardware/300/balloon3_i2c_address_map.pdf | i2C chart PDF linked above] used the 8-bit adresses, as does the kernel, whilst the i2cdump tools use the 7-bit adresses (how helpful!). To add to the confusion the PCF8574 shown on that chart at 0x40, actually appears in /sys/bus/i2c/devices/0-0038. (i.e at 0x38 (8-bit address))
The two I2C buses are 0 and 1. Bus 0 (/dev/i2c-0) is the general purpose bus. Bus 1 (/dev/i2c-1) is the power bus.
So to read the device at 0x38 on the general purpose bus do i2cdump 0 0x1C (0x38 is the 8-bit address, 0x1C is the same 7-bit address)
You could send commands in this way to get the device to change IO lines, but it's much easier to load the pcf8574 module and access it via /sys.
Balloon2 driver issues
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.