// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>

#include <bits/limits.h>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/protocol/i2c-impl.h>
#include <ddk/protocol/platform-bus.h>
#include <ddk/protocol/platform-defs.h>
#include <ddk/protocol/platform-device.h>
#include <hw/reg.h>

#include <zircon/assert.h>
#include <zircon/types.h>

#define I2C_ERROR_SIGNAL ZX_USER_SIGNAL_0
#define I2C_TXN_COMPLETE_SIGNAL ZX_USER_SIGNAL_1

#define AML_I2C_CONTROL_REG_START      (uint32_t)(1 << 0)
#define AML_I2C_CONTROL_REG_ACK_IGNORE (uint32_t)(1 << 1)
#define AML_I2C_CONTROL_REG_STATUS     (uint32_t)(1 << 2)
#define AML_I2C_CONTROL_REG_ERR        (uint32_t)(1 << 3)

#define AML_I2C_MAX_TRANSFER 256

typedef volatile struct {
    uint32_t    control;
    uint32_t    slave_addr;
    uint32_t    token_list_0;
    uint32_t    token_list_1;
    uint32_t    token_wdata_0;
    uint32_t    token_wdata_1;
    uint32_t    token_rdata_0;
    uint32_t    token_rdata_1;
} __PACKED aml_i2c_regs_t;

typedef enum {
    TOKEN_END,
    TOKEN_START,
    TOKEN_SLAVE_ADDR_WR,
    TOKEN_SLAVE_ADDR_RD,
    TOKEN_DATA,
    TOKEN_DATA_LAST,
    TOKEN_STOP
} aml_i2c_token_t;

typedef struct {
    zx_handle_t         irq;
    zx_handle_t         event;
    io_buffer_t         regs_iobuff;
    aml_i2c_regs_t*     virt_regs;
    zx_duration_t       timeout;
} aml_i2c_dev_t;

typedef struct {
    platform_device_protocol_t pdev;
    i2c_impl_protocol_t i2c;
    zx_device_t* zxdev;
    aml_i2c_dev_t* i2c_devs;
    size_t dev_count;
} aml_i2c_t;

static zx_status_t aml_i2c_set_slave_addr(aml_i2c_dev_t *dev, uint16_t addr) {

    addr &= 0x7f;
    uint32_t reg = dev->virt_regs->slave_addr;
    reg = reg & ~0xff;
    reg = reg | ((addr << 1) & 0xff);
    dev->virt_regs->slave_addr = reg;

    return ZX_OK;
}

static int aml_i2c_irq_thread(void *arg) {

    aml_i2c_dev_t *dev = arg;
    zx_status_t status;

    while (1) {
        status = zx_interrupt_wait(dev->irq, NULL);
        if (status != ZX_OK) {
            zxlogf(ERROR, "i2c: interrupt error\n");
            continue;
        }
        uint32_t reg =  dev->virt_regs->control;
        if (reg & AML_I2C_CONTROL_REG_ERR) {
            zx_object_signal(dev->event, 0, I2C_ERROR_SIGNAL);
            zxlogf(ERROR,"i2c: error on bus\n");
        } else {
            zx_object_signal(dev->event, 0, I2C_TXN_COMPLETE_SIGNAL);
        }
    }
    return ZX_OK;
}

static zx_status_t aml_i2c_dumpstate(aml_i2c_dev_t *dev) {

    printf("control reg      : %08x\n",dev->virt_regs->control);
    printf("slave addr  reg  : %08x\n",dev->virt_regs->slave_addr);
    printf("token list0 reg  : %08x\n",dev->virt_regs->token_list_0);
    printf("token list1 reg  : %08x\n",dev->virt_regs->token_list_1);
    printf("token wdata0     : %08x\n",dev->virt_regs->token_wdata_0);
    printf("token wdata1     : %08x\n",dev->virt_regs->token_wdata_1);
    printf("token rdata0     : %08x\n",dev->virt_regs->token_rdata_0);
    printf("token rdata1     : %08x\n",dev->virt_regs->token_rdata_1);

    return ZX_OK;
}

