// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/*
 * Copyright (c) 2023 MediaTek Inc.
 */

/*****************************************************************************/
#include <dm/ofnode.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <dm.h>
#include <adc.h>

#include "common.h"
#include "command.h"
#include "debug_impl.h"
#include "mtk_sar_keypad.h"

u32 gupgrade_ch = CH_DEFAULT;
u16 gadc[KEY_NUMS] = {0};
u8 is_first = true;

static int mtk_sar_get_dts_info(void)
{
    ofnode ini_node;
    ofnode node = {0};
    u32 adc[KEY_NUMS] = {0};
    int ret = false;

    if (is_first == true)
    {
        /* Check device. */
        ini_node = ofnode_path("/pmu_ini");
        if (!ofnode_valid(ini_node))
        {
            UBOOT_ERROR("ofnode_path(/pmu_ini) not found.\n");
            return -ENODEV;
        }

        node = ofnode_find_subnode(ini_node, "sar");
        if (!ofnode_valid(node))
        {
            UBOOT_ERROR("[SAR] ofnode_path(SAR) not found.\n");
            return -ENODEV;
        }

        /*upgrade channel*/
        ret = ofnode_read_u32(node, "upgrade-ch", &gupgrade_ch);
        if (ret)
        {
            UBOOT_ERROR("[SAR] read (upgrade-ch) failed.(%d)\n", ret);
            return -EINVAL;
        }

        /*upgrade adc*/
        ret = ofnode_read_u32_array(node, "upgrade-adc", adc, KEY_NUMS);
        if (ret)
        {
            UBOOT_ERROR("[SAR] read (upgrade-adc) failed.(%d)\n", ret);
            return -EINVAL;
        }

        UBOOT_TRACE("g_upgrade ch [%d]\n", gupgrade_ch);

        for (int idx = 0; idx < KEY_NUMS; idx++)
        {
            gadc[idx] = (adc[idx] & CH_MASK);
            UBOOT_TRACE("g_upgrade adc[%d]=0x%X \n", idx, gadc[idx]);
        }

        is_first = false;
        ret = true;
    }
    else
    {
        UBOOT_TRACE("Get dts already run\n");
        ret = true;
    }

    return ret;
}

static int mtk_sar_check_upgrade(int adc_mode, unsigned int adc_val)
{
    int idx = 0;
    int ret = EN_ADC_MODE_RET_UNKNOWN;

    if (adc_mode == EN_ADC_MODE_UPGRADE)
    {
        for (idx = 0; idx < KEY_NUMS; idx++)
        {
            if (gadc[idx] != ADC_DEFAULT)
            {
                if (adc_val <= gadc[idx])
                {
                    ret = EN_ADC_MODE_RET_UPGRADE;
                }
            }
        }
    }
    else if (adc_mode == EN_ADC_MODE_RECOVERY)
    {
        ret = EN_ADC_MODE_RET_RECOVERY;
    }
    else
    {
        ret = EN_ADC_MODE_RET_UNKNOWN;
        UBOOT_ERROR("Error mode NOT support mode!!!\n");
    }

    UBOOT_INFO("%s: (adc_mode,ret) = (%d, %d)\n", __func__, adc_mode, ret);

    return ret;
}
int mtk_sar_check_status(int adc_mode)
{
    struct udevice *dev;
    unsigned int data = 0;
    int uV;
    int ret = EN_ADC_MODE_RET_UNKNOWN;

    mtk_sar_get_dts_info();

    if (gupgrade_ch != CH_DEFAULT)
    {
        ret = adc_channel_single_shot("sar", gupgrade_ch, &data);

        if (ret)
        {
            UBOOT_ERROR("Error getting single shot for device sar channel %d\n",
                    gupgrade_ch);
            ret = EN_ADC_MODE_RET_UNKNOWN;
            goto exit;
        }

        ret = uclass_get_device_by_name(UCLASS_ADC, "sar", &dev);
        if (!ret && !adc_raw_to_uV(dev, data, &uV))
        {
            printf("get sar_adc = %u, %d uV\n", data, uV);
        }
        else
        {
            printf("get sar_adc = %u\n", data);
        }
        ret = mtk_sar_check_upgrade(adc_mode, data);

    }
    else
    {
        ret = EN_ADC_MODE_RET_UNKNOWN;
        UBOOT_ERROR("Error getting sar channel %d\n", gupgrade_ch);
    }

exit:
    return ret;
}
