I2C

I2C is a two wire bus developed by Phillips originally for the inside of a TV. It is low performance, low distances but simple and very cheap. This has been discovered by the PC industry and got used to hold plug and play data, read temperature, ram configuration, fan speed, battery charging and more. I2C has a master host interface and various sensors acting as slaves. On the motherboard there can be more than one host, resulting in having more than one bus. Usually the host is the master and the other devices are slaves, however be aware, also slave devices can act as masters.

SMbus (System Management bus) is derived from the I2C bus with additional specifications and rules used in PC applications.

Different implementations

Many evolutionary steps have been made to I2C and this causes some incompatibilities. I2C is meant for device internal communications where the configurations is roughly known. Therefore using it as plug and play might cause some misinterpretations, confusions and failures.

The simples way is using I2C to send or receive a stream of bits into a device (usually memory devices). Such chips can be read and written as files, whereas the file is /dev/i2c-<nn> and the chip I2C address is set by the files ioctl function call.

Since devices behaving this way are limited, a new approach got introduced to address registers in a device. Devices supporting registers can be used with the command i2cset and i2cget. There is a pointer register that can be written as usual. To read it or read/write to other registers the device considers the content of this pointer register as the register address. On write access, the bytes following the pointer register end in the register selected by the pointer register. To read, two accesses are necessary write to pointer register, then read from what is selected by the pointer register.

Note

Be aware that there are mainly two I2C bus behaviors, devices that use a pointer registers and devices that don't.

Note

Register access commands can cause disastrous effects on devices that do not follow this registers approach as eeproms. When not taking care eeproms can loose their contents, and if this happens on the eeprom on a DIMM, a PC might even permanently refuse to boot afterwards.

Linux implementations

Linux offers two ways of accessing the devices on the I2C bus:

  • Using a kernel driver as /usr/src/linux/drivers/hwmon/LM75.ko that matches the chip. This driver needs to be added to the ic2-core device driver and see /usr/src/linux/Documentation/i2c/instantiating-driver access is then done via /sys/devices see /usr/src/linux/Documentation/hwmon

  • Use the dev-interface to get the routines to access the chip that can be used in a C program /usr/src/linux/Documentation/i2c/dev-interface . The i2c-dev driver will access the i2c-core driver.

See http://venkateshabbarapu.blogspot.de/2012/11/i2c-driver-in-linux.html for a good overview

lspci | grep SMBus shows what i2c adapters are available on pci.

Create a kernel with support for it plus enable i2c-dev. Check if the files under /dev get created ls /dev/i2c*

The i2c-tools package comes with program i2cdetect -l lets you all adapters available.

An alternative is:

cat /sys/class/i2c-adapter/i2c-*/name

If there are problems check with ls -l /dev/i2c* if device files are there. To check the functionality of the <n> i2c host adapter i2cdetect -F <n> , this list gives also a good overview of all access modes i2c supports

lm_sensors

The packages lm_sensors is mainly targeted to i2c chips on the motherboard.

A lot of device drivers are involved when it comes to i2c. The i2c-core driver communicates to the i2c host hardware via other kernel drivers. In case of a parallel port i2c adapter i2c-core communicates to i2c-algo-bit that actually does bit banging. i2c-algo-bit then might call i2c-philips-par the device driver that philips proposed and this then calls the device driver parport a abstraction layer of all parports and finally on a PC the device driver parport_pc is called that then accesses the hardware. Finally ther is either i2c-dev to access the devices using i2c commands or a device driver as LM75 that creates the data under /sys

Run sensors-detect, it creates as output /etc/modules-load.d/lm_sensors.conf that will be read (after dispatch-conf) by the OpenRC service /etc/init.d/modules-load that holds all stuff detected. Add it to the default rc-update add modules-load default and rc-update add lm_sensors default

/etc/init.d/modules-load restart will now produce errors for all kernel drivers missing. Now build a kernel with the missing drivers.

Type sensors to see what data can be get


Linurs Servernest startpage