diff options
Diffstat (limited to 'drivers/i2c/i2c-dev.c')
| -rw-r--r-- | drivers/i2c/i2c-dev.c | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 5a15e50748de..c21ae20ae362 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 | { |
| @@ -154,6 +182,29 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c | |||
| 154 | return ret; | 182 | return ret; |
| 155 | } | 183 | } |
| 156 | 184 | ||
| 185 | /* This address checking function differs from the one in i2c-core | ||
| 186 | in that it considers an address with a registered device, but no | ||
| 187 | bounded driver, as NOT busy. */ | ||
| 188 | static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) | ||
| 189 | { | ||
| 190 | struct list_head *item; | ||
| 191 | struct i2c_client *client; | ||
| 192 | int res = 0; | ||
| 193 | |||
| 194 | mutex_lock(&adapter->clist_lock); | ||
| 195 | list_for_each(item, &adapter->clients) { | ||
| 196 | client = list_entry(item, struct i2c_client, list); | ||
| 197 | if (client->addr == addr) { | ||
| 198 | if (client->driver) | ||
| 199 | res = -EBUSY; | ||
| 200 | break; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | mutex_unlock(&adapter->clist_lock); | ||
| 204 | |||
| 205 | return res; | ||
| 206 | } | ||
| 207 | |||
| 157 | static int i2cdev_ioctl(struct inode *inode, struct file *file, | 208 | static int i2cdev_ioctl(struct inode *inode, struct file *file, |
| 158 | unsigned int cmd, unsigned long arg) | 209 | unsigned int cmd, unsigned long arg) |
| 159 | { | 210 | { |
| @@ -172,11 +223,22 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file, | |||
| 172 | switch ( cmd ) { | 223 | switch ( cmd ) { |
| 173 | case I2C_SLAVE: | 224 | case I2C_SLAVE: |
| 174 | case I2C_SLAVE_FORCE: | 225 | case I2C_SLAVE_FORCE: |
| 226 | /* NOTE: devices set up to work with "new style" drivers | ||
| 227 | * can't use I2C_SLAVE, even when the device node is not | ||
| 228 | * bound to a driver. Only I2C_SLAVE_FORCE will work. | ||
| 229 | * | ||
| 230 | * Setting the PEC flag here won't affect kernel drivers, | ||
| 231 | * which will be using the i2c_client node registered with | ||
| 232 | * the driver model core. Likewise, when that client has | ||
| 233 | * the PEC flag already set, the i2c-dev driver won't see | ||
| 234 | * (or use) this setting. | ||
| 235 | */ | ||
| 175 | if ((arg > 0x3ff) || | 236 | if ((arg > 0x3ff) || |
| 176 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) | 237 | (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f)) |
| 177 | return -EINVAL; | 238 | return -EINVAL; |
| 178 | if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg)) | 239 | if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg)) |
| 179 | return -EBUSY; | 240 | return -EBUSY; |
| 241 | /* REVISIT: address could become busy later */ | ||
| 180 | client->addr = arg; | 242 | client->addr = arg; |
| 181 | return 0; | 243 | return 0; |
| 182 | case I2C_TENBIT: | 244 | case I2C_TENBIT: |
| @@ -386,6 +448,13 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
| 386 | if (!adap) | 448 | if (!adap) |
| 387 | return -ENODEV; | 449 | return -ENODEV; |
| 388 | 450 | ||
| 451 | /* This creates an anonymous i2c_client, which may later be | ||
| 452 | * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE. | ||
| 453 | * | ||
| 454 | * This client is ** NEVER REGISTERED ** with the driver model | ||
| 455 | * or I2C core code!! It just holds private copies of addressing | ||
| 456 | * information and maybe a PEC flag. | ||
| 457 | */ | ||
| 389 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 458 | client = kzalloc(sizeof(*client), GFP_KERNEL); |
| 390 | if (!client) { | 459 | if (!client) { |
| 391 | i2c_put_adapter(adap); | 460 | i2c_put_adapter(adap); |
| @@ -394,7 +463,6 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
| 394 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); | 463 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); |
| 395 | client->driver = &i2cdev_driver; | 464 | client->driver = &i2cdev_driver; |
| 396 | 465 | ||
| 397 | /* registered with adapter, passed as client to user */ | ||
| 398 | client->adapter = adap; | 466 | client->adapter = adap; |
| 399 | file->private_data = client; | 467 | file->private_data = client; |
| 400 | 468 | ||
| @@ -422,6 +490,14 @@ static const struct file_operations i2cdev_fops = { | |||
| 422 | .release = i2cdev_release, | 490 | .release = i2cdev_release, |
| 423 | }; | 491 | }; |
| 424 | 492 | ||
| 493 | /* ------------------------------------------------------------------------- */ | ||
| 494 | |||
| 495 | /* | ||
| 496 | * The legacy "i2cdev_driver" is used primarily to get notifications when | ||
| 497 | * I2C adapters are added or removed, so that each one gets an i2c_dev | ||
| 498 | * and is thus made available to userspace driver code. | ||
| 499 | */ | ||
| 500 | |||
| 425 | static struct class *i2c_dev_class; | 501 | static struct class *i2c_dev_class; |
| 426 | 502 | ||
| 427 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) | 503 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) |
| @@ -486,6 +562,12 @@ static struct i2c_driver i2cdev_driver = { | |||
| 486 | .detach_client = i2cdev_detach_client, | 562 | .detach_client = i2cdev_detach_client, |
| 487 | }; | 563 | }; |
| 488 | 564 | ||
| 565 | /* ------------------------------------------------------------------------- */ | ||
| 566 | |||
| 567 | /* | ||
| 568 | * module load/unload record keeping | ||
| 569 | */ | ||
| 570 | |||
| 489 | static int __init i2c_dev_init(void) | 571 | static int __init i2c_dev_init(void) |
| 490 | { | 572 | { |
| 491 | int res; | 573 | int res; |
