i2c 应用层与驱动层沟通的结构体就是下面这个, 定义在i2c-dev.c中:
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. 应用层的open和close
应用层的打开和关闭设备函数:
fd = open(“/dev/i2c-0”, O_RDWR );
close(fd);
这两个系统调用分别会调用到i2c-dev.c 中的 .open, 和.release 函数
也就是:
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);
if (!i2c_dev)
return -ENODEV;
adap = i2c_get_adapter(i2c_dev->adap->nr);
if (!adap)
return -ENODEV;
client = kzalloc(sizeof(*client), GFP_KERNEL);
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;
}
static int i2cdev_release(struct inode *inode, struct file *file)
{
struct i2c_client *client = file->private_data;
i2c_put_adapter(client->adapter);
kfree(client);
file->private_data = NULL;
return 0;
}
i2cdev_open() 中先通过次设备号,获得该i2c设备,也就是/dev/i2c-*
i2c_dev = i2c_dev_get_by_minor(minor);
然后通过i2c_dev->adap->nr, 获得与该设备匹配的i2c_adapter。
adap = i2c_get_adapter(i2c_dev->adap->nr);
然后申请一个i2c_client , 每次打开一个i2c设备,都会建立一个i2c_client结构体,用来表示被打开的一个i2c设备。
并给i2c_client赋值, 主要是复制client->driver, 和client->adapter.
client = kzalloc(sizeof(*client), GFP_KERNEL);
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;
client->driver, 该i2c设备的驱动程序。
client->adapter, 该i2c设备依附的i2c_adapter.
2. 应用层的ioctl():
ioctl(fd, request, Addr);
fd 就是打开的i2c设备号。
request,是ioctl 传递给驱动层的commd, 有如下一些定义:
/* ----- commands for the ioctl like i2c_command call:
* note that additional calls are defined in the algorithm and hw
* dependent layers - these can be listed here, or see the
* corresponding header files.
*/
/* -> bit-adapter specific ioctls */
#define I2C_RETRIES 0x0701 /* number of times a device address */
/* should be polled when not */
/* acknowledging */
#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */
/* this is for i2c-dev.c */
#define I2C_SLAVE 0x0703 /* Change slave address */
/* Attn.: Slave address is 7 or 10 bits */
#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */
/* Attn.: Slave address is 7 or 10 bits */
/* This changes the address, even if it */
/* is already taken! */
#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
#define I2C_FUNCS 0x0705 /* Get the adapter functionality */
#define I2C_RDWR 0x0707 /*