[PATCH 1/2] i2c: Add support for custom probe function

2010-06-08 Thread Jean Delvare
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 kh...@linux-fr.org
Acked-by: Mauro Carvalho Chehab mche...@redhat.com
---
 Documentation/i2c/instantiating-devices   |2 +-
 drivers/i2c/i2c-core.c|   16 ++--
 drivers/macintosh/therm_windtunnel.c  |4 ++--
 drivers/media/video/bt8xx/bttv-i2c.c  |2 +-
 drivers/media/video/cx18/cx18-i2c.c   |3 ++-
 drivers/media/video/em28xx/em28xx-cards.c |2 +-
 drivers/media/video/ivtv/ivtv-i2c.c   |9 +
 drivers/media/video/v4l2-common.c |3 ++-
 drivers/usb/host/ohci-pnx4008.c   |2 +-
 drivers/video/matrox/i2c-matroxfb.c   |2 +-
 include/linux/i2c.h   |7 +--
 11 files changed, 31 insertions(+), 21 deletions(-)

--- linux-2.6.35-rc1.orig/drivers/i2c/i2c-core.c2010-06-02 
10:22:57.0 +0200
+++ linux-2.6.35-rc1/drivers/i2c/i2c-core.c 2010-06-02 18:41:29.0 
+0200
@@ -1456,14 +1456,18 @@ static int i2c_detect(struct i2c_adapter
 struct i2c_client *
 i2c_new_probed_device(struct i2c_adapter *adap,
  struct i2c_board_info *info,
- unsigned short const *addr_list)
+ unsigned short const *addr_list,
+ int (*probe)(struct i2c_adapter *, unsigned short addr))
 {
int i;
 
-   /* Stop here if the bus doesn't support probing */
-   if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
-   dev_err(adap-dev, Probing not supported\n);
-   return NULL;
+   if (!probe) {
+   /* Stop here if the bus doesn't support probing */
+   if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
+   dev_err(adap-dev, Probing not supported\n);
+   return NULL;
+   }
+   probe = i2c_default_probe;
}
 
for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
@@ -1482,7 +1486,7 @@ i2c_new_probed_device(struct i2c_adapter
}
 
/* Test address responsiveness */
-   if (i2c_default_probe(adap, addr_list[i]))
+   if (probe(adap, addr_list[i]))
break;
}
 
--- linux-2.6.35-rc1.orig/drivers/macintosh/therm_windtunnel.c  2010-05-31 
09:59:27.0 +0200
+++ linux-2.6.35-rc1/drivers/macintosh/therm_windtunnel.c   2010-06-02 
18:41:29.0 +0200
@@ -322,10 +322,10 @@ do_attach( struct i2c_adapter *adapter )
 
memset(info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, therm_ds1775, I2C_NAME_SIZE);
-   i2c_new_probed_device(adapter, info, scan_ds1775);
+   i2c_new_probed_device(adapter, info, scan_ds1775, NULL);
 
strlcpy(info.type, therm_adm1030, I2C_NAME_SIZE);
-   i2c_new_probed_device(adapter, info, scan_adm1030);
+   i2c_new_probed_device(adapter, info, scan_adm1030, NULL);
 
if( x.thermostat  x.fan ) {
x.running = 1;
--- linux-2.6.35-rc1.orig/drivers/media/video/bt8xx/bttv-i2c.c  2010-05-30 
15:37:17.0 +0200
+++ linux-2.6.35-rc1/drivers/media/video/bt8xx/bttv-i2c.c   2010-06-02 
18:41:29.0 +0200
@@ -411,7 +411,7 @@ void __devinit init_bttv_i2c_ir(struct b
 
memset(info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, ir_video, I2C_NAME_SIZE);
-   i2c_new_probed_device(btv-c.i2c_adap, info, addr_list);
+   i2c_new_probed_device(btv-c.i2c_adap, info, addr_list, NULL);
}
 }
 
--- linux-2.6.35-rc1.orig/drivers/media/video/cx18/cx18-i2c.c   2010-05-31 
09:59:28.0 +0200
+++ linux-2.6.35-rc1/drivers/media/video/cx18/cx18-i2c.c2010-06-02 
18:41:29.0 +0200
@@ -117,7 +117,8 @@ static int cx18_i2c_new_ir(struct cx18 *
break;
}
 
-   return i2c_new_probed_device(adap, info, addr_list) == NULL ? -1 : 0;
+   return i2c_new_probed_device(adap, info, addr_list, NULL) == NULL ?
+  -1 : 0;
 }
 
 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
--- linux-2.6.35-rc1.orig/drivers/media/video/em28xx/em28xx-cards.c 
2010-05-31 09:59:28.0 +0200
+++ linux-2.6.35-rc1/drivers/media/video/em28xx/em28xx-cards.c  2010-06-02 
18:41:29.0 +0200
@@ -2357,7 +2357,7 @@ void em28xx_register_i2c_ir(struct em28x
 
if (dev-init_data.name)
info.platform_data = dev-init_data;
-   i2c_new_probed_device(dev-i2c_adap, info, addr_list);
+   i2c_new_probed_device(dev-i2c_adap, info, addr_list, NULL);
 }
 
 void em28xx_card_setup(struct em28xx *dev)
