diff options
| -rw-r--r-- | drivers/i2c/i2c-dev.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 5a15e50748de..7360f9c37256 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
| @@ -38,6 +38,15 @@ | |||
| 38 | 38 | ||
| 39 | static struct i2c_driver i2cdev_driver; | 39 | static struct i2c_driver i2cdev_driver; |
| 40 | 40 | ||
| 41 | /* | ||
| 42 | * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a | ||
| 43 | * slave (i2c_client) with which messages will be exchanged. It's coupled | ||
| 44 | * with a character special file which is accessed by user mode drivers. | ||
| 45 | * | ||
| 46 | * The list of i2c_dev structures is parallel to the i2c_adapter lists | ||
| 47 | * maintained by the driver model, and is updated using notifications | ||
| 48 | * delivered to the i2cdev_driver. | ||
| 49 | */ | ||
| 41 | struct i2c_dev { | 50 | struct i2c_dev { |
| 42 | struct list_head list; | 51 | struct list_head list; |
| 43 | struct i2c_adapter *adap; | 52 | struct i2c_adapter *adap; |
| @@ -103,6 +112,25 @@ static ssize_t show_adapter_name(struct device *dev, | |||
| 103 | } | 112 | } |
| 104 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | 113 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); |
| 105 | 114 | ||
| 115 | /* ------------------------------------------------------------------------- */ | ||
| 116 | |||
| 117 | /* | ||
| 118 | * After opening an instance of this character special file, a file | ||
| 119 | * descriptor starts out associated only with an i2c_adapter (and bus). | ||
| 120 | * | ||
| 121 | * Using the I2C_RDWR ioctl(), you can then *immediately* issue i2c_msg | ||
| 122 | * traffic to any devices on the bus used by that adapter. That's because | ||
| 123 | * the i2c_msg vectors embed all the addressing information they need, and | ||
| 124 | * are submitted directly to an i2c_adapter. However, SMBus-only adapters | ||
| 125 | * don't support that interface. | ||
| 126 | * | ||
| 127 | * To use read()/write() system calls on that file descriptor, or to use | ||
| 128 | * SMBus interfaces (and work with SMBus-only hosts!), you must first issue | ||
| 129 | * an I2C_SLAVE (or I2C_SLAVE_FORCE) ioctl. That configures an anonymous | ||
| 130 | * (never registered) i2c_client so it holds the addressing information | ||
| 131 | * needed by those system calls and by this SMBus interface. | ||
| 132 | */ | ||
| 133 | |||
| 106 | static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, | 134 | static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, |
| 107 | loff_t *offset) | 135 | loff_t *offset) |
| 108 | { | 136 | { |
| @@ -172,6 +200,16 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 172 | switch ( cmd ) { | 200 | switch ( cmd ) { |
| 173 | case I2C_SLAVE: | 201 | case I2C_SLAVE: |
| 174 | case I2C_SLAVE_FORCE: | 202 | case I2C_SLAVE_FORCE: |
| 203 | /* NOTE: devices set up to work with "new style" drivers | ||
| 204 | * can't use I2C_SLAVE, even when the device node is not | ||
| 205 | * bound to a driver. Only I2C_SLAVE_FORCE will work. | ||
| 206 | * | ||
| 207 | * Setting the PEC flag here won't affect kernel drivers, | ||
| 208 | * which will be using the i2c_client node registered with | ||
| 209 | * the driver model core. Likewise, when that client has | ||
| 210 | * the PEC flag already set, the i2c-dev driver won't see | ||
| 211 | * (or use) this setting. | ||
| 212 | */ | ||
| 175 | if ((arg > 0x3ff) || | 213 | if ((arg > 0x3ff) || |
| 176 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) | 214 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) |
| 177 | return -EINVAL; | 215 | return -EINVAL; |
| @@ -386,6 +424,13 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
| 386 | if (!adap) | 424 | if (!adap) |
| 387 | return -ENODEV; | 425 | return -ENODEV; |
| 388 | 426 | ||
| 427 | /* This creates an anonymous i2c_client, which may later be | ||
| 428 | * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. | ||
| 429 | * | ||
| 430 | * This client is ** NEVER REGISTERED ** with the driver model | ||
| 431 | * or I2C core code!! It just holds private copies of addressing | ||
| 432 | * information and maybe a PEC flag. | ||
| 433 | */ | ||
| 389 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 434 | client = kzalloc(sizeof(*client), GFP_KERNEL); |
| 390 | if (!client) { | 435 | if (!client) { |
| 391 | i2c_put_adapter(adap); | 436 | i2c_put_adapter(adap); |
| @@ -394,7 +439,6 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
| 394 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); | 439 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); |
| 395 | client->driver = &i2cdev_driver; | 440 | client->driver = &i2cdev_driver; |
| 396 | 441 | ||
| 397 | /* registered with adapter, passed as client to user */ | ||
| 398 | client->adapter = adap; | 442 | client->adapter = adap; |
| 399 | file->private_data = client; | 443 | file->private_data = client; |
| 400 | 444 | ||
| @@ -422,6 +466,14 @@ static const struct file_operations i2cdev_fops = { | |||
| 422 | .release = i2cdev_release, | 466 | .release = i2cdev_release, |
| 423 | }; | 467 | }; |
| 424 | 468 | ||
| 469 | /* ------------------------------------------------------------------------- */ | ||
| 470 | |||
| 471 | /* | ||
| 472 | * The legacy "i2cdev_driver" is used primarily to get notifications when | ||
| 473 | * I2C adapters are added or removed, so that each one gets an i2c_dev | ||
| 474 | * and is thus made available to userspace driver code. | ||
| 475 | */ | ||
| 476 | |||
| 425 | static struct class *i2c_dev_class; | 477 | static struct class *i2c_dev_class; |
| 426 | 478 | ||
| 427 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) | 479 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) |
| @@ -486,6 +538,12 @@ static struct i2c_driver i2cdev_driver = { | |||
| 486 | .detach_client = i2cdev_detach_client, | 538 | .detach_client = i2cdev_detach_client, |
| 487 | }; | 539 | }; |
| 488 | 540 | ||
| 541 | /* ------------------------------------------------------------------------- */ | ||
| 542 | |||
| 543 | /* | ||
| 544 | * module load/unload record keeping | ||
| 545 | */ | ||
| 546 | |||
| 489 | static int __init i2c_dev_init(void) | 547 | static int __init i2c_dev_init(void) |
| 490 | { | 548 | { |
| 491 | int res; | 549 | int res; |
