Thursday, June 24, 2010

Linux i2c

My notes while reading Linux kernel i2c source code and the documentation.

  • implements the character devices for userspace, a generic, "remote controlled" i2c chip driver
  • ioctl to select slave
  • read()/write() for a subset of smbus operations
  • i2c-tools with library functions
i2c adapter

A host bus adapter instance
  • class - allow probing for slave devices in class: HWMON, TV, DDC, SPD
  • nr - 'id' number of instance
  • algo - operations to implement

exported API
  • i2c_transfer() - sequence of low level i2c operations
  • i2c_smbus_transfer() - sequence of high level smbus operations

i2c algorithm

operations to implement a type of host bus adapter: bitbang, philips bus controllers
  • master_xfer() - implement low level i2c transaction segment: operations to read or write bytes to/from i2c device
  • smbus_xfer() - implement high level SMbus access
  • functionality() - query available functionality: SMBUS support, 10bit addressing
master_xfer can be omitted for SMbus only access.
smbus_xfer can be omitted for generic SMbus implementation using low level master_xfer

i2c (chip) drivers

Driver for a type of i2c slave device on an i2c bus.
  • io expanders, power supply supervisors, light sensor, clock
driver operations
  • probe() - gets a client handle and id of device which is supposed to be present.
  • remove()
  • detect() - autodetect which type of device is present: fill in the name in board info.
  • ioctl
  • suspend/resume/shutdown

communicates with the slave device through i2c client API. Prefer using SMbus operations, wider support in bus adapters

i2c client

an instance of a slave device
  • connected to a certain adapter (bus)
  • at a certain address (?)
  • controlled by a driver
exported API
  • i2c_master[send|recv]() - individual low level i2c byte level read/write
  • i2c_smbus_[read|write]_byte_data() - individual high level smbus read/write

i2c board info

declaration of a slave device on a bus. i2c slave devices are not enumerated on the bus, layout must be known.

Alternative methods of setting up i2c slave devices

statically at arch_initcall time for platform
  • build an array to declare types of chips and their addresses
  • i2c_register_board_info()
dynamically at parent device init()
  • i2c_new_device()
  • i2c_new_probed_device() - probe a list of slave addresses if there's a device present
  • i2c_unregister_device()
run time detection from a haystack
  • implement detect() - by reading registers from the device to see if it's really there
  • automatically attempted when bus and driver classes match
  • should be avoided, slow and unsafe


a subset of i2c. "pseudocode" signatures for smbus operations:

void quick_command(u1 cmd)

u8 read_byte()
void write_byte(u8 data)

u8 read_byte_data(u8 addr)
void write_byte_data(u8 addr, u8 data)

u16 read_word_data(u8 addr)
void write_word_data(u8 addr, u16 data)

u8[n] read_block_data(u8 addr, u8 length)
void write_block_data(u8 addr, u8 length, u8 data[n])

smbus i2c extensions with no explicit count byte

u8[n] read_i2c_block_data(u8 addr, int n)
void write_i2c_block_data(u8 addr, u8 data[n], int n)

not implemented

u16 process_call(u8 addr, u16 input)
u8[n] block_process_call(u8 addr, u8 length, u8 data[n])
void host_notify(u8 addr, u16 data)

two comm byte block ops

u8[n] read_block_data(u16 addr, u8 length)
void write_block_data(u16 addr, u8 length, u8 data[n])

Existing slave chip drivers
Scattered around the drivers tree, mostly outside the i2c subdirectory. Search cross reference for i2c_client usage.
  • gpio extender
  • eeprom
  • hardware monitoring chips
  • video related devices
  • real time clocks
  • led dimmer
  • keypad
  • battery power
  • audio codec
  • miscellaneous

1 comment:

  1. This comment has been removed by a blog administrator.