// 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 "gauss.h"

#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/threads.h>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.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", status);
    goto fail;
  }

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

  if ((status = gauss_gpio_init(bus)) != ZX_OK) {
    zxlogf(ERROR, "gauss_gpio_init failed: %d", 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", status);
    goto fail;
  }

  status = a113_clk_init(&bus->clocks);
  if (status != ZX_OK) {
    zxlogf(ERROR, "a113_clk_init failed: %d", 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", 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", status);
  }
  if ((status = gauss_usb_init(bus)) != ZX_OK) {
    zxlogf(ERROR, "gauss_usb_init failed: %d", status);
  }
  if ((status = gauss_audio_init(bus)) != ZX_OK) {
    zxlogf(ERROR, "gauss_audio_init failed: %d", 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", status);
  }
#endif

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

  return ZX_OK;
fail:
  zxlogf(ERROR, "gauss_start_thread failed, not all devices have been initialized");
  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");
    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", 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)
