diff options
author | Jean Delvare <khali@linux-fr.org> | 2010-08-11 12:20:56 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2010-08-11 12:20:56 -0400 |
commit | 9a94241afcc9a481691a9c29b7460217925b59b8 (patch) | |
tree | 7f2d42935422a228686bcd8680dc97ff8a1005bc | |
parent | f1c2e33c295de423db5740647bfaa5e2ad139192 (diff) |
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>
-rw-r--r-- | Documentation/i2c/instantiating-devices | 2 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 16 | ||||
-rw-r--r-- | drivers/macintosh/therm_windtunnel.c | 4 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-i2c.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-i2c.c | 3 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-i2c.c | 9 | ||||
-rw-r--r-- | drivers/media/video/v4l2-common.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pnx4008.c | 2 | ||||
-rw-r--r-- | drivers/video/matrox/i2c-matroxfb.c | 2 | ||||
-rw-r--r-- | include/linux/i2c.h | 7 |
11 files changed, 31 insertions, 21 deletions
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices index e89490270aba..87da405a8597 100644 --- a/Documentation/i2c/instantiating-devices +++ b/Documentation/i2c/instantiating-devices | |||
@@ -102,7 +102,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | |||
102 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); | 102 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); |
103 | strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); | 103 | strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE); |
104 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, | 104 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, |
105 | normal_i2c); | 105 | normal_i2c, NULL); |
106 | i2c_put_adapter(i2c_adap); | 106 | i2c_put_adapter(i2c_adap); |
107 | (...) | 107 | (...) |
108 | } | 108 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index df937df845eb..cf14ca063181 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1464,14 +1464,18 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) | |||
1464 | struct i2c_client * | 1464 | struct i2c_client * |
1465 | i2c_new_probed_device(struct i2c_adapter *adap, | 1465 | i2c_new_probed_device(struct i2c_adapter *adap, |
1466 | struct i2c_board_info *info, | 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 | int i; | 1470 | int i; |
1470 | 1471 | ||
1471 | /* Stop here if the bus doesn't support probing */ | 1472 | if (!probe) { |
1472 | if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) { | 1473 | /* Stop here if the bus doesn't support probing */ |
1473 | dev_err(&adap->dev, "Probing not supported\n"); | 1474 | if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) { |
1474 | return NULL; | 1475 | dev_err(&adap->dev, "Probing not supported\n"); |
1476 | return NULL; | ||
1477 | } | ||
1478 | probe = i2c_default_probe; | ||
1475 | } | 1479 | } |
1476 | 1480 | ||
1477 | for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { | 1481 | for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { |
@@ -1490,7 +1494,7 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
1490 | } | 1494 | } |
1491 | 1495 | ||
1492 | /* Test address responsiveness */ | 1496 | /* Test address responsiveness */ |
1493 | if (i2c_default_probe(adap, addr_list[i])) | 1497 | if (probe(adap, addr_list[i])) |
1494 | break; | 1498 | break; |
1495 | } | 1499 | } |
1496 | 1500 | ||
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 5c9367acf0cf..7d1bfeb6a82c 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -322,10 +322,10 @@ do_attach( struct i2c_adapter *adapter ) | |||
322 | 322 | ||
323 | memset(&info, 0, sizeof(struct i2c_board_info)); | 323 | memset(&info, 0, sizeof(struct i2c_board_info)); |
324 | strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); | 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 | strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); | 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 | if( x.thermostat && x.fan ) { | 330 | if( x.thermostat && x.fan ) { |
331 | x.running = 1; | 331 | x.running = 1; |
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index 407fa61e4cda..685d6597ee79 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c | |||
@@ -411,7 +411,7 @@ void __devinit init_bttv_i2c_ir(struct bttv *btv) | |||
411 | 411 | ||
412 | memset(&info, 0, sizeof(struct i2c_board_info)); | 412 | memset(&info, 0, sizeof(struct i2c_board_info)); |
413 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | 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 | ||
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 809f7d37129c..73ce90c2f577 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c | |||
@@ -117,7 +117,8 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw, | |||
117 | break; | 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 | int cx18_i2c_register(struct cx18 *cx, unsigned idx) | 124 | int cx18_i2c_register(struct cx18 *cx, unsigned idx) |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ffbe544e30f4..e7efb4bffabd 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -2385,7 +2385,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev) | |||
2385 | 2385 | ||
2386 | if (dev->init_data.name) | 2386 | if (dev->init_data.name) |
2387 | info.platform_data = &dev->init_data; | 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 | void em28xx_card_setup(struct em28xx *dev) | 2391 | void em28xx_card_setup(struct em28xx *dev) |
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index d391bbdb0b8a..a74fa099c565 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c | |||
@@ -183,8 +183,8 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) | |||
183 | return -1; | 183 | return -1; |
184 | memset(&info, 0, sizeof(struct i2c_board_info)); | 184 | memset(&info, 0, sizeof(struct i2c_board_info)); |
185 | strlcpy(info.type, type, I2C_NAME_SIZE); | 185 | strlcpy(info.type, type, I2C_NAME_SIZE); |
186 | return i2c_new_probed_device(adap, &info, addr_list) == NULL | 186 | return i2c_new_probed_device(adap, &info, addr_list, NULL) |
187 | ? -1 : 0; | 187 | == NULL ? -1 : 0; |
188 | } | 188 | } |
189 | 189 | ||
190 | /* Only allow one IR receiver to be registered per board */ | 190 | /* Only allow one IR receiver to be registered per board */ |
@@ -221,7 +221,8 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) | |||
221 | info.platform_data = init_data; | 221 | info.platform_data = init_data; |
222 | strlcpy(info.type, type, I2C_NAME_SIZE); | 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 | /* Instantiate the IR receiver device using probing -- undesirable */ | 228 | /* Instantiate the IR receiver device using probing -- undesirable */ |
@@ -249,7 +250,7 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv) | |||
249 | 250 | ||
250 | memset(&info, 0, sizeof(struct i2c_board_info)); | 251 | memset(&info, 0, sizeof(struct i2c_board_info)); |
251 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | 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 | int ivtv_i2c_register(struct ivtv *itv, unsigned idx) | 256 | int ivtv_i2c_register(struct ivtv *itv, unsigned idx) |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 3ce7c64e5789..8ee1179be926 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -381,7 +381,8 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, | |||
381 | 381 | ||
382 | /* Create the i2c client */ | 382 | /* Create the i2c client */ |
383 | if (info->addr == 0 && probe_addrs) | 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 | else | 386 | else |
386 | client = i2c_new_device(adapter, info); | 387 | client = i2c_new_device(adapter, info); |
387 | 388 | ||
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index cd74bbdd007c..653d6a60edb5 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -329,7 +329,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) | |||
329 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); | 329 | memset(&i2c_info, 0, sizeof(struct i2c_board_info)); |
330 | strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); | 330 | strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE); |
331 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, | 331 | isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, |
332 | normal_i2c); | 332 | normal_i2c, NULL); |
333 | i2c_put_adapter(i2c_adap); | 333 | i2c_put_adapter(i2c_adap); |
334 | if (!isp1301_i2c_client) { | 334 | if (!isp1301_i2c_client) { |
335 | err("failed to connect I2C to ISP1301 USB Transceiver"); | 335 | err("failed to connect I2C to ISP1301 USB Transceiver"); |
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c index 403b14445a78..0fb280ead3dc 100644 --- a/drivers/video/matrox/i2c-matroxfb.c +++ b/drivers/video/matrox/i2c-matroxfb.c | |||
@@ -191,7 +191,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) { | |||
191 | }; | 191 | }; |
192 | 192 | ||
193 | i2c_new_probed_device(&m2info->maven.adapter, | 193 | i2c_new_probed_device(&m2info->maven.adapter, |
194 | &maven_info, addr_list); | 194 | &maven_info, addr_list, NULL); |
195 | } | 195 | } |
196 | } | 196 | } |
197 | return m2info; | 197 | return m2info; |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 38dd4025aa4e..59a9f3cdc0b5 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -284,12 +284,15 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info); | |||
284 | 284 | ||
285 | /* If you don't know the exact address of an I2C device, use this variant | 285 | /* If you don't know the exact address of an I2C device, use this variant |
286 | * instead, which can probe for device presence in a list of possible | 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 | extern struct i2c_client * | 291 | extern struct i2c_client * |
290 | i2c_new_probed_device(struct i2c_adapter *adap, | 292 | i2c_new_probed_device(struct i2c_adapter *adap, |
291 | struct i2c_board_info *info, | 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 | /* For devices that use several addresses, use i2c_new_dummy() to make | 297 | /* For devices that use several addresses, use i2c_new_dummy() to make |
295 | * client handles for the extra addresses. | 298 | * client handles for the extra addresses. |