From: Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
To: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
Subject: [PATCH] eeprom: at24: Add support for large EEPROMs connected to SMBus adapters
Date: Wed, 4 Feb 2015 08:23:37 -0800 [thread overview]
Message-ID: <1423067017-27607-1-git-send-email-linux@roeck-us.net> (raw)
Large EEPROMS (24c32 and larger) require a two-byte data address
instead of just a single byte. Implement support for such EEPROMs
with SMBus commands.
Support has limitations (reads are not multi-master safe) and is slow,
but it works. Practical use is for a system with 24c32 connected to
Intel 82801I (ICH9).
Signed-off-by: Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
---
drivers/misc/eeprom/at24.c | 52 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 47 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 2d3db81..057d35c 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -198,6 +198,8 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
case I2C_SMBUS_BYTE_DATA:
count = 1;
break;
+ case I2C_SMBUS_BYTE:
+ break;
default:
/*
* When we have a better choice than SMBus calls, use a
@@ -249,6 +251,27 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
status = count;
}
break;
+ case I2C_SMBUS_BYTE:
+ /*
+ * 16-bit data address. Write data address as separate
+ * write operation, then read data without setting
+ * the address again. This is not multi-master safe,
+ * but the best we can do.
+ */
+ status = i2c_smbus_write_byte_data(client,
+ offset >> 8,
+ offset & 0xff);
+ if (status < 0)
+ break;
+ for (i = 0; i < count; i++) {
+ status = i2c_smbus_read_byte(client);
+ if (status < 0)
+ break;
+ buf[i] = status;
+ }
+ if (status >= 0)
+ status = count;
+ break;
default:
status = i2c_transfer(client->adapter, msg, 2);
if (status == 2)
@@ -372,6 +395,16 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,
status = i2c_smbus_write_i2c_block_data(client,
offset, count, buf);
break;
+ case I2C_SMBUS_WORD_DATA:
+ /*
+ * 16-bit data address. Transmit data address
+ * MSB as SMBus command, data address LSB as
+ * first data byte.
+ */
+ status = i2c_smbus_write_word_data(client,
+ offset >> 8,
+ (offset & 0xff) | (buf[0] << 8));
+ break;
case I2C_SMBUS_BYTE_DATA:
status = i2c_smbus_write_byte_data(client,
offset, buf[0]);
@@ -540,10 +573,13 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
/* Use I2C operations unless we're stuck with SMBus extensions. */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- if (chip.flags & AT24_FLAG_ADDR16)
- return -EPFNOSUPPORT;
-
- if (i2c_check_functionality(client->adapter,
+ if (chip.flags & AT24_FLAG_ADDR16) {
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+ I2C_FUNC_SMBUS_READ_BYTE))
+ return -EPFNOSUPPORT;
+ use_smbus = I2C_SMBUS_BYTE;
+ } else if (i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
use_smbus = I2C_SMBUS_I2C_BLOCK_DATA;
} else if (i2c_check_functionality(client->adapter,
@@ -559,7 +595,13 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
/* Use I2C operations unless we're stuck with SMBus extensions. */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- if (i2c_check_functionality(client->adapter,
+ if (chip.flags & AT24_FLAG_ADDR16) {
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_WORD_DATA)) {
+ use_smbus_write = I2C_SMBUS_WORD_DATA;
+ chip.page_size = 1;
+ }
+ } else if (i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
use_smbus_write = I2C_SMBUS_I2C_BLOCK_DATA;
} else if (i2c_check_functionality(client->adapter,
--
2.1.0
next reply other threads:[~2015-02-04 16:23 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-04 16:23 Guenter Roeck [this message]
2015-02-04 17:47 ` [PATCH] eeprom: at24: Add support for large EEPROMs connected to SMBus adapters Wolfram Sang
2015-02-04 19:08 ` Guenter Roeck
2015-02-04 23:35 ` Wolfram Sang
2015-02-05 0:26 ` Guenter Roeck
2015-02-05 14:40 ` Wolfram Sang
2015-02-05 17:53 ` Guenter Roeck
[not found] ` <20150205175326.GA26691-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
2015-02-12 4:01 ` Guenter Roeck
2015-02-16 12:09 ` Wolfram Sang
2015-02-16 15:37 ` Guenter Roeck
2015-03-17 4:20 ` Guenter Roeck
2015-03-18 13:27 ` Wolfram Sang
2015-03-19 3:24 ` Guenter Roeck
[not found] ` <550A4162.8000009-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
2015-03-19 8:16 ` Wolfram Sang
2015-03-19 13:30 ` Guenter Roeck
2015-03-19 17:43 ` Guenter Roeck
2015-03-19 21:39 ` Wolfram Sang
2015-03-25 14:11 ` Guenter Roeck
[not found] ` <5512C213.7030705-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
2015-03-25 16:15 ` Wolfram Sang
2015-03-25 16:37 ` Guenter Roeck
2015-03-27 8:09 ` Wolfram Sang
2015-03-27 12:51 ` Guenter Roeck
2015-03-27 13:01 ` Wolfram Sang
2015-03-27 13:14 ` Guenter Roeck
2015-03-27 15:27 ` Wolfram Sang
2015-03-27 15:42 ` Guenter Roeck
2015-02-04 20:33 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1423067017-27607-1-git-send-email-linux@roeck-us.net \
--to=linux-0h96xk9xttrk1umjsbkqmq@public.gmane.org \
--cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).