// 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 <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/protocol/platform-device-lib.h>
#include <zircon/assert.h>
#include <zircon/types.h>
#include <hw/reg.h>

#include "a113-audio-device.h"

#define REGDUMPEEAUDIO(regval)          \
    zxlogf(INFO, #regval " = 0x%08x\n", \
           a113_ee_audio_read(audio_device, regval));

#define REGDUMPPDM(regval)              \
    zxlogf(INFO, #regval " = 0x%08x\n", \
           a113_ee_audio_read(audio_device, regval));

void a113_pdm_dump_registers(a113_audio_device_t* audio_device) {
    REGDUMPPDM(PDM_CTRL)
    REGDUMPPDM(PDM_HCIC_CTRL1)
    REGDUMPPDM(PDM_HCIC_CTRL2)
    REGDUMPPDM(PDM_F1_CTRL)
    REGDUMPPDM(PDM_F2_CTRL)
    REGDUMPPDM(PDM_F3_CTRL)
    REGDUMPPDM(PDM_HPF_CTRL)
    REGDUMPPDM(PDM_CHAN_CTRL)
    REGDUMPPDM(PDM_CHAN_CTRL1)
    REGDUMPPDM(PDM_COEFF_ADDR)
    REGDUMPPDM(PDM_COEFF_DATA)
    REGDUMPPDM(PDM_CLKG_CTRL)
    REGDUMPPDM(PDM_STS)

    REGDUMPEEAUDIO(EE_AUDIO_CLK_GATE_EN)
    REGDUMPEEAUDIO(EE_AUDIO_CLK_PDMIN_CTRL0)
    REGDUMPEEAUDIO(EE_AUDIO_CLK_PDMIN_CTRL1)

    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_CTRL0)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_CTRL1)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_START_ADDR)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_FINISH_ADDR)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_INT_ADDR)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_STATUS1)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_STATUS2)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_START_ADDRB)
    REGDUMPEEAUDIO(EE_AUDIO_TODDR_B_FINISH_ADDRB)
}

uint32_t a113_pdm_read(a113_audio_device_t* audio_device, uint32_t reg) {
    return readl((uint32_t*)audio_device->pdm_mmio.vaddr + reg);
}

void a113_pdm_write(a113_audio_device_t* audio_device, uint32_t reg, uint32_t value) {
    return writel(value, (uint32_t*)audio_device->pdm_mmio.vaddr + reg);
}

void a113_pdm_update_bits(a113_audio_device_t* audio_device, uint32_t reg,
                          uint32_t mask, uint32_t value) {
    uint32_t register_value = a113_pdm_read(audio_device, reg);
    register_value &= ~mask;
    register_value |= value & mask;
    a113_pdm_write(audio_device, reg, register_value);
}

uint32_t a113_ee_audio_read(a113_audio_device_t* audio_device, uint32_t reg) {
    return readl((uint32_t*)audio_device->ee_audio_mmio.vaddr + reg);
}

void a113_ee_audio_write(a113_audio_device_t* audio_device, uint32_t reg, uint32_t value) {
    return writel(value, (uint32_t*)audio_device->ee_audio_mmio.vaddr + reg);
}

void a113_ee_audio_update_bits(a113_audio_device_t* audio_device, uint32_t reg,
                               uint32_t mask, uint32_t value) {
    uint32_t register_value = a113_ee_audio_read(audio_device, reg);
    register_value &= ~mask;
    register_value |= value & mask;
    a113_ee_audio_write(audio_device, reg, register_value);
}

// Map registers to our address space for future access, and do some very basic
// hardware initialization such as setting clocks.
zx_status_t a113_audio_device_init(a113_audio_device_t* audio_device,
                                   zx_device_t* parent) {
    ZX_DEBUG_ASSERT(audio_device);
    ZX_DEBUG_ASSERT(parent);

    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PDEV,
                                             &audio_device->pdev);
    if (status != ZX_OK) {
        goto init_fail;
    }

    // Map EE_AUDIO registers to our address space.
    status = pdev_map_mmio_buffer(&audio_device->pdev, 0 /* EE_AUDIO */,
                                  ZX_CACHE_POLICY_UNCACHED_DEVICE,
                                  &audio_device->ee_audio_mmio);
    if (status != ZX_OK) {
        zxlogf(ERROR, "a113_audio_device_init: pdev_map_mmio_buffer failed\n");
        goto init_fail;
    }

    // Set clocks. This is done before mapping the PDM registers to our address
    // space. The PDM register is not accessible before the pdm_sysclk is
    // running.
    a113_ee_audio_write(audio_device, EE_AUDIO_CLK_PDMIN_CTRL0,
                        (1 << 31) | (2 << 24) | 79);
    a113_ee_audio_write(audio_device, EE_AUDIO_CLK_PDMIN_CTRL1,
                        (1 << 31) | (2 << 24) | 0);
    a113_ee_audio_write(audio_device, EE_AUDIO_CLK_GATE_EN, 0x000fffff);

    // Map the PDM registers to our address space.
    status = pdev_map_mmio_buffer(&audio_device->pdev, 1 /* PDM */,
                                  ZX_CACHE_POLICY_UNCACHED_DEVICE,
                                  &audio_device->pdm_mmio);
    if (status != ZX_OK) {
        zxlogf(ERROR, "a113_audio_device_init: pdev_map_mmio_buffer failed\n");
        goto init_fail;
    }

    return ZX_OK;

init_fail:
    if (audio_device) {
        mmio_buffer_release(&audio_device->ee_audio_mmio);
        mmio_buffer_release(&audio_device->pdm_mmio);
    };
    return status;
}
