1 #include <linux/kernel.h>
2 #include <linux/module.h>
4 #include <linux/slab.h>
5 #include <linux/init.h>
6 #include <linux/list.h>
8 #include <linux/jiffies.h>
9 #include <linux/miscdevice.h>
10 #include <linux/delay.h>
11 #include <linux/rwsem.h>
14 #include <asm/uaccess.h>
16 #include "i2c-dev-rk29.h"
17 #include "../i2c-core.h"
20 #define I2C_DEV_SCL_RATE 100 * 1000
22 struct completion i2c_dev_complete = {
25 struct i2c_dump_info g_dump;
27 static void i2c_dev_get_list(struct i2c_list_info *list)
29 struct i2c_devinfo *devinfo;
30 struct i2c_adapter *adap = NULL;
33 memset(list, 0, sizeof(struct i2c_list_info));
35 down_read(&__i2c_board_lock);
36 list_for_each_entry(devinfo, &__i2c_board_list, list) {
37 if(devinfo->busnum >= MAX_I2C_BUS) {
39 up_read(&__i2c_board_lock);
42 adap = i2c_get_adapter(devinfo->busnum);
44 list->adap[devinfo->busnum].id = adap->nr;
45 strcpy(list->adap[devinfo->busnum].name, adap->name);
47 index = list->adap[devinfo->busnum].client_nr++;
48 if(index >= MAX_CLIENT_NUM || index == -1)
49 list->adap[devinfo->busnum].client_nr = -1;
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);
57 list->adap_nr = MAX_I2C_BUS;
58 up_read(&__i2c_board_lock);
61 void i2c_dev_dump_start(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
65 memset(&g_dump, 0, sizeof(struct i2c_dump_info));
67 g_dump.addr = msgs[0].addr;
69 for(i = 0; i < num; i++) {
70 if(msgs[i].flags & I2C_M_RD) {
71 if(msgs[i].len >= MAX_VALUE_NUM)
74 g_dump.get_num = msgs[i].len;
77 if(msgs[i].len >= MAX_VALUE_NUM)
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];
88 EXPORT_SYMBOL(i2c_dev_dump_start);
90 void i2c_dev_dump_stop(struct i2c_adapter *adap, struct i2c_msg *msgs, int num, int ret)
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];
104 if(i2c_dev_complete.done == 0)
105 complete(&i2c_dev_complete);
108 EXPORT_SYMBOL(i2c_dev_dump_stop);
110 static void i2c_dev_get_dump(struct i2c_dump_info *dump)
112 init_completion(&i2c_dev_complete);
113 wait_for_completion_killable(&i2c_dev_complete);
117 static int i2c_dev_get_normal(struct i2c_adapter *adap, struct i2c_get_info *get)
120 char buf[MAX_VALUE_NUM];
123 msg.addr = (__u16)get->addr;
124 msg.flags = I2C_M_RD;
127 msg.scl_rate = I2C_DEV_SCL_RATE;
129 ret = i2c_transfer(adap, &msg, 1);
131 for(i = 0; i < get->num; i++)
132 get->value[i] = buf[i];
138 static int i2c_dev_set_normal(struct i2c_adapter *adap, struct i2c_set_info *set)
141 char buf[MAX_VALUE_NUM];
144 msg.addr = (__u16)set->addr;
148 msg.scl_rate = I2C_DEV_SCL_RATE;
150 ret = i2c_transfer(adap, &msg, 1);
151 return(ret == 1)? 0: -1;
153 static int i2c_dev_get_reg8(struct i2c_adapter *adap, struct i2c_get_info *get)
156 struct i2c_msg msgs[2];
158 char buf[MAX_VALUE_NUM];
160 msgs[0].addr = (__u16)get->addr;
164 msgs[0].scl_rate = I2C_DEV_SCL_RATE;
166 msgs[1].addr = get->addr;
167 msgs[1].flags = I2C_M_RD;
168 msgs[1].len = get->num;
170 msgs[1].scl_rate = I2C_DEV_SCL_RATE;
172 ret = i2c_transfer(adap, msgs, 2);
174 for(i = 0; i < get->num; i++)
175 get->value[i] = buf[i];
183 static int i2c_dev_set_reg8(struct i2c_adapter *adap, struct i2c_set_info *set)
187 char buf[MAX_VALUE_NUM + 1];
189 buf[0] = (char)set->reg;
190 for(i = 0; i < set->num; i++)
191 buf[i+1] = (char)set->value[i];
193 msg.addr = (__u16)set->addr;
195 msg.len = set->num + 1;
197 msg.scl_rate = I2C_DEV_SCL_RATE;
200 ret = i2c_transfer(adap, &msg, 1);
201 return (ret == 1)? 0: -1;
204 static int i2c_dev_get_reg16(struct i2c_adapter *adap, struct i2c_get_info *get)
207 struct i2c_msg msgs[2];
209 char buf[MAX_VALUE_NUM * 2];
211 reg[0] = (char)(get->reg & 0xff);
212 reg[1] = (char)((get->reg >>8) & 0xff);
214 msgs[0].addr = (__u16)get->addr;
218 msgs[0].scl_rate = I2C_DEV_SCL_RATE;
220 msgs[1].addr = get->addr;
221 msgs[1].flags = I2C_M_RD;
222 msgs[1].len = get->num * 2;
224 msgs[1].scl_rate = I2C_DEV_SCL_RATE;
226 ret = i2c_transfer(adap, msgs, 2);
228 for(i = 0; i < get->num; i++)
229 get->value[i] = buf[2*i] & (buf[2*i+1]<<8);
236 static int i2c_dev_set_reg16(struct i2c_adapter *adap, struct i2c_set_info *set)
240 char buf[2 * (MAX_VALUE_NUM + 1)];
242 buf[0] = (char)(set->reg & 0xff);
243 buf[1] = (char)((set->reg >>8) & 0xff);
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);
250 msg.addr = set->addr;
252 msg.len = 2 * (set->num + 1);
254 msg.scl_rate = I2C_DEV_SCL_RATE;
256 ret = i2c_transfer(adap, &msg, 1);
257 return (ret == 1)? 0: -1;
260 static int i2c_dev_get_value(struct i2c_get_info *get)
263 struct i2c_adapter *adap = NULL;
265 if(get->num > MAX_VALUE_NUM)
267 adap = i2c_get_adapter(get->id);
272 ret = i2c_dev_get_reg8(adap, get);
275 ret = i2c_dev_get_reg16(adap, get);
281 ret = i2c_dev_get_normal(adap, get);
287 static int i2c_dev_set_value(struct i2c_set_info *set)
290 struct i2c_adapter *adap = NULL;
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)
295 adap = i2c_get_adapter(set->id);
300 ret = i2c_dev_set_reg8(adap, set);
303 ret = i2c_dev_set_reg16(adap, set);
309 ret = i2c_dev_set_normal(adap, set);
315 static int i2c_dev_open(struct inode *inode, struct file *file)
319 static long i2c_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
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;
329 list = kzalloc(sizeof(struct i2c_list_info), GFP_KERNEL);
334 i2c_dev_get_list(list);
335 if(copy_to_user((void __user *)arg, (void *)list, sizeof(struct i2c_list_info)))
340 i2c_dev_get_dump(&dump);
341 if(copy_to_user((void __user *)arg, (void *)&dump, sizeof(struct i2c_dump_info)))
345 if(copy_from_user((void *)&get, (void __user *)arg, sizeof(struct i2c_get_info))) {
349 if(i2c_dev_get_value(&get) < 0) {
353 if(copy_to_user((void __user *)arg, (void *)&get, sizeof(struct i2c_get_info)))
357 if(copy_from_user((void *)&set, (void __user *)arg, sizeof(struct i2c_set_info))) {
361 ret = i2c_dev_set_value(&set);
368 static int i2c_dev_release(struct inode *inode, struct file *file)
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,
379 static struct miscdevice i2c_misc_dev = {
380 .minor = MISC_DYNAMIC_MINOR,
381 .name = I2C_DEV_NAME,
382 .fops = &i2c_dev_fops,
384 static int __init i2c_dev_init(void)
386 return misc_register(&i2c_misc_dev);
388 static void __exit i2c_dev_exit(void)
390 misc_deregister(&i2c_misc_dev);
392 module_init(i2c_dev_init);
393 module_exit(i2c_dev_exit);
395 MODULE_DESCRIPTION("Driver for RK29 I2C Device");
396 MODULE_AUTHOR("kfx, kfx@rock-chips.com");
397 MODULE_LICENSE("GPL");