123 lines
3.3 KiB
C
123 lines
3.3 KiB
C
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/init.h>
|
|
#include <asm/io.h> //含有ioremap函数iounmap函数
|
|
#include <asm/uaccess.h> //含有copy_from_user函数和含有copy_to_user函数
|
|
#include <linux/device.h> //含有类相关的设备函数
|
|
#include <linux/cdev.h>
|
|
#include <linux/platform_device.h> //包含platform函数
|
|
#include <linux/of.h> //包含设备树相关函数
|
|
#include <linux/i2c.h>
|
|
#include <linux/kobject.h> //包含sysfs文件系统对象类
|
|
#include <linux/sysfs.h> //包含sysfs操作文件函数
|
|
#include <linux/regmap.h>
|
|
|
|
|
|
static int recv[16] = {0}; //保存接收数据
|
|
|
|
|
|
static struct kobject *at24c02_kobj; //定义一个led_kobj
|
|
|
|
static struct regmap *at24c02_regmap;
|
|
|
|
|
|
static const struct regmap_config at24c02_config =
|
|
{
|
|
.reg_bits = 8, //寄存器8位
|
|
.val_bits = 8, //数据8位
|
|
.max_register = 255, //最大寄存器255个
|
|
.cache_type = REGCACHE_NONE, //不使用cache
|
|
.volatile_reg = false,
|
|
};
|
|
|
|
static ssize_t at24c02_show(struct kobject* kobjs,struct kobj_attribute *attr,char *buf)
|
|
{
|
|
int ret;
|
|
ret = regmap_write(at24c02_regmap,0x01,0); //先发写地址操作
|
|
if(ret)
|
|
{
|
|
printk(KERN_ERR"write addr failed!\n");
|
|
return ret;
|
|
}
|
|
ret = regmap_read(at24c02_regmap,0x01,&recv[0]); //然后发读数据操作
|
|
if(ret)
|
|
{
|
|
printk(KERN_ERR"read addr failed!\n");
|
|
return ret;
|
|
}
|
|
return sprintf(buf,"read status register=0x%x\n",recv[0]);
|
|
}
|
|
|
|
static ssize_t at24c02_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t count)
|
|
{
|
|
int ret;
|
|
|
|
ret = regmap_write(at24c02_regmap,0x01,0x2f);//写一个字节数据0x2f
|
|
if(!ret)
|
|
{
|
|
printk(KERN_ERR"write data failed!\n");
|
|
}
|
|
return count;
|
|
}
|
|
|
|
static struct kobj_attribute at24c02_attr = __ATTR(at24c02_dev,0660,at24c02_show,at24c02_store);
|
|
|
|
static int at24c02_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
{
|
|
int ret;
|
|
at24c02_kobj = kobject_create_and_add("sys_at24c02",NULL);
|
|
if(at24c02_kobj == NULL)
|
|
{
|
|
printk(KERN_INFO"create at24c02_kobj failed!\n");
|
|
return -1;
|
|
}
|
|
ret = sysfs_create_file(at24c02_kobj, &at24c02_attr.attr);
|
|
if(ret != 0)
|
|
{
|
|
printk(KERN_INFO"create at24c02_dev file failed!\n");
|
|
return -1;
|
|
}
|
|
at24c02_regmap = regmap_init_i2c(client,&at24c02_config);
|
|
return 0;
|
|
}
|
|
|
|
static int at24c02_remove(struct i2c_client *client)
|
|
{
|
|
sysfs_remove_file(at24c02_kobj, &at24c02_attr.attr); //删除属性
|
|
kobject_put(at24c02_kobj); //删除对象
|
|
regmap_exit(at24c02_regmap);
|
|
printk(KERN_INFO "exit sysfs at24c02!\n");
|
|
return 0;
|
|
}
|
|
|
|
static const struct i2c_device_id at24c02_id[] = {
|
|
{ "test,at24c0x", 0 },
|
|
{ }
|
|
};
|
|
|
|
static const struct of_device_id at24c02_of_match[] = {
|
|
{ .compatible = "test,at24c0x"},
|
|
{ },
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(of, at24c02_of_match);
|
|
|
|
static struct i2c_driver at24c02_driver = {
|
|
.driver = {
|
|
.name = "test,at24c0x",
|
|
.owner = THIS_MODULE,
|
|
.of_match_table = at24c02_of_match,
|
|
},
|
|
.probe = at24c02_probe,
|
|
.remove = at24c02_remove,
|
|
.id_table = at24c02_id,
|
|
};
|
|
|
|
|
|
module_i2c_driver(at24c02_driver);
|
|
|
|
MODULE_LICENSE("GPL"); //不加的话加载会有错误提醒
|
|
MODULE_AUTHOR("1477153217@qq.com"); //作者
|
|
MODULE_VERSION("0.1"); //版本
|
|
MODULE_DESCRIPTION("at24c02_driver"); //简单的描述
|