static zx_status_t aml_i2c_start_xfer(aml_i2c_dev_t *dev) {
    //First have to clear the start bit before setting (RTFM)
    dev->virt_regs->control &= ~AML_I2C_CONTROL_REG_START;
    dev->virt_regs->control |= AML_I2C_CONTROL_REG_START;
    return ZX_OK;
}

static zx_status_t aml_i2c_wait_event(aml_i2c_dev_t* dev, uint32_t sig_mask) {

    zx_time_t deadline = zx_deadline_after(dev->timeout);
    uint32_t observed;
    sig_mask |= I2C_ERROR_SIGNAL;
    zx_status_t status = zx_object_wait_one(dev->event, sig_mask, deadline, &observed);
    if (status != ZX_OK) {
        return status;
    }
    zx_object_signal(dev->event,observed,0);
    if (observed & I2C_ERROR_SIGNAL)
        return ZX_ERR_TIMED_OUT;
    return ZX_OK;
}

static zx_status_t aml_i2c_write(aml_i2c_dev_t *dev, const uint8_t *buff, uint32_t len) {
    ZX_DEBUG_ASSERT(len <= AML_I2C_MAX_TRANSFER);
    uint32_t token_num = 0;
    uint64_t token_reg = 0;

    token_reg |= (uint64_t)TOKEN_START << (4*(token_num++));
    token_reg |= (uint64_t)TOKEN_SLAVE_ADDR_WR << (4*(token_num++));

    while (len > 0) {
        bool is_last_iter = len <= 8;
        uint32_t tx_size = is_last_iter ? len : 8;
        for (uint32_t i=0; i < tx_size; i++) {
            token_reg |= (uint64_t)TOKEN_DATA << (4*(token_num++));
        }

        if (is_last_iter) {
            token_reg |= (uint64_t)TOKEN_STOP << (4*(token_num++));
        }

        dev->virt_regs->token_list_0 = (uint32_t)(token_reg & 0xffffffff);
        dev->virt_regs->token_list_1 =
            (uint32_t)((token_reg >> 32) & 0xffffffff);

        uint64_t wdata = 0;
        for (uint32_t i=0; i < tx_size; i++) {
            wdata |= (uint64_t)buff[i] << (8*i);
        }

        dev->virt_regs->token_wdata_0 = (uint32_t)(wdata & 0xffffffff);
        dev->virt_regs->token_wdata_1 = (uint32_t)((wdata >> 32) & 0xffffffff);

        aml_i2c_start_xfer(dev);
        //while (dev->virt_regs->control & 0x4) ;;    // wait for idle
        zx_status_t status = aml_i2c_wait_event(dev, I2C_TXN_COMPLETE_SIGNAL);
        if (status != ZX_OK) {
            return status;
        }

        len -= tx_size;
        buff += tx_size;
        token_num = 0;
        token_reg = 0;
    }

    return ZX_OK;
}

