diff options
author | Gabe Black <gabeblack@google.com> | 2014-04-07 18:45:14 -0700 |
---|---|---|
committer | Marc Jones <marc.jones@se-eng.com> | 2014-12-16 00:02:43 +0100 |
commit | cdb61a6f5d2268b059ac56da3b69ad0313f3fb90 (patch) | |
tree | 57dcfe80e68d872d1080cfc168abc866f0cbffe7 /src/soc/nvidia/tegra | |
parent | be6f8cb0f0a2873a9c16dc454cde1f29f4fab765 (diff) | |
download | coreboot-cdb61a6f5d2268b059ac56da3b69ad0313f3fb90.tar.xz |
i2c: Replace the i2c API.
The new API is in use in depthcharge and is based around the "i2c_transfer"
function instead of i2c_read and i2c_write. The new function takes an array of
i2c_seg structures which represent each portion of the transfer after a start
bit and before the stop bit. If there's more than one segment, they're
seperated by repeated starts.
Some wrapper functions have also been added which make certain common
operations easy. These include reading or writing a byte from a register or
reading or writing a blob of raw data. The i2c device drivers generally use
these wrappers but can call the i2c_transfer function directly if the need
something different.
The tegra i2c driver was very similar to the one in depthcharge and was simple
to convert. The Exynos 5250 and 5420 drivers were ported from depthcharge and
replace the ones in coreboot. The Exynos 5420 driver was ported from the high
speed portion of the one in coreboot and was straightforward to port back. The
low speed portion and the Exynos 5250 drivers had been transplanted from U-Boot
and were replaced with the depthcharge implementation.
BUG=None
TEST=Built and booted on nyan with and without EFS. Built and booted on, pit
and daisy.
BRANCH=None
Original-Change-Id: I1e98c3fa2560be25444ab3d0394bb214b9d56e93
Original-Signed-off-by: Gabe Black <gabeblack@google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/193561
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Reviewed-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Tested-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Original-Commit-Queue: Gabe Black <gabeblack@chromium.org>
Original-Tested-by: Gabe Black <gabeblack@chromium.org>
(cherry picked from commit 00c423fb2c06c69d580ee3ec0a3892ebf164a5fe)
This cherry-pick required additional changes to the following:
src/cpu/allwinner/a10/twi.c
src/drivers/xpowers/axp209/axp209.c
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I691959c66308eeeec219b1bec463b8b365a246d7
Reviewed-on: http://review.coreboot.org/7751
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/soc/nvidia/tegra')
-rw-r--r-- | src/soc/nvidia/tegra/i2c.c | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/src/soc/nvidia/tegra/i2c.c b/src/soc/nvidia/tegra/i2c.c index 8c8a372798..9a4d71bc3c 100644 --- a/src/soc/nvidia/tegra/i2c.c +++ b/src/soc/nvidia/tegra/i2c.c @@ -130,43 +130,35 @@ static int tegra_i2c_request(int bus, unsigned chip, int cont, int restart, data, data_len); } -static int i2c_readwrite(unsigned bus, unsigned chip, unsigned addr, - unsigned alen, uint8_t *buf, unsigned len, int read) +static int i2c_transfer_segment(unsigned bus, unsigned chip, int restart, + int read, void *buf, int len) { const uint32_t max_payload = (IOHEADER_PAYLOADSIZE_MASK + 1) >> IOHEADER_PAYLOADSIZE_SHIFT; - uint8_t abuf[sizeof(addr)]; - - int i; - for (i = 0; i < alen; i++) - abuf[i] = addr >> ((alen - i - 1) * 8); - - if (tegra_i2c_request(bus, chip, !read, 0, 0, abuf, alen)) - return -1; while (len) { int todo = MIN(len, max_payload); int cont = (todo < len); - if (tegra_i2c_request(bus, chip, cont, 0, read, buf, todo)) { - // We should reset the controller here. + if (tegra_i2c_request(bus, chip, cont, restart, + read, buf, todo)) return -1; - } len -= todo; buf += todo; } return 0; } -int i2c_read(unsigned bus, unsigned chip, unsigned addr, - unsigned alen, uint8_t *buf, unsigned len) +int i2c_transfer(unsigned bus, struct i2c_seg *segments, int count) { - return i2c_readwrite(bus, chip, addr, alen, buf, len, 1); -} + struct i2c_seg *seg = segments; -int i2c_write(unsigned bus, unsigned chip, unsigned addr, - unsigned alen, const uint8_t *buf, unsigned len) -{ - return i2c_readwrite(bus, chip, addr, alen, (void *)buf, len, 0); + int i; + for (i = 0; i < count; seg++, i++) { + if (i2c_transfer_segment(bus, seg->chip, i < count - 1, + seg->read, seg->buf, seg->len)) + return -1; + } + return 0; } void i2c_init(unsigned bus) |