Subversion Repositories shark

Rev

Rev 458 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
420 giacomo 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
/* The devfs code is contributed by Philipp Matthias Hahn
30
   <pmhahn@titan.lahn.de> */
31
 
32
/* If you want debugging uncomment: */
33
/* #define DEBUG 1 */
34
 
35
#include <linux/kernel.h>
36
#include <linux/module.h>
37
#include <linux/fs.h>
38
#include <linux/slab.h>
39
#include <linux/smp_lock.h>
40
#include <linux/devfs_fs_kernel.h>
41
#include <linux/init.h>
42
#include <linux/i2c.h>
43
#include <linux/i2c-dev.h>
44
#include <asm/uaccess.h>
45
 
46
static struct i2c_client i2cdev_client_template;
47
 
48
struct i2c_dev {
49
        int minor;
50
        struct i2c_adapter *adap;
51
        struct class_device class_dev;
52
        struct completion released;     /* FIXME, we need a class_device_unregister() */
53
};
54
#define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
55
 
56
#define I2C_MINORS      256
57
static struct i2c_dev *i2c_dev_array[I2C_MINORS];
58
static spinlock_t i2c_dev_array_lock = SPIN_LOCK_UNLOCKED;
59
 
60
struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
61
{
62
        struct i2c_dev *i2c_dev;
63
 
64
        spin_lock(&i2c_dev_array_lock);
65
        i2c_dev = i2c_dev_array[index];
66
        spin_unlock(&i2c_dev_array_lock);
67
        return i2c_dev;
68
}
69
 
70
struct i2c_dev *i2c_dev_get_by_adapter(struct i2c_adapter *adap)
71
{
72
        struct i2c_dev *i2c_dev = NULL;
73
        int i;
74
 
75
        spin_lock(&i2c_dev_array_lock);
76
        for (i = 0; i < I2C_MINORS; ++i) {
77
                if ((i2c_dev_array[i]) &&
78
                    (i2c_dev_array[i]->adap == adap)) {
79
                        i2c_dev = i2c_dev_array[i];
80
                        break;
81
                }
82
        }
83
        spin_unlock(&i2c_dev_array_lock);
84
        return i2c_dev;
85
}
86
 
87
static struct i2c_dev *get_free_i2c_dev(void)
88
{
89
        struct i2c_dev *i2c_dev;
90
        unsigned int i;
91
 
92
        i2c_dev = kmalloc(sizeof(*i2c_dev), GFP_KERNEL);
93
        if (!i2c_dev)
94
                return ERR_PTR(-ENOMEM);
95
        memset(i2c_dev, 0x00, sizeof(*i2c_dev));
96
 
97
        spin_lock(&i2c_dev_array_lock);
98
        for (i = 0; i < I2C_MINORS; ++i) {
99
                if (i2c_dev_array[i])
100
                        continue;
101
                i2c_dev->minor = i;
102
                i2c_dev_array[i] = i2c_dev;
103
                spin_unlock(&i2c_dev_array_lock);
104
                return i2c_dev;
105
        }
106
        spin_unlock(&i2c_dev_array_lock);
107
        kfree(i2c_dev);
108
        return ERR_PTR(-ENODEV);
109
}
110
 
111
static void return_i2c_dev(struct i2c_dev *i2c_dev)
112
{
113
        spin_lock(&i2c_dev_array_lock);
114
        i2c_dev_array[i2c_dev->minor] = NULL;
115
        spin_unlock(&i2c_dev_array_lock);
116
}
117
 
118
static ssize_t show_dev(struct class_device *class_dev, char *buf)
119
{
120
        struct i2c_dev *i2c_dev = to_i2c_dev(class_dev);
121
        return print_dev_t(buf, MKDEV(I2C_MAJOR, i2c_dev->minor));
122
}
123
static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
124
 
125
static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
126
                            loff_t *offset)
127
{
128
        char *tmp;
129
        int ret;
130
 
131
        struct i2c_client *client = (struct i2c_client *)file->private_data;
132
 
133
        if (count > 8192)
134
                count = 8192;
135
 
136
        tmp = kmalloc(count,GFP_KERNEL);
137
        if (tmp==NULL)
138
                return -ENOMEM;
139
 
140
        pr_debug("i2c-dev.o: i2c-%d reading %d bytes.\n",
141
                iminor(file->f_dentry->d_inode), count);
142
 
143
        ret = i2c_master_recv(client,tmp,count);
144
        if (ret >= 0)
145
                ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;
146
        kfree(tmp);
147
        return ret;
148
}
149
 
150
static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t count,
151
                             loff_t *offset)
