// 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 <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>

#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/threads.h>

#include "gauss.h"
#include "gauss-hw.h"

#define GAUSS_TDM_SAMPLE_RATE (48000)
#define GAUSS_TDM_BITS_PER_SLOT (32)
#define GAUSS_TDM_SLOTS_PER_FRAME (8)
#define GAUSS_TDM_CLK_SRC_MULT (20)
#define GAUSS_TDM_CLK_N        (GAUSS_TDM_BITS_PER_SLOT * \
                                GAUSS_TDM_SLOTS_PER_FRAME * \
                                GAUSS_TDM_CLK_SRC_MULT)


// 48khz sample rate, 8 slots, 32bits per slot
#define GAUSS_TDM_CLK_SRC_FREQ (GAUSS_TDM_SAMPLE_RATE * \
                                GAUSS_TDM_CLK_N)

// turn this on to enable Gauss accelerometer test driver
//#define I2C_TEST 1

#if I2C_TEST
static const pbus_i2c_channel_t i2c_test_channels[] = {
    {
        // Gauss accelerometer
        .bus_id = AML_I2C_B,
        .address = 0x18,
    },
};

static const pbus_dev_t i2c_test_dev = {
    .name = "i2c-test",
    .vid = PDEV_VID_GOOGLE,
    .pid = PDEV_PID_GAUSS,
    .did = PDEV_DID_GAUSS_I2C_TEST,
    .i2c_channel_list = i2c_test_channels,
    .i2c_channel_count = countof(i2c_test_channels),
};
#endif

static void gauss_bus_release(void* ctx) {
    gauss_bus_t* bus = ctx;
    mmio_buffer_release(&bus->usb_phy);
    zx_handle_close(bus->bti_handle);
    free(bus);
}

static zx_protocol_device_t gauss_bus_device_protocol = {
    .version = DEVICE_OPS_VERSION,
    .release = gauss_bus_release,
};

#if 0
static aml_i2c_dev_desc_t i2c_devs[] = {
    {.port = AML_I2C_A, .base_phys = 0xffd1f000, .irqnum = (21+32)},
    {.port = AML_I2C_B, .base_phys = 0xffd1e000, .irqnum = (214+32)},
    // Gauss only uses I2C_A and I2C_B
/*
    {.port = AML_I2C_C, .base_phys = 0xffd1d000, .irqnum = (215+32)},
    {.port = AML_I2C_D, .base_phys = 0xffd1c000, .irqnum = (39+32)},
*/
};
#endif

