/*
 * drivers/display/lcd/lcd_bl_ldim/ldim_drv.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the named License,
 * or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 */

#include <common.h>
#include <malloc.h>
#include <asm/arch/gpio.h>
#ifdef CONFIG_OF_LIBFDT
#include <libfdt.h>
#endif
#include <amlogic/aml_lcd.h>
#include <amlogic/aml_ldim.h>
#include "../aml_lcd_reg.h"
#include "../aml_lcd_common.h"
#include "ldim_drv.h"

#define LD_DATA_MIN           10
#define LDIM_BRI_LEVEL_MAX    0xfff
#define LDIM_BRI_LEVEL_MIN    0x7f
static unsigned int ldim_blk_row = 1;
static unsigned int ldim_blk_col = 8;
static struct aml_ldim_driver_s ldim_driver;

static int ldim_on_flag;
static int ldim_level;
static int ldim_set_level(unsigned int level);

static int ldim_power_on(void)
{
	if (ldim_driver.device_power_on) {
		ldim_driver.device_power_on();
		ldim_on_flag = 1;
	}
	if (ldim_level > 0)
		ldim_set_level(ldim_level);

	return 0;
}
static int ldim_power_off(void)
{
	ldim_on_flag = 0;
	if (ldim_driver.device_power_off)
		ldim_driver.device_power_off();

	return 0;
}

static void ldim_brightness_update(unsigned int level)
{
	unsigned int size;
	unsigned int i;

	size = ldim_blk_row * ldim_blk_col;
	for (i = 0; i < size; i++)
		ldim_driver.ldim_matrix_buf[i] = (unsigned short)level;

	if (ldim_driver.device_bri_update)
		ldim_driver.device_bri_update(ldim_driver.ldim_matrix_buf, size);
	else
		LDIMPR("%s: device_bri_update is null\n", __func__);
}

static int ldim_set_level(unsigned int level)
{
	int ret = 0;
	struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
	unsigned int level_max, level_min;

	if (ldim_on_flag == 0) {
		ldim_level = level;
		return 0;
	}

	level_max = lcd_drv->bl_config->level_max;
	level_min = lcd_drv->bl_config->level_min;

	level = ((level - level_min) * (LD_DATA_MAX - LD_DATA_MIN)) /
		(level_max - level_min) + LD_DATA_MIN;
	level &= 0xfff;
	ldim_brightness_update(level);

	return ret;
}

static void ldim_config_print(void)
{
	struct bl_pwm_config_s *ld_pwm;

	LDIMPR("%s:\n", __func__);
	printf("valid_flag            = %d\n"
		"dev_index             = %d\n"
		"ldim_on_flag          = %d\n",
		ldim_driver.valid_flag,
		ldim_driver.dev_index,
		ldim_on_flag);
	if (ldim_driver.ldev_conf) {
		ld_pwm = &ldim_driver.ldev_conf->pwm_config;
		printf("dev_name              = %s\n"
			"cs_hold_delay         = %d\n"
			"cs_clk_delay          = %d\n"
			"en_gpio               = %d\n"
			"en_gpio_on            = %d\n"
			"en_gpio_off           = %d\n"
			"write_check           = %d\n"
			"dim_min               = 0x%03x\n"
			"dim_max               = 0x%03x\n"
			"cmd_size              = %d\n",
			ldim_driver.ldev_conf->name,
			ldim_driver.ldev_conf->cs_hold_delay,
			ldim_driver.ldev_conf->cs_clk_delay,
			ldim_driver.ldev_conf->en_gpio,
			ldim_driver.ldev_conf->en_gpio_on,
			ldim_driver.ldev_conf->en_gpio_off,
			ldim_driver.ldev_conf->write_check,
			ldim_driver.ldev_conf->dim_min,
			ldim_driver.ldev_conf->dim_max,
			ldim_driver.ldev_conf->cmd_size);
		if (ld_pwm->pwm_port < BL_PWM_MAX) {
			printf("pwm_port              = %d\n"
				"pwm_pol               = %d\n"
				"pwm_freq              = %d\n"
				"pwm_duty              = %d%%\n"
				"pinmux_flag           = %d\n",
				ld_pwm->pwm_port, ld_pwm->pwm_method,
				ld_pwm->pwm_freq, ld_pwm->pwm_duty,
				ld_pwm->pinmux_flag);
		}
	} else {
		printf("device config is null\n");
	}
}

