#include "lip/phy/lip_phy_cfg_defs.h"
#if LIP_PHY_SUPPORT_YT8521S
#include "yt8521s_regs.h"
#include "lip/phy/lip_phy_defs.h"

static t_lip_errs f_spec_cfg(const t_lip_phy_mdio_acc *regs_acc, const t_lip_phy_cfg *cfg);
static t_lip_errs f_get_mode(const t_lip_phy_mdio_acc *regs_acc, t_lip_phy_mode *mode);
static t_lip_errs f_rd_intflags(const t_lip_phy_mdio_acc *regs_acc, uint32_t *intflags);
#if LIP_PHY_USE_STATS
static t_lip_errs f_upd_stats(const t_lip_phy_mdio_acc *regs_acc, const t_lip_phy_state *state, t_lip_phy_stats *stats);
#endif

t_lip_phy_info lip_phy_yt8521s = {
    .name = "YT8521S",
    .model_id  = LIP_PHY_MODEL_ID(YT8521S_ID_VENDOR, YT8521S_ID_MODEL),
    .an_features = LIP_PHY_AN_FEAT_MODE_10_T_FD | LIP_PHY_AN_FEAT_MODE_10_T_HD
                   | LIP_PHY_AN_FEAT_MODE_100_TX_FD | LIP_PHY_AN_FEAT_MODE_100_TX_HD
                   | LIP_PHY_AN_FEAT_MODE_1000_T_FD
                   | LIP_PHY_AN_FEAT_PAUSE_SYM | LIP_PHY_AN_FEAT_PAUSE_ASYM
                   | LIP_PHY_AN_FEAT_EEE_100_TX | LIP_PHY_AN_FEAT_EEE_1000_T,
    .spec_features = 0,
    .spec_cfg = f_spec_cfg,
    .get_mode = f_get_mode,
    .rd_intflags = f_rd_intflags,
#if LIP_PHY_USE_STATS
    .update_stats =  f_upd_stats,
#endif
};


static t_lip_errs f_spec_cfg(const t_lip_phy_mdio_acc *regs_acc, const t_lip_phy_cfg *cfg) {
    t_lip_errs err = LIP_ERR_SUCCESS;

    return err;
}
static t_lip_errs f_get_mode(const t_lip_phy_mdio_acc *regs_acc, t_lip_phy_mode *mode) {
    uint16_t stat;
    t_lip_errs err = lip_phy_mdio_reg_read(regs_acc, YT8521S_REGADDR_SPEC_STAT, &stat);
    if (err == LIP_ERR_SUCCESS) {
        mode->flags = 0;
        if (stat & YT8521S_REGFLD_SPEC_STAT_DUPLEX) {
            mode->flags |= LIP_PHY_MODE_FLAG_DUPLEX_FULL;
        }
        uint8_t speed = LBITFIELD_GET(stat, YT8521S_REGFLD_SPEC_STAT_SPEED);
        if (speed == YT8521S_REGFLDVAL_SPEC_STAT_SPEED_1000) {
            mode->speed = LIP_PHY_SPEED_1000;
        } else if (speed == YT8521S_REGFLDVAL_SPEC_STAT_SPEED_100) {
            mode->speed = LIP_PHY_SPEED_100;
        } else if (speed == YT8521S_REGFLDVAL_SPEC_STAT_SPEED_10) {
            mode->speed = LIP_PHY_SPEED_10;
        } else {
            mode->speed = LIP_PHY_SPEED_INVALID;
        }

        if (speed == YT8521S_REGFLDVAL_SPEC_STAT_SPEED_1000) {
            /** @todo read master or slave mode */
            //mode->flags |= LIP_PHY_MODE_FLAG_MASTER;
            //err = lip_phy_mdio_reg_read(regs_acc, YT8521S_REGADDR_SPEC_STAT, &stat);
        }

    }
    return err;
}
static t_lip_errs f_rd_intflags(const t_lip_phy_mdio_acc *regs_acc, uint32_t *intflags) {
    t_lip_errs err = LIP_ERR_SUCCESS;

    return err;
}
#if LIP_PHY_USE_STATS
static t_lip_errs f_upd_stats(const t_lip_phy_mdio_acc *regs_acc, const t_lip_phy_state *state, t_lip_phy_stats *stats) {
    t_lip_errs err = LIP_ERR_SUCCESS;


    return err;
}
#endif

#endif