static int gauss_start_thread(void* arg) {
    gauss_bus_t* bus = arg;
    zx_status_t status;

    // Sysmem is started early so zx_vmo_create_contiguous() works.
    if ((status = gauss_sysmem_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_sysmem_init failed: %d\n", status);
        goto fail;
    }

    if ((status = gauss_clk_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_clk_init failed: %d\n", status);
        goto fail;
    }

    if ((status = gauss_gpio_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_gpio_init failed: %d\n", status);
        goto fail;
    }

    // pinmux for Gauss i2c
    gpio_impl_set_alt_function(&bus->gpio, I2C_SCK_A, 1);
    gpio_impl_set_alt_function(&bus->gpio, I2C_SDA_A, 1);
    gpio_impl_set_alt_function(&bus->gpio, I2C_SCK_B, 1);
    gpio_impl_set_alt_function(&bus->gpio, I2C_SDA_B, 1);

    // Config pinmux for gauss PDM pins
    gpio_impl_set_alt_function(&bus->gpio, A113_GPIOA(14), 1);
    gpio_impl_set_alt_function(&bus->gpio, A113_GPIOA(15), 1);
    gpio_impl_set_alt_function(&bus->gpio, A113_GPIOA(16), 1);
    gpio_impl_set_alt_function(&bus->gpio, A113_GPIOA(17), 1);
    gpio_impl_set_alt_function(&bus->gpio, A113_GPIOA(18), 1);

    gpio_impl_set_alt_function(&bus->gpio, TDM_BCLK_C, 1);
    gpio_impl_set_alt_function(&bus->gpio, TDM_FSYNC_C, 1);
    gpio_impl_set_alt_function(&bus->gpio, TDM_MOSI_C, 1);
    gpio_impl_set_alt_function(&bus->gpio, TDM_MISO_C, 2);

    gpio_impl_set_alt_function(&bus->gpio, SPK_MUTEn, 0);
    gpio_impl_config_out(&bus->gpio, SPK_MUTEn, 1);

    if ((status = gauss_i2c_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_i2c_init failed: %d\n", status);
        goto fail;
    }

    status = a113_clk_init(&bus->clocks);
    if (status != ZX_OK) {
        zxlogf(ERROR, "a113_clk_init failed: %d\n",status);
        goto fail;
    }

    // Set mpll2 to 20x our desired sckl frequency.
    // tdm divides down by 20 for sclk
    uint64_t actual_freq;
    a113_clk_set_mpll2(bus->clocks, GAUSS_TDM_CLK_SRC_FREQ, &actual_freq);

    zxlogf(INFO,"Requested sample rate = %d, actual = %ld\n",GAUSS_TDM_SAMPLE_RATE,
                                                       actual_freq / GAUSS_TDM_CLK_N);

    if ((status = gauss_pcie_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_pcie_init failed: %d\n", status);
    }
    if ((status = gauss_usb_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_usb_init failed: %d\n", status);
    }
    if ((status = gauss_audio_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_audio_init failed: %d\n", status);
    }

#if I2C_TEST
    if ((status = pbus_device_add(&bus->pbus, &i2c_test_dev, 0)) != ZX_OK) {
        zxlogf(ERROR, "a113_i2c_init could not add i2c_test_dev: %d\n", status);
    }
#endif

    if ((status = gauss_raw_nand_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_raw_nand_init failed: %d\n", status);
    }

    return ZX_OK;
fail:
    zxlogf(ERROR, "gauss_start_thread failed, not all devices have been initialized\n");
    return status;
}

static zx_status_t gauss_bus_bind(void* ctx, zx_device_t* parent) {
    gauss_bus_t* bus = calloc(1, sizeof(gauss_bus_t));
    if (!bus) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PBUS, &bus->pbus);
    if (status != ZX_OK) {
        goto fail;
    }

    // get dummy IOMMU implementation in the platform bus
    status = device_get_protocol(parent, ZX_PROTOCOL_IOMMU, &bus->iommu);
    if (status != ZX_OK) {
        zxlogf(ERROR, "gauss_bus_bind: could not get ZX_PROTOCOL_IOMMU\n");
        goto fail;
    }
    status = iommu_get_bti(&bus->iommu, 0, BTI_BOARD, &bus->bti_handle);
    if (status != ZX_OK) {
        zxlogf(ERROR, "gauss_bus_bind: iommu_get_bti failed: %d\n", status);
        goto fail;
    }

    bus->parent = parent;

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "gauss-bus",
        .ctx = bus,
        .ops = &gauss_bus_device_protocol,
        .flags = DEVICE_ADD_NON_BINDABLE,
    };

    status = device_add(parent, &args, NULL);
    if (status != ZX_OK) {
        goto fail;
    }

    thrd_t t;
    int thrd_rc = thrd_create_with_name(&t, gauss_start_thread, bus, "gauss_start_thread");
    if (thrd_rc != thrd_success) {
        status = thrd_status_to_zx_status(thrd_rc);
        goto fail;
    }
    return ZX_OK;

fail:
    printf("gauss_bus_bind failed %d\n", status);
    gauss_bus_release(bus);
    return status;
}

static zx_driver_ops_t gauss_bus_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = gauss_bus_bind,
};

ZIRCON_DRIVER_BEGIN(gauss_bus, gauss_bus_driver_ops, "zircon", "0.1", 3)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PBUS),
    BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_GOOGLE),
    BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_PID, PDEV_PID_GAUSS),
ZIRCON_DRIVER_END(gauss_bus)
