// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2014-2019, Toradex AG
 */

/*
 * Helpers for Freescale PMIC PF0100
*/

#include <common.h>
#include <i2c.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/iomux.h>
#include <asm/arch/mx6-pins.h>
#include <asm/gpio.h>
#include <asm/mach-imx/iomux-v3.h>

#include "pf0100_otp.inc"
#include "pf0100.h"

/* define for PMIC register dump */
/*#define DEBUG */

#define WARNBAR "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"

/* use GPIO: EXT_IO1 to switch on VPGM, ON: 1 */
static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = {
	MX6_PAD_NANDF_D3__GPIO2_IO03 | MUX_PAD_CTRL(NO_PAD_CTRL),
#	define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 3)
};

unsigned pmic_init(void)
{
	int rc;
	struct udevice *dev = NULL;
	unsigned programmed = 0;
	uchar bus = 1;
	uchar devid, revid, val;

	puts("PMIC:  ");
	rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev);
	if (rc) {
		printf("failed to get device for PMIC at address 0x%x\n",
		       PFUZE100_I2C_ADDR);
		return 0;
	}

	/* check for errors in PMIC fuses */
	if (dm_i2c_read(dev, PFUZE100_INTSTAT3, &val, 1) < 0) {
		puts("i2c pmic INTSTAT3 register read failed\n");
		return 0;
	}
	if (val & PFUZE100_BIT_OTP_ECCI) {
		puts("\n" WARNBAR);
		puts("WARNING: ecc errors found in pmic fuse banks\n");
		puts(WARNBAR);
	}
	if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE1, &val, 1) < 0) {
		puts("i2c pmic ECC_SE1 register read failed\n");
		return 0;
	}
	if (val & PFUZE100_BITS_ECC_SE1) {
		puts(WARNBAR);
		puts("WARNING: ecc has made bit corrections in banks 1 to 5\n");
		puts(WARNBAR);
	}
	if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE2, &val, 1) < 0) {
		puts("i2c pmic ECC_SE2 register read failed\n");
		return 0;
	}
	if (val & PFUZE100_BITS_ECC_SE2) {
		puts(WARNBAR);
		puts("WARNING: ecc has made bit corrections in banks 6 to 10\n"
		    );
		puts(WARNBAR);
	}
	if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE1, &val, 1) < 0) {
		puts("i2c pmic ECC_DE register read failed\n");
		return 0;
	}
	if (val & PFUZE100_BITS_ECC_DE1) {
		puts(WARNBAR);
		puts("ERROR: banks 1 to 5 have uncorrectable bits\n");
		puts(WARNBAR);
	}
	if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE2, &val, 1) < 0) {
		puts("i2c pmic ECC_DE register read failed\n");
		return 0;
	}
	if (val & PFUZE100_BITS_ECC_DE2) {
		puts(WARNBAR);
		puts("ERROR: banks 6 to 10 have uncorrectable bits\n");
		puts(WARNBAR);
	}

	/* get device ident */
	if (dm_i2c_read(dev, PFUZE100_DEVICEID, &devid, 1) < 0) {
		puts("i2c pmic devid read failed\n");
		return 0;
	}
	if (dm_i2c_read(dev, PFUZE100_REVID, &revid, 1) < 0) {
		puts("i2c pmic revid read failed\n");
		return 0;
	}
	printf("device id: 0x%.2x, revision id: 0x%.2x, ", devid, revid);

	/* get device programmed state */
	val = PFUZE100_PAGE_REGISTER_PAGE1;
	if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) {
		puts("i2c write failed\n");
		return 0;
	}
	if (dm_i2c_read(dev, PFUZE100_FUSE_POR1, &val, 1) < 0) {
		puts("i2c fuse_por read failed\n");
		return 0;
	}
	if (val & PFUZE100_FUSE_POR_M)
		programmed++;

	if (dm_i2c_read(dev, PFUZE100_FUSE_POR2, &val, 1) < 0) {
		puts("i2c fuse_por read failed\n");
		return programmed;
	}
	if (val & PFUZE100_FUSE_POR_M)
		programmed++;

	if (dm_i2c_read(dev, PFUZE100_FUSE_POR3, &val, 1) < 0) {
		puts("i2c fuse_por read failed\n");
		return programmed;
	}
	if (val & PFUZE100_FUSE_POR_M)
		programmed++;

	switch (programmed) {
	case 0:
		puts("not programmed\n");
		break;
	case 3:
		puts("programmed\n");
		break;
	default:
		puts("undefined programming state\n");
		break;
	}

