diff options
| author | Jean Delvare <khali@linux-fr.org> | 2008-07-14 16:38:36 -0400 |
|---|---|---|
| committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-14 16:38:36 -0400 |
| commit | 4735c98f8447acb1c8977e2b8024640f7bf36dd6 (patch) | |
| tree | 7f7c65b1feef6a0213caa20218cd6080488cc62b | |
| parent | 8508159e2f3b82bf109f0ec77bcbd8ff3f3a7e17 (diff) | |
i2c: Add detection capability to new-style drivers
Add a mechanism to let new-style i2c drivers optionally autodetect
devices they would support on selected buses and ask i2c-core to
instantiate them. This is a replacement for legacy i2c drivers, much
cleaner.
Where drivers had to implement both a legacy i2c_driver and a
new-style i2c_driver so far, this mechanism makes it possible to get
rid of the legacy i2c_driver and implement both enumerated and
detected device support with just one (new-style) i2c_driver.
Here is a quick conversion guide for these drivers, step by step:
* Delete the legacy driver definition, registration and removal.
Delete the attach_adapter and detach_client methods of the legacy
driver.
* Change the prototype of the legacy detect function from
static int foo_detect(struct i2c_adapter *adapter, int address, int kind);
to
static int foo_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
* Set the new-style driver detect callback to this new function, and
set its address_data to &addr_data (addr_data is generally provided
by I2C_CLIENT_INSMOD.)
* Add the appropriate class to the new-style driver. This is
typically the class the legacy attach_adapter method was checking
for. Class checking is now mandatory (done by i2c-core.) See
<linux/i2c.h> for the list of available classes.
* Remove the i2c_client allocation and freeing from the detect
function. A pre-allocated client is now handed to you by i2c-core,
and is freed automatically.
* Make the detect function fill the type field of the i2c_board_info
structure it was passed as a parameter, and return 0, on success. If
the detection fails, return -ENODEV.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
| -rw-r--r-- | Documentation/i2c/writing-clients | 29 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.c | 223 | ||||
| -rw-r--r-- | include/linux/i2c.h | 36 |
3 files changed, 272 insertions, 16 deletions
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 63722d3c9cdf..6b61b3a2e90b 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients | |||
| @@ -44,6 +44,10 @@ static struct i2c_driver foo_driver = { | |||
| 44 | .id_table = foo_ids, | 44 | .id_table = foo_ids, |
| 45 | .probe = foo_probe, | 45 | .probe = foo_probe, |
| 46 | .remove = foo_remove, | 46 | .remove = foo_remove, |
| 47 | /* if device autodetection is needed: */ | ||
| 48 | .class = I2C_CLASS_SOMETHING, | ||
| 49 | .detect = foo_detect, | ||
| 50 | .address_data = &addr_data, | ||
| 47 | 51 | ||
| 48 | /* else, driver uses "legacy" binding model: */ | 52 | /* else, driver uses "legacy" binding model: */ |
| 49 | .attach_adapter = foo_attach_adapter, | 53 | .attach_adapter = foo_attach_adapter, |
| @@ -217,6 +221,31 @@ in the I2C bus driver. You may want to save the returned i2c_client | |||
| 217 | reference for later use. | 221 | reference for later use. |
| 218 | 222 | ||
| 219 | 223 | ||
| 224 | Device Detection (Standard driver model) | ||
| 225 | ---------------------------------------- | ||
| 226 | |||
| 227 | Sometimes you do not know in advance which I2C devices are connected to | ||
| 228 | a given I2C bus. This is for example the case of hardware monitoring | ||
| 229 | devices on a PC's SMBus. In that case, you may want to let your driver | ||
| 230 | detect supported devices automatically. This is how the legacy model | ||
| 231 | was working, and is now available as an extension to the standard | ||
| 232 | driver model (so that we can finally get rid of the legacy model.) | ||
| 233 | |||
| 234 | You simply have to define a detect callback which will attempt to | ||
| 235 | identify supported devices (returning 0 for supported ones and -ENODEV | ||
| 236 | for unsupported ones), a list of addresses to probe, and a device type | ||
| 237 | (or class) so that only I2C buses which may have that type of device | ||
| 238 | connected (and not otherwise enumerated) will be probed. The i2c | ||
| 239 | core will then call you back as needed and will instantiate a device | ||
| 240 | for you for every successful detection. | ||
| 241 | |||
| 242 | Note that this mechanism is purely optional and not suitable for all | ||
| 243 | devices. You need some reliable way to identify the supported devices | ||
| 244 | (typically using device-specific, dedicated identification registers), | ||
| 245 | otherwise misdetections are likely to occur and things can get wrong | ||
| 246 | quickly. | ||
| 247 | |||
| 248 | |||
| 220 | Device Deletion (Standard driver model) | 249 | Device Deletion (Standard driver model) |
| 221 | --------------------------------------- | 250 | --------------------------------------- |
| 222 | 251 | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 5e249d758828..0a79f7661017 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -42,7 +42,9 @@ | |||
| 42 | static DEFINE_MUTEX(core_lock); | 42 | static DEFINE_MUTEX(core_lock); |
| 43 | static DEFINE_IDR(i2c_adapter_idr); | 43 | static DEFINE_IDR(i2c_adapter_idr); |
| 44 | 44 | ||
| 45 | #define is_newstyle_driver(d) ((d)->probe || (d)->remove) | 45 | #define is_newstyle_driver(d) ((d)->probe || (d)->remove || (d)->detect) |
| 46 | |||
| 47 | static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); | ||
| 46 | 48 | ||
| 47 | /* ------------------------------------------------------------------------- */ | 49 | /* ------------------------------------------------------------------------- */ |
| 48 | 50 | ||
| @@ -418,6 +420,10 @@ static int i2c_do_add_adapter(struct device_driver *d, void *data) | |||
| 418 | struct i2c_driver *driver = to_i2c_driver(d); | 420 | struct i2c_driver *driver = to_i2c_driver(d); |
| 419 | struct i2c_adapter *adap = data; | 421 | struct i2c_adapter *adap = data; |
| 420 | 422 | ||
| 423 | /* Detect supported devices on that bus, and instantiate them */ | ||
| 424 | i2c_detect(adap, driver); | ||
| 425 | |||
| 426 | /* Let legacy drivers scan this bus for matching devices */ | ||
| 421 | if (driver->attach_adapter) { | 427 | if (driver->attach_adapter) { |
| 422 | /* We ignore the return code; if it fails, too bad */ | 428 | /* We ignore the return code; if it fails, too bad */ |
| 423 | driver->attach_adapter(adap); | 429 | driver->attach_adapter(adap); |
| @@ -457,7 +463,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
| 457 | if (adap->nr < __i2c_first_dynamic_bus_num) | 463 | if (adap->nr < __i2c_first_dynamic_bus_num) |
| 458 | i2c_scan_static_board_info(adap); | 464 | i2c_scan_static_board_info(adap); |
| 459 | 465 | ||
| 460 | /* let legacy drivers scan this bus for matching devices */ | 466 | /* Notify drivers */ |
| 461 | dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, | 467 | dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, |
| 462 | i2c_do_add_adapter); | 468 | i2c_do_add_adapter); |
| 463 | 469 | ||
| @@ -563,8 +569,19 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data) | |||
| 563 | { | 569 | { |
| 564 | struct i2c_driver *driver = to_i2c_driver(d); | 570 | struct i2c_driver *driver = to_i2c_driver(d); |
| 565 | struct i2c_adapter *adapter = data; | 571 | struct i2c_adapter *adapter = data; |
| 572 | struct i2c_client *client, *_n; | ||
| 566 | int res; | 573 | int res; |
| 567 | 574 | ||
| 575 | /* Remove the devices we created ourselves */ | ||
| 576 | list_for_each_entry_safe(client, _n, &driver->clients, detected) { | ||
| 577 | if (client->adapter == adapter) { | ||
| 578 | dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", | ||
| 579 | client->name, client->addr); | ||
| 580 | list_del(&client->detected); | ||
| 581 | i2c_unregister_device(client); | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 568 | if (!driver->detach_adapter) | 585 | if (!driver->detach_adapter) |
| 569 | return 0; | 586 | return 0; |
| 570 | res = driver->detach_adapter(adapter); | 587 | res = driver->detach_adapter(adapter); |
| @@ -651,7 +668,11 @@ static int __attach_adapter(struct device *dev, void *data) | |||
| 651 | struct i2c_adapter *adapter = to_i2c_adapter(dev); | 668 | struct i2c_adapter *adapter = to_i2c_adapter(dev); |
| 652 | struct i2c_driver *driver = data; | 669 | struct i2c_driver *driver = data; |
| 653 | 670 | ||
| 654 | driver->attach_adapter(adapter); | 671 | i2c_detect(adapter, driver); |
| 672 | |||
| 673 | /* Legacy drivers scan i2c busses directly */ | ||
| 674 | if (driver->attach_adapter) | ||
| 675 | driver->attach_adapter(adapter); | ||
| 655 | 676 | ||
| 656 | return 0; | 677 | return 0; |
| 657 | } | 678 | } |
| @@ -695,10 +716,9 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
| 695 | 716 | ||
| 696 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); | 717 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); |
| 697 | 718 | ||
| 698 | /* legacy drivers scan i2c busses directly */ | 719 | INIT_LIST_HEAD(&driver->clients); |
| 699 | if (driver->attach_adapter) | 720 | /* Walk the adapters that are already present */ |
| 700 | class_for_each_device(&i2c_adapter_class, driver, | 721 | class_for_each_device(&i2c_adapter_class, driver, __attach_adapter); |
| 701 | __attach_adapter); | ||
| 702 | 722 | ||
| 703 | mutex_unlock(&core_lock); | 723 | mutex_unlock(&core_lock); |
| 704 | return 0; | 724 | return 0; |
| @@ -709,6 +729,17 @@ static int __detach_adapter(struct device *dev, void *data) | |||
| 709 | { | 729 | { |
| 710 | struct i2c_adapter *adapter = to_i2c_adapter(dev); | 730 | struct i2c_adapter *adapter = to_i2c_adapter(dev); |
| 711 | struct i2c_driver *driver = data; | 731 | struct i2c_driver *driver = data; |
| 732 | struct i2c_client *client, *_n; | ||
| 733 | |||
| 734 | list_for_each_entry_safe(client, _n, &driver->clients, detected) { | ||
| 735 | dev_dbg(&adapter->dev, "Removing %s at 0x%x\n", | ||
| 736 | client->name, client->addr); | ||
| 737 | list_del(&client->detected); | ||
| 738 | i2c_unregister_device(client); | ||
| 739 | } | ||
| 740 | |||
| 741 | if (is_newstyle_driver(driver)) | ||
| 742 | return 0; | ||
| 712 | 743 | ||
| 713 | /* Have a look at each adapter, if clients of this driver are still | 744 | /* Have a look at each adapter, if clients of this driver are still |
| 714 | * attached. If so, detach them to be able to kill the driver | 745 | * attached. If so, detach them to be able to kill the driver |
| @@ -747,10 +778,7 @@ void i2c_del_driver(struct i2c_driver *driver) | |||
| 747 | { | 778 | { |
| 748 | mutex_lock(&core_lock); | 779 | mutex_lock(&core_lock); |
| 749 | 780 | ||
| 750 | /* legacy driver? */ | 781 | class_for_each_device(&i2c_adapter_class, driver, __detach_adapter); |
| 751 | if (!is_newstyle_driver(driver)) | ||
| 752 | class_for_each_device(&i2c_adapter_class, driver, | ||
| 753 | __detach_adapter); | ||
| 754 | 782 | ||
| 755 | driver_unregister(&driver->driver); | 783 | driver_unregister(&driver->driver); |
| 756 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); | 784 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); |
| @@ -1205,6 +1233,179 @@ int i2c_probe(struct i2c_adapter *adapter, | |||
| 1205 | } | 1233 | } |
| 1206 | EXPORT_SYMBOL(i2c_probe); | 1234 | EXPORT_SYMBOL(i2c_probe); |
| 1207 | 1235 | ||
| 1236 | /* Separate detection function for new-style drivers */ | ||
| 1237 | static int i2c_detect_address(struct i2c_client *temp_client, int kind, | ||
| 1238 | struct i2c_driver *driver) | ||
| 1239 | { | ||
| 1240 | struct i2c_board_info info; | ||
| 1241 | struct i2c_adapter *adapter = temp_client->adapter; | ||
| 1242 | int addr = temp_client->addr; | ||
| 1243 | int err; | ||
| 1244 | |||
| 1245 | /* Make sure the address is valid */ | ||
| 1246 | if (addr < 0x03 || addr > 0x77) { | ||
| 1247 | dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n", | ||
| 1248 | addr); | ||
| 1249 | return -EINVAL; | ||
| 1250 | } | ||
| 1251 | |||
| 1252 | /* Skip if already in use */ | ||
| 1253 | if (i2c_check_addr(adapter, addr)) | ||
| 1254 | return 0; | ||
| 1255 | |||
| 1256 | /* Make sure there is something at this address, unless forced */ | ||
| 1257 | if (kind < 0) { | ||
| 1258 | if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, | ||
| 1259 | I2C_SMBUS_QUICK, NULL) < 0) | ||
| 1260 | return 0; | ||
| 1261 | |||
| 1262 | /* prevent 24RF08 corruption */ | ||
| 1263 | if ((addr & ~0x0f) == 0x50) | ||
| 1264 | i2c_smbus_xfer(adapter, addr, 0, 0, 0, | ||
| 1265 | I2C_SMBUS_QUICK, NULL); | ||
| 1266 | } | ||
| 1267 | |||
| 1268 | /* Finally call the custom detection function */ | ||
| 1269 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 1270 | info.addr = addr; | ||
| 1271 | err = driver->detect(temp_client, kind, &info); | ||
| 1272 | if (err) { | ||
| 1273 | /* -ENODEV is returned if the detection fails. We catch it | ||
| 1274 | here as this isn't an error. */ | ||
| 1275 | return err == -ENODEV ? 0 : err; | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | /* Consistency check */ | ||
| 1279 | if (info.type[0] == '\0') { | ||
| 1280 | dev_err(&adapter->dev, "%s detection function provided " | ||
| 1281 | "no name for 0x%x\n", driver->driver.name, | ||
| 1282 | addr); | ||
| 1283 | } else { | ||
| 1284 | struct i2c_client *client; | ||
| 1285 | |||
| 1286 | /* Detection succeeded, instantiate the device */ | ||
| 1287 | dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n", | ||
| 1288 | info.type, info.addr); | ||
| 1289 | client = i2c_new_device(adapter, &info); | ||
| 1290 | if (client) | ||
| 1291 | list_add_tail(&client->detected, &driver->clients); | ||
| 1292 | else | ||
| 1293 | dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n", | ||
| 1294 | info.type, info.addr); | ||
| 1295 | } | ||
| 1296 | return 0; | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) | ||
| 1300 | { | ||
| 1301 | const struct i2c_client_address_data *address_data; | ||
| 1302 | struct i2c_client *temp_client; | ||
| 1303 | int i, err = 0; | ||
| 1304 | int adap_id = i2c_adapter_id(adapter); | ||
| 1305 | |||
| 1306 | address_data = driver->address_data; | ||
| 1307 | if (!driver->detect || !address_data) | ||
| 1308 | return 0; | ||
| 1309 | |||
| 1310 | /* Set up a temporary client to help detect callback */ | ||
| 1311 | temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
| 1312 | if (!temp_client) | ||
| 1313 | return -ENOMEM; | ||
| 1314 | temp_client->adapter = adapter; | ||
| 1315 | |||
| 1316 | /* Force entries are done first, and are not affected by ignore | ||
| 1317 | entries */ | ||
| 1318 | if (address_data->forces) { | ||
| 1319 | const unsigned short * const *forces = address_data->forces; | ||
| 1320 | int kind; | ||
| 1321 | |||
| 1322 | for (kind = 0; forces[kind]; kind++) { | ||
| 1323 | for (i = 0; forces[kind][i] != I2C_CLIENT_END; | ||
| 1324 | i += 2) { | ||
| 1325 | if (forces[kind][i] == adap_id | ||
| 1326 | || forces[kind][i] == ANY_I2C_BUS) { | ||
| 1327 | dev_dbg(&adapter->dev, "found force " | ||
| 1328 | "parameter for adapter %d, " | ||
| 1329 | "addr 0x%02x, kind %d\n", | ||
| 1330 | adap_id, forces[kind][i + 1], | ||
| 1331 | kind); | ||
| 1332 | temp_client->addr = forces[kind][i + 1]; | ||
| 1333 | err = i2c_detect_address(temp_client, | ||
| 1334 | kind, driver); | ||
| 1335 | if (err) | ||
| 1336 | goto exit_free; | ||
| 1337 | } | ||
| 1338 | } | ||
| 1339 | } | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | /* Stop here if we can't use SMBUS_QUICK */ | ||
| 1343 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) { | ||
| 1344 | if (address_data->probe[0] == I2C_CLIENT_END | ||
| 1345 | && address_data->normal_i2c[0] == I2C_CLIENT_END) | ||
| 1346 | goto exit_free; | ||
| 1347 | |||
| 1348 | dev_warn(&adapter->dev, "SMBus Quick command not supported, " | ||
| 1349 | "can't probe for chips\n"); | ||
| 1350 | err = -EOPNOTSUPP; | ||
| 1351 | goto exit_free; | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | /* Stop here if the classes do not match */ | ||
| 1355 | if (!(adapter->class & driver->class)) | ||
| 1356 | goto exit_free; | ||
| 1357 | |||
| 1358 | /* Probe entries are done second, and are not affected by ignore | ||
| 1359 | entries either */ | ||
| 1360 | for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) { | ||
| 1361 | if (address_data->probe[i] == adap_id | ||
| 1362 | || address_data->probe[i] == ANY_I2C_BUS) { | ||
| 1363 | dev_dbg(&adapter->dev, "found probe parameter for " | ||
| 1364 | "adapter %d, addr 0x%02x\n", adap_id, | ||
| 1365 | address_data->probe[i + 1]); | ||
| 1366 | temp_client->addr = address_data->probe[i + 1]; | ||
| 1367 | err = i2c_detect_address(temp_client, -1, driver); | ||
| 1368 | if (err) | ||
| 1369 | goto exit_free; | ||
| 1370 | } | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | /* Normal entries are done last, unless shadowed by an ignore entry */ | ||
| 1374 | for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) { | ||
| 1375 | int j, ignore; | ||
| 1376 | |||
| 1377 | ignore = 0; | ||
| 1378 | for (j = 0; address_data->ignore[j] != I2C_CLIENT_END; | ||
| 1379 | j += 2) { | ||
| 1380 | if ((address_data->ignore[j] == adap_id || | ||
| 1381 | address_data->ignore[j] == ANY_I2C_BUS) | ||
| 1382 | && address_data->ignore[j + 1] | ||
| 1383 | == address_data->normal_i2c[i]) { | ||
| 1384 | dev_dbg(&adapter->dev, "found ignore " | ||
| 1385 | "parameter for adapter %d, " | ||
| 1386 | "addr 0x%02x\n", adap_id, | ||
| 1387 | address_data->ignore[j + 1]); | ||
| 1388 | ignore = 1; | ||
| 1389 | break; | ||
| 1390 | } | ||
| 1391 | } | ||
| 1392 | if (ignore) | ||
| 1393 | continue; | ||
| 1394 | |||
| 1395 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " | ||
| 1396 | "addr 0x%02x\n", adap_id, | ||
| 1397 | address_data->normal_i2c[i]); | ||
| 1398 | temp_client->addr = address_data->normal_i2c[i]; | ||
| 1399 | err = i2c_detect_address(temp_client, -1, driver); | ||
| 1400 | if (err) | ||
| 1401 | goto exit_free; | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | exit_free: | ||
| 1405 | kfree(temp_client); | ||
| 1406 | return err; | ||
| 1407 | } | ||
| 1408 | |||
| 1208 | struct i2c_client * | 1409 | struct i2c_client * |
| 1209 | i2c_new_probed_device(struct i2c_adapter *adap, | 1410 | i2c_new_probed_device(struct i2c_adapter *adap, |
| 1210 | struct i2c_board_info *info, | 1411 | struct i2c_board_info *info, |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 50cbab4b62b0..08be0d21864c 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
| @@ -45,6 +45,7 @@ struct i2c_adapter; | |||
| 45 | struct i2c_client; | 45 | struct i2c_client; |
| 46 | struct i2c_driver; | 46 | struct i2c_driver; |
| 47 | union i2c_smbus_data; | 47 | union i2c_smbus_data; |
| 48 | struct i2c_board_info; | ||
| 48 | 49 | ||
| 49 | /* | 50 | /* |
| 50 | * The master routines are the ones normally used to transmit data to devices | 51 | * The master routines are the ones normally used to transmit data to devices |
| @@ -94,15 +95,33 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, | |||
| 94 | u8 command, u8 length, | 95 | u8 command, u8 length, |
| 95 | const u8 *values); | 96 | const u8 *values); |
| 96 | 97 | ||
| 97 | /* | 98 | /** |
| 98 | * A driver is capable of handling one or more physical devices present on | 99 | * struct i2c_driver - represent an I2C device driver |
| 99 | * I2C adapters. This information is used to inform the driver of adapter | 100 | * @class: What kind of i2c device we instantiate (for detect) |
| 100 | * events. | 101 | * @detect: Callback for device detection |
| 102 | * @address_data: The I2C addresses to probe, ignore or force (for detect) | ||
| 103 | * @clients: List of detected clients we created (for i2c-core use only) | ||
| 101 | * | 104 | * |
| 102 | * The driver.owner field should be set to the module owner of this driver. | 105 | * The driver.owner field should be set to the module owner of this driver. |
| 103 | * The driver.name field should be set to the name of this driver. | 106 | * The driver.name field should be set to the name of this driver. |
| 107 | * | ||
| 108 | * For automatic device detection, both @detect and @address_data must | ||
| 109 | * be defined. @class should also be set, otherwise only devices forced | ||
| 110 | * with module parameters will be created. The detect function must | ||
| 111 | * fill at least the name field of the i2c_board_info structure it is | ||
| 112 | * handed upon successful detection, and possibly also the flags field. | ||
| 113 | * | ||
| 114 | * If @detect is missing, the driver will still work fine for enumerated | ||
| 115 | * devices. Detected devices simply won't be supported. This is expected | ||
| 116 | * for the many I2C/SMBus devices which can't be detected reliably, and | ||
| 117 | * the ones which can always be enumerated in practice. | ||
| 118 | * | ||
| 119 | * The i2c_client structure which is handed to the @detect callback is | ||
| 120 | * not a real i2c_client. It is initialized just enough so that you can | ||
| 121 | * call i2c_smbus_read_byte_data and friends on it. Don't do anything | ||
| 122 | * else with it. In particular, calling dev_dbg and friends on it is | ||
| 123 | * not allowed. | ||
| 104 | */ | 124 | */ |
| 105 | |||
| 106 | struct i2c_driver { | 125 | struct i2c_driver { |
| 107 | int id; | 126 | int id; |
| 108 | unsigned int class; | 127 | unsigned int class; |
| @@ -142,6 +161,11 @@ struct i2c_driver { | |||
| 142 | 161 | ||
| 143 | struct device_driver driver; | 162 | struct device_driver driver; |
| 144 | const struct i2c_device_id *id_table; | 163 | const struct i2c_device_id *id_table; |
| 164 | |||
| 165 | /* Device detection callback for automatic device creation */ | ||
| 166 | int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); | ||
| 167 | const struct i2c_client_address_data *address_data; | ||
| 168 | struct list_head clients; | ||
| 145 | }; | 169 | }; |
| 146 | #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) | 170 | #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) |
| 147 | 171 | ||
| @@ -157,6 +181,7 @@ struct i2c_driver { | |||
| 157 | * @dev: Driver model device node for the slave. | 181 | * @dev: Driver model device node for the slave. |
| 158 | * @irq: indicates the IRQ generated by this device (if any) | 182 | * @irq: indicates the IRQ generated by this device (if any) |
| 159 | * @list: list of active/busy clients (DEPRECATED) | 183 | * @list: list of active/busy clients (DEPRECATED) |
| 184 | * @detected: member of an i2c_driver.clients list | ||
| 160 | * @released: used to synchronize client releases & detaches and references | 185 | * @released: used to synchronize client releases & detaches and references |
| 161 | * | 186 | * |
| 162 | * An i2c_client identifies a single device (i.e. chip) connected to an | 187 | * An i2c_client identifies a single device (i.e. chip) connected to an |
| @@ -174,6 +199,7 @@ struct i2c_client { | |||
| 174 | struct device dev; /* the device structure */ | 199 | struct device dev; /* the device structure */ |
| 175 | int irq; /* irq issued by device */ | 200 | int irq; /* irq issued by device */ |
| 176 | struct list_head list; /* DEPRECATED */ | 201 | struct list_head list; /* DEPRECATED */ |
| 202 | struct list_head detected; | ||
| 177 | struct completion released; | 203 | struct completion released; |
| 178 | }; | 204 | }; |
| 179 | #define to_i2c_client(d) container_of(d, struct i2c_client, dev) | 205 | #define to_i2c_client(d) container_of(d, struct i2c_client, dev) |
