i2c驱动注册流程实例分析

本文深入解析Linux内核中I2C驱动的注册流程,以GSL3680触摸屏驱动为例。从module_init()开始,介绍了电源初始化、GPIO分配、设备适配器获取、配置文件读取和设备初始化等步骤。重点分析了驱动注册函数i2c_add_driver()及其背后的i2c_register_driver()、driver_register()和bus_add_driver()等,详述了如何通过一系列调用最终执行驱动的probe()函数。
摘要由CSDN通过智能技术生成

本文以触摸屏GSL3680为例详细分析驱动从注册到调用的整个流程。程序详见GSL3680目录下的gslX680.c文件。

谨以本文记录当时分析思路为之后回顾保留资料,同时纪念那在力源思创昏天黑的的加班日子。

该TP驱动调用module_init(gsl_ts_init);对整个tp模块驱动进行初始化。函数gsl_ts_init()中先初始化电源;接着分配gpio口;之后获取adapter总线上的主设备;又读取配置文件;然后初始化了一个设备;最后注册该tp所用的相关驱动函数。

这里主要分析最后一步,tp所用的相关驱动函数注册。


例程中所调用的驱动注册函数代码为:ret = i2c_add_driver(&gsl_ts_driver);

第一步:分析该行代码

i2c_add_driver()是一个宏,其原型是:

#define i2c_add_driver(driver) \
	i2c_register_driver(THIS_MODULE, driver)

它封装了函数i2c_register_driver()。

它的参数&gsl_ts_driver是一个结构体指针,原型为:

struct i2c_driver {
	unsigned int class;
	int (*attach_adapter)(struct i2c_adapter *) __deprecated;
	int (*detach_adapter)(struct i2c_adapter *) __deprecated;
	int (*probe)(struct i2c_client *, const struct i2c_device_id *);
	int (*remove)(struct i2c_client *);
	void (*shutdown)(struct i2c_client *);
	int (*suspend)(struct i2c_client *, pm_message_t mesg);
	int (*resume)(struct i2c_client *);
	void (*alert)(struct i2c_client *, unsigned int data);
	int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
	struct device_driver driver;
	const struct i2c_device_id *id_table;
	int (*detect)(struct i2c_client *, struct i2c_board_info *);
	const unsigned short *address_list;
	struct list_head clients;
}

初始化后的gsl_ts_driver结构体:

static struct i2c_driver gsl_ts_driver = {
	.driver = {
		.name = GSLX680_I2C_NAME,
		.owner = THIS_MODULE,
	},
#ifndef CONFIG_HAS_EARLYSUSPEND
	.suspend	= gsl_ts_suspend,
	.resume	= gsl_ts_resume,
#endif
	.probe		= gsl_ts_probe,
	.remove		= __devexit_p(gsl_ts_remove),
	.id_table	= gsl_ts_id,
	.address_list	= gsl_addresses,
};

该结构体初始化了相关的操作函数和设备驱动对应设备的名字和所属模块。


第二步:分析驱动注册函数i2c_register_driver(),原型如下:

int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
	int res;

	/* Can't register until after driver model init */
	if (unlikely(WARN_ON(!i2c_bus_type.p)))
		return -EAGAIN;

	/* add the driver to the list of i2c drivers in the driver core */
	driver->driver.owner = owner;/*设置它的所属模块*/
	driver->driver.bus = &i2c_bus_type;/*设置它的总线类型*/

	/* When registration returns, the driver core
	 * will have called probe() for all matchin
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值