#ifdef DEBUG
	{
		unsigned int i, j;

		for (i = 0; i < 16; i++)
			printf("\t%x", i);
		for (j = 0; j < 0x80; ) {
			printf("\n%2x", j);
			for (i = 0; i < 16; i++) {
				dm_i2c_read(dev, j + i, &val, 1);
				printf("\t%2x", val);
			}
			j += 0x10;
		}
		printf("\nEXT Page 1");

		val = PFUZE100_PAGE_REGISTER_PAGE1;
		if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) {
			puts("i2c write failed\n");
			return 0;
		}

		for (j = 0x80; j < 0x100; ) {
			printf("\n%2x", j);
			for (i = 0; i < 16; i++) {
				dm_i2c_read(dev, j + i, &val, 1);
				printf("\t%2x", val);
			}
			j += 0x10;
		}
		printf("\nEXT Page 2");

		val = PFUZE100_PAGE_REGISTER_PAGE2;
		if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) {
			puts("i2c write failed\n");
			return 0;
		}

		for (j = 0x80; j < 0x100; ) {
			printf("\n%2x", j);
			for (i = 0; i < 16; i++) {
				dm_i2c_read(dev, j + i, &val, 1);
				printf("\t%2x", val);
			}
			j += 0x10;
		}
		printf("\n");
	}
#endif /* DEBUG */

	return programmed;
}

#ifndef CONFIG_SPL_BUILD
static int pf0100_prog(void)
{
	int rc;
	struct udevice *dev = NULL;
	unsigned char bus = 1;
	unsigned char val;
	unsigned int i;

	if (pmic_init() == 3) {
		puts("PMIC already programmed, exiting\n");
		return CMD_RET_FAILURE;
	}
	/* set up gpio to manipulate vprog, initially off */
	imx_iomux_v3_setup_multiple_pads(pmic_prog_pads,
					 ARRAY_SIZE(pmic_prog_pads));
	gpio_direction_output(PMIC_PROG_VOLTAGE, 0);

	rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev);
	if (rc) {
		printf("failed to get device for PMIC at address 0x%x\n",
		       PFUZE100_I2C_ADDR);
		return CMD_RET_FAILURE;
	}

	for (i = 0; i < ARRAY_SIZE(pmic_otp_prog); i++) {
		switch (pmic_otp_prog[i].cmd) {
		case pmic_i2c:
			val = (unsigned char) (pmic_otp_prog[i].value & 0xff);
			if (dm_i2c_write(dev, pmic_otp_prog[i].reg, &val, 1)) {
				printf("i2c write failed, reg 0x%2x, value 0x%2x\n",
				       pmic_otp_prog[i].reg, val);
				return CMD_RET_FAILURE;
			}
			break;
		case pmic_delay:
			udelay(pmic_otp_prog[i].value * 1000);
			break;
		case pmic_vpgm:
			gpio_direction_output(PMIC_PROG_VOLTAGE,
					      pmic_otp_prog[i].value);
			break;
		case pmic_pwr:
			/* TODO */
			break;
		}
	}
	return CMD_RET_SUCCESS;
}

static int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
		char * const argv[])
{
	int ret;
	puts("Programming PMIC OTP...");
	ret = pf0100_prog();
	if (ret == CMD_RET_SUCCESS)
		puts("done.\n");
	else
		puts("failed.\n");
	return ret;
}

U_BOOT_CMD(
	pf0100_otp_prog, 1, 0, do_pf0100_prog,
	"Program the OTP fuses on the PMIC PF0100",
	""
);
#endif /* CONFIG_SPL_BUILD */
