i2c驱动

i2c_dev

驱动注册

static int __init i2c_dev_init(void){
   register_chrdev_region
}
i2cdev_attach_adapter

i2c-dev.c的核心

static const struct file_operations i2cdev_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.read		= i2cdev_read,
	.write		= i2cdev_write,
	.unlocked_ioctl	= i2cdev_ioctl,
	.compat_ioctl	= compat_i2cdev_ioctl,
	.open		= i2cdev_open,
	.release	= i2cdev_release,
};

i2cdev_open

adap = i2c_get_adapter(minor);//根据次设备号找到i2c_adapter
client = kzalloc(sizeof(*client),GFP_KERNEL);//分配i2c_client
client->adapter = adap;
file-> private_data = client; //client和adapter建立联系,作为文件私有暂存

i2cdev_ioctl

client = file-> private_data;
client->addr = arg;

i2c_ioctl_rdwr();
i2c_transfer();

i2cdev_ioctl_smbus();
i2c_smbus_xfer();


smbus:系统管理总线
master_xfer:i2c传输,传输一个或多个i2c_msg
i2c_adapter核心是i2c_algorithm
i2c_algorithm核心是master_xfer,实现取决于硬件

i2c_smbus_read_byte() //接收
i2c_smbus_write_byte() //发送
i2c_smbus_read_byte_data() //读取
i2c_smbus_write_byte_data() //写

i2c_driver

如果I2C设备节点的compatible属性跟of_match_table的某项兼容,则匹配成功
i2c_client.name跟某个of_match_table[i].compatible值相同,则匹配成功
i2c_driver跟i2c_client匹配成功后,就调用i2c_driver.probe函数。

i2c_client表示一个I2C设备

int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len);

i2c_driver

  static struct i2c_driver xxxx_driver =
     {
         .driver =
         {
             .owner = THIS_MODULE, 
             .name = "xxxx",
         }, 
        .id_table = xxxx_idtable,
        .probe = xxxx_probe, 
     }

driver_register

int driver_register(struct device_driver *drv) 
{ 
    ret = bus_add_driver(drv);//把drv驱动,注册到总线 
} 
int bus_add_driver(struct device_driver *drv) 
{ 
    if (drv->bus->p->drivers_autoprobe) { 
        error = driver_attach(drv);   
} 

driver_attach()
//try to bind driver to devices.

int driver_attach(struct device_driver *drv) 
{ 
    return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
} 

probe

static int probe(struct device *dev, struct device_driver *drv) 
{ 
    if (dev->bus->probe) { 
        ret = dev->bus->probe(dev); 
        if (ret) 
            goto probe_failed; 
    }  
    else if (drv->probe) { 
        ret = drv->probe(dev); 
        if (ret) 
            goto probe_failed; 
    } 
    driver_bound(dev); 
    ret = 1; 
    pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name);
} 

参考:
https://blog.csdn.net/lxllinux/article/details/80902071
https://blog.csdn.net/thisway_diy/article/details/119906457
https://blog.csdn.net/thisway_diy/article/details/119906577

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值