我需要创建一个Linux内核驱动程序,通过接口板与I2C上的一堆MCU连接。因为它们的数量很多,即大约1-18,我们正在使用恩智浦/ TI I2C多路复用器。
我已经导入了NXP / TI I2C Multiplexer内核驱动程序,并将其合并到DTS文件中。我已经成功地将所有I2C多路复用器列为不同的i2c-x节点。
MCU全部使用相同的地址0x08。我创建了一个内核驱动程序,为它创建了一个hwmon
+ sysfs
接口。
但是,insmod
上的驱动程序仅触发__init
功能。并且不会打扰probe()
。
在参考许多文档时,我只能在插入
时触发探测功能static struct i2c_board_info xxxx_i2c_devices[] = {
{
I2C_BOARD_INFO("xxxx", 0x08),
},
};
及其相应的
i2c_register_board_info(0, xxxx_i2c_devices, ARRAY_SIZE(xxxx_i2c_devices));
但是,这只会在HWMON
中创建一个实例,而不是我想象的那样。我提到了https://www.kernel.org/doc/Documentation/i2c/instantiating-devices
如果没有主板init
的更改,我尝试使用方法3,但内核甚至不会调用probe()
并检测function()
,只会调用__init
司机的功能。
跟随司机 - https://github.com/1119553797/sprd-kernel-common/blob/sprdb2g_gonk4.0/drivers/hwmon/w83l785ts.c
如果需要,将发布整个内核驱动程序,以供参考使用内核3.0.8,一个使用板级更改到同一个内核的自定义板。
答案 0 :(得分:1)
好的,经过广泛的谷歌搜索和修补后,不同的方法是一种解决方法。
首先在DTS中,我们可以直接在Mux寻址中分配I2C地址。对于.e.g。
i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
adc0: nau7802@2a {
compatible = "nuvoton,nau7802";
reg = <0x2a>;
nuvoton,vldo = <3000>;
};
};
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
adc1: nau7802@2a {
compatible = "nuvoton,nau7802";
reg = <0x2a>;
nuvoton,vldo = <3000>;
};
};
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
adc2: nau7802@2a {
compatible = "nuvoton,nau7802";
reg = <0x2a>;
nuvoton,vldo = <3000>;
};
};
然后在驱动程序中,为了识别VendorID,ProductID结构,如上例“nuvoton,nau7802”,我们必须做出以下更改: -
static const struct i2c_device_id nau7802_i2c_id[] = {
{ "nau7802", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id);
static const struct of_device_id nau7802_dt_ids[] = {
{ .compatible = "nuvoton,nau7802" },
{},
};
MODULE_DEVICE_TABLE(of, nau7802_dt_ids);
static struct i2c_driver nau7802_driver = {
.probe = nau7802_probe,
.remove = nau7802_remove,
.id_table = nau7802_i2c_id,
.driver = {
.name = "nau7802",
.of_match_table = nau7802_dt_ids,
},
};
可以简单地跳过“adc1”等部分。 “MODULE_DEVICE_TABLE(of,”意思是device_tree信息,来自我可以收集的内容。
如果您找到一种不需要DTS&amp; D的更好的方法,请告诉我。 board _init changes。