// 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 <limits.h>

#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/platform-defs.h>
#include <soc/aml-a113/a113-hw.h>

#include "gauss.h"

static const pbus_mmio_t gpio_mmios[] = {
    {
        .base = 0xff634400,
        .length = 0x11C00,
    },
    {
        .base = 0xff800000,
        .length = PAGE_SIZE,
    },
    {
        .base = 0xffd00000,
        .length = 0x10000,
    },
};

static const pbus_irq_t gpio_irqs[] = {
    {
        .irq = 64,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = 65,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = 66,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = 67,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = 68,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = 69,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = 70,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
    {
        .irq = 71,
        .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
    },
};

static const pbus_dev_t gpio_dev = {
    .name = "gpio",
    .vid = PDEV_VID_AMLOGIC,
    .pid = PDEV_PID_AMLOGIC_A113,
    .did = PDEV_DID_AMLOGIC_GPIO,
    .mmio_list = gpio_mmios,
    .mmio_count = countof(gpio_mmios),
    .irq_list = gpio_irqs,
    .irq_count = countof(gpio_irqs),
};

zx_status_t gauss_gpio_init(gauss_bus_t* bus) {
  zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_GPIO_IMPL, &gpio_dev);
  if (status != ZX_OK) {
    zxlogf(ERROR, "gauss_gpio_init: pbus_protocol_device_add failed: %d\n", status);
    return status;
  }

  return device_get_protocol(bus->parent, ZX_PROTOCOL_GPIO_IMPL, &bus->gpio);
}
