drivers: i2c_nrfx_twim: restore previous behavior without concat buffer

The Nordic TWIM peripheral generates a start condition for each bus
transaction.  Devices such as the SSD1306 display and some NXP sensors
can only tolerate the presence of a start condition and device address
after a stop condition.  Those devices will not operate correctly when
these signals are observed while the bus is already active.  This
motivated the addition of a RAM buffer into which message fragments
could be collected so TWIM can transmit them without injecting
unnecessary start conditions.

However many I2C devices interpret these signals as a repeated start
and ignore them and so function properly without a buffer
concatenating the message fragments.

There is no default for the concat-buf-size property, and the previous
strict requirement for one when performing scatter/gather I/O
transactions broke working drivers for devices that tolerate the
repeated starts.  Allow those drivers to work by respecting the
property description and attempting to concatenate messages only if a
buffer in which to place them has been provided.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2020-08-19 14:29:35 -05:00 committed by Maureen Helm
commit afdb98a4a9
2 changed files with 12 additions and 6 deletions

View file

@ -67,12 +67,13 @@ static int i2c_nrfx_twim_transfer(struct device *dev, struct i2c_msg *msgs,
break;
}
/* Merge this fragment with the next if it's not the last
* fragment, this one doesn't end a bus transaction, the next
* one doesn't start a bus transaction, and the direction of
* the next fragment is the same as this one.
/* Merge this fragment with the next if we have a buffer, this
* isn't the last fragment, it doesn't end a bus transaction,
* the next one doesn't start a bus transaction, and the
* direction of the next fragment is the same as this one.
*/
bool concat_next = ((i + 1) < num_msgs)
bool concat_next = (concat_buf_size > 0)
&& ((i + 1) < num_msgs)
&& !(msgs[i].flags & I2C_MSG_STOP)
&& !(msgs[i + 1].flags & I2C_MSG_RESTART)
&& ((msgs[i].flags & I2C_MSG_READ)