// Copyright 2019 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 <string.h>

#include <ddk/protocol/i2c-lib.h>
#include <ddk/protocol/i2c.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>

#include "tlv320adc.h"

namespace audio {
namespace mt8167 {

constexpr float Tlv320adc::kMaxGain;
constexpr float Tlv320adc::kMinGain;

std::unique_ptr<Tlv320adc> Tlv320adc::Create(ddk::PDev pdev, uint32_t i2c_index) {
    auto i2c = pdev.GetI2c(i2c_index);
    if (!i2c.is_valid()) {
        zxlogf(ERROR, "%s failed to allocate i2c\n", __func__);
        return nullptr;
    }

    fbl::AllocChecker ac;
    auto ptr = std::unique_ptr<Tlv320adc>(new (&ac) Tlv320adc(i2c));
    if (!ac.check()) {
        return nullptr;
    }
    return ptr;
}

zx_status_t Tlv320adc::Reset() {
    return WriteReg(0, 1, 0x01);
}

zx_status_t Tlv320adc::SetGain(float gain) {
    gain = fbl::clamp(gain, kMinGain, kMaxGain);

    // TODO(andresoportus): Add fine vol control at reg 82.
    uint8_t gain_reg = static_cast<uint8_t>(gain * 2.f) & 0x7F;

    zx_status_t status;
    status = WriteReg(0, 83, gain_reg); // Left gain.
    if (status != ZX_OK) {
        return status;
    }
    status = WriteReg(0, 84, gain_reg); // Right gain.
    if (status != ZX_OK) {
        return status;
    }
    current_gain_ = gain;
    return status;
}

bool Tlv320adc::ValidGain(float gain) {
    return (gain <= kMaxGain) && (gain >= kMinGain);
}

zx_status_t Tlv320adc::Init() {
    zx_status_t status = Standby();

    uint8_t defaults[][2] = {
        // Clocks.
        {4, 0x00}, // PLL_CLKIN = MCLK (device pin), CODEC_CLKIN = MCLK (device pin).
        // MCLK (22.7 MHz) % NADC % MADC = ADC_MOD_CLK (5.675 MHz) = DMCLK (Digital Microphone CLK).
        {18, 0x82}, // ADC NADC Clock Divider = 2, enabled.
        {19, 0x82}, // ADC MADC Clock Divider = 2, enabled.
        {20, 0x80}, // ADC AOSR = 128.

        // ADC Audio Interface.
        {27, 0x00}, // I2S, 16 bits, BCLK is input, WCLK is input, 3-stating of DOUT disabled.
        {28, 0x00}, // Data Slot Offset Programmability 1 (Ch_Offset_1).
        {37, 0x00}, // Data Slot Offset Programmability 2 (Ch_Offset_2).
        {38, 0x00}, // L+R channels enabled.

        // Pins.
        {51, 0x28}, // DMCLK/GPIO2 Control, DMCLK out = ADC_MOD_CLK out for the digital microphone.
        {52, 0x04}, // DMDIN/GPIO1 Control, DMDIN is in input mode.

        // ADC Config.
        {80, 0x01}, // ADC Digital-Microphone Polarity Select.
        {83, 0x00}, // Left ADC Volume Control, 0dB.
        {84, 0x00}, // Right ADC Volume Control, 0dB
        {82, 0x00}, // ADC Fine Volume Control. Not muted, gain 0.
    };
    for (auto& i : defaults) {
        status = WriteReg(0, i[0], i[1]);
        if (status != ZX_OK) {
            return status;
        }
    }
    zx_nanosleep(zx_deadline_after(ZX_MSEC(100))); // To allow ADC clocks to sync, not on datasheet.
    status = WriteReg(0, 53, 0x12);                // DOUT (OUT Pin) Control bus keeper enabled,
                                                   // output for codec interface.
    if (status != ZX_OK) {
        return status;
    }
    return ExitStandby();
}

zx_status_t Tlv320adc::Standby() {
    return WriteReg(0, 81, 0x02); // ADC Digital.  ADC Off, use DMDIN, MIC off, no soft stepping.
}

zx_status_t Tlv320adc::ExitStandby() {
    return WriteReg(0, 81, 0xCE); // ADC Digital.  ADC On, use DMDIN, MIC on, no soft stepping.
}

zx_status_t Tlv320adc::WriteReg(uint8_t page, uint8_t reg, uint8_t value) {
    uint8_t write_buf[2];
    write_buf[0] = 0;
    write_buf[1] = page;
    i2c_.WriteSync(write_buf, 2);
    write_buf[0] = reg;
    write_buf[1] = value;
    return i2c_.WriteSync(write_buf, 2);
}
} // namespace mt8167
} // namespace audio
