I2C device linux driver

c, i2c, linux, linux-device-driver, linux-kernel

Solution

Thank you, guys. I've found what I want a couple hours ago. So as I see there are three types of drivers. One is supposed to be inserted into the kernel, and you need to rebuild your kernel to use them. There are also drivers that you can use through the `sysfs` using device attributes (they appear in `/sys/bus/i2c/driver/your_driver/`). And, third - my type - drivers that look like character devices. Actually, you can combine them.

So, if you want to use last type of devices it'll be a bit difficult to find correct examples, because almost all examples are devoted to the first two types of drivers. Anyway, if you want to create a character device, you need to describe functions from the `file_operations` structure. But all functions like `i2c_transfer`, `i2c_smbus_read_byte`. Etc. (full list) required either`struct i2c_adapter` or `struct i2c_client`. And there two questions, how to get there structures, and how to attach driver to the appropriate i2c bus, such as i2c-2?

So there is a function that is not described here: `i2c_get_adapter`. As a parameter, you need to pass the i2c bus number. It returns a link to a `i2c_adapter` structure. The `i2c_client` structure you can get with `i2c_new_dummy` function passing `i2c_adapter` and slave address to it as parameters.

After that you can use functions such as `i2c_transfer`, `i2c_smbus_read_byte` etc. In the end you can describe `file_operations` structure functions, and release driver, representing your i2c device, without using sysfs and rebuilding your kernel.

Result code looks like:

u8 ret; 
struct i2c_client * my_client; 
struct i2c_adapter * my_adap = i2c_get_adapter(1); // 1 means i2c-1 bus
my_client = i2c_new_dummy (my_adap, 0x69); // 0x69 - slave address on i2c bus
i2c_smbus_write_byte(my_client, 0x0f); 
ret = i2c_smbus_read_byte(my_client);

You can use this code directly in your functions for the file_operations structure.

Hope this info will be useful for beginners like me.

Problem

How to make a character device for i2c device, with open, close, ioctl etc. functions? I was looking for information about it last two weeks and couldn't find anything working. I found some information in Essential Linux Device Drivers, but it was written for 2.6 kernel, and i use 3.4.79 (i'm trying to write this driver for cubieboard2 on cubian distr) so this book has many deprecated functions, i tried to write my driver like there, but it still don't work (give me kernel errors while i'm truing to cat character device). Can anyone explain me what to do with it, or at least give me a working example. so, there is my code: http://pastebin.com/T7PBTpym i just try to get i2c bus works, but on my oscilloscope i don't see anything on i2c lines, while i get no errors when i compile it. Also i can't find how to attach device driver to i2c bus number. because i have 4 i2c buses on my cubieboard2, and how to attach device driver to i2c-1 bus, for example?

Original source

Related problems