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; |