// 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(const ddk::I2cChannel& i2c, uint32_t i2c_index) {
    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).
        // DMCLK (Digital Mic CLK, example range 1.45MHz to 4.8MHz) is based on MCLK, e.g.:
        // DMCLK = MCLK 22.5792 MHz (from Aud1) % NADC % MADC = ADC_MOD_CLK (2.8224 MHz).
        // DMCLK = MCLK 24.576 MHz (from Aud2) % NADC % MADC = ADC_MOD_CLK (3.072 MHz).
        // We need to keep MADC x AOSR > IADC (188 for PRB_R1)
        {18, 0x82}, // ADC NADC Clock Divider = 2, enabled.
        {19, 0x84}, // ADC MADC Clock Divider = 4, enabled.
        {20, 0x40}, // ADC AOSR = 64.

        // 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.
        {61, 0x01}, // ADC Processing Block Selection, PRB_R1.
        {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
