Commit 9a94241afcc9a481691a9c29b7460217925b59b8
1 parent
f1c2e33c29
Exists in
master
and in
7 other branches
i2c: Add support for custom probe function
The probe method used by i2c_new_probed_device() may not be suitable for all cases. Let the caller provide its own, optional probe function. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Showing 11 changed files with 31 additions and 21 deletions Side-by-side Diff
- Documentation/i2c/instantiating-devices
- drivers/i2c/i2c-core.c
- drivers/macintosh/therm_windtunnel.c
- drivers/media/video/bt8xx/bttv-i2c.c
- drivers/media/video/cx18/cx18-i2c.c
- drivers/media/video/em28xx/em28xx-cards.c
- drivers/media/video/ivtv/ivtv-i2c.c
- drivers/media/video/v4l2-common.c
- drivers/usb/host/ohci-pnx4008.c
- drivers/video/matrox/i2c-matroxfb.c
- include/linux/i2c.h
Documentation/i2c/instantiating-devices
... | ... | @@ -102,7 +102,7 @@ |
102 | 102 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); |
103 | 103 | strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); |
104 | 104 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, |
105 | - normal_i2c); | |
105 | + normal_i2c, NULL); | |
106 | 106 | i2c_put_adapter(i2c_adap); |
107 | 107 | (...) |
108 | 108 | } |
drivers/i2c/i2c-core.c
... | ... | @@ -1464,14 +1464,18 @@ |
1464 | 1464 | struct i2c_client * |
1465 | 1465 | i2c_new_probed_device(struct i2c_adapter *adap, |
1466 | 1466 | struct i2c_board_info *info, |
1467 | - unsigned short const *addr_list) | |
1467 | + unsigned short const *addr_list, | |
1468 | + int (*probe)(struct i2c_adapter *, unsigned short addr)) | |
1468 | 1469 | { |
1469 | 1470 | int i; |
1470 | 1471 | |
1471 | - /* Stop here if the bus doesn't support probing */ | |
1472 | - if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) { | |
1473 | - dev_err(&adap->dev, "Probing not supported\n"); | |
1474 | - return NULL; | |
1472 | + if (!probe) { | |
1473 | + /* Stop here if the bus doesn't support probing */ | |
1474 | + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) { | |
1475 | + dev_err(&adap->dev, "Probing not supported\n"); | |
1476 | + return NULL; | |
1477 | + } | |
1478 | + probe = i2c_default_probe; | |
1475 | 1479 | } |
1476 | 1480 | |
1477 | 1481 | for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { |
... | ... | @@ -1490,7 +1494,7 @@ |
1490 | 1494 | } |
1491 | 1495 | |
1492 | 1496 | /* Test address responsiveness */ |
1493 | - if (i2c_default_probe(adap, addr_list[i])) | |
1497 | + if (probe(adap, addr_list[i])) | |
1494 | 1498 | break; |
1495 | 1499 | } |
1496 | 1500 |
drivers/macintosh/therm_windtunnel.c
... | ... | @@ -322,10 +322,10 @@ |
322 | 322 | |
323 | 323 | memset(&info, 0, sizeof(struct i2c_board_info)); |
324 | 324 | strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); |
325 | - i2c_new_probed_device(adapter, &info, scan_ds1775); | |
325 | + i2c_new_probed_device(adapter, &info, scan_ds1775, NULL); | |
326 | 326 | |
327 | 327 | strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); |
328 | - i2c_new_probed_device(adapter, &info, scan_adm1030); | |
328 | + i2c_new_probed_device(adapter, &info, scan_adm1030, NULL); | |
329 | 329 | |
330 | 330 | if( x.thermostat && x.fan ) { |
331 | 331 | x.running = 1; |
drivers/media/video/bt8xx/bttv-i2c.c
... | ... | @@ -411,7 +411,7 @@ |
411 | 411 | |
412 | 412 | memset(&info, 0, sizeof(struct i2c_board_info)); |
413 | 413 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); |
414 | - i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); | |
414 | + i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL); | |
415 | 415 | } |
416 | 416 | } |
417 | 417 |
drivers/media/video/cx18/cx18-i2c.c
... | ... | @@ -117,7 +117,8 @@ |
117 | 117 | break; |
118 | 118 | } |
119 | 119 | |
120 | - return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0; | |
120 | + return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? | |
121 | + -1 : 0; | |
121 | 122 | } |
122 | 123 | |
123 | 124 | int cx18_i2c_register(struct cx18 *cx, unsigned idx) |
drivers/media/video/em28xx/em28xx-cards.c
... | ... | @@ -2385,7 +2385,7 @@ |
2385 | 2385 | |
2386 | 2386 | if (dev->init_data.name) |
2387 | 2387 | info.platform_data = &dev->init_data; |
2388 | - i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); | |
2388 | + i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL); | |
2389 | 2389 | } |
2390 | 2390 | |
2391 | 2391 | void em28xx_card_setup(struct em28xx *dev) |
drivers/media/video/ivtv/ivtv-i2c.c
... | ... | @@ -183,8 +183,8 @@ |
183 | 183 | return -1; |
184 | 184 | memset(&info, 0, sizeof(struct i2c_board_info)); |
185 | 185 | strlcpy(info.type, type, I2C_NAME_SIZE); |
186 | - return i2c_new_probed_device(adap, &info, addr_list) == NULL | |
187 | - ? -1 : 0; | |
186 | + return i2c_new_probed_device(adap, &info, addr_list, NULL) | |
187 | + == NULL ? -1 : 0; | |
188 | 188 | } |
189 | 189 | |
190 | 190 | /* Only allow one IR receiver to be registered per board */ |
... | ... | @@ -221,7 +221,8 @@ |
221 | 221 | info.platform_data = init_data; |
222 | 222 | strlcpy(info.type, type, I2C_NAME_SIZE); |
223 | 223 | |
224 | - return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0; | |
224 | + return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? | |
225 | + -1 : 0; | |
225 | 226 | } |
226 | 227 | |
227 | 228 | /* Instantiate the IR receiver device using probing -- undesirable */ |
... | ... | @@ -249,7 +250,7 @@ |
249 | 250 | |
250 | 251 | memset(&info, 0, sizeof(struct i2c_board_info)); |
251 | 252 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); |
252 | - return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list); | |
253 | + return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL); | |
253 | 254 | } |
254 | 255 | |
255 | 256 | int ivtv_i2c_register(struct ivtv *itv, unsigned idx) |
drivers/media/video/v4l2-common.c
... | ... | @@ -381,7 +381,8 @@ |
381 | 381 | |
382 | 382 | /* Create the i2c client */ |
383 | 383 | if (info->addr == 0 && probe_addrs) |
384 | - client = i2c_new_probed_device(adapter, info, probe_addrs); | |
384 | + client = i2c_new_probed_device(adapter, info, probe_addrs, | |
385 | + NULL); | |
385 | 386 | else |
386 | 387 | client = i2c_new_device(adapter, info); |
387 | 388 |
drivers/usb/host/ohci-pnx4008.c
... | ... | @@ -329,7 +329,7 @@ |
329 | 329 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); |
330 | 330 | strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); |
331 | 331 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, |
332 | - normal_i2c); | |
332 | + normal_i2c, NULL); | |
333 | 333 | i2c_put_adapter(i2c_adap); |
334 | 334 | if (!isp1301_i2c_client) { |
335 | 335 | err("failed to connect I2C to ISP1301 USB Transceiver"); |
drivers/video/matrox/i2c-matroxfb.c
include/linux/i2c.h
... | ... | @@ -284,12 +284,15 @@ |
284 | 284 | |
285 | 285 | /* If you don't know the exact address of an I2C device, use this variant |
286 | 286 | * instead, which can probe for device presence in a list of possible |
287 | - * addresses. | |
287 | + * addresses. The "probe" callback function is optional. If it is provided, | |
288 | + * it must return 1 on successful probe, 0 otherwise. If it is not provided, | |
289 | + * a default probing method is used. | |
288 | 290 | */ |
289 | 291 | extern struct i2c_client * |
290 | 292 | i2c_new_probed_device(struct i2c_adapter *adap, |
291 | 293 | struct i2c_board_info *info, |
292 | - unsigned short const *addr_list); | |
294 | + unsigned short const *addr_list, | |
295 | + int (*probe)(struct i2c_adapter *, unsigned short addr)); | |
293 | 296 | |
294 | 297 | /* For devices that use several addresses, use i2c_new_dummy() to make |
295 | 298 | * client handles for the extra addresses. |