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

/*
 * 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 */

/* use Apalis GPIO1 to switch on VPGM, ON: 1 */
static iomux_v3_cfg_t const pmic_prog_pads[] = {
	MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
#	define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 4)
};

unsigned pmic_init(void)
{
	unsigned programmed = 0;
	uchar bus = 1;
	uchar devid, revid, val;

	puts("PMIC: ");
	if (!((0 == i2c_set_bus_num(bus)) &&
	      (0 == i2c_probe(PFUZE100_I2C_ADDR)))) {
		puts("i2c bus failed\n");
		return 0;
	}
	/* get device ident */
	if (i2c_read(PFUZE100_I2C_ADDR, PFUZE100_DEVICEID, 1, &devid, 1) < 0) {
		puts("i2c pmic devid read failed\n");
		return 0;
	}
	if (i2c_read(PFUZE100_I2C_ADDR, PFUZE100_REVID, 1, &revid, 1) < 0) {
		puts("i2c pmic revid read failed\n");
		return 0;
	}
	printf("device id: 0x%.2x, revision id: 0x%.2x\n", devid, revid);

#ifdef DEBUG
	{
		unsigned 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++) {
				i2c_read(PFUZE100_I2C_ADDR, j+i, 1, &val, 1);
				printf("\t%2x", val);
			}
			j += 0x10;
		}
		printf("\nEXT Page 1");

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

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

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

		for (j = 0x80; j < 0x100; ) {
			printf("\n%2x", j);
			for (i = 0; i < 16; i++) {
				i2c_read(PFUZE100_I2C_ADDR, j+i, 1, &val, 1);
				printf("\t%2x", val);
			}
			j += 0x10;
		}
		printf("\n");
	}
#endif
	/* get device programmed state */
	val = PFUZE100_PAGE_REGISTER_PAGE1;
	if (i2c_write(PFUZE100_I2C_ADDR, PFUZE100_PAGE_REGISTER, 1, &val, 1)) {
		puts("i2c write failed\n");
		return 0;
	}
	if (i2c_read(PFUZE100_I2C_ADDR, PFUZE100_FUSE_POR1, 1, &val, 1) < 0) {
		puts("i2c fuse_por read failed\n");
		return 0;
	}
	if (val & PFUZE100_FUSE_POR_M)
		programmed++;

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

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

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

	/* The following is needed during production */
	if (programmed != 3) {
		/* set VGEN1 to 1.2V */
		val = PFUZE100_VGEN1_VAL;
		if (i2c_write(PFUZE100_I2C_ADDR, PFUZE100_VGEN1CTL, 1,
			      &val, 1)) {
			puts("i2c write failed\n");
			return programmed;
		}

		/* set SWBST to 5.0V */
		val = PFUZE100_SWBST_VAL;
		if (i2c_write(PFUZE100_I2C_ADDR, PFUZE100_SWBSTCTL, 1,
			      &val, 1)) {
			puts("i2c write failed\n");
		}
	}
	return programmed;
}

int pf0100_prog(void)
{
	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);

	if (!((0 == i2c_set_bus_num(bus)) &&
	      (0 == i2c_probe(PFUZE100_I2C_ADDR)))) {
		puts("i2c bus failed\n");
		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 (i2c_write(PFUZE100_I2C_ADDR, pmic_otp_prog[i].reg,
				      1, &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;
}

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",
	""
);
