1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/i2c.h>
4 #include <linux/miscdevice.h>
5 #include <linux/delay.h>
6 #include <linux/fs.h>
7 #include <linux/device.h>
8
9
10 //声明一个i2c client指针--保存probe中的i2c client
11 static struct i2c_client *at24_client;
12 static struct miscdevice e2prom_misc;
13
14
15 //重写类似于i2c_master_send()/i2c_master_recv()
16 int at24_i2c_send(struct i2c_client *client, char *buf, int count)
17 {
18 int ret;
19
20 struct i2c_adapter *adapter = client->adapter;
21 struct i2c_msg msg;
22
23 msg.addr = client->addr;
24 msg.flags = 0; //读1还是写0
25 msg.len = count;
26 msg.buf = buf;
27 //参数1---适配器--来自于i2c client
28 //参数2--数据包
29 //参数3--数据包的个数
30 //返回值--正确返回消息的个数,错误返回负数
31 ret = i2c_transfer(adapter, &msg, 1);
32
33 return ret==1?count:ret;
34
35 }
36
37 int at24_i2c_recv(struct i2c_client *client, char *buf, int count)
38 {
39 int ret;
40
41 struct i2c_adapter *adapter = client->adapter;
42 struct i2c_msg msg;
43
44 msg.addr = client->addr;
45 msg.flags = 1; //读1还是写0
46 msg.len = count;
47 msg.buf = buf;
48 //参数1---适配器--来自于i2c client
49 //参数2--数据包
50 //参数3--数据包的个数
51 //返回值--正确返回消息的个数,错误返回负数
52 ret = i2c_transfer(adapter, &msg, 1);
53
54 return ret==1?count:ret;
55
56 }
57
58
59 const struct file_operations at24_fops = {
60
61
62 };
63
64
65 int at24_drv_probe(struct i2c_client *client, const struct i2c_device_id *id)
66 {
67
68 printk("id->name = %s, id->driver_data = 0x%x\n", id->name, id->driver_data);
69
70 // 0- 保存i2c_client
71 at24_client = client;
72
73 // 1, 与用户交互
74 e2prom_misc.name = "at24_dev";
75 e2prom_misc.minor = MISC_DYNAMIC_MINOR,
76 e2prom_misc.fops = &at24_fops,
77 misc_register(&e2prom_misc);
78
79 // 2, 与硬件交互(初始化硬件)--最终委托i2c adpater层与硬件打交道
80 // e2prom上电就能工作,并不需要特定一些初始化
81 //以下代码主要演示如何操作从设备
82
83
84 int ret;
85
86 char sendbuf[10] = {0x8/*写的地址*/, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b, 0x8b, 0x9b};
87
88 ret = at24_i2c_send(client, sendbuf, 10);
89 if(ret < 0)
90 {
91 printk("at24_i2c_send error\n");
92 misc_deregister(&e2prom_misc);
93 return ret;
94 }
95
96 mdelay(3);
97 //验证是否写入正确
98 //先写地址
99 char addr = 0x8;
100 ret = at24_i2c_send(client, &addr, 1);
101 if(ret < 0)
102 {
103 printk("at24_i2c_send error\n");
104 misc_deregister(&e2prom_misc);
105 return ret;
106 }
107 char recvbuf[8];
108 ret = at24_i2c_recv(client, recvbuf, 8);
109 if(ret < 0)
110 {
111 printk("at24_i2c_recv error\n");
112 misc_deregister(&e2prom_misc);
113 return ret;
114 }
115 int i;
116 for(i=0; i<8; i++)
117 printk("recvbuf[%d] = 0x%x\n", i, recvbuf[i]);
118
119
120 return 0;
121
122
123 }
124
125
126
127 int at24_drv_remove(struct i2c_client *client)
128 {
129 misc_deregister(&e2prom_misc);
130
131 return 0;
132 }
133
134
135
136 const struct i2c_device_id at24_id_table[] = {
137 {"at24c02", 0x2},
138 {"at24c04", 0x4},
139 {"at24c08", 0x5},
140 {"at24c16", 0x6},
141 {},
142 };
143
144
145 struct i2c_driver at24_i2c_drv = {
146 .probe = at24_drv_probe,
147 .remove = at24_drv_remove,
148 .driver = {
149 .name = "at24_drv", //一定要有--/sys/bus/i2c/drivers/at24_drv
150 },
151 .id_table = at24_id_table,
152
153 };
154
155
156 static int __init at24_i2c_drv_init(void)
157 {
158
159 //注册一个i2c driver
160 return i2c_add_driver(&at24_i2c_drv);
161
162
163 }
164
165 static void __exit at24_i2c_drv_exit(void)
166 {
167 i2c_del_driver(&at24_i2c_drv);
168 }
169
170
171 late_initcall(at24_i2c_drv_init);
172 module_exit(at24_i2c_drv_exit);
173 MODULE_LICENSE("GPL");