Subversion Repositories shark

Rev

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