当前位置: 技术问答>linux和unix
关于LINUX I2C驱动的Probe方法
来源: 互联网 发布时间:2016-11-11
本文导语: 我在编写LINUX I2C驱动时,使用了Probe方式。因为是为Input设备编写的,所以参照了在driversinputkeyboard下的很多驱动,例如adp588-key.c,他们都是使用Probe方式。文档上说(linux-2.6.32.2Documentationi2cinstantiating-devices),利用pro...
我在编写LINUX I2C驱动时,使用了Probe方式。因为是为Input设备编写的,所以参照了在driversinputkeyboard下的很多驱动,例如adp588-key.c,他们都是使用Probe方式。文档上说(linux-2.6.32.2Documentationi2cinstantiating-devices),利用probe方法会自动生成i2c_client.会自动调用i2c_driver的.probe。可我编写的驱动没有自动调用i2c_driver的.probe,在此请教高手。声明:我是新手。
文档上描述的方法:
Method 1: Declare the I2C devices by bus number
-----------------------------------------------
This method is appropriate when the I2C bus is a system bus as is the case
for many embedded systems. On such systems, each I2C bus has a number
which is known in advance. It is thus possible to pre-declare the I2C
devices which live on this bus. This is done with an array of struct
i2c_board_info which is registered by calling i2c_register_board_info().
Example (from omap2 h4):
static struct i2c_board_info __initdata h4_i2c_board_info[] = {
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(125),
},
{ /* EEPROM on mainboard */
I2C_BOARD_INFO("24c01", 0x52),
.platform_data = &m24c01,
},
{ /* EEPROM on cpu card */
I2C_BOARD_INFO("24c01", 0x57),
.platform_data = &m24c01,
},
};
static void __init omap_h4_init(void)
{
(...)
i2c_register_board_info(1, h4_i2c_board_info,
ARRAY_SIZE(h4_i2c_board_info));
(...)
}
The above code declares 3 devices on I2C bus 1, including their respective
addresses and custom data needed by their drivers. When the I2C bus in
question is registered, the I2C devices will be instantiated automatically
by i2c-core.
The devices will be automatically unbound and destroyed when the I2C bus
they sit on goes away (if ever.)
---------------------------------------------------------------------------------
对应我的驱动:
static struct i2c_board_info __initdata xxx_i2c_board_info[] = {
{
I2C_BOARD_INFO("xxx", 0x58),
.irq = IRQ_EINT18,
.platform_data = (void *)&xxx_kpad_data,
},
}
static const struct i2c_device_id xxx_id[] = {
{"xxx", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, xxx_id);
static struct i2c_driver xxx_driver = {
.driver = {
.name = "xxx",
},
.probe = xxx_probe,
.remove = __devexit_p(xxx_remove),
.id_table = xxx_id,
};
static int __init xxx_init(void)
{
//register board info xxx
i2c_register_board_info(0, xxx_i2c_board_info, ARRAY_SIZE(xxx_i2c_board_info));
return i2c_add_driver(&xxx_driver);
}
我满心希望xxx_probe会自动调用,但是并没有。希望大侠指点。再者,能否说明一下这总自动生成、调用的来龙去脉!
如果编译有什么关键点,也请指出。我的平台:s3c2440 linux内核:2.6.32
文档上描述的方法:
Method 1: Declare the I2C devices by bus number
-----------------------------------------------
This method is appropriate when the I2C bus is a system bus as is the case
for many embedded systems. On such systems, each I2C bus has a number
which is known in advance. It is thus possible to pre-declare the I2C
devices which live on this bus. This is done with an array of struct
i2c_board_info which is registered by calling i2c_register_board_info().
Example (from omap2 h4):
static struct i2c_board_info __initdata h4_i2c_board_info[] = {
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(125),
},
{ /* EEPROM on mainboard */
I2C_BOARD_INFO("24c01", 0x52),
.platform_data = &m24c01,
},
{ /* EEPROM on cpu card */
I2C_BOARD_INFO("24c01", 0x57),
.platform_data = &m24c01,
},
};
static void __init omap_h4_init(void)
{
(...)
i2c_register_board_info(1, h4_i2c_board_info,
ARRAY_SIZE(h4_i2c_board_info));
(...)
}
The above code declares 3 devices on I2C bus 1, including their respective
addresses and custom data needed by their drivers. When the I2C bus in
question is registered, the I2C devices will be instantiated automatically
by i2c-core.
The devices will be automatically unbound and destroyed when the I2C bus
they sit on goes away (if ever.)
---------------------------------------------------------------------------------
对应我的驱动:
static struct i2c_board_info __initdata xxx_i2c_board_info[] = {
{
I2C_BOARD_INFO("xxx", 0x58),
.irq = IRQ_EINT18,
.platform_data = (void *)&xxx_kpad_data,
},
}
static const struct i2c_device_id xxx_id[] = {
{"xxx", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, xxx_id);
static struct i2c_driver xxx_driver = {
.driver = {
.name = "xxx",
},
.probe = xxx_probe,
.remove = __devexit_p(xxx_remove),
.id_table = xxx_id,
};
static int __init xxx_init(void)
{
//register board info xxx
i2c_register_board_info(0, xxx_i2c_board_info, ARRAY_SIZE(xxx_i2c_board_info));
return i2c_add_driver(&xxx_driver);
}
我满心希望xxx_probe会自动调用,但是并没有。希望大侠指点。再者,能否说明一下这总自动生成、调用的来龙去脉!
如果编译有什么关键点,也请指出。我的平台:s3c2440 linux内核:2.6.32
|
个人猜测是这样的,注册的i2c_board_info数组中的信息没有生成i2c_client.
i2c_register_board_info的传统用法是在内核初始化时,在i2c_adapter注册之前。这点注释中已经说明了。查看i2c_adapter的注册代码可以发现,i2c_adapter注册的时候会扫描已经注册的board_info的链表,为每一个注册的信息调用i2c_new_device函数生成i2c_client,这样在i2c_driver注册的时候,设备和驱动就能匹配并调用probe.
如果楼主在adapter注册之后调用i2c_register_board_info,注册的信息没有机会生成i2c_client,从而无法与i2c_driver匹配,当然不会调用probe。
我是从代码中得到的结论。
我的博客讲了一种i2c的用法,楼主可以参考:http://blog.csdn.net/yuanlulu/archive/2011/01/24/6161698.aspx
i2c_register_board_info的传统用法是在内核初始化时,在i2c_adapter注册之前。这点注释中已经说明了。查看i2c_adapter的注册代码可以发现,i2c_adapter注册的时候会扫描已经注册的board_info的链表,为每一个注册的信息调用i2c_new_device函数生成i2c_client,这样在i2c_driver注册的时候,设备和驱动就能匹配并调用probe.
如果楼主在adapter注册之后调用i2c_register_board_info,注册的信息没有机会生成i2c_client,从而无法与i2c_driver匹配,当然不会调用probe。
我是从代码中得到的结论。
我的博客讲了一种i2c的用法,楼主可以参考:http://blog.csdn.net/yuanlulu/archive/2011/01/24/6161698.aspx
|
probe 被调用的前提是 driver 和device 配对成功
检查一下 总线的 driver 和 device 是否配对成功 深入到 i2c_add_driver 函数面了解一下
检查一下 总线的 driver 和 device 是否配对成功 深入到 i2c_add_driver 函数面了解一下
|
检查一下i2c_register_board_info的返回值。
这个函数的第一个参数是总线编号,你试试其它编号,比如1、2
这个函数的第一个参数是总线编号,你试试其它编号,比如1、2
|
moduler_init(init_func);
这里init_func函数会被调用到,然后在里面调用probe
这里init_func函数会被调用到,然后在里面调用probe
|
/**
* i2c_register_board_info - statically declare I2C devices
* @busnum: identifies the bus to which these devices belong
* @info: vector of i2c device descriptors
* @len: how many descriptors in the vector; may be zero to reserve
* the specified bus number.
*
* Systems using the Linux I2C driver stack can declare tables of board info
* while they initialize. This should be done in board-specific init code
* near arch_initcall() time, or equivalent, before any I2C adapter driver is
* registered. For example, mainboard init code could define several devices,
* as could the init code for each daughtercard in a board stack.
*
* The I2C devices will be created later, after the adapter for the relevant
* bus has been registered. After that moment, standard driver model tools
* are used to bind "new style" I2C drivers to the devices. The bus number
* for any device declared using this routine is not available for dynamic
* allocation.
*
* The board info passed can safely be __initdata, but be careful of embedded
* pointers (for platform_data, functions, etc) since that won't be copied.
*/
* i2c_register_board_info - statically declare I2C devices
* @busnum: identifies the bus to which these devices belong
* @info: vector of i2c device descriptors
* @len: how many descriptors in the vector; may be zero to reserve
* the specified bus number.
*
* Systems using the Linux I2C driver stack can declare tables of board info
* while they initialize. This should be done in board-specific init code
* near arch_initcall() time, or equivalent, before any I2C adapter driver is
* registered. For example, mainboard init code could define several devices,
* as could the init code for each daughtercard in a board stack.
*
* The I2C devices will be created later, after the adapter for the relevant
* bus has been registered. After that moment, standard driver model tools
* are used to bind "new style" I2C drivers to the devices. The bus number
* for any device declared using this routine is not available for dynamic
* allocation.
*
* The board info passed can safely be __initdata, but be careful of embedded
* pointers (for platform_data, functions, etc) since that won't be copied.
*/