Linux Device Driver Tutorial Part 39 – Real I2C Bus Linux Device Driver

This is the Series on Linux Device Driver. The aim of this series is to provide easy and practical examples that anyone can understand. This is the Linux Device Driver Tutorial Part 39 – Real I2C Bus Linux Device Driver example using Raspberry PI.

We are using the Raspberry PI 4 Model B for this demonstration.

Real I2C Bus Linux Device Driver


Hardware Required

Bring up Raspberry PI

  1. Install Raspberry Pi OS (32-bit) with desktop in the SD card.
  2. Then install the kernel header using sudo apt install raspberrypi-kernel-headers

For your information, In our Raspberry PI 4 board, kernel 5.4.51-v7l+ is installed.

Please enable the I2C in the Raspberry Pi.


In our last tutorial, we have seen how to write the dummy I2C bus driver in the Linux kernel. It doesn’t send any data to the Salve device. So in this tutorial, we have come up with the real I2C bus Linux device driver. Using this I2C bus driver, we can send data to the slave device. Let’s start.

We have discussed the APIs too in the last tutorials. In this tutorial, we just used a new API called i2c_add_numbered_adapter(). This API will allocate the bus number that we are asking if that is available. In the last tutorial, we have not used this. Instead, we used i2c_add_adapter(). This API will allocate the bus number dynamically.

We can move to the example straightaway since we don’t have any other thing to discuss.

Example Programming

In this I2C client Driver tutorial, we have just written the I2C Client driver which communicates to the slave device called SSD1306 OLED I2C Display by using its internal I2C bus driver. That example demonstrates it will just fill something into the display while loading and it will clear the display while unloading. The same thing only we are going to try with our own I2C bus driver in this tutorial.

Connection Diagram

  • SCL – GPIO 20
  • SDA – GPIO 21


I2C Bus Driver Source Code

[Get the source code form the GitHub]

Note: In the below example I have implemented the I2C communication by using the bit-banging method (Linux Kernel’s  GPIO API has been used). I have not implemented the I2C read part. And also we have not handled arbitration, clock stretching, etc in this tutorial as this is just an example program. This is only for demonstration purposes.


I2C Client Device Driver Source code

We just took the last tutorial’s I2C Client driver example code. We made the below changes on top of that.

  • Changed the macro I2C_BUS_AVAILABLE value from 1 to 5 as we have asked our i2c bus number as 5.

[Get the source code from the GitHub]


Testing the Device Driver

  • Build the driver by using Makefile (sudo make) in both bus and client driver directories.
  • Load the bus driver first using sudo insmod driver_bus.ko
  • Load the client driver using sudo insmod driver_client.ko
  • See the Display is filled.
  • For your understanding, I have given the I2C’s capture for the first command in SSD1306_DisplayInit() which is 0xAE.

Click here if you don’t see the timing diagram


  • Unload the driver using sudo rmmod driver_client
  • See the Display has been cleared.
  • Unload the driver using sudo rmmod driver_bus

Output Video

Click here if you don’t see the output gif

In our next tutorial, we will see how to write a complete I2C bus driver using  I2C-GPIO.

0 0 vote
Article Rating
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x
%d bloggers like this: