驱动并没有注册任何字符设备或者杂项设备,只是向sys文件系统注册了一个二进制属性文件。因此要访问设备,必须通过该文件的读写函数来。
读写函数在probe函数中指定为at24_bin_write和at24_bin_read
1:写函数
static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
struct at24_data *at24;
/* 通过kobj获取device,再获取driver_data */
at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
return at24_write(at24, buf, off, count);
}
static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off,
size_t count)
{
ssize_t retval = 0;
if (unlikely(!count))
return count;
/*
* Write data to chip, protecting against concurrent updates
* from this host, but not from other I2C masters.
*/
/* 访问设备前,加锁*/
mutex_lock(&at24->lock);
while (count) {
ssize_t status;
status = at24_eeprom_write(at24, buf, off, count);//写入数据
if (status <= 0) {
if (retval == 0)
retval = status;
break;
}
buf += status;//调整偏移量
off += status;
count -= status;
retval += status;
}
mutex_unlock(&at24->lock);
return retval;
}
static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,
unsigned offset, size_t count)
{
struct i2c_client *client;
struct i2c_msg msg;
ssize_t status;
unsigned long timeout, write_time;
unsigned next_page;
/* Get corresponding I2C address and adjust offset */
client = at24_translate_offset(at24, &offset);//用于计算地址信息对于多i2c设备的地址
/* write_max is at most a page */
if (count > at24->write_max)//表明最大一次只能写一个page
count = at24->write_max;
/* Never roll over backwards, to the start of this page */