// 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/protocol/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_channels = i2c_test_channels,
    .i2c_channel_count = countof(i2c_test_channels),
};
#endif

static const pbus_i2c_channel_t led_i2c_channels[] = {
    {
        .bus_id = AML_I2C_A,
        .address = 0x3f,
    },
};

static const pbus_dev_t led_dev = {
    .name = "led",
    .vid = PDEV_VID_GOOGLE,
    .pid = PDEV_PID_GAUSS,
    .did = PDEV_DID_GAUSS_LED,
    .i2c_channels = led_i2c_channels,
    .i2c_channel_count = countof(led_i2c_channels),
};

static void gauss_bus_release(void* ctx) {
    gauss_bus_t* bus = ctx;
    io_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;

    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_set_alt_function(&bus->gpio, I2C_SCK_A, 1);
    gpio_set_alt_function(&bus->gpio, I2C_SDA_A, 1);
    gpio_set_alt_function(&bus->gpio, I2C_SCK_B, 1);
    gpio_set_alt_function(&bus->gpio, I2C_SDA_B, 1);

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

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

    gpio_set_alt_function(&bus->gpio, SPK_MUTEn, 0);
    gpio_config(&bus->gpio, SPK_MUTEn, GPIO_DIR_OUT);
    gpio_write(&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->bti_handle, &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);
        goto fail;
    }
    if ((status = gauss_usb_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_usb_init failed: %d\n", status);
        goto fail;
    }
    if ((status = gauss_audio_init(bus)) != ZX_OK) {
        zxlogf(ERROR, "gauss_audio_init failed: %d\n", status);
        goto fail;
    }

#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);
        goto fail;
    }
#endif

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

    if ((status = pbus_device_add(&bus->pbus, &led_dev, 0)) != ZX_OK) {
        zxlogf(ERROR, "a113_i2c_init could not add i2c_led_dev: %d\n", status);
        goto fail;
    }

    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_PLATFORM_BUS, &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_PLATFORM_BUS),
    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)