static zx_status_t aml_i2c_read(aml_i2c_dev_t *dev, uint8_t *buff, uint32_t len) {

    ZX_DEBUG_ASSERT(len <= AML_I2C_MAX_TRANSFER);
    uint32_t token_num = 0;
    uint64_t token_reg = 0;

    token_reg |= (uint64_t)TOKEN_START << (4*(token_num++));
    token_reg |= (uint64_t)TOKEN_SLAVE_ADDR_RD << (4*(token_num++));

    while (len > 0) {
        bool is_last_iter = len <= 8;
        uint32_t rx_size = is_last_iter ? len : 8;

        for (uint32_t i=0; i < (rx_size - 1); i++) {
            token_reg |= (uint64_t)TOKEN_DATA << (4*(token_num++));
        }
        if (is_last_iter) {
            token_reg |= (uint64_t)TOKEN_DATA_LAST << (4*(token_num++));
            token_reg |= (uint64_t)TOKEN_STOP << (4*(token_num++));
        } else {
            token_reg |= (uint64_t)TOKEN_DATA << (4*(token_num++));
        }

        dev->virt_regs->token_list_0 = (uint32_t)(token_reg & 0xffffffff);
        token_reg = token_reg >> 32;
        dev->virt_regs->token_list_1 = (uint32_t)(token_reg);

        //clear registers to prevent data leaking from last xfer
        dev->virt_regs->token_rdata_0 = 0;
        dev->virt_regs->token_rdata_1 = 0;

        aml_i2c_start_xfer(dev);

        zx_status_t status = aml_i2c_wait_event(dev, I2C_TXN_COMPLETE_SIGNAL);
        if (status != ZX_OK) {
            return status;
        }

        //while (dev->virt_regs->control & 0x4) ;;    // wait for idle

        uint64_t rdata;
        rdata = dev->virt_regs->token_rdata_0;
        rdata |= (uint64_t)(dev->virt_regs->token_rdata_1) << 32;

        for (uint32_t i=0; i < sizeof(rdata); i++) {
            buff[i] = (uint8_t)((rdata >> (8*i) & 0xff));
        }

        len -= rx_size;
        buff += rx_size;
        token_num = 0;
        token_reg = 0;
    }

    return ZX_OK;
}

/* create instance of aml_i2c_t and do basic initialization.  There will
be one of these instances for each of the soc i2c ports.
*/
static zx_status_t aml_i2c_dev_init(aml_i2c_t* i2c, unsigned index) {
    aml_i2c_dev_t* device = &i2c->i2c_devs[index];

    device->timeout = ZX_SEC(1);

    zx_status_t status;

    status = pdev_map_mmio_buffer(&i2c->pdev, index, ZX_CACHE_POLICY_UNCACHED_DEVICE,
                                  &device->regs_iobuff);
    if (status != ZX_OK) {
        zxlogf(ERROR, "aml_i2c_dev_init: pdev_map_mmio_buffer failed %d\n", status);
        return status;
    }

    device->virt_regs = (aml_i2c_regs_t*)io_buffer_virt(&device->regs_iobuff);

    status = pdev_map_interrupt(&i2c->pdev, index, &device->irq);
    if (status != ZX_OK) {
        return status;
    }

    status = zx_event_create(0, &device->event);
    if (status != ZX_OK) {
        return status;
    }

    thrd_t irqthrd;
    thrd_create_with_name(&irqthrd, aml_i2c_irq_thread, device, "i2c_irq_thread");

    return ZX_OK;
}

static uint32_t aml_i2c_get_bus_count(void* ctx) {
    aml_i2c_t* i2c = ctx;

    return i2c->dev_count;
}

static zx_status_t aml_i2c_get_max_transfer_size(void* ctx, uint32_t bus_id, size_t* out_size) {
    *out_size = AML_I2C_MAX_TRANSFER;
    return ZX_OK;
}

static zx_status_t aml_i2c_set_bitrate(void* ctx, uint32_t bus_id, uint32_t bitrate) {
    // TODO(hollande,voydanoff) implement this
    return ZX_ERR_NOT_SUPPORTED;
}

static zx_status_t aml_i2c_transact(void* ctx, uint32_t bus_id, uint16_t address,
                                    const void* write_buf, size_t write_length,
                                    void* read_buf, size_t read_length) {
    if (!read_length && !write_length) {
        return ZX_ERR_INVALID_ARGS;
    }
    aml_i2c_t* i2c = ctx;
    if (bus_id >= i2c->dev_count) {
        return ZX_ERR_INVALID_ARGS;
    }
    aml_i2c_dev_t *dev = &i2c->i2c_devs[bus_id];

    zx_status_t status = aml_i2c_set_slave_addr(dev, address);
    if (status != ZX_OK) {
        return status;
    }

    if (write_length) {
        status = aml_i2c_write(dev, write_buf, write_length);
        if (status != ZX_OK) {
            return status;
        }
    }
    if (read_length) {
        status = aml_i2c_read(dev, read_buf, read_length);
        if (status != ZX_OK) {
            return status;
        }
    }

    return ZX_OK;
}

