Linux Kernel 设备驱动之I2C之host描述
来源:互联网 发布:用51单片机产生正弦波 编辑:程序博客网 时间:2024/04/29 11:19
对于I2C传输来说,其由三部分组成,一个是I2C控制端,二是控制端对外提供的总线,三是总线上的设备。
所以,存在三个方面的抽象,控制端一般叫host或者adapter等,其结构如下:/* * i2c_adapter is the structure used to identify a physical i2c bus along * with the access algorithms necessary to access it. */struct i2c_adapter { struct module *owner; unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_data;这两个是I2C传输数据的关键。
/* data fields that are valid for all devices */ const struct i2c_lock_operations *lock_ops; struct rt_mutex bus_lock; struct rt_mutex mux_lock;
int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */
int nr; char name[48]; struct completion dev_released;
struct mutex userspace_clients_lock; struct list_head userspace_clients;
struct i2c_bus_recovery_info *bus_recovery_info; const struct i2c_adapter_quirks *quirks;};
对于adapter来说,要么静态定义,要么动态分配,在简单初始化后,调用函数
i2c_add_adapter()或者函数i2c_add_numbered_adapter()把adapter添加到
i2c驱动的框架层。
这两个函数都是调用i2c_register_adapter()完成adapter的注册。
static int i2c_register_adapter(struct i2c_adapter *adap){ int res = -EINVAL;
/* Can't register until after driver model init */ if (WARN_ON(!is_registered)) { res = -EAGAIN; goto out_list; }
/* Sanity checks */ if (WARN(!adap->name[0], "i2c adapter has no name")) goto out_list;
if (!adap->algo) { pr_err("adapter '%s': no algo supplied!\n", adap->name); goto out_list; }
if (!adap->lock_ops) adap->lock_ops = &i2c_adapter_lock_ops;
rt_mutex_init(&adap->bus_lock); rt_mutex_init(&adap->mux_lock); mutex_init(&adap->userspace_clients_lock); INIT_LIST_HEAD(&adap->userspace_clients);
/* Set default timeout to 1 second if not already set */ if (adap->timeout == 0) adap->timeout = HZ;
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);设备模型中设备注册 if (res) { pr_err("adapter '%s': can't register device (%d)\n", adap->name, res); goto out_list; }
dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
//PM支持回调
pm_runtime_no_callbacks(&adap->dev); pm_suspend_ignore_children(&adap->dev, true); pm_runtime_enable(&adap->dev);
#ifdef CONFIG_I2C_COMPAT res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev, adap->dev.parent); if (res) dev_warn(&adap->dev, "Failed to create compatibility class link\n");#endif
i2c_init_recovery(adap);
/* create pre-declared device nodes */ of_i2c_register_devices(adap); i2c_acpi_register_devices(adap); i2c_acpi_install_space_handler(adap);
if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap);
/* Notify drivers */ mutex_lock(&core_lock); bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); mutex_unlock(&core_lock);这一步是对总线上设备探测,这里的回调函数是__process_new_adapter
return 0;
out_list: mutex_lock(&core_lock); idr_remove(&i2c_adapter_idr, adap->nr); mutex_unlock(&core_lock); return res;}
在添加总线时,我们看看是否有设备在总线上,如果有则调用设备的驱动,对设备初始化。这里并不一定对设备初始化,
也可以提前做些事情。static int __process_new_adapter(struct device_driver *d, void *data){ return i2c_do_add_adapter(to_i2c_driver(d), data);}
static int i2c_do_add_adapter(struct i2c_driver *driver,设备驱动 struct i2c_adapter *adap)host对象{ /* Detect supported devices on that bus, and instantiate them */ i2c_detect(adap, driver);
/* Let legacy drivers scan this bus for matching devices */ if (driver->attach_adapter) { dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n", driver->driver.name); dev_warn(&adap->dev, "Please use another way to instantiate your i2c_client\n"); /* We ignore the return code; if it fails, too bad */ driver->attach_adapter(adap); } return 0;}
- Linux Kernel 设备驱动之I2C之host描述
- Linux Kernel 设备驱动之I2C之host之数据传输
- Linux Kernel 设备驱动之I2C之client描述
- Linux Kernel 设备驱动之I2C之i2c设备文件
- linux设备驱动之I2C
- Linux Kernel 设备驱动之I2C之client之发送消息格式
- Linux Kernel 设备驱动之I2C之client读写数据API
- Linux Kernel input设备之描述
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- Linux设备驱动之I2C架构分析
- sql映射的xml文件
- C语言进阶:串口
- tableview 自定义cell 不显示 self 与 sel.contentview 的区别 多选右移cell不移动的问题
- HTML 转义字符
- Lua——table.insert
- Linux Kernel 设备驱动之I2C之host描述
- CFileDialog类应用详解
- C++日期类(运算符的重载)
- Win7彻底卸载Oracle 11g(图文步骤)
- git 新建本地仓库,到提交
- Jsoup实现网络爬虫抓取数据
- CODEVS 1230 元素查找
- CT107D蓝桥杯EEPROM使用(8)
- 解决 vc6 unresolved external symbol ___security_cookie 问题