aboutsummaryrefslogtreecommitdiff
path: root/src/soc/qualcomm/ipq806x/i2c.c
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@google.com>2014-12-06 10:44:58 -0800
committerPatrick Georgi <pgeorgi@google.com>2015-04-15 21:56:05 +0200
commit6fe4e5e34c584f7f4ad2c071b311e6b6a878b623 (patch)
treef994cd6055d5823cd2d908f5b467e96362a9c826 /src/soc/qualcomm/ipq806x/i2c.c
parentfa00ae7de6a9605deb5d1d8a930d2b0f4969e082 (diff)
ipq806x: add i2c driver
this change ports i2c and other relevant drivers from depthcharge for ipq806x. BUG=chrome-os-partner:33647 BRANCH=ToT TEST=Booted storm using vboot2 Change-Id: I3d9a431aa8adb9b91dbccdf031647dfadbafc24c Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: a0c615d0a49fd9c0ffa231353800882fff6ab90b Original-Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Original-Change-Id: Id7cc3932ed4ae54f46336aaebde35e84125ebebd Original-Reviewed-on: https://chromium-review.googlesource.com/229428 Original-Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Original-Tested-by: Vadim Bendebury <vbendeb@chromium.org> Original-Commit-Queue: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: http://review.coreboot.org/9685 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/qualcomm/ipq806x/i2c.c')
-rw-r--r--src/soc/qualcomm/ipq806x/i2c.c114
1 files changed, 53 insertions, 61 deletions
diff --git a/src/soc/qualcomm/ipq806x/i2c.c b/src/soc/qualcomm/ipq806x/i2c.c
index 9bae822a8e..a4d1c00856 100644
--- a/src/soc/qualcomm/ipq806x/i2c.c
+++ b/src/soc/qualcomm/ipq806x/i2c.c
@@ -1,5 +1,5 @@
/*
- * This file is part of the depthcharge project.
+ * This file is part of the coreboot project.
*
* Copyright (C) 2014 The Linux Foundation. All rights reserved.
*
@@ -27,43 +27,25 @@
* SUCH DAMAGE.
*/
+#include <arch/io.h>
#include <assert.h>
-#include <libpayload.h>
-
-#include "base/container_of.h"
-#include "drivers/bus/i2c/i2c.h"
-#include "drivers/bus/i2c/ipq806x_qup.h"
-#include "drivers/bus/i2c/ipq806x_gsbi.h"
-#include "drivers/bus/i2c/ipq806x.h"
-
-static int i2c_init(unsigned gsbi_id)
-{
- gsbi_return_t gsbi_ret = 0;
- qup_return_t qup_ret = 0;
- qup_config_t gsbi4_qup_config = {
- QUP_MINICORE_I2C_MASTER,
- 100000,
- 24000000,
- QUP_MODE_FIFO
- };
-
- gsbi_ret = gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY);
- if (GSBI_SUCCESS != gsbi_ret)
- return 1;
-
- qup_ret = qup_init(gsbi_id, &gsbi4_qup_config);
- if (QUP_SUCCESS != qup_ret)
- return 1;
-
- qup_ret = qup_reset_i2c_master_status(gsbi_id);
- if (QUP_SUCCESS != qup_ret)
- return 1;
-
- return 0;
-}
+#include <console/console.h>
+#include <delay.h>
+#include <device/i2c.h>
+#include <stdlib.h>
+#include <string.h>
+#include <soc/gsbi.h>
+#include <soc/qup.h>
+
+static const qup_config_t gsbi4_qup_config = {
+ QUP_MINICORE_I2C_MASTER,
+ 100000,
+ 24000000,
+ QUP_MODE_FIFO
+};
static int i2c_read(uint32_t gsbi_id, uint8_t slave,
- uint8_t *data, int data_len)
+ uint8_t *data, int data_len)
{
qup_data_t obj;
qup_return_t qup_ret = 0;
@@ -100,44 +82,54 @@ static int i2c_write(uint32_t gsbi_id, uint8_t slave,
return 0;
}
-static int i2c_transfer(struct I2cOps *me, I2cSeg *segments, int seg_count)
+static int i2c_init(unsigned bus)
{
- Ipq806xI2c *bus = container_of(me, Ipq806xI2c, ops);
- I2cSeg *seg = segments;
- int ret = 0;
+ static uint8_t initialized = 0;
+ unsigned gsbi_id = bus;
- if (!bus->initialized)
- if (0 != i2c_init(bus->gsbi_id))
- return 1;
+ if (initialized)
+ return 0;
- while (seg_count--) {
- if (seg->read)
- ret = i2c_read(bus->gsbi_id, seg->chip,
- seg->buf, seg->len);
- else
- ret = i2c_write(bus->gsbi_id, seg->chip,
- seg->buf, seg->len,
- (seg_count ? 0 : 1));
- seg++;
+ if (gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY)) {
+ printk(BIOS_ERR, "failed to initialize gsbi\n");
+ return 1;
}
- if (QUP_SUCCESS != ret) {
- qup_set_state(bus->gsbi_id, QUP_STATE_RESET);
+ if (qup_init(gsbi_id, &gsbi4_qup_config)) {
+ printk(BIOS_ERR, "failed to initialize qup\n");
return 1;
}
+ if (qup_reset_i2c_master_status(gsbi_id)) {
+ printk(BIOS_ERR, "failed to reset i2c master status\n");
+ return 1;
+ }
+
+ initialized = 1;
return 0;
}
-Ipq806xI2c *new_ipq806x_i2c(unsigned gsbi_id)
+int platform_i2c_transfer(unsigned bus, struct i2c_seg *segments, int seg_count)
{
- Ipq806xI2c *bus = 0;
+ struct i2c_seg *seg = segments;
+ int ret = 0;
+
+ if (i2c_init(bus))
+ return 1;
- if (!i2c_init(gsbi_id)) {
- bus = xzalloc(sizeof(*bus));
- bus->gsbi_id = gsbi_id;
- bus->initialized = 1;
- bus->ops.transfer = &i2c_transfer;
+ while (seg_count--) {
+ if (seg->read)
+ ret = i2c_read(bus, seg->chip, seg->buf, seg->len);
+ else
+ ret = i2c_write(bus, seg->chip, seg->buf, seg->len,
+ (seg_count ? 0 : 1));
+ seg++;
}
- return bus;
+
+ if (ret) {
+ qup_set_state(bus, QUP_STATE_RESET);
+ return 1;
+ }
+
+ return 0;
}