Merge remote-tracking branch 'origin/upstream/linux-linaro-lsk-v3.10-android+android...
[firefly-linux-kernel-4.4.55.git] / drivers / i2c / busses / i2c-dev-rk29.c
1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/fs.h>
4 #include <linux/slab.h>
5 #include <linux/init.h>
6 #include <linux/list.h>
7 #include <linux/i2c.h>
8 #include <linux/jiffies.h>
9 #include <linux/miscdevice.h>
10 #include <linux/delay.h>
11 #include <linux/rwsem.h>
12
13
14 #include <asm/uaccess.h>
15
16 #include "i2c-dev-rk29.h"
17 #include "../i2c-core.h"
18
19
20 #define I2C_DEV_SCL_RATE        100 * 1000
21
22 struct completion               i2c_dev_complete = {
23         .done = -1,
24 };
25 struct i2c_dump_info    g_dump;
26
27 static void i2c_dev_get_list(struct i2c_list_info *list)
28 {
29         struct i2c_devinfo      *devinfo;
30         struct i2c_adapter *adap = NULL;
31         int index;
32
33         memset(list, 0, sizeof(struct i2c_list_info));
34         
35         down_read(&__i2c_board_lock);
36         list_for_each_entry(devinfo, &__i2c_board_list, list) {
37                 if(devinfo->busnum >= MAX_I2C_BUS) {
38                         list->adap_nr = -1;
39                         up_read(&__i2c_board_lock);
40                         return;
41                 }
42                 adap = i2c_get_adapter(devinfo->busnum);
43                 if(adap != NULL) {
44                         list->adap[devinfo->busnum].id = adap->nr;
45                         strcpy(list->adap[devinfo->busnum].name, adap->name);
46
47                         index = list->adap[devinfo->busnum].client_nr++;
48                         if(index >= MAX_CLIENT_NUM || index == -1)
49                                 list->adap[devinfo->busnum].client_nr = -1;
50                         else {
51                                 list->adap[devinfo->busnum].client[index].addr = devinfo->board_info.addr;
52                                 strcpy(list->adap[devinfo->busnum].client[index].name,
53                                                 devinfo->board_info.type);
54                         }
55                 }
56         }
57         list->adap_nr = MAX_I2C_BUS;
58         up_read(&__i2c_board_lock);
59         return;
60 }
61 void i2c_dev_dump_start(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
62 {
63         int i, j;
64         
65         memset(&g_dump, 0, sizeof(struct i2c_dump_info));
66         g_dump.id = adap->nr;
67         g_dump.addr = msgs[0].addr;
68         
69         for(i = 0; i < num; i++) {
70                 if(msgs[i].flags & I2C_M_RD) {
71                         if(msgs[i].len >= MAX_VALUE_NUM)
72                                 g_dump.get_num = -1;
73                         else
74                                 g_dump.get_num = msgs[i].len;
75                 }
76                 else {
77                         if(msgs[i].len >= MAX_VALUE_NUM)
78                                 g_dump.set_num = -1;
79                         else {
80                                 g_dump.set_num = msgs[i].len;
81                                 for(j = 0; j < msgs[i].len; j++)
82                                         g_dump.set_value[j] = msgs[i].buf[j];
83                         }
84                 }
85         }
86         return;
87 }
88 EXPORT_SYMBOL(i2c_dev_dump_start);
89
90 void i2c_dev_dump_stop(struct i2c_adapter *adap, struct i2c_msg *msgs, int num, int ret)
91 {
92         int i, j;
93         
94         if(ret < 0) {
95                 g_dump.get_num = 0;
96                 g_dump.set_num = 0;
97         }
98         for(i = 0; i < num; i++) {
99                 if((msgs[i].flags & I2C_M_RD) && (g_dump.get_num > 0)) {
100                         for(j = 0; j < msgs[i].len; j++)
101                                 g_dump.get_value[j] = msgs[i].buf[j];
102                 }
103         }
104         if(i2c_dev_complete.done == 0)
105                 complete(&i2c_dev_complete);
106         return;
107 }
108 EXPORT_SYMBOL(i2c_dev_dump_stop);
109
110 static void i2c_dev_get_dump(struct i2c_dump_info *dump)
111 {
112         init_completion(&i2c_dev_complete);
113         wait_for_completion_killable(&i2c_dev_complete);
114         *dump = g_dump;
115         return;
116 }
117 static int i2c_dev_get_normal(struct i2c_adapter *adap, struct i2c_get_info *get)
118 {
119         struct i2c_msg msg;
120         char buf[MAX_VALUE_NUM];
121         int ret, i;
122
123         msg.addr = (__u16)get->addr;
124         msg.flags = I2C_M_RD;
125         msg.len = get->num;
126         msg.buf = buf;
127         msg.scl_rate = I2C_DEV_SCL_RATE;
128
129         ret = i2c_transfer(adap, &msg, 1);
130         if(ret == 1) {
131                 for(i = 0; i < get->num; i++)
132                         get->value[i] = buf[i];
133                 return 0;
134         }
135         else
136                 return -1;
137 }
138 static int i2c_dev_set_normal(struct i2c_adapter *adap, struct i2c_set_info *set)
139 {
140         struct i2c_msg msg;
141         char buf[MAX_VALUE_NUM];
142         int ret;
143
144         msg.addr = (__u16)set->addr;
145         msg.flags = 0;
146         msg.len = set->num;
147         msg.buf = buf;
148         msg.scl_rate = I2C_DEV_SCL_RATE;
149
150         ret = i2c_transfer(adap, &msg, 1);
151         return(ret == 1)? 0: -1;
152 }
153 static int i2c_dev_get_reg8(struct i2c_adapter *adap, struct i2c_get_info *get)
154 {
155         int ret, i;
156         struct i2c_msg msgs[2];
157         char reg = get->reg;
158         char buf[MAX_VALUE_NUM];
159         
160         msgs[0].addr = (__u16)get->addr;
161         msgs[0].flags = 0;
162         msgs[0].len = 1;
163         msgs[0].buf = &reg;
164         msgs[0].scl_rate = I2C_DEV_SCL_RATE;
165
166         msgs[1].addr = get->addr;
167         msgs[1].flags = I2C_M_RD;
168         msgs[1].len = get->num;
169         msgs[1].buf = buf;
170         msgs[1].scl_rate = I2C_DEV_SCL_RATE;
171
172         ret = i2c_transfer(adap, msgs, 2);
173         if(ret == 2) {
174                 for(i = 0; i < get->num; i++)
175                         get->value[i] = buf[i];
176                 return 0;
177         }
178         else
179                 return -1;
180
181 }
182
183 static int i2c_dev_set_reg8(struct i2c_adapter *adap, struct i2c_set_info *set)
184 {
185         int ret, i;
186         struct i2c_msg msg;
187         char buf[MAX_VALUE_NUM + 1];
188
189         buf[0] = (char)set->reg;
190         for(i = 0; i < set->num; i++) 
191                 buf[i+1] = (char)set->value[i];
192         
193         msg.addr = (__u16)set->addr;
194         msg.flags = 0;
195         msg.len = set->num + 1;
196         msg.buf = buf;
197         msg.scl_rate = I2C_DEV_SCL_RATE;
198
199
200         ret = i2c_transfer(adap, &msg, 1);
201         return (ret == 1)? 0: -1;
202 }
203
204 static int i2c_dev_get_reg16(struct i2c_adapter *adap, struct i2c_get_info *get)
205 {
206         int ret, i;
207         struct i2c_msg msgs[2];
208         char reg[2];
209         char buf[MAX_VALUE_NUM * 2];
210
211         reg[0] = (char)(get->reg & 0xff);
212         reg[1] = (char)((get->reg >>8) & 0xff);
213         
214         msgs[0].addr = (__u16)get->addr;
215         msgs[0].flags = 0;
216         msgs[0].len = 2;
217         msgs[0].buf = reg;
218         msgs[0].scl_rate = I2C_DEV_SCL_RATE;
219
220         msgs[1].addr = get->addr;
221         msgs[1].flags = I2C_M_RD;
222         msgs[1].len = get->num * 2;
223         msgs[1].buf = buf;
224         msgs[1].scl_rate = I2C_DEV_SCL_RATE;
225
226         ret = i2c_transfer(adap, msgs, 2);
227         if(ret == 2) {
228                 for(i = 0; i < get->num; i++)
229                         get->value[i] = buf[2*i] & (buf[2*i+1]<<8);
230                 return 0;
231         }
232         else
233                 return -1;
234
235 }
236 static int i2c_dev_set_reg16(struct i2c_adapter *adap, struct i2c_set_info *set)
237 {
238         struct i2c_msg msg;
239         int ret, i;
240         char buf[2 * (MAX_VALUE_NUM + 1)];
241
242         buf[0] = (char)(set->reg & 0xff);
243         buf[1] = (char)((set->reg >>8) & 0xff);
244         
245         for(i = 0; i < set->num; i++) {
246                 buf[2 * (i + 1)] = (char)(set->value[i] & 0xff);
247                 buf[2 * (i + 1) + 1] = (char)((set->value[i]>>8) & 0xff);
248         }
249
250         msg.addr = set->addr;
251         msg.flags = 0;
252         msg.len = 2 * (set->num + 1);
253         msg.buf = buf;
254         msg.scl_rate = I2C_DEV_SCL_RATE;
255
256         ret = i2c_transfer(adap, &msg, 1);
257         return (ret == 1)? 0: -1;
258 }
259
260 static int i2c_dev_get_value(struct i2c_get_info *get)
261 {
262         int ret = 0;
263         struct i2c_adapter *adap = NULL;
264         
265         if(get->num > MAX_VALUE_NUM)
266                 return -1;
267         adap = i2c_get_adapter(get->id);
268         if(adap == NULL)
269                 return -1;
270         switch(get->mode) {
271                 case 'b': 
272                         ret = i2c_dev_get_reg8(adap, get);
273                         break;
274                 case 's':
275                         ret = i2c_dev_get_reg16(adap, get);
276                         break;
277                 case 'o':
278                         ret = -1;
279                         break;
280                 default:
281                         ret = i2c_dev_get_normal(adap, get);
282                         break;
283         }
284         return ret;
285 }
286
287 static int i2c_dev_set_value(struct i2c_set_info *set)
288 {
289         int ret = 0;
290         struct i2c_adapter *adap = NULL;
291
292         printk("id=%d, addr=0x%x, mode = %c, num = %d, reg = 0x%x, value[0] = %d,",set->id, set->addr, set->mode, set->num, set->reg, set->value[0]);
293         if(set->num > MAX_VALUE_NUM)
294                 return -1;
295         adap = i2c_get_adapter(set->id);
296         if(adap == NULL)
297                 return -1;
298         switch(set->mode) {
299                 case 'b': 
300                         ret = i2c_dev_set_reg8(adap, set);
301                         break;
302                 case 's':
303                         ret = i2c_dev_set_reg16(adap, set);
304                         break;
305                 case 'o':
306                         ret = -1;
307                         break;
308                 default:
309                         ret = i2c_dev_set_normal(adap, set);
310                         break;
311         }
312         return ret;     
313 }
314
315 static int i2c_dev_open(struct inode *inode, struct file *file)
316 {
317         return 0;
318 }
319 static long i2c_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
320 {
321         int ret = 0;
322         struct i2c_list_info *list = NULL;
323         struct i2c_dump_info dump;
324         struct i2c_get_info get;
325         struct i2c_set_info set;
326
327         switch(cmd) {
328                 case I2C_LIST:
329                         list = kzalloc(sizeof(struct i2c_list_info), GFP_KERNEL);
330                         if(list == NULL) {
331                                 ret = -ENOMEM;
332                                 break;
333                         }
334                         i2c_dev_get_list(list);
335                         if(copy_to_user((void __user *)arg, (void *)list, sizeof(struct i2c_list_info)))  
336                                 ret = -EFAULT;
337                         kfree(list);
338                         break;
339                 case I2C_DUMP:
340                         i2c_dev_get_dump(&dump);
341                         if(copy_to_user((void __user *)arg, (void *)&dump, sizeof(struct i2c_dump_info)))  
342                                 ret = -EFAULT;
343                         break;
344                 case I2C_GET:
345                         if(copy_from_user((void *)&get, (void __user *)arg, sizeof(struct i2c_get_info))) { 
346                                 ret = -EFAULT;
347                                 break;
348                         }
349                         if(i2c_dev_get_value(&get) < 0) {
350                                 ret = -EFAULT;
351                                 break;
352                         }
353                         if(copy_to_user((void __user *)arg, (void *)&get, sizeof(struct i2c_get_info)))  
354                                 ret = -EFAULT;
355                         break;
356                 case I2C_SET:
357                         if(copy_from_user((void *)&set, (void __user *)arg, sizeof(struct i2c_set_info))) { 
358                                 ret = -EFAULT;
359                                 break;
360                         }
361                         ret = i2c_dev_set_value(&set);
362                         break;
363                 default:
364                         break;
365         }
366         return ret;
367 }
368 static int i2c_dev_release(struct inode *inode, struct file *file)
369 {
370         return 0;
371 }
372
373 static struct file_operations i2c_dev_fops = {
374         .owner                   = THIS_MODULE,
375         .open                    = i2c_dev_open,
376         .unlocked_ioctl  = i2c_dev_ioctl,
377         .release                 = i2c_dev_release,
378 };
379 static struct miscdevice i2c_misc_dev = {
380         .minor = MISC_DYNAMIC_MINOR,
381         .name = I2C_DEV_NAME,
382         .fops = &i2c_dev_fops,
383 };
384 static int __init i2c_dev_init(void)
385 {
386         return misc_register(&i2c_misc_dev);
387 }
388 static void __exit i2c_dev_exit(void)
389 {
390         misc_deregister(&i2c_misc_dev);
391 }
392 module_init(i2c_dev_init);
393 module_exit(i2c_dev_exit);
394
395 MODULE_DESCRIPTION("Driver for RK29 I2C Device");
396 MODULE_AUTHOR("kfx, kfx@rock-chips.com");
397 MODULE_LICENSE("GPL");
398