i2c-c2k: Don't send ACK for the last received byte

According to the I2C spec the last byte of a read transfer must not be
acknowledged. The i2c-c2k driver ACKs the last byte and then reads an
extra byte which it NAKs. This extra byte causes issues with certain
slaves like the Infineon TPM where the TPM considers the byte as
consumed, while the driver doesn't. The i2c-c2k kernel driver
implements the correct behavior and does not send an ACK for the last
byte.

Change-Id: I8f20402ebd65560685b869a81d8507011f344e62
diff --git a/drivers/i2c/busses/i2c-c2k.c b/drivers/i2c/busses/i2c-c2k.c
index 0ea2fba..1253b36 100644
--- a/drivers/i2c/busses/i2c-c2k.c
+++ b/drivers/i2c/busses/i2c-c2k.c
@@ -133,18 +133,25 @@
 
 	unsigned int data, status = 0;
 	int count = 0;
+	uint32_t ack_expected = I2C_DATA_RECEIVE_ACK;
 
 	while (len) {
+		count = 0;
 
-		/* Get and return the data */
-		writel(readl(pdev->map_base + I2C_CNTR) & ~I2C_IFLG, pdev->map_base + I2C_CNTR);
+		if (len > 1) {
+			/* more data to read, acknowledge the received byte */
+			writel(I2C_AAK, pdev->map_base + I2C_CNTR);
+                } else {
+			/* last byte, don't send acknowledge */
+			writel(0, pdev->map_base + I2C_CNTR);
+			ack_expected = I2C_DATA_RECEIVE_NACK;
+		}
 
 		udelay (I2C_DELAY * 5);
 
 		status = readl(pdev->map_base + I2C_STAT);
 		dev_dbg(pdev, "i2c_get_data len %d status 0x%x\n", len, status);
-		count++;
-		while ((status & 0xff) != I2C_DATA_RECEIVE_ACK) {
+		while ((status & 0xff) != ack_expected) {
 			udelay (I2C_DELAY * 10000);
 			if (count > 40) {
 				writel(I2C_STP, pdev->map_base + I2C_CNTR);	/*stop */
@@ -161,17 +168,6 @@
 		return_data++;
 		dev_dbg(pdev, "i2c_get_data data 0x%x\n",data);
 	}
-	writel(readl(pdev->map_base + I2C_CNTR) & ~(I2C_AAK | I2C_IFLG), pdev->map_base + I2C_CNTR);
-	while ((status & 0xff) != I2C_DATA_RECEIVE_NACK) {
-		udelay (I2C_DELAY);
-		if (count > 200) {
-			writel(I2C_STP, pdev->map_base + I2C_CNTR);	/*stop */
-			return (status);
-		}
-		status = readl(pdev->map_base + I2C_STAT);
-		count++;
-		dev_dbg(pdev, "i2c_get_data I2C_AAK status 0x%x\n", status);
-	}
 	writel(I2C_STP, pdev->map_base + I2C_CNTR);	/* stop */
 
 	return (0);