diff options
-rw-r--r-- | Documentation/i2c/instantiating-devices | 44 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 123 | ||||
-rw-r--r-- | include/linux/i2c.h | 3 |
3 files changed, 168 insertions, 2 deletions
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices index b55ce57a84db..c740b7b41088 100644 --- a/Documentation/i2c/instantiating-devices +++ b/Documentation/i2c/instantiating-devices | |||
@@ -165,3 +165,47 @@ was done there. Two significant differences are: | |||
165 | Once again, method 3 should be avoided wherever possible. Explicit device | 165 | Once again, method 3 should be avoided wherever possible. Explicit device |
166 | instantiation (methods 1 and 2) is much preferred for it is safer and | 166 | instantiation (methods 1 and 2) is much preferred for it is safer and |
167 | faster. | 167 | faster. |
168 | |||
169 | |||
170 | Method 4: Instantiate from user-space | ||
171 | ------------------------------------- | ||
172 | |||
173 | In general, the kernel should know which I2C devices are connected and | ||
174 | what addresses they live at. However, in certain cases, it does not, so a | ||
175 | sysfs interface was added to let the user provide the information. This | ||
176 | interface is made of 2 attribute files which are created in every I2C bus | ||
177 | directory: new_device and delete_device. Both files are write only and you | ||
178 | must write the right parameters to them in order to properly instantiate, | ||
179 | respectively delete, an I2C device. | ||
180 | |||
181 | File new_device takes 2 parameters: the name of the I2C device (a string) | ||
182 | and the address of the I2C device (a number, typically expressed in | ||
183 | hexadecimal starting with 0x, but can also be expressed in decimal.) | ||
184 | |||
185 | File delete_device takes a single parameter: the address of the I2C | ||
186 | device. As no two devices can live at the same address on a given I2C | ||
187 | segment, the address is sufficient to uniquely identify the device to be | ||
188 | deleted. | ||
189 | |||
190 | Example: | ||
191 | # echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device | ||
192 | |||
193 | While this interface should only be used when in-kernel device declaration | ||
194 | can't be done, there is a variety of cases where it can be helpful: | ||
195 | * The I2C driver usually detects devices (method 3 above) but the bus | ||
196 | segment your device lives on doesn't have the proper class bit set and | ||
197 | thus detection doesn't trigger. | ||
198 | * The I2C driver usually detects devices, but your device lives at an | ||
199 | unexpected address. | ||
200 | * The I2C driver usually detects devices, but your device is not detected, | ||
201 | either because the detection routine is too strict, or because your | ||
202 | device is not officially supported yet but you know it is compatible. | ||
203 | * You are developing a driver on a test board, where you soldered the I2C | ||
204 | device yourself. | ||
205 | |||
206 | This interface is a replacement for the force_* module parameters some I2C | ||
207 | drivers implement. Being implemented in i2c-core rather than in each | ||
208 | device driver individually, it is much more efficient, and also has the | ||
209 | advantage that you do not have to reload the driver to change a setting. | ||
210 | You can also instantiate the device before the driver is loaded or even | ||
211 | available, and you don't need to know what driver the device needs. | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a2f1cd3766f3..eb084fa0df83 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -38,11 +38,12 @@ | |||
38 | #include "i2c-core.h" | 38 | #include "i2c-core.h" |
39 | 39 | ||
40 | 40 | ||
41 | /* core_lock protects i2c_adapter_idr, and guarantees | 41 | /* core_lock protects i2c_adapter_idr, userspace_devices, and guarantees |
42 | that device detection, deletion of detected devices, and attach_adapter | 42 | that device detection, deletion of detected devices, and attach_adapter |
43 | and detach_adapter calls are serialized */ | 43 | and detach_adapter calls are serialized */ |
44 | static DEFINE_MUTEX(core_lock); | 44 | static DEFINE_MUTEX(core_lock); |
45 | static DEFINE_IDR(i2c_adapter_idr); | 45 | static DEFINE_IDR(i2c_adapter_idr); |
46 | static LIST_HEAD(userspace_devices); | ||
46 | 47 | ||
47 | static int i2c_check_addr(struct i2c_adapter *adapter, int addr); | 48 | static int i2c_check_addr(struct i2c_adapter *adapter, int addr); |
48 | static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); | 49 | static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); |
@@ -373,8 +374,128 @@ show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) | |||
373 | return sprintf(buf, "%s\n", adap->name); | 374 | return sprintf(buf, "%s\n", adap->name); |
374 | } | 375 | } |
375 | 376 | ||
377 | /* | ||
378 | * Let users instantiate I2C devices through sysfs. This can be used when | ||
379 | * platform initialization code doesn't contain the proper data for | ||
380 | * whatever reason. Also useful for drivers that do device detection and | ||
381 | * detection fails, either because the device uses an unexpected address, | ||
382 | * or this is a compatible device with different ID register values. | ||
383 | * | ||
384 | * Parameter checking may look overzealous, but we really don't want | ||
385 | * the user to provide incorrect parameters. | ||
386 | */ | ||
387 | static ssize_t | ||
388 | i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, | ||
389 | const char *buf, size_t count) | ||
390 | { | ||
391 | struct i2c_adapter *adap = to_i2c_adapter(dev); | ||
392 | struct i2c_board_info info; | ||
393 | struct i2c_client *client; | ||
394 | char *blank, end; | ||
395 | int res; | ||
396 | |||
397 | dev_warn(dev, "The new_device interface is still experimental " | ||
398 | "and may change in a near future\n"); | ||
399 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
400 | |||
401 | blank = strchr(buf, ' '); | ||
402 | if (!blank) { | ||
403 | dev_err(dev, "%s: Missing parameters\n", "new_device"); | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | if (blank - buf > I2C_NAME_SIZE - 1) { | ||
407 | dev_err(dev, "%s: Invalid device name\n", "new_device"); | ||
408 | return -EINVAL; | ||
409 | } | ||
410 | memcpy(info.type, buf, blank - buf); | ||
411 | |||
412 | /* Parse remaining parameters, reject extra parameters */ | ||
413 | res = sscanf(++blank, "%hi%c", &info.addr, &end); | ||
414 | if (res < 1) { | ||
415 | dev_err(dev, "%s: Can't parse I2C address\n", "new_device"); | ||
416 | return -EINVAL; | ||
417 | } | ||
418 | if (res > 1 && end != '\n') { | ||
419 | dev_err(dev, "%s: Extra parameters\n", "new_device"); | ||
420 | return -EINVAL; | ||
421 | } | ||
422 | |||
423 | if (info.addr < 0x03 || info.addr > 0x77) { | ||
424 | dev_err(dev, "%s: Invalid I2C address 0x%hx\n", "new_device", | ||
425 | info.addr); | ||
426 | return -EINVAL; | ||
427 | } | ||
428 | |||
429 | client = i2c_new_device(adap, &info); | ||
430 | if (!client) | ||
431 | return -EEXIST; | ||
432 | |||
433 | /* Keep track of the added device */ | ||
434 | mutex_lock(&core_lock); | ||
435 | list_add_tail(&client->detected, &userspace_devices); | ||
436 | mutex_unlock(&core_lock); | ||
437 | dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device", | ||
438 | info.type, info.addr); | ||
439 | |||
440 | return count; | ||
441 | } | ||
442 | |||
443 | /* | ||
444 | * And of course let the users delete the devices they instantiated, if | ||
445 | * they got it wrong. This interface can only be used to delete devices | ||
446 | * instantiated by i2c_sysfs_new_device above. This guarantees that we | ||
447 | * don't delete devices to which some kernel code still has references. | ||
448 | * | ||
449 | * Parameter checking may look overzealous, but we really don't want | ||
450 | * the user to delete the wrong device. | ||
451 | */ | ||
452 | static ssize_t | ||
453 | i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | ||
454 | const char *buf, size_t count) | ||
455 | { | ||
456 | struct i2c_adapter *adap = to_i2c_adapter(dev); | ||
457 | struct i2c_client *client, *next; | ||
458 | unsigned short addr; | ||
459 | char end; | ||
460 | int res; | ||
461 | |||
462 | /* Parse parameters, reject extra parameters */ | ||
463 | res = sscanf(buf, "%hi%c", &addr, &end); | ||
464 | if (res < 1) { | ||
465 | dev_err(dev, "%s: Can't parse I2C address\n", "delete_device"); | ||
466 | return -EINVAL; | ||
467 | } | ||
468 | if (res > 1 && end != '\n') { | ||
469 | dev_err(dev, "%s: Extra parameters\n", "delete_device"); | ||
470 | return -EINVAL; | ||
471 | } | ||
472 | |||
473 | /* Make sure the device was added through sysfs */ | ||
474 | res = -ENOENT; | ||
475 | mutex_lock(&core_lock); | ||
476 | list_for_each_entry_safe(client, next, &userspace_devices, detected) { | ||
477 | if (client->addr == addr && client->adapter == adap) { | ||
478 | dev_info(dev, "%s: Deleting device %s at 0x%02hx\n", | ||
479 | "delete_device", client->name, client->addr); | ||
480 | |||
481 | list_del(&client->detected); | ||
482 | i2c_unregister_device(client); | ||
483 | res = count; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | mutex_unlock(&core_lock); | ||
488 | |||
489 | if (res < 0) | ||
490 | dev_err(dev, "%s: Can't find device in list\n", | ||
491 | "delete_device"); | ||
492 | return res; | ||
493 | } | ||
494 | |||
376 | static struct device_attribute i2c_adapter_attrs[] = { | 495 | static struct device_attribute i2c_adapter_attrs[] = { |
377 | __ATTR(name, S_IRUGO, show_adapter_name, NULL), | 496 | __ATTR(name, S_IRUGO, show_adapter_name, NULL), |
497 | __ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device), | ||
498 | __ATTR(delete_device, S_IWUSR, NULL, i2c_sysfs_delete_device), | ||
378 | { }, | 499 | { }, |
379 | }; | 500 | }; |
380 | 501 | ||
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 5f8157610c64..844d2662a875 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -178,7 +178,8 @@ struct i2c_driver { | |||
178 | * @driver: device's driver, hence pointer to access routines | 178 | * @driver: device's driver, hence pointer to access routines |
179 | * @dev: Driver model device node for the slave. | 179 | * @dev: Driver model device node for the slave. |
180 | * @irq: indicates the IRQ generated by this device (if any) | 180 | * @irq: indicates the IRQ generated by this device (if any) |
181 | * @detected: member of an i2c_driver.clients list | 181 | * @detected: member of an i2c_driver.clients list or i2c-core's |
182 | * userspace_devices list | ||
182 | * | 183 | * |
183 | * An i2c_client identifies a single device (i.e. chip) connected to an | 184 | * An i2c_client identifies a single device (i.e. chip) connected to an |
184 | * i2c bus. The behaviour exposed to Linux is defined by the driver | 185 | * i2c bus. The behaviour exposed to Linux is defined by the driver |