summaryrefslogtreecommitdiff
path: root/src/include/device/i2c.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/device/i2c.h')
-rw-r--r--src/include/device/i2c.h84
1 files changed, 78 insertions, 6 deletions
diff --git a/src/include/device/i2c.h b/src/include/device/i2c.h
index 997d201341..da9d1bcb3c 100644
--- a/src/include/device/i2c.h
+++ b/src/include/device/i2c.h
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2013 Google, Inc.
+ * Copyright (C) 2014 Google, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,11 +21,83 @@
#define _DEVICE_I2C_H_
#include <stdint.h>
+#include <stdlib.h>
-/* note: chip is the 7-bit I2C address */
-int i2c_read(unsigned bus, unsigned chip, unsigned addr,
- unsigned alen, uint8_t *buf, unsigned len);
-int i2c_write(unsigned bus, unsigned chip, unsigned addr,
- unsigned alen, const uint8_t *buf, unsigned len);
+struct i2c_seg
+{
+ int read;
+ uint8_t chip;
+ uint8_t *buf;
+ int len;
+};
+
+int i2c_transfer(unsigned bus, struct i2c_seg *segments, int count);
+
+/*
+ * Read a raw chunk of data in one segment and one frame.
+ *
+ * [start][slave addr][r][data][stop]
+ */
+static inline int i2c_read_raw(unsigned bus, uint8_t chip, uint8_t *data,
+ int len)
+{
+ struct i2c_seg seg =
+ { .read = 1, .chip = chip, .buf = data, .len = len };
+ return i2c_transfer(bus, &seg, 1);
+}
+
+/*
+ * Write a raw chunk of data in one segment and one frame.
+ *
+ * [start][slave addr][w][data][stop]
+ */
+static inline int i2c_write_raw(unsigned bus, uint8_t chip, uint8_t *data,
+ int len)
+{
+ struct i2c_seg seg =
+ { .read = 0, .chip = chip, .buf = data, .len = len };
+ return i2c_transfer(bus, &seg, 1);
+}
+
+/**
+ * Read a byte with two segments in one frame
+ *
+ * [start][slave addr][w][register addr][start][slave addr][r][data][stop]
+ */
+static inline int i2c_readb(unsigned bus, uint8_t chip, uint8_t reg,
+ uint8_t *data)
+{
+ struct i2c_seg seg[2];
+
+ seg[0].read = 0;
+ seg[0].chip = chip;
+ seg[0].buf = &reg;
+ seg[0].len = 1;
+ seg[1].read = 1;
+ seg[1].chip = chip;
+ seg[1].buf = data;
+ seg[1].len = 1;
+
+ return i2c_transfer(bus, seg, ARRAY_SIZE(seg));
+}
+
+/**
+ * Write a byte with one segment in one frame.
+ *
+ * [start][slave addr][w][register addr][data][stop]
+ */
+static inline int i2c_writeb(unsigned bus, uint8_t chip, uint8_t reg,
+ uint8_t data)
+{
+ struct i2c_seg seg;
+ uint8_t buf[] = {reg, data};
+
+ seg.read = 0;
+ seg.chip = chip;
+ seg.buf = buf;
+ seg.len = ARRAY_SIZE(buf);
+
+ return i2c_transfer(bus, &seg, 1);
+}
#endif /* _DEVICE_I2C_H_ */