i2c: Add i2c_new_probed_device()

Add a new helper function to instantiate an i2c device. It is meant as a
replacement for i2c_new_device() when you don't know for sure at which
address your I2C/SMBus device lives. This happens frequently on TV
adapters for example, you know there is a tuner chip on the bus, but
depending on the exact board model and revision, it can live at different
addresses. So, the new i2c_new_probed_device() function will probe the bus
according to a list of addresses, and as soon as one of these addresses
responds, it will call i2c_new_device() on that one address.

This function will make it possible to port the old i2c drivers to the
new model quickly.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 1812439..0fd4acb 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1092,6 +1092,69 @@
 }
 EXPORT_SYMBOL(i2c_probe);
 
+struct i2c_client *
+i2c_new_probed_device(struct i2c_adapter *adap,
+		      struct i2c_board_info *info,
+		      unsigned short const *addr_list)
+{
+	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;
+	}
+
+	mutex_lock(&adap->clist_lock);
+	for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
+		/* Check address validity */
+		if (addr_list[i] < 0x03 || addr_list[i] > 0x77) {
+			dev_warn(&adap->dev, "Invalid 7-bit address "
+				 "0x%02x\n", addr_list[i]);
+			continue;
+		}
+
+		/* Check address availability */
+		if (__i2c_check_addr(adap, addr_list[i])) {
+			dev_dbg(&adap->dev, "Address 0x%02x already in "
+				"use, not probing\n", addr_list[i]);
+			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)) {
+			if (i2c_smbus_xfer(adap, addr_list[i], 0,
+					   I2C_SMBUS_READ, 0,
+					   I2C_SMBUS_BYTE, NULL) >= 0)
+				break;
+		} else {
+			if (i2c_smbus_xfer(adap, addr_list[i], 0,
+					   I2C_SMBUS_WRITE, 0,
+					   I2C_SMBUS_QUICK, NULL) >= 0)
+				break;
+		}
+	}
+	mutex_unlock(&adap->clist_lock);
+
+	if (addr_list[i] == I2C_CLIENT_END) {
+		dev_dbg(&adap->dev, "Probing failed, no device found\n");
+		return NULL;
+	}
+
+	info->addr = addr_list[i];
+	return i2c_new_device(adap, info);
+}
+EXPORT_SYMBOL_GPL(i2c_new_probed_device);
+
 struct i2c_adapter* i2c_get_adapter(int id)
 {
 	struct i2c_adapter *adapter;