152
{
153
        int ret;
154
        char *tmp;
155
        struct i2c_client *client = (struct i2c_client *)file->private_data;
156
 
157
        if (count > 8192)
158
                count = 8192;
159
 
160
        tmp = kmalloc(count,GFP_KERNEL);
161
        if (tmp==NULL)
162
                return -ENOMEM;
163
        if (copy_from_user(tmp,buf,count)) {
164
                kfree(tmp);
165
                return -EFAULT;
166
        }
167
 
168
        pr_debug("i2c-dev.o: i2c-%d writing %d bytes.\n",
169
                iminor(file->f_dentry->d_inode), count);
170
 
171
        ret = i2c_master_send(client,tmp,count);
172
        kfree(tmp);
173
        return ret;
174
}
175
 
176
int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
177
                  unsigned long arg)
178
{
179
        struct i2c_client *client = (struct i2c_client *)file->private_data;
180
        struct i2c_rdwr_ioctl_data rdwr_arg;
181
        struct i2c_smbus_ioctl_data data_arg;
182
        union i2c_smbus_data temp;
183
        struct i2c_msg *rdwr_pa;
184
        u8 **data_ptrs;
185
        int i,datasize,res;
186
        unsigned long funcs;
187
 
188
        dev_dbg(&client->dev, "i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
189
                iminor(inode),cmd, arg);
190
 
191
        switch ( cmd ) {
192
        case I2C_SLAVE:
193
        case I2C_SLAVE_FORCE:
194
                if ((arg > 0x3ff) ||
195
                    (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
196
                        return -EINVAL;
197
                if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg))
198
                        return -EBUSY;
199
                client->addr = arg;
200
                return 0;
201
        case I2C_TENBIT:
202
                if (arg)
203
                        client->flags |= I2C_M_TEN;
204
                else
205
                        client->flags &= ~I2C_M_TEN;
206
                return 0;
207
        case I2C_PEC:
208
                if (arg)
209
                        client->flags |= I2C_CLIENT_PEC;
210
                else
211
                        client->flags &= ~I2C_CLIENT_PEC;
212
                return 0;
213
        case I2C_FUNCS:
214
                funcs = i2c_get_functionality(client->adapter);
215
                return (copy_to_user((unsigned long __user *)arg, &funcs,
216
                                     sizeof(unsigned long)))?-EFAULT:0;
217
 
218
        case I2C_RDWR:
219
                if (copy_from_user(&rdwr_arg,
220
                                   (struct i2c_rdwr_ioctl_data __user *)arg,
221
                                   sizeof(rdwr_arg)))
222
                        return -EFAULT;
223
 
224
                /* Put an arbritrary limit on the number of messages that can
225
                 * be sent at once */
226
                if (rdwr_arg.nmsgs > 42)
227
                        return -EINVAL;
228
 
229
                rdwr_pa = (struct i2c_msg *)
230
                        kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
231
                        GFP_KERNEL);
232
 
233
                if (rdwr_pa == NULL) return -ENOMEM;
234
 
235
                if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
236
                                   rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
237
                        kfree(rdwr_pa);
238
                        return -EFAULT;
239
                }
240
 
241
                data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *),
242
                                            GFP_KERNEL);
243
                if (data_ptrs == NULL) {
244
                        kfree(rdwr_pa);
245
                        return -ENOMEM;
246
                }
247
 
248
                res = 0;
249
                for( i=0; i<rdwr_arg.nmsgs; i++ ) {
250
                        /* Limit the size of the message to a sane amount */
251
                        if (rdwr_pa[i].len > 8192) {
252
                                res = -EINVAL;
253
                                break;
254
                        }
255
                        data_ptrs[i] = rdwr_pa[i].buf;
256
                        rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
257
                        if(rdwr_pa[i].buf == NULL) {
258
                                res = -ENOMEM;
259
                                break;
260
                        }
261
                        if(copy_from_user(rdwr_pa[i].buf,
262
                                data_ptrs[i],
263
                                rdwr_pa[i].len)) {
264
                                        ++i; /* Needs to be kfreed too */
265
                                        res = -EFAULT;
266
                                break;
267
                        }
268
                }
269
                if (res < 0) {
270
                        int j;
271
                        for (j = 0; j < i; ++j)
272
                                kfree(rdwr_pa[j].buf);
273
                        kfree(data_ptrs);
274
                        kfree(rdwr_pa);
275
                        return res;
276
                }
277
 
278
                res = i2c_transfer(client->adapter,
279
                        rdwr_pa,
280
                        rdwr_arg.nmsgs);
281
                while(i-- > 0) {
282
                        if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
283
                                if(copy_to_user(
284
                                        data_ptrs[i],
285
                                        rdwr_pa[i].buf,
286
                                        rdwr_pa[i].len)) {
287
                                        res = -EFAULT;
288
                                }
289
                        }
290
                        kfree(rdwr_pa[i].buf);
291
                }
292
                kfree(data_ptrs);
