/*
    * R820t.hpp
    * Rafael Micro R820T / R820T2 silicon tuner.
    *
    * The tuner sits on the RTL2832U's I2C bus; all register traffic is carried
    * by the demod's I2C repeater (managed by the RtlSdr layer, which enables the
    * repeater around every call here).  This module owns the tuner-side logic:
    * the init register array, the PLL/VCO frequency synthesis, the RF tracking
    * filter / mux band selection, and the LNA/Mixer/VGA gain stages.
    *
    * Register/algorithm facts follow the publicly documented R820T programming
    * model (as used by osmocom rtl-sdr); the implementation here is original.
    * Copyright (c) 2026 Daniel Hammer
*/

#pragma once
#include <cstdint>

namespace Drivers::USB::Radio {

    // I2C bus address of the tuner on the RTL2832U (8-bit form).
    static constexpr uint8_t R820T_I2C_ADDR  = 0x34;
    // Chip-id register (reg 0) reads back this value for an R820T/R820T2.
    static constexpr uint8_t R820T_CHECK_VAL = 0x69;

    // First writable register; the 27-entry shadow covers regs 0x05..0x1f.
    static constexpr uint8_t R820T_REG_SHADOW_START = 5;
    static constexpr uint8_t R820T_NUM_REGS         = 27;

    struct R820tDev {
        uint8_t  slotId;
        uint32_t xtal;       // reference crystal, Hz (28.8 MHz on RTL-SDR)
        uint32_t intFreq;    // IF the demod expects the signal at, Hz (3.57 MHz)
        uint8_t  regs[32];   // register shadow (index == register number)
        bool     hasLock;    // PLL lock state after the last tune
        bool     inited;
    };

    // Detect an R820T/R820T2 on the demod I2C bus.  The caller must have the
    // demod's I2C repeater enabled.  Returns true if the chip id matches.
    bool R820tDetect(uint8_t slotId);

    // Initialise the tuner (writes the init register array + base setup).  The
    // caller must have the I2C repeater enabled.  Returns true on success.
    bool R820tInit(R820tDev& d, uint8_t slotId, uint32_t xtal, uint32_t intFreq);

    // Tune to an RF center frequency (Hz).  Programs the RF mux band and the PLL
    // for an LO of rfHz + intFreq.  Updates d.hasLock.  Repeater must be on.
    bool R820tSetFreq(R820tDev& d, uint64_t rfHz);

    // Configure gain.  manual==0 puts LNA/mixer in AGC; manual!=0 selects the
    // closest fixed gain to tenthsDb from the LNA+mixer step tables.
    bool R820tSetGain(R820tDev& d, int manual, int tenthsDb);

    // Put the tuner into standby (mute / power down).
    void R820tStandby(R820tDev& d);

    // The discrete gain table (tenths of dB), for advertising to userspace.
    const int* R820tGainTable(int* count);

}