static i2c_impl_protocol_ops_t i2c_ops = {
    .get_bus_count = aml_i2c_get_bus_count,
    .get_max_transfer_size = aml_i2c_get_max_transfer_size,
    .set_bitrate = aml_i2c_set_bitrate,
    .transact = aml_i2c_transact,
};

static void aml_i2c_release(void* ctx) {
    aml_i2c_t* i2c = ctx;
    for (unsigned i = 0; i < i2c->dev_count; i++) {
        aml_i2c_dev_t* device = &i2c->i2c_devs[i];
        io_buffer_release(&device->regs_iobuff);
        zx_handle_close(device->event);
        zx_handle_close(device->irq);
    }
    free(i2c->i2c_devs);
    free(i2c);
}

static zx_protocol_device_t i2c_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .release = aml_i2c_release,
};

static zx_status_t aml_i2c_bind(void* ctx, zx_device_t* parent) {
    zx_status_t status;

    aml_i2c_t* i2c = calloc(1, sizeof(aml_i2c_t));
    if (!i2c) {
        return ZX_ERR_NO_MEMORY;
    }

    if ((status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &i2c->pdev)) != ZX_OK) {
        zxlogf(ERROR, "aml_i2c_bind: ZX_PROTOCOL_PLATFORM_DEV not available\n");
        goto fail;
    }

    platform_bus_protocol_t pbus;
    if ((status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_BUS, &pbus)) != ZX_OK) {
        zxlogf(ERROR, "aml_i2c_bind: ZX_PROTOCOL_PLATFORM_BUS not available\n");
        goto fail;
    }

    pdev_device_info_t info;
    status = pdev_get_device_info(&i2c->pdev, &info);
    if (status != ZX_OK) {
        zxlogf(ERROR, "aml_i2c_bind: pdev_get_device_info failed\n");
        goto fail;
    }

    if (info.mmio_count != info.irq_count) {
        zxlogf(ERROR, "aml_i2c_bind: mmio_count %u does not matchirq_count %u\n",
               info.mmio_count, info.irq_count);
        status = ZX_ERR_INVALID_ARGS;
        goto fail;
    }
    i2c->i2c_devs = calloc(info.mmio_count, sizeof(aml_i2c_dev_t));
    if (!i2c->i2c_devs) {
        goto fail;
    }
    i2c->dev_count = info.mmio_count;

    for (unsigned i = 0; i < i2c->dev_count; i++) {
        zx_status_t status = aml_i2c_dev_init(i2c, i);
        if (status != ZX_OK) {
            zxlogf(ERROR, "aml_i2c_bind: aml_i2c_dev_init failed: %d\n", status);
            goto fail;
        }
    }

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "aml-i2c",
        .ctx = i2c,
        .ops = &i2c_device_proto,
        .flags = DEVICE_ADD_NON_BINDABLE,
    };

    status = device_add(parent, &args, &i2c->zxdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "aml_i2c_bind: device_add failed\n");
        goto fail;
    }

    i2c->i2c.ops = &i2c_ops;
    i2c->i2c.ctx = i2c;
    pbus_set_protocol(&pbus, ZX_PROTOCOL_I2C_IMPL, &i2c->i2c);

    return ZX_OK;

fail:
    aml_i2c_release(i2c);
    return status;
}

static zx_driver_ops_t aml_i2c_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = aml_i2c_bind,
};

ZIRCON_DRIVER_BEGIN(aml_i2c, aml_i2c_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PLATFORM_DEV),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_AMLOGIC),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_GENERIC),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_AMLOGIC_I2C),
ZIRCON_DRIVER_END(aml_i2c)