static struct aml_ldim_driver_s ldim_driver = {
	.valid_flag = 0, /* default invalid, active when bl_ctrl_method=ldim */
	.dev_index = 0,
	.ldev_conf = NULL,
	.ldim_matrix_buf = NULL,
	.power_on = ldim_power_on,
	.power_off = ldim_power_off,
	.set_level = ldim_set_level,
	.config_print = ldim_config_print,
	.pinmux_ctrl = NULL,
	.device_power_on = NULL,
	.device_power_off = NULL,
	.device_bri_update = NULL,
};

struct aml_ldim_driver_s *aml_ldim_get_driver(void)
{
		return &ldim_driver;
}

#ifdef CONFIG_OF_LIBFDT
static int ldim_config_load_from_dts(char *dt_addr)
{
	struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
	int parent_offset;
	char *propdata;
	char propname[30];
	int child_offset;
	unsigned int index;

	parent_offset = fdt_path_offset(dt_addr, "/backlight");
	if (parent_offset < 0) {
		LDIMERR("not find /backlight node %s\n", fdt_strerror(parent_offset));
		return -1;
	}

	index = lcd_drv->lcd_config->backlight_index;
	sprintf(propname,"/backlight/backlight_%d", index);
	child_offset = fdt_path_offset(dt_addr, propname);
	if (child_offset < 0) {
		LDIMERR("not find %s node %s\n", propname, fdt_strerror(child_offset));
		return -1;
	}

	propdata = (char *)fdt_getprop(dt_addr, child_offset, "bl_ldim_region_row_col", NULL);
	if (propdata == NULL) {
		LDIMERR("failed to get bl_ldim_region_row_col\n");
		ldim_blk_row = 1;
		ldim_blk_col = 8;
	} else {
		ldim_blk_row = be32_to_cpup((u32*)propdata);
		ldim_blk_col = be32_to_cpup((((u32*)propdata)+1));
	}

	propdata = (char *)fdt_getprop(dt_addr, child_offset, "ldim_dev_index", NULL);
	if (propdata == NULL) {
		LDIMERR("failed to get ldim_dev_index\n");
		ldim_driver.dev_index = 0;
	} else {
		ldim_driver.dev_index = be32_to_cpup((u32*)propdata);
	}

	return 0;
}
#endif

int aml_ldim_probe(char *dt_addr, int flag)
{
	unsigned int size;
	int ret = -1;

	ldim_on_flag = 0;
	ldim_level = 0;

	switch (flag) {
	case 0: /* dts */
#ifdef CONFIG_OF_LIBFDT
		if (dt_addr) {
			if (lcd_debug_print_flag)
				LDIMPR("load ldim_config from dts\n");
			ldim_config_load_from_dts(dt_addr);
			ret = aml_ldim_device_probe(dt_addr);
		}
#endif
		break;
	case 1: /* bsp */
		LDIMPR("%s: not support bsp config\n", __func__);
		break;
	case 2: /* unifykey */
		LDIMPR("%s: not support unifykey config\n", __func__);
		break;
	default:
		break;
	}

	if (ret) {
		LDIMERR("%s failed\n", __func__);
		return ret;
	}

	size = ldim_blk_row * ldim_blk_col;
	ldim_driver.ldim_matrix_buf = (unsigned short *)malloc(sizeof(unsigned short) * size);
	if (ldim_driver.ldim_matrix_buf == NULL) {
		LDIMERR("ldim_matrix_buf malloc error\n");
		return -1;
	}

	ldim_driver.valid_flag = 1;

	LDIMPR("%s is ok\n", __func__);

	return ret;
}

