i2c子系统之adapter device和client device注册——i2c_add_number_adapter()
来源:互联网 发布:理财软件排行 编辑:程序博客网 时间:2024/04/29 21:19
如前文所述,在probe函数会调用函数i2c_add_number_adapter(),通过此函数来实现adapter device和client device的注册
i2c_add_number_adapter()函数如下:
int i2c_add_numbered_adapter(struct i2c_adapter *adap){intid;intstatus;if (adap->nr & ~MAX_ID_MASK)return -EINVAL;retry:if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)return -ENOMEM;mutex_lock(&core_lock);/* "above" here means "above or equal to", sigh; * we need the "equal to" result to force the result */status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);if (status == 0 && id != adap->nr) {status = -EBUSY;idr_remove(&i2c_adapter_idr, id);}mutex_unlock(&core_lock);if (status == -EAGAIN)goto retry;if (status == 0)status = i2c_register_adapter(adap);return status;}函数前面部分应该是用来提高搜索效率相关,此处省略分析。直接分析
i2c_register_adapter()函数,如下:
static int i2c_register_adapter(struct i2c_adapter *adap){int res = 0;。。。 。。。dev_set_name(&adap->dev, "i2c-%d", adap->nr);adap->dev.bus = &i2c_bus_type;adap->dev.type = &i2c_adapter_type;res = device_register(&adap->dev); 。。。 。。。/* create pre-declared device nodes */if (adap->nr < __i2c_first_dynamic_bus_num)i2c_scan_static_board_info(adap);/* Notify drivers */printk("bus_search\n");mutex_lock(&core_lock);bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);mutex_unlock(&core_lock);return 0;out_list:mutex_lock(&core_lock);idr_remove(&i2c_adapter_idr, adap->nr);mutex_unlock(&core_lock);return res;}
函数首先通过:
dev_set_name(&adap->dev, "i2c-%d", adap->nr); adap->dev.bus = &i2c_bus_type;adap->dev.type = &i2c_adapter_type;res = device_register(&adap->dev);
语句,将名为i2c-0的adapter设备注册到i2c_bus_type型的i2c总线上上,其中通过
adap->dev.type = &i2c_adapter_type;
指定了本次注册的设备类型为i2c_adapter_type(因为还有client设备同时需要注册到这条i2c总线上)
最后同构device_register()将adapter注册到i2c总线上。
接着然后判断if条件是否成立(此处成立),__i2c_first_dynamic_bus_num的判断分析见另一篇博文,
条件成立则执行函数i2c_scan_static_board_info(adap),如下:
static void i2c_scan_static_board_info(struct i2c_adapter *adapter){struct i2c_devinfo*devinfo;down_read(&__i2c_board_lock);list_for_each_entry(devinfo, &__i2c_board_list, list) {if (devinfo->busnum == adapter->nr&& !i2c_new_device(adapter,&devinfo->board_info))dev_err(&adapter->dev,"Can't create device at 0x%02x\n",devinfo->board_info.addr);}up_read(&__i2c_board_lock);}在此函数中完成一个重要的工作。首先从__i2c_board_list链表上获取一个devinfo信息结构体,此结
构体由前面的i2c_register_board_info()添加到i2c设备链表上的。结构体中包含板上的i2c at24c02设
备相关信息。然后在此函数中调用i2c_new_device()以从链表上获取的devinfo作为参数,
i2c_new_device函数根据devinfo中的设备相关信息来创建client,内核中使用client来代表at24c02设备。
struct i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info){。。。 。。。 client->dev.parent = &client->adapter->dev;client->dev.bus = &i2c_bus_type;client->dev.type = &i2c_client_type; 。。。 。。。 status = device_register(&client->dev);}
可见client和adapter同样都被注册到i2c_bus_type总线上了,并且还通过
client->dev.type = &i2c_client_type;
指定了设备类型i2c_client_type。最后通过device_register()函数将此client注册到i2c总线上。
所以此i2c总线同时包含了adapter和client,即i2c主机(s3c2440的i2c控制器)、i2c从设备at24c02。
到这一步内核实现了adapter device和client device的注册,接着要通过函数bus_for_each_drv()
来扫描i2c总线,检测刚注册到i2c总线的adapter是否有对应的驱动。
bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
不过目前肯定失败,因为到目前为止还未注册adapter driver。
所以系统接着执行后续步骤。
总结
至此,执行完i2c_add_numbered_adapter函数后,内核的i2c总线上已有adapter device和client device,
但是i2c总线此时还未有adapter driver和client driver。
i2c子系统将继续执行初始化函数,下步就是将i2c设备作为字符设备注册到系统,并且注册adapter的驱动,
以及在/dev目录下生成i2c设备文件等操作。实现这一步的函数是i2c_dev_init()。
- i2c子系统之adapter device和client device注册——i2c_add_number_adapter()
- 协议[I2C]_I2C子系统之adapter device和client device注册——I2C_add_number_adapter()
- i2c子系统之 adapter driver注册——i2c_dev_init()
- I2C子系统之 adapter driver注册——I2C_dev_init()
- i2c device 注册方式
- 协议[I2C]_I2C子系统之 adapter driver注册——I2C_dev_init()
- soc camera子系统之注册video device设备
- linux IIC子系统分析(五)——I2C plaform device 初始化
- soc camera 子系统之soc camera host 与soc camera device 注册
- soc camera子系统之初始化i2c client
- OMAP3630 I2C device驱动
- Linux I2C device driver
- linux内核的I2C子系统详解4——i2c-s3c2410.c文件中的adapter、algorithm
- i2c子系统之i2c bus初始化——i2c_init()
- I2C子系统之I2C bus初始化——I2C_init()
- Platform Device和Platform_driver注册过程
- usb hub和usb device注册过程
- struct device — The basic device structure
- Windows杂记
- html转化生成dom
- Debian包管理工具——APT的工作原理详解
- 酷壳陈皓:如何学好C++语言
- mac下卸载mysql的方法
- i2c子系统之adapter device和client device注册——i2c_add_number_adapter()
- android分辨率详解
- 完全仿QQ好友列表,自定义ExpandableListView!
- 2D仿真组一期计划-日志1.0Beta
- android2.2 2.3状态栏区别
- Launcher 个人心得
- Http头 Range、Content-Range
- SQL获取所有用户名,数据库名、所有表名、所有字段名及字段类型
- jsp标签====jstl标准标签库