//
// Copyright 2017 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#include "ad937x_config_t.hpp"
#include "ad937x_default_config.hpp"

const int16_t ad937x_config_t::DEFAULT_TX_FIR[DEFAULT_TX_FIR_SIZE] = {-94,
    -26,
    282,
    177,
    -438,
    -368,
    756,
    732,
    -1170,
    -1337,
    1758,
    2479,
    -2648,
    -5088,
    4064,
    16760,
    16759,
    4110,
    -4881,
    -2247,
    2888,
    1917,
    -1440,
    -1296,
    745,
    828,
    -358,
    -474,
    164,
    298,
    -16,
    -94};

const int16_t ad937x_config_t::DEFAULT_TX_FIR_15366[DEFAULT_TX_FIR_SIZE] = {4,
    -16,
    -5,
    75,
    -13,
    -229,
    85,
    547,
    -293,
    -1158,
    738,
    2290,
    -1640,
    -4805,
    3687,
    17108,
    17108,
    3687,
    -4805,
    -1640,
    2290,
    738,
    -1158,
    -293,
    547,
    85,
    -229,
    -13,
    75,
    -5,
    -16,
    4};

const int16_t ad937x_config_t::DEFAULT_RX_FIR[DEFAULT_RX_FIR_SIZE] = {-20,
    6,
    66,
    22,
    -128,
    -54,
    240,
    126,
    -402,
    -248,
    634,
    444,
    -956,
    -756,
    1400,
    1244,
    -2028,
    -2050,
    2978,
    3538,
    -4646,
    -7046,
    9536,
    30880,
    30880,
    9536,
    -7046,
    -4646,
    3538,
    2978,
    -2050,
    -2028,
    1244,
    1400,
    -756,
    -956,
    444,
    634,
    -248,
    -402,
    126,
    240,
    -54,
    -128,
    22,
    66,
    6,
    -20};

const int16_t ad937x_config_t::DEFAULT_RX_FIR_15366[DEFAULT_RX_FIR_SIZE] = {-16,
    -22,
    18,
    74,
    24,
    -132,
    -152,
    132,
    372,
    38,
    -598,
    -474,
    638,
    1178,
    -206,
    -1952,
    -984,
    2362,
    3152,
    -1612,
    -6544,
    -2164,
    12806,
    26836,
    26836,
    12806,
    -2164,
    -6544,
    -1612,
    3152,
    2362,
    -984,
    -1952,
    -206,
    1178,
    638,
    -474,
    -598,
    38,
    372,
    132,
    -152,
    -132,
    24,
    74,
    18,
    -22,
    -16};

const int16_t ad937x_config_t::DEFAULT_OBSRX_FIR[DEFAULT_RX_FIR_SIZE] = {-14,
    -19,
    44,
    41,
    -89,
    -95,
    175,
    178,
    -303,
    -317,
    499,
    527,
    -779,
    -843,
    1184,
    1317,
    -1781,
    -2059,
    2760,
    3350,
    -4962,
    -7433,
    9822,
    32154,
    32154,
    9822,
    -7433,
    -4962,
    3350,
    2760,
    -2059,
    -1781,
    1317,
    1184,
    -843,
    -779,
    527,
    499,
    -317,
    -303,
    178,
    175,
    -95,
    -89,
    41,
    44,
    -19,
    -14};

const int16_t ad937x_config_t::DEFAULT_OBSRX_FIR_15366[DEFAULT_RX_FIR_SIZE] = {-2,
    3,
    12,
    -19,
    -28,
    44,
    74,
    -92,
    -169,
    150,
    353,
    -203,
    -671,
    203,
    1179,
    -66,
    -1952,
    -347,
    3153,
    1307,
    -5595,
    -4820,
    11323,
    29525,
    29525,
    11323,
    -4820,
    -5595,
    1307,
    3153,
    -347,
    -1952,
    -66,
    1179,
    203,
    -671,
    -203,
    353,
    150,
    -169,
    -92,
    74,
    44,
    -28,
    -19,
    12,
    3,
    -2};

const int16_t ad937x_config_t::DEFAULT_SNIFFER_FIR[DEFAULT_RX_FIR_SIZE] = {-1,
    -5,
    -14,
    -23,
    -16,
    24,
    92,
    137,
    80,
    -120,
    -378,
    -471,
    -174,
    507,
    1174,
    1183,
    98,
    -1771,
    -3216,
    -2641,
    942,
    7027,
    13533,
    17738,
    17738,
    13533,
    7027,
    942,
    -2641,
    -3216,
    -1771,
    98,
    1183,
    1174,
    507,
    -174,
    -471,
    -378,
    -120,
    80,
    137,
    92,
    24,
    -16,
    -23,
    -14,
    -5,
    -1};

const int16_t ad937x_config_t::DEFAULT_SNIFFER_FIR_15366[DEFAULT_RX_FIR_SIZE] = {10,
    31,
    59,
    71,
    30,
    -92,
    -283,
    -456,
    -466,
    -175,
    440,
    1192,
    1683,
    1444,
    198,
    -1871,
    -3988,
    -4942,
    -3512,
    958,
    8118,
    16519,
    23993,
    28395,
    28395,
    23993,
    16519,
    8118,
    958,
    -3512,
    -4942,
    -3988,
    -1871,
    198,
    1444,
    1683,
    1192,
    440,
    -175,
    -466,
    -456,
    -283,
    -92,
    30,
    71,
    59,
    31,
    10};

