0

I am learning about how to develop a Linux I2C kernel driver, and I learn from websites below.
How to instantiate I2C devices
I2C Driver for Linux Based Embedded System
...
Next, I found a sample that shows how to implement a I2C touchpad driver, but it really confused me.
linux/drivers/input/mouse/synaptics_i2c.c

My question is, how Linux kernel bind this driver to correctly device?
This driver don't provide 'detect' callback, no specify the I2C slave address via i2c_driver.address_list, and there is seems no anyone to call i2c_board_info to register the address info (I grep a whole Linux codebase).
I thought the driver MUST be specify the slave address or provide the 'detect' callback, just like
drivers/hwmon/adc128d818.c
or linux/drivers/rtc/rtc-ds1307.c (it will be register by i2c_board_info)

Please let me know what I missed, thanks.

Lak Fu
  • 165
  • 3
  • 12
  • Short answer: `compatible` string in your driver is matching corresponding `compatible` string from your device tree file (`.dts`). Then matching happens, and `probe()` function being called. See [this](https://stackoverflow.com/questions/38641710/mcp23017-i2c-device-driver-probe-function-is-not-called) and [this](https://stackoverflow.com/questions/40262148/ive-added-a-max7320-i2c-output-chip-how-can-i-get-the-kernel-to-load-the-drive) for details. – Sam Protsenko Nov 07 '17 at 15:33
  • Thanks for your answer, you mean that "synaptics_i2c.c" rely on device tree? Even I don't declare '.of_match_table = of_match_ptr(synaptics_i2c_of_match),'?? In "synaptics_i2c.c", the point that confuse me is, if you are not defined CONFIG_OF, it seems not to declare .compatible, in this case, how it work? – Lak Fu Nov 08 '17 at 01:31
  • Look at [i2c_device_match()](http://elixir.free-electrons.com/linux/v4.14-rc8/source/drivers/i2c/i2c-core-base.c#L98) function. It tries to do 3 kind of matches: first device tree match (OF), then ACPI match, and if both failed -- then I2C match. So if you neither use Device Tree or ACPI, matching will happen using your [i2c_device_table->name](http://elixir.free-electrons.com/linux/latest/source/drivers/input/mouse/synaptics_i2c.c#L649), in [i2c_match_id()](http://elixir.free-electrons.com/linux/v4.14-rc8/source/drivers/i2c/i2c-core-base.c#L83) function. – Sam Protsenko Nov 08 '17 at 13:20
  • See also [this](https://stackoverflow.com/questions/24606448/usage-of-driver-data-member-of-i2c-device-id-table/27934228#27934228) answer for details. – Sam Protsenko Nov 08 '17 at 13:21
  • Oh, that exactly is my question - I2C match. It looks like a string match mechanism. In driver, we provide the name by filling i2c_device_id struct, but kernel how to know a device's name? Without OP and ACPI, how I2C match happen? Is it rely on I2C_BOARD_INFO? If I want my device bind to my driver by I2C match, what I need to prepare? Modify kernel and call I2C_BOARD_INFO to add my device info, right? Anyway, thank you so much!! – Lak Fu Nov 09 '17 at 03:53
  • More specifically, in func i2c_match_id(), it compare the client->name and id->name, but I2C protocol only defined "address", not any string "name", I don't understand how kernel founds the "name" used there. – Lak Fu Nov 09 '17 at 04:11
  • @SamProtsenko Thanks, I got it. – Lak Fu Nov 14 '17 at 02:45
  • Sorry, wanted to write you the complete answer, but was really busy on work this week... It compares driver name from driver structure (see `DRIVER_NAME` in your code) with device name from i2c device structure (see `synaptics_i2c_id_table`). As I understand, this code is only needed when both Device Tree and ACPI is missing (for platform drivers perhaps?). – Sam Protsenko Nov 14 '17 at 21:31
  • @SamProtsenko You are a really good man. Actually, I found the answer from your early post too. You must have helped many people, including me. Thank you. I am study how to submit a driver (for my boss) to Linux official main tree, but the first, I need to know how to write a correct driver. XD – Lak Fu Nov 24 '17 at 03:06
  • I always encourage and welcome upstreaming, everyone benefits from it. Good luck with your efforts, and I hope you'll find all the answers here on SO. Also, please remember that kernel itself is a big source of examples. You pretty much always can find driver very similar to yours, and use its code as a template. It's GPL in the end ;) – Sam Protsenko Nov 24 '17 at 22:39

2 Answers2

0

The i2c device declaration is start from device tree.

Declare the i2c devices in device tree.

Example:

i2c1: i2c@400a0000 {
    /* ... master properties skipped ... */
    clock-frequency = <100000>;

    flash@50 {
        compatible = "atmel,24c256";
        reg = <0x50>;
    };

    pca9532: gpio@60 {
        compatible = "nxp,pca9532";
        gpio-controller;
        #gpio-cells = <2>;
        reg = <0x60>;
    };
};

Where,

1) 400a000 is a i2c bus address 2) pca9532 and flash are driver names 3) @50 and @60 are slave address 4) the attribute “compatible” to find and map device with the driver 5) other attribute which is inside cell of each entries are specific to the driver which will be used for device initialization during the probe

https://www.kernel.org/doc/Documentation/i2c/instantiating-devices

Sathesh
  • 51
  • 7
  • Thanks for your response, I had read that document before. You mean that "synaptics_i2c.c" rely on device tree? The point that confuse me is, if you are not define CONFIG_OF, it seems not to declare .compatible, in this case, how it work? – Lak Fu Nov 08 '17 at 01:34
0

I finally figured out my question.
Refer to http://www.embedded-bits.co.uk/2009/i2c-in-the-2632-linux-kernel/
There is need to register my I2C device with i2c_new_probed_device() or i2c_new_device on Kernel to let it have a mapping table about slave address and device name.

Lak Fu
  • 165
  • 3
  • 12