/*
 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <debug.h>
#include <delay_timer.h>
#include <errno.h>
#include <hi3660.h>
#include <mmio.h>

#include "hikey960_private.h"

#define ADC_ADCIN0				0
#define ADC_ADCIN1				1
#define ADC_ADCIN2				2

#define HKADC_DATA_GRADE0			0
#define HKADC_DATA_GRADE1			100
#define HKADC_DATA_GRADE2			300
#define HKADC_DATA_GRADE3			500
#define HKADC_DATA_GRADE4			700
#define HKADC_DATA_GRADE5			900
#define HKADC_DATA_GRADE6			1100
#define HKADC_DATA_GRADE7			1300
#define HKADC_DATA_GRADE8			1500
#define HKADC_DATA_GRADE9			1700
#define HKADC_DATA_GRADE10			1800

#define BOARDID_VALUE0				0
#define BOARDID_VALUE1				1
#define BOARDID_VALUE2				2
#define BOARDID_VALUE3				3
#define BOARDID_VALUE4				4
#define BOARDID_VALUE5				5
#define BOARDID_VALUE6				6
#define BOARDID_VALUE7				7
#define BOARDID_VALUE8				8
#define BOARDID_VALUE9				9
#define BOARDID_UNKNOWN				0xF

#define BOARDID3_BASE				5


static void init_adc(void)
{
	/* reset hkadc */
	mmio_write_32(CRG_PERRSTEN2_REG, PERRSTEN2_HKADCSSI);
	/* wait a few clock cycles */
	udelay(2);
	mmio_write_32(CRG_PERRSTDIS2_REG, PERRSTEN2_HKADCSSI);
	udelay(2);
	/* enable hkadc clock */
	mmio_write_32(CRG_PERDIS2_REG, PEREN2_HKADCSSI);
	udelay(2);
	mmio_write_32(CRG_PEREN2_REG, PEREN2_HKADCSSI);
	udelay(2);
}

static int get_adc(unsigned int channel, unsigned int *value)
{
	unsigned int	data, value1, value0;

	if (channel > HKADC_CHANNEL_MAX) {
		WARN("invalid channel:%d\n", channel);
		return -EFAULT;
	}
	/* configure the read/write operation for external HKADC */
	mmio_write_32(HKADC_WR01_DATA_REG, HKADC_WR01_VALUE | channel);
	mmio_write_32(HKADC_WR23_DATA_REG, HKADC_WR23_VALUE);
	mmio_write_32(HKADC_WR45_DATA_REG, HKADC_WR45_VALUE);
	/* configure the number of accessing registers */
	mmio_write_32(HKADC_WR_NUM_REG, HKADC_WR_NUM_VALUE);
	/* configure delay of accessing registers */
	mmio_write_32(HKADC_DELAY01_REG, HKADC_CHANNEL0_DELAY01_VALUE);
	mmio_write_32(HKADC_DELAY23_REG, HKADC_DELAY23_VALUE);

	/* start HKADC */
	mmio_write_32(HKADC_DSP_START_REG, 1);
	do {
		data = mmio_read_32(HKADC_DSP_START_REG);
	} while (data & 1);

	/* convert AD result */
	value1 = mmio_read_32(HKADC_DSP_RD2_DATA_REG) & 0xffff;
	value0 = mmio_read_32(HKADC_DSP_RD3_DATA_REG) & 0xffff;

	data = ((value1 << 4) & HKADC_VALUE_HIGH) |
	       ((value0 >> 4) & HKADC_VALUE_LOW);
	*value = data;
	return 0;
}

static int get_value(unsigned int channel, unsigned int *value)
{
	int ret;

	ret = get_adc(channel, value);
	if (ret)
		return ret;

	/* convert ADC value to micro-volt */
	ret = ((*value & HKADC_VALID_VALUE) * HKADC_VREF_1V8) / HKADC_ACCURACY;
	*value = ret;
	return 0;
}

static int adcin_data_remap(unsigned int adcin_value)
{
	int	ret;

	if (adcin_value < HKADC_DATA_GRADE1)
		ret = BOARDID_VALUE0;
	else if (adcin_value < HKADC_DATA_GRADE2)
		ret = BOARDID_VALUE1;
	else if (adcin_value < HKADC_DATA_GRADE3)
		ret = BOARDID_VALUE2;
	else if (adcin_value < HKADC_DATA_GRADE4)
		ret = BOARDID_VALUE3;
	else if (adcin_value < HKADC_DATA_GRADE5)
		ret = BOARDID_VALUE4;
	else if (adcin_value < HKADC_DATA_GRADE6)
		ret = BOARDID_VALUE5;
	else if (adcin_value < HKADC_DATA_GRADE7)
		ret = BOARDID_VALUE6;
	else if (adcin_value < HKADC_DATA_GRADE8)
		ret = BOARDID_VALUE7;
	else if (adcin_value < HKADC_DATA_GRADE9)
		ret = BOARDID_VALUE8;
	else if (adcin_value < HKADC_DATA_GRADE10)
		ret = BOARDID_VALUE9;
	else
		ret = BOARDID_UNKNOWN;
	return ret;
}

int hikey960_read_boardid(unsigned int *id)
{
	unsigned int	adcin0, adcin1, adcin2;
	unsigned int	adcin0_remap, adcin1_remap, adcin2_remap;

	assert(id != NULL);

	init_adc();

	/* read ADC channel0 data */
	get_value(ADC_ADCIN0, &adcin0);
	adcin0_remap = adcin_data_remap(adcin0);
	INFO("[BDID]adcin0:%d adcin0_remap:%d\n", adcin0, adcin0_remap);
	if (adcin0_remap == BOARDID_UNKNOWN)
		return -EINVAL;
	/* read ADC channel1 data */
	get_value(ADC_ADCIN1, &adcin1);
	adcin1_remap = adcin_data_remap(adcin1);
	INFO("[BDID]adcin1:%d adcin1_remap:%d\n", adcin1, adcin1_remap);
	if (adcin1_remap == BOARDID_UNKNOWN)
		return -EINVAL;
	/* read ADC channel2 data */
	get_value(ADC_ADCIN2, &adcin2);
	adcin2_remap = adcin_data_remap(adcin2);
	INFO("[BDID]adcin2:%d adcin2_remap:%d\n", adcin2, adcin2_remap);
	if (adcin2_remap == BOARDID_UNKNOWN)
		return -EINVAL;
	*id = BOARDID3_BASE * 1000 + (adcin2_remap * 100) +
		(adcin1_remap * 10) + adcin0_remap;
	INFO("[BDID]boardid: %d\n", *id);
	return 0;
}
