
We will discuss about the I2C master/controller/adapter driver in Linux. Generally, Linux I2C master controller driver registers the I2C controller in the Linux I2C subsystem. The I2C master driver is required to let the Linux OS know that there is a controller that exists. We will discuss this in detail and we will also check on the master side implementation of the I2C driver.
Description:
In any of the SOC, I2C is the common bus provided for onboard devices like eeprom, rtc, etc. This bus is used to connect the slow and small devices on the platform. Any communication between the I2C slave devices over I2C bus is done by the master side implementation on the SOC. There is a hardware controller that is present on the SOC which implements the I2C communication in SOC. To enable this I2C HW controller, we need the I2C master driver in Linux. The main function of I2C master driver is to program the hardware registers for I2C communication. At the same time, expose the standard functions to the Linux OS for I2C as per the Linux I2C framework.
Linux defines the standard implementation for the I2C master driver. For any new SOC which has the new controller that is not known to the Linux, one must write the I2C master or adapter driver
This I2C master driver registers the new bus to the user space for communication. The I2C master must provide one bus, but it can provide more than one bus as well.
These drivers are present inside the drivers/I2C/busses/ in the kernel source.
Let us take an example of the I2C-i801 driver which is present inside the drivers/I2C/busses.
First, let us understand a little bit on I2C-i801. It is the I2C/SMBus bus controller that is implemented on Intel Platforms. The I2C-i801 controller is accessed internally over PCI. Hence, it is implemented as the PCI driver.
On any other platform controllers, it could be memory mapped. Hence, simply accessing the physical memory controller registers can be accessed. These details can be fetched from the hardware datasheet of the controller. In such case, this can be implemented as platform driver; the same can be seen in the already available I2C bus drivers.
Let us focus on the example of the I2C-i801 driver.
The “i2c_adapter” struct is the structure which needs to be instantiated in Linux for the new bus registration.
Few important fields are a must, and we should provide the values to these fields.
The adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; // is the class of the I2C devices. Linux defines various classes for the I2C devices that need to select the class which are supported by this controller.
The adapter.algo = smb_algorithm; // field defines the types of the I2C/SMbus function that is supported by the I2C controller.
This field consists of reference of the object to the “struct i2c_algorithm” that is defined by the Linux I2C SMBus framework.
The “.smbus_xfer” is the callback to the function which is used to program the hardware registers for the I2C/SMBus access. This will be the lower level function for the hardware access.
The “.functionality” is the type of the I2C/SMBus functions that is supported by this controller driver. Few examples of the Macros which can be used in this field are as follows: