All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
To: Irina Tirdea
	<irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@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>
Subject: Re: [PATCH v3 1/8] i2c: core: Add support for best effort block read emulation
Date: Sun, 05 Jul 2015 12:58:31 +0100	[thread overview]
Message-ID: <55991BE7.6050705@kernel.org> (raw)
In-Reply-To: <1435916017-12859-2-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

On 03/07/15 10:33, Irina Tirdea wrote:
> 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>
Looks good to me - I vaguely wondered if it would make sense to use
an endian conversion in the word case, but as we have possible odd
numbers of bytes that gets fiddly.

I wonder what devices do if you do a word read beyond their end address?
Perhaps in odd cases we should always fall back to byte reads?

> ---
>  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.
Add something here about addressing assumptions.  You get odd devices which
will give bulk reads of addresses not mapped to a nice linear region when
you do byte reads.
> + */
> +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 */
>  
>  /**
> 

WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron <jic23@kernel.org>
To: Irina Tirdea <irina.tirdea@intel.com>,
	Wolfram Sang <wsa@the-dreams.de>,
	linux-iio@vger.kernel.org, linux-i2c@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
	Srinivas Pandruvada <srinivas.pandruvada@intel.com>,
	Peter Meerwald <pmeerw@pmeerw.net>
Subject: Re: [PATCH v3 1/8] i2c: core: Add support for best effort block read emulation
Date: Sun, 05 Jul 2015 12:58:31 +0100	[thread overview]
Message-ID: <55991BE7.6050705@kernel.org> (raw)
In-Reply-To: <1435916017-12859-2-git-send-email-irina.tirdea@intel.com>

On 03/07/15 10:33, Irina Tirdea wrote:
> 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@intel.com>
Looks good to me - I vaguely wondered if it would make sense to use
an endian conversion in the word case, but as we have possible odd
numbers of bytes that gets fiddly.

I wonder what devices do if you do a word read beyond their end address?
Perhaps in odd cases we should always fall back to byte reads?

> ---
>  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.
Add something here about addressing assumptions.  You get odd devices which
will give bulk reads of addresses not mapped to a nice linear region when
you do byte reads.
> + */
> +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 */
>  
>  /**
> 


  parent reply	other threads:[~2015-07-05 11:58 UTC|newest]

Thread overview: 46+ 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
2015-07-03  9:33 ` Irina Tirdea
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
2015-07-05 12:10       ` Jonathan Cameron
     [not found] ` <1435916017-12859-1-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-03  9:33   ` [PATCH v3 1/8] i2c: core: Add support for best effort block read emulation Irina Tirdea
2015-07-03  9:33     ` Irina Tirdea
     [not found]     ` <1435916017-12859-2-git-send-email-irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2015-07-05 11:58       ` Jonathan Cameron [this message]
2015-07-05 11:58         ` Jonathan Cameron
     [not found]         ` <55991BE7.6050705-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2015-07-10 17:14           ` Tirdea, Irina
2015-07-10 17:14             ` Tirdea, Irina
2015-07-10 17:14             ` Tirdea, Irina
     [not found]             ` <1F3AC3675D538145B1661F571FE1805F2F067FA4-pww93C2UFcwu0RiL9chJVbfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2015-07-11 17:40               ` Jonathan Cameron
2015-07-11 17:40                 ` Jonathan Cameron
2015-08-01 19:53               ` Wolfram Sang
2015-08-01 19:53                 ` Wolfram Sang
2015-08-04 13:51                 ` Tirdea, Irina
2015-08-04 13:51                   ` Tirdea, Irina
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
2015-07-03  9:33     ` 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-01 19:57         ` Wolfram Sang
2015-08-04 13:52         ` Tirdea, Irina
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
2015-07-03  9:33     ` 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-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-03  9:33     ` Irina Tirdea
2015-07-05 12:06     ` Jonathan Cameron
2015-07-03  9:33   ` [PATCH v3 6/8] iio: gyro: bmg160: " Irina Tirdea
2015-07-03  9:33     ` 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-05 12:08         ` Jonathan Cameron
2015-07-10 17:31         ` Tirdea, Irina
2015-07-10 17:31           ` Tirdea, Irina
     [not found]           ` <1F3AC3675D538145B1661F571FE1805F2F068001-pww93C2UFcwu0RiL9chJVbfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2015-07-10 17:46             ` Pandruvada, Srinivas
2015-07-10 17:46               ` Pandruvada, Srinivas
2015-07-10 17:46               ` Pandruvada, Srinivas
2015-07-03  9:33   ` [PATCH v3 8/8] iio: accel: kxcjk-1013: " Irina Tirdea
2015-07-03  9:33     ` 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-05 12:11         ` 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=55991BE7.6050705@kernel.org \
    --to=jic23-dgejt+ai2ygdnm+yrofe0a@public.gmane.org \
    --cc=irina.tirdea-ral2JQCrhuEAvxtiuMwx3w@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.