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