293
                kfree(rdwr_pa);
294
                return res;
295
 
296
        case I2C_SMBUS:
297
                if (copy_from_user(&data_arg,
298
                                   (struct i2c_smbus_ioctl_data __user *) arg,
299
                                   sizeof(struct i2c_smbus_ioctl_data)))
300
                        return -EFAULT;
301
                if ((data_arg.size != I2C_SMBUS_BYTE) &&
302
                    (data_arg.size != I2C_SMBUS_QUICK) &&
303
                    (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
304
                    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
305
                    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
306
                    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
307
                    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
308
                    (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
309
                        dev_dbg(&client->dev,
310
                                "size out of range (%x) in ioctl I2C_SMBUS.\n",
311
                                data_arg.size);
312
                        return -EINVAL;
313
                }
314
                /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
315
                   so the check is valid if size==I2C_SMBUS_QUICK too. */
316
                if ((data_arg.read_write != I2C_SMBUS_READ) &&
317
                    (data_arg.read_write != I2C_SMBUS_WRITE)) {
318
                        dev_dbg(&client->dev,
319
                                "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
320
                                data_arg.read_write);
321
                        return -EINVAL;
322
                }
323
 
324
                /* Note that command values are always valid! */
325
 
326
                if ((data_arg.size == I2C_SMBUS_QUICK) ||
327
                    ((data_arg.size == I2C_SMBUS_BYTE) &&
328
                    (data_arg.read_write == I2C_SMBUS_WRITE)))
329
                        /* These are special: we do not use data */
330
                        return i2c_smbus_xfer(client->adapter, client->addr,
331
                                              client->flags,
332
                                              data_arg.read_write,
333
                                              data_arg.command,
334
                                              data_arg.size, NULL);
335
 
336
                if (data_arg.data == NULL) {
337
                        dev_dbg(&client->dev,
338
                                "data is NULL pointer in ioctl I2C_SMBUS.\n");
339
                        return -EINVAL;
340
                }
341
 
342
                if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
343
                    (data_arg.size == I2C_SMBUS_BYTE))
344
                        datasize = sizeof(data_arg.data->byte);
345
                else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
346
                         (data_arg.size == I2C_SMBUS_PROC_CALL))
347
                        datasize = sizeof(data_arg.data->word);
348
                else /* size == smbus block, i2c block, or block proc. call */
349
                        datasize = sizeof(data_arg.data->block);
350
 
351
                if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
352
                    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
353
                    (data_arg.read_write == I2C_SMBUS_WRITE)) {
354
                        if (copy_from_user(&temp, data_arg.data, datasize))
355
                                return -EFAULT;
356
                }
357
                res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
358
                      data_arg.read_write,
359
                      data_arg.command,data_arg.size,&temp);
360
                if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
361
                              (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
362
                              (data_arg.read_write == I2C_SMBUS_READ))) {
363
                        if (copy_to_user(data_arg.data, &temp, datasize))
364
                                return -EFAULT;
365
                }
366
                return res;
367
 
368
        default:
369
                return i2c_control(client,cmd,arg);
370
        }
371
        return 0;
372
}
373
 
374
static int i2cdev_open(struct inode *inode, struct file *file)
375
{
376
        unsigned int minor = iminor(inode);
377
        struct i2c_client *client;
378
        struct i2c_adapter *adap;
379
        struct i2c_dev *i2c_dev;
380
 
381
        i2c_dev = i2c_dev_get_by_minor(minor);
382
        if (!i2c_dev)
383
                return -ENODEV;
384
 
385
        adap = i2c_get_adapter(i2c_dev->adap->nr);
386
        if (!adap)
387
                return -ENODEV;
388
 
389
        client = kmalloc(sizeof(*client), GFP_KERNEL);
390
        if (!client) {
391
                i2c_put_adapter(adap);
392
                return -ENOMEM;
393
        }
394
        memcpy(client, &i2cdev_client_template, sizeof(*client));
395
 
396
        /* registered with adapter, passed as client to user */
397
        client->adapter = adap;
398
        file->private_data = client;
399
 
400
        return 0;
401
}
402
 
403
static int i2cdev_release(struct inode *inode, struct file *file)
404
{
405
        struct i2c_client *client = file->private_data;
406
 
407
        i2c_put_adapter(client->adapter);
408
        kfree(client);
409
        file->private_data = NULL;
410
 
411
        return 0;
412
}
413
 
414
static struct file_operations i2cdev_fops = {
415
        .owner          = THIS_MODULE,
416
        .llseek         = no_llseek,
417
        .read           = i2cdev_read,
418
        .write          = i2cdev_write,
419
        .ioctl          = i2cdev_ioctl,
420
        .open           = i2cdev_open,
421
        .release        = i2cdev_release,
422
};
423
 
