From 6fe4e5e34c584f7f4ad2c071b311e6b6a878b623 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Sat, 6 Dec 2014 10:44:58 -0800 Subject: 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 Original-Commit-Id: a0c615d0a49fd9c0ffa231353800882fff6ab90b Original-Signed-off-by: Daisuke Nojiri Original-Change-Id: Id7cc3932ed4ae54f46336aaebde35e84125ebebd Original-Reviewed-on: https://chromium-review.googlesource.com/229428 Original-Reviewed-by: Vadim Bendebury Original-Tested-by: Vadim Bendebury Original-Commit-Queue: Vadim Bendebury Reviewed-on: http://review.coreboot.org/9685 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/qualcomm/ipq806x/i2c.c | 114 +++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 61 deletions(-) (limited to 'src/soc/qualcomm/ipq806x/i2c.c') 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 #include -#include - -#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 +#include +#include +#include +#include +#include +#include + +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; } -- cgit v1.2.3