了解了i2c總線的主要結構成員及適配器、設備驅動的註冊後,現在我們從上而下的來研究一下i2c總線的使用(仍然以i2c-dev.c為例):
1、這是面向用戶的虛擬字符設備所提供的所有i2c總線操作接口函數:
static const struct file_operations i2cdev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = i2cdev_read,
.write = i2cdev_write,
.ioctl = i2cdev_ioctl,
.open = i2cdev_open,
.release = i2cdev_release,
};
1)drivers/i2c/i2c-dev.c
static int i2cdev_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct i2c_client *client;
struct i2c_adapter *adap;
struct i2c_dev *i2c_dev;
i2c_dev = i2c_dev_get_by_minor(minor); //通過設備文件的從設備號查找對應的i2c_dev
if (!i2c_dev)
return -ENODEV;
adap = i2c_get_adapter(i2c_dev->adap->nr); //查找對於的adap
if (!adap)
return -ENODEV;
client = kzalloc(sizeof(*client), GFP_KERNEL); //i2c從設備描述結構體
if (!client) {
i2c_put_adapter(adap);
return -ENOMEM;
}
snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
client->driver = &i2cdev_driver;
/* registered with adapter, passed as client to user */
client->adapter = adap;
file->private_data = client;
return 0;
}
注:
i2cdev_open的主要作用是構建並初始化用於描述i2c從設備的結構體struct i2c_client。
2)drivers/i2c/i2c-dev.c
i2cdev_read
-> i2c_master_recv
-> i2c_transfer
-> adap->algo->master_xfer(s3c24xx_i2c_xfer)
3)drivers/i2c/i2c-dev.c
i2cdev_write
-> i2c_master_send
-> i2c_transfer
-> adap->algo->master_xfer(s3c24xx_i2c_xfer)
7)drivers/i2c/busses/i2c-s3c2410.c
s3c24xx_i2c_xfer
-> s3c24xx_i2c_doxfer(wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5)) <----|
-> s3c24xx_i2c_irq |
-> i2s_s3c_irq_nextbyte |
-> s3c24xx_i2c_stop |
-> s3c24xx_i2c_master_complete(wake_up(&i2c->wait))------------------|
1、這是面向用戶的虛擬字符設備所提供的所有i2c總線操作接口函數:
static const struct file_operations i2cdev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = i2cdev_read,
.write = i2cdev_write,
.ioctl = i2cdev_ioctl,
.open = i2cdev_open,
.release = i2cdev_release,
};
1)drivers/i2c/i2c-dev.c
static int i2cdev_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct i2c_client *client;
struct i2c_adapter *adap;
struct i2c_dev *i2c_dev;
i2c_dev = i2c_dev_get_by_minor(minor); //通過設備文件的從設備號查找對應的i2c_dev
if (!i2c_dev)
return -ENODEV;
adap = i2c_get_adapter(i2c_dev->adap->nr); //查找對於的adap
if (!adap)
return -ENODEV;
client = kzalloc(sizeof(*client), GFP_KERNEL); //i2c從設備描述結構體
if (!client) {
i2c_put_adapter(adap);
return -ENOMEM;
}
snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
client->driver = &i2cdev_driver;
/* registered with adapter, passed as client to user */
client->adapter = adap;
file->private_data = client;
return 0;
}
注:
i2cdev_open的主要作用是構建並初始化用於描述i2c從設備的結構體struct i2c_client。
2)drivers/i2c/i2c-dev.c
i2cdev_read
-> i2c_master_recv
-> i2c_transfer
-> adap->algo->master_xfer(s3c24xx_i2c_xfer)
3)drivers/i2c/i2c-dev.c
i2cdev_write
-> i2c_master_send
-> i2c_transfer
-> adap->algo->master_xfer(s3c24xx_i2c_xfer)
7)drivers/i2c/busses/i2c-s3c2410.c
s3c24xx_i2c_xfer
-> s3c24xx_i2c_doxfer(wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5)) <----|
-> s3c24xx_i2c_irq |
-> i2s_s3c_irq_nextbyte |
-> s3c24xx_i2c_stop |
-> s3c24xx_i2c_master_complete(wake_up(&i2c->wait))------------------|
全站熱搜
留言列表