424
static void release_i2c_dev(struct class_device *dev)
425
{
426
        struct i2c_dev *i2c_dev = to_i2c_dev(dev);
427
        complete(&i2c_dev->released);
428
}
429
 
430
static struct class i2c_dev_class = {
431
        .name           = "i2c-dev",
432
        .release        = &release_i2c_dev,
433
};
434
 
435
static int i2cdev_attach_adapter(struct i2c_adapter *adap)
436
{
437
        struct i2c_dev *i2c_dev;
438
        int retval;
439
 
440
        i2c_dev = get_free_i2c_dev();
441
        if (IS_ERR(i2c_dev))
442
                return PTR_ERR(i2c_dev);
443
 
444
        devfs_mk_cdev(MKDEV(I2C_MAJOR, i2c_dev->minor),
445
                        S_IFCHR|S_IRUSR|S_IWUSR, "i2c/%d", i2c_dev->minor);
446
        dev_dbg(&adap->dev, "Registered as minor %d\n", i2c_dev->minor);
447
 
448
        /* register this i2c device with the driver core */
449
        i2c_dev->adap = adap;
450
        if (adap->dev.parent == &legacy_bus)
451
                i2c_dev->class_dev.dev = &adap->dev;
452
        else
453
                i2c_dev->class_dev.dev = adap->dev.parent;
454
        i2c_dev->class_dev.class = &i2c_dev_class;
455
        snprintf(i2c_dev->class_dev.class_id, BUS_ID_SIZE, "i2c-%d", i2c_dev->minor);
456
        retval = class_device_register(&i2c_dev->class_dev);
457
        if (retval)
458
                goto error;
459
        class_device_create_file(&i2c_dev->class_dev, &class_device_attr_dev);
460
        return 0;
461
error:
462
        return_i2c_dev(i2c_dev);
463
        kfree(i2c_dev);
464
        return retval;
465
}
466
 
467
static int i2cdev_detach_adapter(struct i2c_adapter *adap)
468
{
469
        struct i2c_dev *i2c_dev;
470
 
471
        i2c_dev = i2c_dev_get_by_adapter(adap);
472
        if (!i2c_dev)
473
                return -ENODEV;
474
 
475
        init_completion(&i2c_dev->released);
476
        devfs_remove("i2c/%d", i2c_dev->minor);
477
        return_i2c_dev(i2c_dev);
478
        class_device_unregister(&i2c_dev->class_dev);
479
        wait_for_completion(&i2c_dev->released);
480
        kfree(i2c_dev);
481
 
482
        dev_dbg(&adap->dev, "Adapter unregistered\n");
483
        return 0;
484
}
485
 
486
static int i2cdev_detach_client(struct i2c_client *client)
487
{
488
        return 0;
489
}
490
 
491
static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
492
                           void *arg)
493
{
494
        return -1;
495
}
496
 
497
static struct i2c_driver i2cdev_driver = {
498
        .owner          = THIS_MODULE,
499
        .name           = "dev_driver",
500
        .id             = I2C_DRIVERID_I2CDEV,
501
        .flags          = I2C_DF_NOTIFY,
502
        .attach_adapter = i2cdev_attach_adapter,
503
        .detach_adapter = i2cdev_detach_adapter,
504
        .detach_client  = i2cdev_detach_client,
505
        .command        = i2cdev_command,
506
};
507
 
508
static struct i2c_client i2cdev_client_template = {
509
        .name           = "I2C /dev entry",
510
        .id             = 1,
511
        .addr           = -1,
512
        .driver         = &i2cdev_driver,
513
};
514
 
515
static int __init i2c_dev_init(void)
516
{
517
        int res;
518
 
519
        printk(KERN_INFO "i2c /dev entries driver\n");
520
 
521
        if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
522
                printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n",
523
                       I2C_MAJOR);
524
                return -EIO;
525
        }
526
        devfs_mk_dir("i2c");
527
        class_register(&i2c_dev_class);
528
        if ((res = i2c_add_driver(&i2cdev_driver))) {
529
                printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n");
530
                devfs_remove("i2c");
531
                unregister_chrdev(I2C_MAJOR,"i2c");
532
                return res;
533
        }
534
        return 0;
535
}
536
 
537
static void __exit i2c_dev_exit(void)
538
{
539
        i2c_del_driver(&i2cdev_driver);
540
        class_unregister(&i2c_dev_class);
541
        devfs_remove("i2c");
542
        unregister_chrdev(I2C_MAJOR,"i2c");
543
}
544
 
545
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
546
                "Simon G. Vogl <simon@tk.uni-linz.ac.at>");
547
MODULE_DESCRIPTION("I2C /dev entries driver");
548
MODULE_LICENSE("GPL");
549
 
550
module_init(i2c_dev_init);
551
module_exit(i2c_dev_exit);