From: Irina Tirdea <irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>,
Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Srinivas Pandruvada
<srinivas.pandruvada-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Peter Meerwald <pmeerw-jW+XmwGofnusTnJN9+BGXg@public.gmane.org>,
Irina Tirdea
<irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: [PATCH v3 1/8] i2c: core: Add support for best effort block read emulation
Date: Fri, 3 Jul 2015 12:33:30 +0300 [thread overview]
Message-ID: <1435916017-12859-2-git-send-email-irina.tirdea@intel.com> (raw)
In-Reply-To: <1435916017-12859-1-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
There are devices that need to handle block transactions
regardless of the capabilities exported by the adapter.
For performance reasons, they need to use i2c read blocks
if available, otherwise emulate the block transaction with word
or byte transactions.
Add support for a helper function that would read a data block
using the best transfer available: I2C_FUNC_SMBUS_READ_I2C_BLOCK,
I2C_FUNC_SMBUS_READ_WORD_DATA or I2C_FUNC_SMBUS_READ_BYTE_DATA.
Signed-off-by: Irina Tirdea <irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
drivers/i2c/i2c-core.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/i2c.h | 3 +++
2 files changed, 63 insertions(+)
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 96771ea..55a3455 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -2914,6 +2914,66 @@ trace:
}
EXPORT_SYMBOL(i2c_smbus_xfer);
+/**
+ * i2c_smbus_read_i2c_block_data_or_emulated - read block or emulate
+ * @client: Handle to slave device
+ * @command: Byte interpreted by slave
+ * @length: Size of data block; SMBus allows at most 32 bytes
+ * @values: Byte array into which data will be read; big enough to hold
+ * the data returned by the slave. SMBus allows at most 32 bytes.
+ *
+ * This executes the SMBus "block read" protocol if supported by the adapter.
+ * If block read is not supported, it emulates it using either word or byte
+ * read protocols depending on availability.
+ *
+ * Before using this function you must double-check if the I2C slave does
+ * support exchanging a block transfer with a byte transfer.
+ */
+s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
+ u8 command, u8 length, u8 *values)
+{
+ u8 i;
+ int status;
+
+ if (length > I2C_SMBUS_BLOCK_MAX)
+ length = I2C_SMBUS_BLOCK_MAX;
+
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+ return i2c_smbus_read_i2c_block_data(client, command,
+ length, values);
+ } else if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_WORD_DATA)) {
+ for (i = 0; i < length; i += 2) {
+ status = i2c_smbus_read_word_data(client, command + i);
+ if (status < 0)
+ return status;
+ values[i] = status & 0xff;
+ if ((i + 1) < length)
+ values[i + 1] = status >> 8;
+ }
+ if (i > length)
+ return length;
+ return i;
+ } else if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
+ for (i = 0; i < length; i++) {
+ status = i2c_smbus_read_byte_data(client, command + i);
+ if (status < 0)
+ return status;
+ values[i] = status;
+ }
+ return i;
+ }
+
+ dev_err(&client->adapter->dev, "Unsupported transactions: %d,%d,%d\n",
+ I2C_SMBUS_I2C_BLOCK_DATA, I2C_SMBUS_WORD_DATA,
+ I2C_SMBUS_BYTE_DATA);
+
+ return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data_or_emulated);
+
#if IS_ENABLED(CONFIG_I2C_SLAVE)
int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
{
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index e83a738..faf518d 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -121,6 +121,9 @@ extern s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client,
u8 command, u8 length,
const u8 *values);
+extern s32
+i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
+ u8 command, u8 length, u8 *values);
#endif /* I2C */
/**
--
1.9.1
next prev parent reply other threads:[~2015-07-03 9:33 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-03 9:33 [PATCH v3 0/8] Add support for best effort block read emulation Irina Tirdea
[not found] ` <1435916017-12859-1-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-03 9:33 ` Irina Tirdea [this message]
[not found] ` <1435916017-12859-2-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-05 11:58 ` [PATCH v3 1/8] i2c: core: " Jonathan Cameron
[not found] ` <55991BE7.6050705-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2015-07-10 17:14 ` Tirdea, Irina
[not found] ` <1F3AC3675D538145B1661F571FE1805F2F067FA4-pww93C2UFcwu0RiL9chJVbfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2015-07-11 17:40 ` Jonathan Cameron
2015-08-01 19:53 ` Wolfram Sang
2015-08-04 13:51 ` Tirdea, Irina
2015-07-03 9:33 ` [PATCH v3 2/8] eeprom: at24: use i2c_smbus_read_i2c_block_data_or_emulated Irina Tirdea
[not found] ` <1435916017-12859-3-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-08-01 19:57 ` Wolfram Sang
2015-08-04 13:52 ` Tirdea, Irina
2015-07-03 9:33 ` [PATCH v3 3/8] iio: accel: bmc150: use available_scan_masks Irina Tirdea
[not found] ` <1435916017-12859-4-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-05 12:10 ` Jonathan Cameron
2015-07-03 9:33 ` [PATCH v3 4/8] iio: accel: bmc150: optimize i2c transfers in trigger handler Irina Tirdea
2015-07-05 12:06 ` Jonathan Cameron
2015-07-03 9:33 ` [PATCH v3 6/8] iio: gyro: bmg160: " Irina Tirdea
[not found] ` <1435916017-12859-7-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-05 12:08 ` Jonathan Cameron
2015-07-10 17:31 ` Tirdea, Irina
[not found] ` <1F3AC3675D538145B1661F571FE1805F2F068001-pww93C2UFcwu0RiL9chJVbfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2015-07-10 17:46 ` Pandruvada, Srinivas
2015-07-03 9:33 ` [PATCH v3 8/8] iio: accel: kxcjk-1013: " Irina Tirdea
[not found] ` <1435916017-12859-9-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-05 12:11 ` Jonathan Cameron
2015-07-03 9:33 ` [PATCH v3 5/8] iio: gyro: bmg160: use available_scan_masks Irina Tirdea
2015-07-03 9:33 ` [PATCH v3 7/8] iio: accel: kxcjk-1013: " Irina Tirdea
[not found] ` <1435916017-12859-8-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-05 12:10 ` Jonathan Cameron
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=1435916017-12859-2-git-send-email-irina.tirdea@intel.com \
--to=irina.tirdea-ral2jqcrhueavxtiumwx3w@public.gmane.org \
--cc=jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=pmeerw-jW+XmwGofnusTnJN9+BGXg@public.gmane.org \
--cc=srinivas.pandruvada-ral2JQCrhuEAvxtiuMwx3w@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).