summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@chromium.org>2019-12-08 13:13:09 -0700
committerCommit Bot <commit-bot@chromium.org>2021-09-27 02:30:43 +0000
commit5073a53041fce71cf6deea941bbfedd943b9177c (patch)
tree16c8665eee9743ae5dc489c6811151e2ce269dd7 /common
parentd043ef2ea042e17f7aec57013d4ea16af1949cd2 (diff)
downloadchrome-ec-5073a53041fce71cf6deea941bbfedd943b9177c.tar.gz
i2c: add generic read/modify/write operations
i2c_update is used to set or clear a mask i2c_field_update is used to clear out a field before the set Conflicts: common/i2c_master.c: i2c_read_offset16 not yet introduced. include/i2c.h : i2c_info_t not yet introduced. BUG=none BRANCH=none TEST=make buildall -j Change-Id: I7f8f93f4894fb9635092931a93961d328eacfeb9 Signed-off-by: Denis Brockus <dbrockus@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1956437 Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Commit-Queue: Jett Rink <jettrink@chromium.org> (cherry picked from commit d3129132f6e05cbce0141b5549272731bafb034f) Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3128751 Reviewed-by: JuHyun Kim <jkim@invensense.com> Reviewed-by: Zhuohao Lee <zhuohao@chromium.org> Tested-by: JuHyun Kim <jkim@invensense.com> Commit-Queue: Zhuohao Lee <zhuohao@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/i2c_master.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/common/i2c_master.c b/common/i2c_master.c
index ec2cad96df..df9dbe57c2 100644
--- a/common/i2c_master.c
+++ b/common/i2c_master.c
@@ -304,6 +304,92 @@ int i2c_write8(int port, int slave_addr, int offset, int data)
return i2c_xfer(port, slave_addr, buf, 2, 0, 0);
}
+int i2c_update8(const int port,
+ const uint16_t slave_addr_flags,
+ const int offset,
+ const uint8_t mask,
+ const enum mask_update_action action)
+{
+ int rv;
+ int val, oldval;
+
+ rv = i2c_read8(port, slave_addr_flags, offset, &oldval);
+ if (rv)
+ return rv;
+
+ val = (action == MASK_SET) ? oldval | mask
+ : oldval & ~mask;
+
+ if (val != oldval)
+ return i2c_write8(port, slave_addr_flags, offset, val);
+
+ return EC_SUCCESS;
+}
+
+int i2c_update16(const int port,
+ const uint16_t slave_addr_flags,
+ const int offset,
+ const uint16_t mask,
+ const enum mask_update_action action)
+{
+ int rv;
+ int val, oldval;
+
+ rv = i2c_read16(port, slave_addr_flags, offset, &oldval);
+ if (rv)
+ return rv;
+
+ val = (action == MASK_SET) ? oldval | mask
+ : oldval & ~mask;
+
+ if (val != oldval)
+ return i2c_write16(port, slave_addr_flags, offset, val);
+
+ return EC_SUCCESS;
+}
+
+int i2c_field_update8(const int port,
+ const uint16_t slave_addr_flags,
+ const int offset,
+ const uint8_t field_mask,
+ const uint8_t set_value)
+{
+ int rv;
+ int val, oldval;
+
+ rv = i2c_read8(port, slave_addr_flags, offset, &oldval);
+ if (rv)
+ return rv;
+
+ val = (oldval & (~field_mask)) | set_value;
+
+ if (val != oldval)
+ return i2c_write8(port, slave_addr_flags, offset, val);
+
+ return EC_SUCCESS;
+}
+
+int i2c_field_update16(const int port,
+ const uint16_t slave_addr_flags,
+ const int offset,
+ const uint16_t field_mask,
+ const uint16_t set_value)
+{
+ int rv;
+ int val, oldval;
+
+ rv = i2c_read16(port, slave_addr_flags, offset, &oldval);
+ if (rv)
+ return rv;
+
+ val = (oldval & (~field_mask)) | set_value;
+
+ if (val != oldval)
+ return i2c_write16(port, slave_addr_flags, offset, val);
+
+ return EC_SUCCESS;
+}
+
int i2c_read_string(int port, int slave_addr, int offset, uint8_t *data,
int len)
{