--- linux-2.6.35-rc1.orig/drivers/media/video/ivtv/ivtv-i2c.c   2010-05-31 
09:59:28.0 +0200
+++ 

[PATCH 1/2] i2c: Add support for custom probe function

2010-04-04 Thread Jean Delvare
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 kh...@linux-fr.org
---
 Documentation/i2c/instantiating-devices   |2 
 drivers/i2c/i2c-core.c|   65 -
 drivers/macintosh/therm_windtunnel.c  |4 -
 drivers/media/video/bt8xx/bttv-i2c.c  |2 
 drivers/media/video/cx18/cx18-i2c.c   |3 -
 drivers/media/video/em28xx/em28xx-cards.c |2 
 drivers/media/video/ivtv/ivtv-i2c.c   |9 ++--
 drivers/media/video/v4l2-common.c |3 -
 drivers/usb/host/ohci-pnx4008.c   |2 
 drivers/video/matrox/i2c-matroxfb.c   |2 
 include/linux/i2c.h   |7 ++-
 11 files changed, 58 insertions(+), 43 deletions(-)

--- linux-2.6.34-rc3.orig/drivers/i2c/i2c-core.c2010-04-03 
21:09:36.0 +0200
+++ linux-2.6.34-rc3/drivers/i2c/i2c-core.c 2010-04-04 13:28:17.0 
+0200
@@ -1376,17 +1376,46 @@ static int i2c_detect(struct i2c_adapter
return err;
 }
 
+/*
+ * Legacy default probe function, mostly relevant for SMBus. The default
+ * probe method is a quick write, but it is known to corrupt the 24RF08
+ * EEPROMs due to a state machine bug, and could also irreversibly
+ * write-protect some EEPROMs, so for address ranges 0x30-0x37 and 0x50-0x5f,
+ * we use a byte read instead. Also, some bus drivers don't implement quick
+ * write, so we fallback to a byte read in that case too.
+ * Returns 1 if probe succeeded, 0 if not.
+ */
+static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)
+{
+   int err;
+   union i2c_smbus_data dummy;
+
+   if ((addr  ~0x07) == 0x30 || (addr  ~0x0f) == 0x50
+|| !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
+   err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
+I2C_SMBUS_BYTE, dummy);
+   else
+   err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,
+I2C_SMBUS_QUICK, NULL);
+
+   return err = 0;
+}
+
 struct i2c_client *
 i2c_new_probed_device(struct i2c_adapter *adap,
  struct i2c_board_info *info,
- unsigned short const *addr_list)
+ unsigned short const *addr_list,
+ int (*probe)(struct i2c_adapter *, unsigned short addr))
 {
int i;
 
-   /* Stop here if the bus doesn't support probing */
-   if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
-   dev_err(adap-dev, Probing not supported\n);
-   return NULL;
+   if (!probe) {
+   /* Stop here if the bus doesn't support probing */
+   if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
+   dev_err(adap-dev, Probing not supported\n);
+   return NULL;
+   }
+   probe = i2c_default_probe;
}
 
for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
@@ -1404,29 +1433,9 @@ i2c_new_probed_device(struct i2c_adapter
continue;
}
 
-   /* Test address responsiveness
-  The default probe method is a quick write, but it is known
-  to corrupt the 24RF08 EEPROMs due to a state machine bug,
-  and could also irreversibly write-protect some EEPROMs, so
-  for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte
-  read instead. Also, some bus drivers don't implement
-  quick write, so we fallback to a byte read it that case
-  too. */
-   if ((addr_list[i]  ~0x07) == 0x30
-|| (addr_list[i]  ~0x0f) == 0x50
-|| !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
-   union i2c_smbus_data data;
-
-   if (i2c_smbus_xfer(adap, addr_list[i], 0,
-  I2C_SMBUS_READ, 0,
-  I2C_SMBUS_BYTE, data) = 0)
-   break;
-   } else {
-   if (i2c_smbus_xfer(adap, addr_list[i], 0,
-  I2C_SMBUS_WRITE, 0,
-  I2C_SMBUS_QUICK, NULL) = 0)
-   break;
-   }
+   /* Test address responsiveness */
+   if (probe(adap, addr_list[i]))
+   break;
}
 
if (addr_list[i] == I2C_CLIENT_END) {
--- linux-2.6.34-rc3.orig/drivers/macintosh/therm_windtunnel.c  2010-03-20 
14:27:51.0 +0100
+++ linux-2.6.34-rc3/drivers/macintosh/therm_windtunnel.c   2010-04-04 
10:12:14.0 +0200
@@ -323,10 +323,10 @@ do_attach( struct i2c_adapter *adapter )