ad937x_config_t::ad937x_config_t(spiSettings_t* sps, const size_t deserializer_lane_xbar)
    : _rx(DEFAULT_RX_SETTINGS)
    , _rxProfile(DEFAULT_RX_PROFILE)
    , _framer(DEFAULT_FRAMER)
    , _rxGainCtrl(DEFAULT_RX_GAIN)
    , _rxPeakAgc(DEFAULT_RX_PEAK_AGC)
    , _rxPowerAgc(DEFAULT_RX_POWER_AGC)
    , _rxAgcCtrl(DEFAULT_RX_AGC_CTRL)
    ,

    _tx(DEFAULT_TX_SETTINGS)
    , _txProfile(DEFAULT_TX_PROFILE)
    , _deframer(DEFAULT_DEFRAMER)
    ,
    // TODO: Remove if ADI ever fixes this
    // The TX bring up requires a valid ORX profile
    // https://github.com/EttusResearch/uhddev/blob/f0f8f58471c3fed94279c32f00e9f8da7db40efd/mpm/lib/mykonos/adi/mykonos.c#L16590

    _obsRx(DEFAULT_ORX_SETTINGS)
    , _orxFramer(DEFAULT_ORX_FRAMER)
    , _orxProfile(DEFAULT_ORX_PROFILE)
    , _orxGainCtrl(DEFAULT_ORX_GAIN)
    , _orxPeakAgc(DEFAULT_ORX_PEAK_AGC)
    , _orxPowerAgc(DEFAULT_ORX_POWER_AGC)
    , _orxAgcCtrl(DEFAULT_ORX_AGC_CTRL)
    ,

    // TODO: Remove if ADI ever fixes this
    // ORX bring up requires a valid sniffer gain control struct
    // https://github.com/EttusResearch/uhddev/blob/f0f8f58471c3fed94279c32f00e9f8da7db40efd/mpm/lib/mykonos/adi/mykonos.c#L5752

    _snifferGainCtrl(DEFAULT_SNIFFER_GAIN)
    ,

    _armGpio(DEFAULT_ARM_GPIO)
    , _gpio3v3(DEFAULT_GPIO_3V3)
    , _gpio(DEFAULT_GPIO)
    ,

    _auxIo(DEFAULT_AUX_IO)
    , _clocks(DEFAULT_CLOCKS)
    ,

    tx_fir_config(DEFAULT_TX_FIR_GAIN,
        std::vector<int16_t>(DEFAULT_TX_FIR, DEFAULT_TX_FIR + DEFAULT_TX_FIR_SIZE))
    , rx_fir_config(DEFAULT_RX_FIR_GAIN,
          std::vector<int16_t>(DEFAULT_RX_FIR, DEFAULT_RX_FIR + DEFAULT_RX_FIR_SIZE))
    , _orx_fir_config(DEFAULT_RX_FIR_GAIN,
          std::vector<int16_t>(
              DEFAULT_OBSRX_FIR, DEFAULT_OBSRX_FIR + DEFAULT_RX_FIR_SIZE))
    , _sniffer_rx_fir_config(DEFAULT_RX_FIR_GAIN,
          std::vector<int16_t>(
              DEFAULT_SNIFFER_FIR, DEFAULT_SNIFFER_FIR + DEFAULT_RX_FIR_SIZE))
{
    _device.spiSettings                = sps;
    _deframer.deserializerLaneCrossbar = deserializer_lane_xbar;

    _init_pointers();

    device = &_device;
}

// This function sets up all the pointers in all of our local members that represent the
// device struct This function should only be called during construction.
void ad937x_config_t::_init_pointers()
{
    _device.rx     = &_rx;
    _device.tx     = &_tx;
    _device.obsRx  = &_obsRx;
    _device.auxIo  = &_auxIo;
    _device.clocks = &_clocks;

    _rx.rxProfile               = &_rxProfile;
    _rx.framer                  = &_framer;
    _rx.rxGainCtrl              = &_rxGainCtrl;
    _rx.rxAgcCtrl               = &_rxAgcCtrl;
    _rxProfile.rxFir            = rx_fir_config.fir;
    _rxProfile.customAdcProfile = nullptr;
    _rxAgcCtrl.peakAgc          = &_rxPeakAgc;
    _rxAgcCtrl.powerAgc         = &_rxPowerAgc;

    _tx.txProfile    = &_txProfile;
    _txProfile.txFir = tx_fir_config.fir;
    _tx.deframer     = &_deframer;

    // AD9373
    _tx.dpdConfig  = nullptr;
    _tx.clgcConfig = nullptr;
    _tx.vswrConfig = nullptr;

    // TODO: ideally we set none of this information and leave the profile as nullptr
    // Check that the API supports this
    _obsRx.orxProfile            = &_orxProfile;
    _obsRx.orxGainCtrl           = &_orxGainCtrl;
    _obsRx.orxAgcCtrl            = &_orxAgcCtrl;
    _orxProfile.rxFir            = _orx_fir_config.fir;
    _orxProfile.customAdcProfile = nullptr;
    _orxAgcCtrl.peakAgc          = &_orxPeakAgc;
    _orxAgcCtrl.powerAgc         = &_orxPowerAgc;

    _obsRx.snifferProfile  = &_snifferProfile;
    _snifferProfile.rxFir  = _sniffer_rx_fir_config.fir;
    _obsRx.snifferGainCtrl = &_snifferGainCtrl;
    // sniffer has no AGC ctrl, so leave as null
    _obsRx.framer = &_orxFramer;

    _auxIo.gpio3v3 = &_gpio3v3;
    _auxIo.gpio    = &_gpio;
    _auxIo.armGpio = &_armGpio;
}