i2c: tegra: use repeated start for reads

I2C read transactions are typically implemented as follows:

START(write) address REPEATED_START(read) data... STOP

However, Tegra's I2C driver currently implements reads as follows:

START(write) address STOP START(read) data... STOP

This sequence confuses at least the AS3722 PMIC on the Jetson TK1 board,
leading to corrupted read data in some cases. Fix the driver to chain
the transactions together using repeated starts to solve this.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Yen Lin <yelin@nvidia.com>
diff --git a/arch/arm/include/asm/arch-tegra/tegra_i2c.h b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
index 853e59b..7ca6907 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_i2c.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_i2c.h
@@ -124,6 +124,8 @@
 /* bit fields definitions for IO Packet Header 3 format */
 #define PKT_HDR3_READ_MODE_SHIFT	19
 #define PKT_HDR3_READ_MODE_MASK		(1 << PKT_HDR3_READ_MODE_SHIFT)
+#define PKT_HDR3_REPEAT_START_SHIFT	16
+#define PKT_HDR3_REPEAT_START_MASK	(1 << PKT_HDR3_REPEAT_START_SHIFT)
 #define PKT_HDR3_SLAVE_ADDR_SHIFT	0
 #define PKT_HDR3_SLAVE_ADDR_MASK	(0x3ff << PKT_HDR3_SLAVE_ADDR_SHIFT)
 
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 594e5dd..97f0ca4 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -110,7 +110,8 @@
 static void send_packet_headers(
 	struct i2c_bus *i2c_bus,
 	struct i2c_trans_info *trans,
-	u32 packet_id)
+	u32 packet_id,
+	bool end_with_repeated_start)
 {
 	u32 data;
 
@@ -132,6 +133,8 @@
 	/* Enable Read if it is not a write transaction */
 	if (!(trans->flags & I2C_IS_WRITE))
 		data |= PKT_HDR3_READ_MODE_MASK;
+	if (end_with_repeated_start)
+		data |= PKT_HDR3_REPEAT_START_MASK;
 
 	/* Write I2C specific header */
 	writel(data, &i2c_bus->control->tx_fifo);
@@ -209,7 +212,8 @@
 	int_status = readl(&control->int_status);
 	writel(int_status, &control->int_status);
 
-	send_packet_headers(i2c_bus, trans, 1);
+	send_packet_headers(i2c_bus, trans, 1,
+			    trans->flags & I2C_USE_REPEATED_START);
 
 	words = DIV_ROUND_UP(trans->num_bytes, 4);
 	last_bytes = trans->num_bytes & 3;
@@ -267,7 +271,7 @@
 }
 
 static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data,
-				u32 len)
+				u32 len, bool end_with_repeated_start)
 {
 	int error;
 	struct i2c_trans_info trans_info;
@@ -275,6 +279,8 @@
 	trans_info.address = addr;
 	trans_info.buf = data;
 	trans_info.flags = I2C_IS_WRITE;
+	if (end_with_repeated_start)
+		trans_info.flags |= I2C_USE_REPEATED_START;
 	trans_info.num_bytes = len;
 	trans_info.is_10bit_address = 0;
 
@@ -463,7 +469,8 @@
 }
 
 /* i2c write version without the register address */
-int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len)
+int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len,
+		   bool end_with_repeated_start)
 {
 	int rc;
 
@@ -475,7 +482,8 @@
 	debug("\n");
 
 	/* Shift 7-bit address over for lower-level i2c functions */
-	rc = tegra_i2c_write_data(bus, chip << 1, buffer, len);
+	rc = tegra_i2c_write_data(bus, chip << 1, buffer, len,
+				  end_with_repeated_start);
 	if (rc)
 		debug("i2c_write_data(): rc=%d\n", rc);
 
@@ -516,7 +524,7 @@
 	if (!bus)
 		return 1;
 	reg = 0;
-	rc = i2c_write_data(bus, chip, &reg, 1);
+	rc = i2c_write_data(bus, chip, &reg, 1, false);
 	if (rc) {
 		debug("Error probing 0x%x.\n", chip);
 		return 1;
@@ -554,7 +562,7 @@
 				data[alen - i - 1] =
 					(addr + offset) >> (8 * i);
 			}
-			if (i2c_write_data(bus, chip, data, alen)) {
+			if (i2c_write_data(bus, chip, data, alen, true)) {
 				debug("i2c_read: error sending (0x%x)\n",
 					addr);
 				return 1;
@@ -591,7 +599,7 @@
 		for (i = 0; i < alen; i++)
 			data[alen - i - 1] = (addr + offset) >> (8 * i);
 		data[alen] = buffer[offset];
-		if (i2c_write_data(bus, chip, data, alen + 1)) {
+		if (i2c_write_data(bus, chip, data, alen + 1, false)) {
 			debug("i2c_write: error sending (0x%x)\n", addr);
 			return 1;
 		}