// 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 <soc/aml-common/aml-i2c.h>

#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/syscalls.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 zx_status_t gauss_get_initial_mode(void* ctx, usb_mode_t* out_mode) {
    *out_mode = USB_MODE_HOST;
    return ZX_OK;
}

static zx_status_t gauss_set_mode(void* ctx, usb_mode_t mode) {
    gauss_bus_t* bus = ctx;
    return gauss_usb_set_mode(bus, mode);
}

usb_mode_switch_protocol_ops_t usb_mode_switch_ops = {
    .get_initial_mode = gauss_get_initial_mode,
    .set_mode = gauss_set_mode,
};

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

    status = pbus_set_protocol(&bus->pbus, ZX_PROTOCOL_USB_MODE_SWITCH, &bus->usb_mode_switch);
    if (status != ZX_OK) {
        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 = 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) {
    zx_status_t status;

    gauss_bus_t* bus = calloc(1, sizeof(gauss_bus_t));
    if (!bus) {
        return ZX_ERR_NO_MEMORY;
    }

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

    bus->parent = parent;
    bus->usb_mode_switch.ops = &usb_mode_switch_ops;
    bus->usb_mode_switch.ctx = bus;

   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) {
        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)
