#include <common.h>
#include <dm.h>
#include <efi.h>
#include <fs.h>
#include <i2c.h>
#include <led_aw2015.h>
#include <linux/printk.h>
#include <linux/ctype.h>
#include <vsprintf.h>

DECLARE_GLOBAL_DATA_PTR;

// Copied from
// http://eureka-partner/I746d141b78040e0772a4c1f4111eb5afc12d70e6
// Reads "led_calibration_LUT.txt" from the factory partition.
// Forwards errors, returns 0 on success.
int get_cal_string(char *buf, int len)
{
	int ret;
	loff_t len_read;
	const loff_t seek = 21;

	ret = fs_set_blk_dev("mmc", "0:3", FS_TYPE_EXT);
	if (ret) {
		pr_err("LED: fs_set_blk_dev error=%d\n", ret);
		return ret;
	}
	// Leave space for terminator
	ret = fs_read("led_calibration_LUT.txt", (ulong) buf, seek, len - 1,
		      &len_read);
	if (ret) {
		pr_err("LED: fs_read error=%d\n", ret);
		return ret;
	}
	// fs_read does not add a null terminator
	buf[len_read] = '\0';

	return 0;
}

// Copied from
// http://eureka-partner/I746d141b78040e0772a4c1f4111eb5afc12d70e6
// Gets calibration settings for the status LED:
// pwm_r, pwm_g, pwm_b, current_r, current_g, current_b
// On failure, |settings| is not modified.
int get_cal_settings(unsigned int *settings, const char color_header[])
{
	int i;
	unsigned long settings_[N_CAL_SETTINGS];

	// Max length to cover all color lines
	// 4 colors * (color_name + ":4095:" + xxx[,|;|\n] * 6)
	// 4 * (14 + 6 + 4 * 6 )
	const int max_chars = 176;
	// Add one for null terminator
	char buf[max_chars + 1];
	int ret;

	ret = get_cal_string(buf, max_chars);
	if (ret != 0) {
		pr_err("LED: failed to get_cal_string\n");
		return ret;
	}

	char *p, *p_next;

	p = strstr(buf, color_header);
	if (!p) {
		pr_err("LED: \"%s\" not found in cal file segment: %s\n",
		       color_header, buf);
		return -1;
	}
	p += strlen(color_header);

	for (i = 0; i < N_CAL_SETTINGS; ++i) {
		unsigned long value = simple_strtoul(p, &p_next, 10);

		if (value > 255) {
			pr_err("LED: value %ld is too large\n",
			       settings_[i]);
			return -1;
		}
		settings_[i] = value;

		// Skip check that |p_next| is valid on last iteration
		if (i == 5)
			break;
		// Is there not a separator, or not another number
		if ((*p_next != ',' && *p_next != ';') ||
		    !isdigit(p_next[1])) {
			// Is this the first current
			if (i == 3) {
				// One current instead of RGB current
				settings_[4] = value;
				settings_[5] = value;
				break;
			}
			// Invalid
			pr_err("LED calibration file is malformed\n");
			return -1;
		}

		p = p_next + 1;
	}

	for (i = 0; i < N_CAL_SETTINGS; ++i)
		settings[i] = (unsigned int)settings_[i];

	return 0;
}

void reg_write(struct udevice *led_devp, int reg, int mask, int val) {
	int old_val;
	int new_val;

	old_val = dm_i2c_reg_read(led_devp, reg);
	if (old_val < 0) {
		pr_err("LED: read %d reg failed\n", reg);
		return;
	}
	new_val = (old_val & ~mask) | (val & mask);
	dm_i2c_reg_write(led_devp, reg, new_val);
}

void turn_on_white_led(struct udevice *led_devp) {
	/* default calibration settings */
	unsigned int cal_settings[N_CAL_SETTINGS] =
		{128, 128, 128, 100, 100, 100};
	int i;

	/* TODO(b/195092280 uncomment once the calibration file is ready) */
	if (get_cal_settings(cal_settings, "White:4095:")) {
		pr_err("LED: failed to get_cal_settings for white led\n");
		return;
	}
	for(i = 0; i < 3; ++i) {
		reg_write(led_devp, AW2015_REG_LCFG1 + i, AW2015_LED_LEDMD_MASK,
			AW2015_LED_ON_MODE);
		reg_write(led_devp, AW2015_REG_PWM1 + i, AW2015_LED_PWM_MASK,
			cal_settings[i]);
		reg_write(led_devp, AW2015_REG_ILED1 + i, AW2015_LED_ILED_MASK,
			cal_settings[3+i]);
        }
}

void enable_led_chip(void)
{
	int gpio_node;
	int led_enable_gpio;
	pr_info("%s\n", __func__);

	/* pull high the LED enabling ping */
	gpio_node = fdt_path_offset(gd->fdt_blob, "/led_enable_gpio");
	if (gpio_node >= 0) {
		qca_gpio_init(gpio_node);
		led_enable_gpio = fdtdec_get_int(gd->fdt_blob, gpio_node, "led_enable_gpio", 0);
		if (led_enable_gpio >= 0) {
			gpio_set_value(led_enable_gpio, GPIO_OUT_HIGH);
			pr_info("enabled LED pin %d\n", led_enable_gpio)	;
		}
	}
}

void sys_led_init(enum LED_ANIMATION led_animation)
{
	int ret;
	struct udevice *bus, *dev;

	enable_led_chip();

	ret = uclass_get_device_by_seq(UCLASS_I2C, BUS_NUM, &bus);
	if (ret) {
		pr_err("LED: i2c get bus failed\n");
		return;
	}
	ret = dm_i2c_probe(bus, I2C_LED_REG, 0, &dev);
	if (ret) {
		pr_err("LED: dm_i2c_probe failed\n");
		return;
	}

	reg_write(dev, AW2015_REG_RSTIDR, AW2015_LED_RSTIDR_MASK,
		  AW2015_LED_RSTIDR_RESET);
	reg_write(dev, AW2015_REG_GCR, AW2015_LED_CHIPEN_MASK,
		  AW2015_LED_CHIP_ENABLE);
	reg_write(dev, AW2015_REG_GCR, AW2015_LED_CHARGE_DISABLE_MASK,
		  AW2015_LED_CHARGE_DISABLE);
	reg_write(dev, AW2015_REG_IMAX, AW2015_LED_IMX_MASK,
		  AW2015_LED_12_75mA);
	reg_write(dev, AW2015_REG_LEDCTR, AW2015_LED_PWMLOG_MASK,
		  AW2015_LED_PWMLOG_LEANER);
	/* disable LEDs to avoid red lighting first */
	reg_write(dev, AW2015_REG_LEDEN, AW2015_LED_LEDEN_MASK,
		  AW2015_LED_LEDEN_TURN_OFF_ALL);

	switch(led_animation) {
	case WHITE:
		turn_on_white_led(dev);
		break;
	default:
		pr_err("LED: unknown led animation\n");
	}
	/* enable 3 LEDs at once after all set */
	reg_write(dev, AW2015_REG_LEDEN, AW2015_LED_LEDEN_MASK,
		  AW2015_LED_LEDEN_TURN_ON_ALL);
}
