[PATCH 1/2] eeprom: at24: added quirk for 24c08 devices

Brendan Higgins brendanhiggins at google.com
Sun Aug 21 11:34:17 AEST 2016


Some 24c08 devices exhibits a quirk where they will not NACK durring an
acknowledge poll. Added a STOP after the dummy write to address problem.
---
 drivers/misc/eeprom/at24.c         | 12 +++++++++++-
 include/linux/platform_data/at24.h |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 9ceb63b..c647efb 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -120,7 +120,11 @@ static const struct i2c_device_id at24_ids[] = {
 		AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },
 	{ "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
 	/* 24rf08 quirk is handled at i2c-core */
-	{ "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
+	/* 24c08 exhibits a quirk where it will not NACK durring an
+	 * acknowledge poll so we have to send a stop after the dummy write in
+	 * a read.
+	 */
+	{ "24c08", AT24_DEVICE_MAGIC(8192 / 8, AT24_FLAG_STOPPOLL) },
 	{ "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
 	{ "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
 	{ "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
@@ -212,6 +216,12 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
 		msgbuf[i++] = offset;
 
 		msg[0].addr = client->addr;
+		/*
+		 * Some EEPROMs do not perform the acknowledge poll correctly
+		 * and have to send a STOP after the dummy write.
+		 */
+		if (at24->chip.flags & AT24_FLAG_STOPPOLL)
+			msg[0].flags = I2C_M_STOP;
 		msg[0].buf = msgbuf;
 		msg[0].len = i;
 
diff --git a/include/linux/platform_data/at24.h b/include/linux/platform_data/at24.h
index be830b1..1773822 100644
--- a/include/linux/platform_data/at24.h
+++ b/include/linux/platform_data/at24.h
@@ -47,6 +47,7 @@ struct at24_platform_data {
 #define AT24_FLAG_READONLY	0x40	/* sysfs-entry will be read-only */
 #define AT24_FLAG_IRUGO		0x20	/* sysfs-entry will be world-readable */
 #define AT24_FLAG_TAKE8ADDR	0x10	/* take always 8 addresses (24c00) */
+#define AT24_FLAG_STOPPOLL	0x08	/* Send stop before ACK poll */
 
 	void		(*setup)(struct nvmem_device *nvmem, void *context);
 	void		*context;
-- 
2.8.0.rc3.226.g39d4020



More information about the openbmc mailing list