]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/i2c/i2c-dev.c
i2c-dev: Cleanups
[mv-sheeva.git] / drivers / i2c / i2c-dev.c
1 /*
2     i2c-dev.c - i2c-bus driver, char device interface  
3
4     Copyright (C) 1995-97 Simon G. Vogl
5     Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
6     Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 /* Note that this is a complete rewrite of Simon Vogl's i2c-dev module.
24    But I have used so much of his original code and ideas that it seems
25    only fair to recognize him as co-author -- Frodo */
26
27 /* The I2C_RDWR ioctl code is written by Kolja Waschk <waschk@telos.de> */
28
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/fs.h>
32 #include <linux/slab.h>
33 #include <linux/smp_lock.h>
34 #include <linux/init.h>
35 #include <linux/i2c.h>
36 #include <linux/i2c-dev.h>
37 #include <asm/uaccess.h>
38
39 static struct i2c_client i2cdev_client_template;
40
41 struct i2c_dev {
42         struct i2c_adapter *adap;
43         struct class_device *class_dev;
44 };
45
46 #define I2C_MINORS      256
47 static struct i2c_dev *i2c_dev_array[I2C_MINORS];
48 static DEFINE_SPINLOCK(i2c_dev_array_lock);
49
50 static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
51 {
52         struct i2c_dev *i2c_dev;
53
54         spin_lock(&i2c_dev_array_lock);
55         i2c_dev = i2c_dev_array[index];
56         spin_unlock(&i2c_dev_array_lock);
57         return i2c_dev;
58 }
59
60 static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
61 {
62         struct i2c_dev *i2c_dev;
63
64         i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
65         if (!i2c_dev)
66                 return ERR_PTR(-ENOMEM);
67
68         spin_lock(&i2c_dev_array_lock);
69         if (i2c_dev_array[adap->nr]) {
70                 spin_unlock(&i2c_dev_array_lock);
71                 dev_err(&adap->dev, "i2c-dev already has a device assigned to this adapter\n");
72                 goto error;
73         }
74         i2c_dev->adap = adap;
75         i2c_dev_array[adap->nr] = i2c_dev;
76         spin_unlock(&i2c_dev_array_lock);
77         return i2c_dev;
78 error:
79         kfree(i2c_dev);
80         return ERR_PTR(-ENODEV);
81 }
82
83 static void return_i2c_dev(struct i2c_dev *i2c_dev)
84 {
85         spin_lock(&i2c_dev_array_lock);
86         i2c_dev_array[i2c_dev->adap->nr] = NULL;
87         spin_unlock(&i2c_dev_array_lock);
88 }
89
90 static ssize_t show_adapter_name(struct class_device *class_dev, char *buf)
91 {
92         struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt));
93
94         if (!i2c_dev)
95                 return -ENODEV;
96         return sprintf(buf, "%s\n", i2c_dev->adap->name);
97 }
98 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
99
100 static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
101                             loff_t *offset)
102 {
103         char *tmp;
104         int ret;
105
106         struct i2c_client *client = (struct i2c_client *)file->private_data;
107
108         if (count > 8192)
109                 count = 8192;
110
111         tmp = kmalloc(count,GFP_KERNEL);
112         if (tmp==NULL)
113                 return -ENOMEM;
114
115         pr_debug("i2c-dev: i2c-%d reading %zd bytes.\n",
116                 iminor(file->f_dentry->d_inode), count);
117
118         ret = i2c_master_recv(client,tmp,count);
119         if (ret >= 0)
120                 ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;
121         kfree(tmp);
122         return ret;
123 }
124
125 static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t count,
126                              loff_t *offset)
127 {
128         int ret;
129         char *tmp;
130         struct i2c_client *client = (struct i2c_client *)file->private_data;
131
132         if (count > 8192)
133                 count = 8192;
134
135         tmp = kmalloc(count,GFP_KERNEL);
136         if (tmp==NULL)
137                 return -ENOMEM;
138         if (copy_from_user(tmp,buf,count)) {
139                 kfree(tmp);
140                 return -EFAULT;
141         }
142
143         pr_debug("i2c-dev: i2c-%d writing %zd bytes.\n",
144                 iminor(file->f_dentry->d_inode), count);
145
146         ret = i2c_master_send(client,tmp,count);
147         kfree(tmp);
148         return ret;
149 }
150
151 static int i2cdev_ioctl(struct inode *inode, struct file *file,
152                 unsigned int cmd, unsigned long arg)
153 {
154         struct i2c_client *client = (struct i2c_client *)file->private_data;
155         struct i2c_rdwr_ioctl_data rdwr_arg;
156         struct i2c_smbus_ioctl_data data_arg;
157         union i2c_smbus_data temp;
158         struct i2c_msg *rdwr_pa;
159         u8 __user **data_ptrs;
160         int i,datasize,res;
161         unsigned long funcs;
162
163         dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
164                 cmd, arg);
165
166         switch ( cmd ) {
167         case I2C_SLAVE:
168         case I2C_SLAVE_FORCE:
169                 if ((arg > 0x3ff) || 
170                     (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
171                         return -EINVAL;
172                 if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg))
173                         return -EBUSY;
174                 client->addr = arg;
175                 return 0;
176         case I2C_TENBIT:
177                 if (arg)
178                         client->flags |= I2C_M_TEN;
179                 else
180                         client->flags &= ~I2C_M_TEN;
181                 return 0;
182         case I2C_PEC:
183                 if (arg)
184                         client->flags |= I2C_CLIENT_PEC;
185                 else
186                         client->flags &= ~I2C_CLIENT_PEC;
187                 return 0;
188         case I2C_FUNCS:
189                 funcs = i2c_get_functionality(client->adapter);
190                 return (copy_to_user((unsigned long __user *)arg, &funcs,
191                                      sizeof(unsigned long)))?-EFAULT:0;
192
193         case I2C_RDWR:
194                 if (copy_from_user(&rdwr_arg, 
195                                    (struct i2c_rdwr_ioctl_data __user *)arg, 
196                                    sizeof(rdwr_arg)))
197                         return -EFAULT;
198
199                 /* Put an arbitrary limit on the number of messages that can
200                  * be sent at once */
201                 if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
202                         return -EINVAL;
203                 
204                 rdwr_pa = (struct i2c_msg *)
205                         kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), 
206                         GFP_KERNEL);
207
208                 if (rdwr_pa == NULL) return -ENOMEM;
209
210                 if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
211                                    rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
212                         kfree(rdwr_pa);
213                         return -EFAULT;
214                 }
215
216                 data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
217                 if (data_ptrs == NULL) {
218                         kfree(rdwr_pa);
219                         return -ENOMEM;
220                 }
221
222                 res = 0;
223                 for( i=0; i<rdwr_arg.nmsgs; i++ ) {
224                         /* Limit the size of the message to a sane amount */
225                         if (rdwr_pa[i].len > 8192) {
226                                 res = -EINVAL;
227                                 break;
228                         }
229                         data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
230                         rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
231                         if(rdwr_pa[i].buf == NULL) {
232                                 res = -ENOMEM;
233                                 break;
234                         }
235                         if(copy_from_user(rdwr_pa[i].buf,
236                                 data_ptrs[i],
237                                 rdwr_pa[i].len)) {
238                                         ++i; /* Needs to be kfreed too */
239                                         res = -EFAULT;
240                                 break;
241                         }
242                 }
243                 if (res < 0) {
244                         int j;
245                         for (j = 0; j < i; ++j)
246                                 kfree(rdwr_pa[j].buf);
247                         kfree(data_ptrs);
248                         kfree(rdwr_pa);
249                         return res;
250                 }
251
252                 res = i2c_transfer(client->adapter,
253                         rdwr_pa,
254                         rdwr_arg.nmsgs);
255                 while(i-- > 0) {
256                         if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
257                                 if(copy_to_user(
258                                         data_ptrs[i],
259                                         rdwr_pa[i].buf,
260                                         rdwr_pa[i].len)) {
261                                         res = -EFAULT;
262                                 }
263                         }
264                         kfree(rdwr_pa[i].buf);
265                 }
266                 kfree(data_ptrs);
267                 kfree(rdwr_pa);
268                 return res;
269
270         case I2C_SMBUS:
271                 if (copy_from_user(&data_arg,
272                                    (struct i2c_smbus_ioctl_data __user *) arg,
273                                    sizeof(struct i2c_smbus_ioctl_data)))
274                         return -EFAULT;
275                 if ((data_arg.size != I2C_SMBUS_BYTE) && 
276                     (data_arg.size != I2C_SMBUS_QUICK) &&
277                     (data_arg.size != I2C_SMBUS_BYTE_DATA) && 
278                     (data_arg.size != I2C_SMBUS_WORD_DATA) &&
279                     (data_arg.size != I2C_SMBUS_PROC_CALL) &&
280                     (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
281                     (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
282                     (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
283                         dev_dbg(&client->adapter->dev,
284                                 "size out of range (%x) in ioctl I2C_SMBUS.\n",
285                                 data_arg.size);
286                         return -EINVAL;
287                 }
288                 /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1, 
289                    so the check is valid if size==I2C_SMBUS_QUICK too. */
290                 if ((data_arg.read_write != I2C_SMBUS_READ) && 
291                     (data_arg.read_write != I2C_SMBUS_WRITE)) {
292                         dev_dbg(&client->adapter->dev, 
293                                 "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
294                                 data_arg.read_write);
295                         return -EINVAL;
296                 }
297
298                 /* Note that command values are always valid! */
299
300                 if ((data_arg.size == I2C_SMBUS_QUICK) ||
301                     ((data_arg.size == I2C_SMBUS_BYTE) && 
302                     (data_arg.read_write == I2C_SMBUS_WRITE)))
303                         /* These are special: we do not use data */
304                         return i2c_smbus_xfer(client->adapter, client->addr,
305                                               client->flags,
306                                               data_arg.read_write,
307                                               data_arg.command,
308                                               data_arg.size, NULL);
309
310                 if (data_arg.data == NULL) {
311                         dev_dbg(&client->adapter->dev,
312                                 "data is NULL pointer in ioctl I2C_SMBUS.\n");
313                         return -EINVAL;
314                 }
315
316                 if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
317                     (data_arg.size == I2C_SMBUS_BYTE))
318                         datasize = sizeof(data_arg.data->byte);
319                 else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || 
320                          (data_arg.size == I2C_SMBUS_PROC_CALL))
321                         datasize = sizeof(data_arg.data->word);
322                 else /* size == smbus block, i2c block, or block proc. call */
323                         datasize = sizeof(data_arg.data->block);
324
325                 if ((data_arg.size == I2C_SMBUS_PROC_CALL) || 
326                     (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || 
327                     (data_arg.read_write == I2C_SMBUS_WRITE)) {
328                         if (copy_from_user(&temp, data_arg.data, datasize))
329                                 return -EFAULT;
330                 }
331                 res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
332                       data_arg.read_write,
333                       data_arg.command,data_arg.size,&temp);
334                 if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || 
335                               (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || 
336                               (data_arg.read_write == I2C_SMBUS_READ))) {
337                         if (copy_to_user(data_arg.data, &temp, datasize))
338                                 return -EFAULT;
339                 }
340                 return res;
341
342         default:
343                 return i2c_control(client,cmd,arg);
344         }
345         return 0;
346 }
347
348 static int i2cdev_open(struct inode *inode, struct file *file)
349 {
350         unsigned int minor = iminor(inode);
351         struct i2c_client *client;
352         struct i2c_adapter *adap;
353         struct i2c_dev *i2c_dev;
354
355         i2c_dev = i2c_dev_get_by_minor(minor);
356         if (!i2c_dev)
357                 return -ENODEV;
358
359         adap = i2c_get_adapter(i2c_dev->adap->nr);
360         if (!adap)
361                 return -ENODEV;
362
363         client = kmalloc(sizeof(*client), GFP_KERNEL);
364         if (!client) {
365                 i2c_put_adapter(adap);
366                 return -ENOMEM;
367         }
368         memcpy(client, &i2cdev_client_template, sizeof(*client));
369
370         /* registered with adapter, passed as client to user */
371         client->adapter = adap;
372         file->private_data = client;
373
374         return 0;
375 }
376
377 static int i2cdev_release(struct inode *inode, struct file *file)
378 {
379         struct i2c_client *client = file->private_data;
380
381         i2c_put_adapter(client->adapter);
382         kfree(client);
383         file->private_data = NULL;
384
385         return 0;
386 }
387
388 static struct file_operations i2cdev_fops = {
389         .owner          = THIS_MODULE,
390         .llseek         = no_llseek,
391         .read           = i2cdev_read,
392         .write          = i2cdev_write,
393         .ioctl          = i2cdev_ioctl,
394         .open           = i2cdev_open,
395         .release        = i2cdev_release,
396 };
397
398 static struct class *i2c_dev_class;
399
400 static int i2cdev_attach_adapter(struct i2c_adapter *adap)
401 {
402         struct i2c_dev *i2c_dev;
403
404         i2c_dev = get_free_i2c_dev(adap);
405         if (IS_ERR(i2c_dev))
406                 return PTR_ERR(i2c_dev);
407
408         pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",
409                  adap->name, adap->nr);
410
411         /* register this i2c device with the driver core */
412         i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL,
413                                                  MKDEV(I2C_MAJOR, adap->nr),
414                                                  &adap->dev, "i2c-%d",
415                                                  adap->nr);
416         if (!i2c_dev->class_dev)
417                 goto error;
418         class_device_create_file(i2c_dev->class_dev, &class_device_attr_name);
419         return 0;
420 error:
421         return_i2c_dev(i2c_dev);
422         kfree(i2c_dev);
423         return -ENODEV;
424 }
425
426 static int i2cdev_detach_adapter(struct i2c_adapter *adap)
427 {
428         struct i2c_dev *i2c_dev;
429
430         i2c_dev = i2c_dev_get_by_minor(adap->nr);
431         if (!i2c_dev)
432                 return -ENODEV;
433
434         return_i2c_dev(i2c_dev);
435         class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
436         kfree(i2c_dev);
437
438         pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
439         return 0;
440 }
441
442 static int i2cdev_detach_client(struct i2c_client *client)
443 {
444         return 0;
445 }
446
447 static struct i2c_driver i2cdev_driver = {
448         .driver = {
449                 .name   = "dev_driver",
450         },
451         .id             = I2C_DRIVERID_I2CDEV,
452         .attach_adapter = i2cdev_attach_adapter,
453         .detach_adapter = i2cdev_detach_adapter,
454         .detach_client  = i2cdev_detach_client,
455 };
456
457 static struct i2c_client i2cdev_client_template = {
458         .name           = "I2C /dev entry",
459         .addr           = -1,
460         .driver         = &i2cdev_driver,
461 };
462
463 static int __init i2c_dev_init(void)
464 {
465         int res;
466
467         printk(KERN_INFO "i2c /dev entries driver\n");
468
469         res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
470         if (res)
471                 goto out;
472
473         i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
474         if (IS_ERR(i2c_dev_class))
475                 goto out_unreg_chrdev;
476
477         res = i2c_add_driver(&i2cdev_driver);
478         if (res)
479                 goto out_unreg_class;
480
481         return 0;
482
483 out_unreg_class:
484         class_destroy(i2c_dev_class);
485 out_unreg_chrdev:
486         unregister_chrdev(I2C_MAJOR, "i2c");
487 out:
488         printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
489         return res;
490 }
491
492 static void __exit i2c_dev_exit(void)
493 {
494         i2c_del_driver(&i2cdev_driver);
495         class_destroy(i2c_dev_class);
496         unregister_chrdev(I2C_MAJOR,"i2c");
497 }
498
499 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
500                 "Simon G. Vogl <simon@tk.uni-linz.ac.at>");
501 MODULE_DESCRIPTION("I2C /dev entries driver");
502 MODULE_LICENSE("GPL");
503
504 module_init(i2c_dev_init);
505 module_exit(i2c_dev_exit);