-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local class = require 'mc.class'
local log = require 'mc.logging'
local pmbus = require 'device_tree.adapters.power_mgmt.protocol.pmbus'
local psu_pmbus = class(pmbus)
local IT22PEEA <const> = 'IT22PEEA'
local MAX_MDU_NUM <const> = 2

local psu_model = ""
local psu_dc_version = 0

-- get_model 电源型号
function psu_pmbus:get_model()
    local raw_model = self:get_dynamic_block(self.cmd.MFR_MODEL)
    local trimmed_model = raw_model:gsub("%s+$", "")
    psu_model = trimmed_model
    return trimmed_model
end

-- get_firmware_version 电源版本
function psu_pmbus:get_firmware_version()
    local soft_load_info = self:get_soft_load_info()
    local fw_version = { 0, 0 }
    local app_count = 1
    for i = 1, soft_load_info.soft_cnt, 1 do
        local soft_info = soft_load_info.soft_info[i]
        log:info('soft_load_info.soft_cnt: %d, soft_info.module_num :%d', soft_load_info.soft_cnt,
            soft_info.module_num)
        local module_num = soft_info.module_num > MAX_MDU_NUM and 1 or soft_info.module_num
        for j = 1, module_num, 1 do
            if j < module_num then
                -- 下发FC切换通道
                self:load_app_ctrl_cmd(self.cmd.MFR_QB_SOFT_VER, j)
                -- 查询切换是否成功
                self:load_app_ctrl_cmd_read(self.cmd.MFR_QB_SOFT_VER)
            end
            fw_version[app_count] = self:get_soft_version(soft_info.soft_id)
            if not fw_version[app_count] then
                return 'N/A'
            end
            app_count = app_count + 1
        end
    end
    local input_type = self:get_power_supply_type()
    psu_dc_version = fw_version[1]
    return string.format('DC:%x%02x PFC:%s%x%02x', ((fw_version[1] >> 8) & 0xff), fw_version[1] & 0xff,
        input_type == 0 and '(QB)' or '', ((fw_version[2] >> 8) & 0xff), fw_version[2] & 0xff)
end

function psu_pmbus:get_linear_16(cmd)
    -- 天成超级节点现网存在两个固件版本，输出电压转换算法不一致，0x102版本以上使用linear_16 Q9算法转换，0x102即258版本以下使用linear_11算法转换
    if psu_model == IT22PEEA then
        if psu_dc_version < 258 then
            return self:get_linear_11(cmd)
        end
        return tonumber(string.format("%.2f", self:chip_wordread(cmd) / 512))
    else
        return tonumber(string.format("%.2f", self:chip_wordread(cmd) / 4096))
    end
end

-- get_output_voltage 输出电压
function psu_pmbus:get_output_voltage()
    return self:get_linear_16(self.cmd.READ_12VOUT)
end

return psu_pmbus
