Linux I2C core

来源:互联网 发布:初级程序员考试大纲 编辑:程序博客网 时间:2024/06/05 02:11

Linux I2C core

File path : kernel/driver/i2c/i2c-core.c

I2C bus driver and device driver以I2C core作为核心,i2c-core.c中为bus driver and device driver提供了一组不依赖于硬件平台的接口函数。

(1)增加/删除 i2c_adapter

int i2c_add_adapter(struct i2c_adapter *adap);int i2c_del_adapter(struct i2c_adapter *adap);

(2)增加/删除 i2c_driver

int i2c_register_driver(struct module *owner, struct *driver);int i2c_del_driver(struct i2c_driver *driver);inline int i2c_add_driver(struct i2c_driver *driver);

(3)i2c_client 依附/脱离

int i2c_attach_client(struct i2c_client *client);int i2c_detach_client(struct i2c_client *client);

当一个具体的client被侦测到并被关联到的时候,设备和sysfs文件将被注册,相反,在client被取消关联的时候,sysfs文件和设备也被注销,从下面的代码所示:

int i2c_attach_client(struct i2c_client *client){    ...    device_register(&client->dev);    device_create_file(&client->dev, &dev_attr_client_name);    return 0;    }    int i2c_detach_client(struct i2c_client *client)    {    ...    device_remove_file(&client->dev, &dev_attr_client_name);    device_unregister(&client->dev);    ...}

(4)I2C 传输、发送和接收。

int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num);int i2c_master_send(struct i2c_client *client,const char *buf ,int count);int i2c_master_recv(struct i2c_client *client, char *buf ,int count);

i2c_transfer() 函 数 用 于 进 行 I2C 适 配 器 和 I2C 设 备 之 间 的 一 组 消 息 交 互 ,i2c_master_send()函数和 i2c_master_recv()函数内部会调用i2c_transfer()函数分别完成一条写消息和一条读消息,如下代码所示:

int i2c_master_send(struct i2c_client *client,const char *buf ,int count){    int ret;    struct i2c_adapter *adap=client->adapter;    struct i2c_msg msg;    /*构造一个写消息*/    msg.addr = client->addr;    msg.flags = client->flags & I2C_M_TEN;    msg.len = count;    msg.buf = (char *)buf;    /*传输消息*/    ret = i2c_transfer(adap, &msg, 1);    return (ret == 1) ? count : ret;}
int i2c_master_recv(struct i2c_client *client, char *buf ,int count){    struct i2c_adapter *adap=client->adapter;    struct i2c_msg msg;    int ret;    /*构造一个读消息*/    msg.addr = client->addr;    msg.flags = client->flags & I2C_M_TEN;    msg.flags |= I2C_M_RD;    msg.len = count;    msg.buf = buf;    /*传输消息*/    ret = i2c_transfer(adap, &msg, 1);    /* 成功(1 条消息被处理), 返回读的字节数 */    return (ret == 1) ? count : ret;}

i2c_transfer()函数本身不具备驱动适配器物理硬件完成消息交互的能力,它只是寻找到 i2c_adapter 对应的 i2c_algorithm,并使用 i2c_algorithm 的master_xfer()

int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num){    int ret;    if (adap->algo->master_xfer) {        down(&adap->bus_lock);        ***ret = adap->algo->master_xfer(adap,msgs,num); /* 消息传输 */***        up(&adap->bus_lock);        return ret;    } else {        dev_dbg(&adap->dev, "I2C level transfers not supported\n");        return -ENOSYS;    }}
0 0
原创粉丝点击