/*
 * drivers/display/lcd/lcd_bl_ldim/iw7019.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 <spi.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"
#include "ldim_dev_drv.h"

struct ldim_dev_config_s *ldim_dev_config;

struct ldim_spi_dev_info_s ldim_spi_dev = {
	.modalias = "ldim_dev",
	.mode = SPI_MODE_0,
	.max_speed_hz = 1000000, /* 1MHz */
	.bus_num = 0, /* SPI bus No. */
	.chip_select = 0, /* the device index on the spi bus */
	.wordlen = 8,
};


void ldim_set_gpio(int index, int value)
{
	int gpio;
	char *str;

	if (index >= BL_GPIO_NUM_MAX) {
		LDIMERR("%s: invalid index %d\n", __func__, index);
		return;
	} else {
		str = ldim_dev_config->gpio_name[index];
		gpio = aml_lcd_gpio_name_map_num(str);
	}
	switch (value) {
	case LCD_GPIO_OUTPUT_LOW:
	case LCD_GPIO_OUTPUT_HIGH:
		aml_lcd_gpio_set(gpio, value);
		break;
	case LCD_GPIO_INPUT:
	default:
		value = LCD_GPIO_INPUT;
		aml_lcd_gpio_set(gpio, value);
		break;
	}
	if (lcd_debug_print_flag)
		LDIMPR("set gpio %s[%d] value: %d\n", str, index, value);
}

unsigned int ldim_get_gpio(int index)
{
	int gpio;
	char *str;
	unsigned int value;

	if (index >= BL_GPIO_NUM_MAX) {
		LDIMERR("%s: invalid index %d\n", __func__, index);
		return -1;
	} else {
		str = ldim_dev_config->gpio_name[index];
		gpio = aml_lcd_gpio_name_map_num(str);
	}
	value = aml_lcd_gpio_input_get(gpio);
	return value;
}

static unsigned int pwm_reg[6] = {
	PWM_PWM_A,
	PWM_PWM_B,
	PWM_PWM_C,
	PWM_PWM_D,
	PWM_PWM_E,
	PWM_PWM_F,
};

void ldim_set_duty_pwm(struct bl_pwm_config_s *bl_pwm)
{
	unsigned int pwm_hi = 0, pwm_lo = 0;
	unsigned int port = bl_pwm->pwm_port;
	unsigned int vs[4], ve[4], sw, n, i;

	bl_pwm->pwm_level = bl_pwm->pwm_cnt * bl_pwm->pwm_duty / 100;

	LDIMPR("pwm port %d: duty=%d%%, duty_max=%d, duty_min=%d\n",
		bl_pwm->pwm_port, bl_pwm->pwm_duty,
		bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min);

	switch (bl_pwm->pwm_method) {
	case BL_PWM_POSITIVE:
		pwm_hi = bl_pwm->pwm_level;
		pwm_lo = bl_pwm->pwm_cnt - bl_pwm->pwm_level;
		break;
	case BL_PWM_NEGATIVE:
		pwm_lo = bl_pwm->pwm_level;
		pwm_hi = bl_pwm->pwm_cnt - bl_pwm->pwm_level;
		break;
	default:
		LDIMERR("port %d: invalid pwm_method %d\n",
			port, bl_pwm->pwm_method);
		break;
	}
	LDIMPR("port %d: pwm_cnt=%d, pwm_hi=%d, pwm_lo=%d\n",
		port, bl_pwm->pwm_cnt, pwm_hi, pwm_lo);

	switch (port) {
	case BL_PWM_A:
	case BL_PWM_B:
	case BL_PWM_C:
	case BL_PWM_D:
	case BL_PWM_E:
	case BL_PWM_F:
		lcd_cbus_write(pwm_reg[port], (pwm_hi << 16) | pwm_lo);
		break;
	case BL_PWM_VS:
		memset(vs, 0xffff, sizeof(unsigned int) * 4);
		memset(ve, 0xffff, sizeof(unsigned int) * 4);
		n = bl_pwm->pwm_freq;
		sw = (bl_pwm->pwm_cnt * 10 / n + 5) / 10;
		pwm_hi = (pwm_hi * 10 / n + 5) / 10;
		pwm_hi = (pwm_hi > 1) ? pwm_hi : 1;
		if (lcd_debug_print_flag)
			LDIMPR("n=%d, sw=%d, pwm_high=%d\n", n, sw, pwm_hi);
		for (i = 0; i < n; i++) {
			vs[i] = 1 + (sw * i);
			ve[i] = vs[i] + pwm_hi - 1;
			if (lcd_debug_print_flag)
				LDIMPR("vs[%d]=%d, ve[%d]=%d\n", i, vs[i], i, ve[i]);
		}
		lcd_vcbus_write(VPU_VPU_PWM_V0, (ve[0] << 16) | (vs[0]));
		lcd_vcbus_write(VPU_VPU_PWM_V1, (ve[1] << 16) | (vs[1]));
		lcd_vcbus_write(VPU_VPU_PWM_V2, (ve[2] << 16) | (vs[2]));
		lcd_vcbus_write(VPU_VPU_PWM_V3, (ve[3] << 16) | (vs[3]));
		break;
	default:
		break;
	}
}

/* set ldim pwm_vs */
static int ldim_pwm_pinmux_ctrl(int status)
{
	struct bl_pwm_config_s *ld_pwm = &ldim_dev_config->pwm_config;
	int i;

	if (ld_pwm->pwm_port >= BL_PWM_MAX)
		return 0;

	if (lcd_debug_print_flag)
		LDIMPR("%s: %d\n", __func__, status);

	if (status) {
		bl_pwm_ctrl(ld_pwm, 1);
		/* set pinmux */
		ld_pwm->pinmux_flag = 1;
		i = 0;
		while (i < LCD_PINMUX_NUM) {
			if (ld_pwm->pinmux_clr[i][0] == LCD_PINMUX_END)
				break;
			lcd_pinmux_clr_mask(ld_pwm->pinmux_clr[i][0],
				ld_pwm->pinmux_clr[i][1]);
			if (lcd_debug_print_flag) {
				LDIMPR("%s: port=%d, pinmux_clr=%d,0x%08x\n",
					__func__, ld_pwm->pwm_port,
					ld_pwm->pinmux_clr[i][0],
					ld_pwm->pinmux_clr[i][1]);
			}
			i++;
		}
		i = 0;
		while (i < LCD_PINMUX_NUM) {
			if (ld_pwm->pinmux_set[i][0] == LCD_PINMUX_END)
				break;
			lcd_pinmux_set_mask(ld_pwm->pinmux_set[i][0],
				ld_pwm->pinmux_set[i][1]);
			if (lcd_debug_print_flag) {
				LDIMPR("%s: port=%d, pinmux_set=%d,0x%08x\n",
					__func__, ld_pwm->pwm_port,
					ld_pwm->pinmux_set[i][0],
					ld_pwm->pinmux_set[i][1]);
			}
			i++;
		}
	} else {
		i = 0;
		while (i < LCD_PINMUX_NUM) {
			if (ld_pwm->pinmux_set[i][0] == LCD_PINMUX_END)
				break;
			lcd_pinmux_clr_mask(ld_pwm->pinmux_set[i][0],
				ld_pwm->pinmux_set[i][1]);
			if (lcd_debug_print_flag) {
				LDIMPR("%s: port=%d, pinmux_clr=%d,0x%08x\n",
					__func__, ld_pwm->pwm_port,
					ld_pwm->pinmux_set[i][0],
					ld_pwm->pinmux_set[i][1]);
			}
			i++;
		}
		ld_pwm->pinmux_flag = 0;

		bl_pwm_ctrl(ld_pwm, 0);
	}

	return 0;
}

#ifdef CONFIG_OF_LIBFDT
static int aml_ldim_pinmux_load_from_dts(char *dt_addr, struct ldim_dev_config_s *ldev_conf)
{
	int parent_offset;
	char *propdata;
	char propname[30];
	int i, temp, len = 0;
	int ret = 0;
	struct bl_pwm_config_s *ld_pwm = &ldev_conf->pwm_config;

	/* get pinmux */
	sprintf(propname, "/pinmux/%s_pin", ldim_dev_config->pinmux_name);
	parent_offset = fdt_path_offset(dt_addr, propname);
	if (parent_offset < 0) {
		LDIMERR("not find ldim_pwm_pin node\n");
		ld_pwm->pinmux_set[0][0] = LCD_PINMUX_END;
		ld_pwm->pinmux_set[0][1] = 0x0;
		ld_pwm->pinmux_clr[0][0] = LCD_PINMUX_END;
		ld_pwm->pinmux_clr[0][1] = 0x0;
		return -1;
	} else {
		propdata = (char *)fdt_getprop(dt_addr, parent_offset, "amlogic,setmask", &len);
		if (propdata == NULL) {
			LDIMERR("failed to get amlogic,setmask\n");
			ld_pwm->pinmux_set[0][0] = LCD_PINMUX_END;
			ld_pwm->pinmux_set[0][1] = 0x0;
		} else {
			temp = len / 8;
			for (i = 0; i < temp; i++) {
				ld_pwm->pinmux_set[i][0] = be32_to_cpup((((u32*)propdata)+2*i));
				ld_pwm->pinmux_set[i][1] = be32_to_cpup((((u32*)propdata)+2*i+1));
			}
			if (temp < (LCD_PINMUX_NUM - 1)) {
				ld_pwm->pinmux_set[temp][0] = LCD_PINMUX_END;
				ld_pwm->pinmux_set[temp][1] = 0x0;
			}
		}

		propdata = (char *)fdt_getprop(dt_addr, parent_offset, "amlogic,clrmask", &len);
		if (propdata == NULL) {
			LDIMERR("failed to get amlogic,clrmask\n");
			ld_pwm->pinmux_clr[0][0] = LCD_PINMUX_END;
			ld_pwm->pinmux_clr[0][1] = 0x0;
		} else {
			temp = len / 8;
			for (i = 0; i < temp; i++) {
				ld_pwm->pinmux_clr[i][0] = be32_to_cpup((((u32*)propdata)+2*i));
				ld_pwm->pinmux_clr[i][1] = be32_to_cpup((((u32*)propdata)+2*i+1));
			}
			if (temp < (LCD_PINMUX_NUM - 1)) {
				ld_pwm->pinmux_clr[temp][0] = LCD_PINMUX_END;
				ld_pwm->pinmux_clr[temp][1] = 0x0;
			}
		}
		if (lcd_debug_print_flag) {
			i = 0;
			while (i < LCD_PINMUX_NUM) {
				if (ld_pwm->pinmux_set[i][0] == LCD_PINMUX_END)
					break;
				LDIMPR("pinmux set: %d, 0x%08x\n",
				ld_pwm->pinmux_set[i][0], ld_pwm->pinmux_set[i][1]);
				i++;
			}
			i = 0;
			while (i < LCD_PINMUX_NUM) {
				if (ld_pwm->pinmux_clr[i][0] == LCD_PINMUX_END)
					break;
				LDIMPR("pinmux clr: %d, 0x%08x\n",
				ld_pwm->pinmux_clr[i][0], ld_pwm->pinmux_clr[i][1]);
				i++;
			}
		}
	}

	return ret;
}
#endif

static int aml_ldim_pinmux_load_from_bsp(struct ldim_dev_config_s *ldev_conf)
{
	char propname[50] = "ldim_pwm_vs_pin";
	unsigned int i, j;
	int set_cnt = 0, clr_cnt = 0;
	struct bl_pwm_config_s *ld_pwm = &ldev_conf->pwm_config;

	for (i = 0; i < 2; i++) {
		if (strncmp(ldev_conf->ldim_pinmux->name, "invalid", 7) == 0)
			break;
		if (strncmp(ldev_conf->ldim_pinmux->name, propname, strlen(propname)) == 0) {
			for (j = 0; j < LCD_PINMUX_NUM; j++ ) {
				if (ldev_conf->ldim_pinmux->pinmux_set[j][0] == LCD_PINMUX_END)
					break;
				ld_pwm->pinmux_set[j][0] = ldev_conf->ldim_pinmux->pinmux_set[j][0];
				ld_pwm->pinmux_set[j][1] = ldev_conf->ldim_pinmux->pinmux_set[j][1];
				set_cnt++;
			}
			for (j = 0; j < LCD_PINMUX_NUM; j++ ) {
				if (ldev_conf->ldim_pinmux->pinmux_clr[j][0] == LCD_PINMUX_END)
					break;
				ld_pwm->pinmux_clr[j][0] = ldev_conf->ldim_pinmux->pinmux_clr[j][0];
				ld_pwm->pinmux_clr[j][1] = ldev_conf->ldim_pinmux->pinmux_clr[j][1];
				clr_cnt++;
			}
			break;
		}
		ldev_conf->ldim_pinmux++;
	}
	if (set_cnt < LCD_PINMUX_NUM) {
		ld_pwm->pinmux_set[set_cnt][0] = LCD_PINMUX_END;
		ld_pwm->pinmux_set[set_cnt][1] = 0x0;
	}
	if (clr_cnt < LCD_PINMUX_NUM) {
		ld_pwm->pinmux_clr[clr_cnt][0] = LCD_PINMUX_END;
		ld_pwm->pinmux_clr[clr_cnt][1] = 0x0;
	}

	if (lcd_debug_print_flag) {
		i = 0;
		while (i < LCD_PINMUX_NUM) {
			if (ld_pwm->pinmux_set[i][0] == LCD_PINMUX_END)
				break;
			LDIMPR("ldim_pinmux set: %d, 0x%08x\n",
				ld_pwm->pinmux_set[i][0], ld_pwm->pinmux_set[i][1]);
			i++;
		}
		i = 0;
		while (i < LCD_PINMUX_NUM) {
			if (ld_pwm->pinmux_clr[i][0] == LCD_PINMUX_END)
				break;
			LDIMPR("ldim_pinmux clr: %d, 0x%08x\n",
				ld_pwm->pinmux_clr[i][0], ld_pwm->pinmux_clr[i][1]);
			i++;
		}
	}

	return 0;
}

#ifdef CONFIG_OF_LIBFDT
static int ldim_dev_get_config_from_dts(char *dt_addr, int index)
{
	int parent_offset, child_offset;
	char propname[30];
	char *propdata;
	char *p;
	const char *str;
	unsigned char cmd_size;
	int temp;
	struct bl_pwm_config_s *ld_pwm = &ldim_dev_config->pwm_config;
	struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
	int i, j;
	int ret = 0;

	strcpy(ldim_dev_config->name, "ldim_dev");
	memset(ldim_dev_config->init_on, 0, LDIM_SPI_INIT_ON_SIZE);
	memset(ldim_dev_config->init_off, 0, LDIM_SPI_INIT_OFF_SIZE);
	ldim_dev_config->init_on[0] = 0xff;
	ldim_dev_config->init_off[0] = 0xff;

	if (dt_addr == NULL) {
		LDIMERR("%s: dt_addr is NULL\n", __func__);
		return -1;
	}

	parent_offset = fdt_path_offset(dt_addr, "/local_diming_device");
	if (parent_offset < 0) {
		LDIMERR("not find /local_diming_device node: %s\n",fdt_strerror(parent_offset));
		return -1;
	}
	propdata = (char *)fdt_getprop(dt_addr, parent_offset, "status", NULL);
	if (propdata == NULL) {
		LDIMERR("not find local_diming_device status, default to disabled\n");
		return -1;
	} else {
		if (strncmp(propdata, "okay", 2)) {
			LDIMPR("local_diming_device status disabled\n");
			return -1;
		}
	}

	/* init gpio */
	i = 0;
	propdata = (char *)fdt_getprop(dt_addr, parent_offset, "ldim_dev_gpio_names", NULL);
	if (propdata == NULL) {
		LDIMERR("failed to get ldim_dev_gpio_names\n");
	} else {
		p = propdata;
		while (i < BL_GPIO_NUM_MAX) {
			if (i > 0)
				p += strlen(p) + 1;
			str = p;
			if (strlen(str) == 0)
				break;
			strcpy(ldim_dev_config->gpio_name[i], str);
			if (lcd_debug_print_flag)
				LDIMPR("i=%d, gpio=%s\n", i, ldim_dev_config->gpio_name[i]);
			i++;
		}
	}
	for (j = i; j < BL_GPIO_NUM_MAX; j++) {
		strcpy(ldim_dev_config->gpio_name[j], "invalid");
	}

	/* get device config */
	sprintf(propname,"/local_diming_device/ldim_dev_%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, "ldim_dev_name", NULL);
	if (propdata == NULL)
		LDIMERR("failed to get ldim_dev_name\n");
	else
		strcpy(ldim_dev_config->name, propdata);
	LDIMPR("get config: %s(%d)\n", ldim_dev_config->name, index);

	propdata = (char *)fdt_getprop(dt_addr, child_offset, "ldim_pwm_port", NULL);
	if (propdata == NULL) {
		LDIMERR("failed to get ldim_pwm_port\n");
		ld_pwm->pwm_port = BL_PWM_MAX;
	} else {
		ld_pwm->pwm_port = bl_pwm_str_to_pwm(propdata);
	}
	LDIMPR("pwm_port: %s(%u)\n", propdata, ld_pwm->pwm_port);
	if (ld_pwm->pwm_port < BL_PWM_MAX) {
		propdata = (char *)fdt_getprop(dt_addr, child_offset, "ldim_pwm_attr", NULL);
		if (propdata == NULL) {
			LDIMERR("failed to get ldim_pwm_attr\n");
			ld_pwm->pwm_method = BL_PWM_POSITIVE;
			if (ld_pwm->pwm_port == BL_PWM_VS)
				ld_pwm->pwm_freq = 1;
			else
				ld_pwm->pwm_freq = 60;
			ld_pwm->pwm_duty = 50;
		} else {
			ld_pwm->pwm_method = be32_to_cpup((u32*)propdata);
			ld_pwm->pwm_freq = be32_to_cpup((((u32*)propdata)+1));
			ld_pwm->pwm_duty = be32_to_cpup((((u32*)propdata)+2));
		}
		if (ld_pwm->pwm_port == BL_PWM_VS) {
			if (ld_pwm->pwm_freq > 4) {
				LDIMERR("pwm_vs wrong freq %d\n", ld_pwm->pwm_freq);
				ld_pwm->pwm_freq = BL_FREQ_VS_DEFAULT;
			}
		} else {
			if (ld_pwm->pwm_freq > XTAL_HALF_FREQ_HZ)
				ld_pwm->pwm_freq = XTAL_HALF_FREQ_HZ;
		}
		LDIMPR("get pwm pol = %d, freq = %d, duty = %d%%\n",
			ld_pwm->pwm_method, ld_pwm->pwm_freq, ld_pwm->pwm_duty);
	}

	propdata = (char *)fdt_getprop(dt_addr, child_offset, "en_gpio_on_off", NULL);
	if (propdata == NULL) {
		LDIMERR("failed to get en_gpio_on_off\n");
	} else {
		ldim_dev_config->en_gpio = be32_to_cpup((u32*)propdata);
		ldim_dev_config->en_gpio_on = be32_to_cpup((((u32*)propdata)+1));
		ldim_dev_config->en_gpio_off = be32_to_cpup((((u32*)propdata)+2));
	}
	if (lcd_debug_print_flag) {
		LDIMPR("en_gpio=%s(%d), en_gpio_on=%d, en_gpio_off=%d\n",
		ldim_dev_config->gpio_name[ldim_dev_config->en_gpio],
		ldim_dev_config->en_gpio, ldim_dev_config->en_gpio_on,
		ldim_dev_config->en_gpio_off);
	}

	propdata = (char *)fdt_getprop(dt_addr, child_offset, "dim_max_min", NULL);
	if (propdata == NULL) {
		LDIMERR("failed to get dim_max_min\n");
	} else {
		ldim_dev_config->dim_max = be32_to_cpup((u32*)propdata);
		ldim_dev_config->dim_min = be32_to_cpup((((u32*)propdata)+1));
	}
	if (lcd_debug_print_flag) {
		LDIMPR("dim_max=0x%03x, dim_min=0x%03x\n",
		ldim_dev_config->dim_max, ldim_dev_config->dim_min);
	}

	propdata = (char *)fdt_getprop(dt_addr, child_offset, "type", NULL);
	if (propdata == NULL)
		LDIMERR("failed to get type\n");
	else {
		ldim_dev_config->type = be32_to_cpup((u32*)propdata);
		LDIMPR("type: %d\n", ldim_dev_config->type);
		}

	propdata = (char *)fdt_getprop(dt_addr, child_offset, "ldim_pwm_pinmux_sel", NULL);
	if (propdata == NULL)
		LDIMERR("failed to get ldim_pwm_name\n");
	else
		strcpy(ldim_dev_config->pinmux_name, propdata);
	LDIMPR("ldim_pwm_pinmux_sel: %s\n", ldim_dev_config->pinmux_name);

	if (ldim_dev_config->type >= LDIM_DEV_TYPE_MAX) {
		LDIMERR("type num is out of support\n");
		return -1;
	}

	switch (ldim_dev_config->type) {
	case LDIM_DEV_TYPE_SPI:
		ldim_drv->spi_dev = &ldim_spi_dev;
		/* get spi config */
		/*
		propdata = (char *)fdt_getprop(dt_addr, parent_offset, "spi_bus_num", NULL);
		if (propdata == NULL)
			LDIMERR("failed to get spi_bus_num\n");
		else
			ldim_spi_dev.bus_num = be32_to_cpup((u32*)propdata);
		*/

		ldim_spi_dev.bus_num = 0; /* fix value */
		propdata = (char *)fdt_getprop(dt_addr, child_offset, "spi_chip_select", NULL);
		if (propdata == NULL)
			LDIMERR("failed to get spi_chip_select\n");
		else
			ldim_spi_dev.chip_select = be32_to_cpup((u32*)propdata);

		propdata = (char *)fdt_getprop(dt_addr, child_offset, "spi_max_frequency", NULL);
		if (propdata == NULL)
			LDIMERR("failed to get spi_max_frequency\n");
		else
			ldim_spi_dev.max_speed_hz = be32_to_cpup((u32*)propdata);

		propdata = (char *)fdt_getprop(dt_addr, child_offset, "spi_mode", NULL);
		if (propdata == NULL)
			LDIMERR("failed to get spi_mode\n");
		else
			ldim_spi_dev.mode = be32_to_cpup((u32*)propdata);

		if (lcd_debug_print_flag) {
			LDIMPR("spi bus_num=%d, chip_select=%d, max_frequency=%d, mode=%d\n",
				ldim_spi_dev.bus_num, ldim_spi_dev.chip_select,
				ldim_spi_dev.max_speed_hz, ldim_spi_dev.mode);
		}

		propdata = (char *)fdt_getprop(dt_addr, child_offset, "spi_cs_delay", NULL);
		if (propdata == NULL) {
			LDIMERR("failed to get spi_cs_delay\n");
		} else {
			ldim_dev_config->cs_hold_delay = be32_to_cpup((u32*)propdata);
			ldim_dev_config->cs_clk_delay = be32_to_cpup((((u32*)propdata)+1));
		}
		if (lcd_debug_print_flag) {
			LDIMPR("cs_hold_delay=%dus, cs_clk_delay=%dus\n",
				ldim_dev_config->cs_hold_delay, ldim_dev_config->cs_clk_delay);
		}

		propdata = (char *)fdt_getprop(dt_addr, child_offset, "spi_write_check", NULL);
		if (propdata == NULL)
			LDIMERR("failed to get spi_write_check\n");
		else
			ldim_dev_config->write_check = (unsigned char)(be32_to_cpup((u32*)propdata));
		if (lcd_debug_print_flag)
			LDIMPR("write_check=%d\n", ldim_dev_config->write_check);

		/* get init_cmd */
		propdata = (char *)fdt_getprop(dt_addr, child_offset, "cmd_size", NULL);
		if (propdata == NULL) {
			LDIMERR("failed to get cmd_size\n");
		} else {
			temp = be32_to_cpup((u32*)propdata);
			if (temp > 1)
				ldim_dev_config->cmd_size = (unsigned char)temp;
			else
				ldim_dev_config->cmd_size = 1;
		}
		if (lcd_debug_print_flag)
			LDIMPR("cmd_size=%d\n", ldim_dev_config->cmd_size);
		cmd_size = ldim_dev_config->cmd_size;
		if (cmd_size > 1) {
			propdata = (char *)fdt_getprop(dt_addr, child_offset, "init_on", NULL);
			if (propdata == NULL) {
				LDIMPR("no init_on\n");
				ldim_dev_config->init_on[0] = 0xff;
			} else {
				i = 0;
				while (i < LDIM_SPI_INIT_ON_SIZE) {
					for (j = 0; j < cmd_size; j++) {
						ldim_dev_config->init_on[i+j] =
							(unsigned char)(be32_to_cpup((((u32*)propdata)+i+j)));
					}
					if (ldim_dev_config->init_on[i] == 0xff)
						break;
					else
						i += cmd_size;
				}
			}
			propdata = (char *)fdt_getprop(dt_addr, child_offset, "init_off", NULL);
			if (propdata == NULL) {
				LDIMPR("no init_off\n");
				ldim_dev_config->init_off[0] = 0xff;
			} else {
				i = 0;
				while (i < LDIM_SPI_INIT_OFF_SIZE) {
					for (j = 0; j < cmd_size; j++) {
						ldim_dev_config->init_off[i+j] =
							(unsigned char)(be32_to_cpup((((u32*)propdata)+i+j)));
					}
					if (ldim_dev_config->init_off[i] == 0xff)
						break;
					else
						i += cmd_size;
				}
			}
		}
		break;
	case LDIM_DEV_TYPE_I2C:
		break;
	case LDIM_DEV_TYPE_NORMAL:
	default:
		break;
	}

	/* pinmux */
	/* new kernel dts pinctrl detect */
	propdata = (char *)fdt_getprop(dt_addr, parent_offset, "pinctrl_version", NULL);
	if (propdata)
		ldim_dev_config->pinctrl_ver = (unsigned char)(be32_to_cpup((u32*)propdata));
	LDIMPR("pinctrl_version: %d\n", ldim_dev_config->pinctrl_ver);

	switch (ldim_dev_config->pinctrl_ver) {
	case 0:
		ret = aml_ldim_pinmux_load_from_dts(dt_addr, ldim_drv->ldev_conf);
		break;
	case 1:
		ret = aml_ldim_pinmux_load_from_bsp(ldim_drv->ldev_conf);
		break;
	default:
		ret = aml_ldim_pinmux_load_from_dts(dt_addr, ldim_drv->ldev_conf);
		break;
	}

	return ret;
}
#endif

static int ldim_dev_add_driver(struct ldim_dev_config_s *ldev_conf, int index)
{
	int ret = -1;

#ifdef CONFIG_AML_SPICC
	if (strcmp(ldev_conf->name, "iw7019") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_IW7019
		ret = ldim_dev_iw7019_probe();
#endif
		goto ldim_dev_add_driver_next;
	}

	if (strcmp(ldev_conf->name, "iw7027") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_IW7027
		ret = ldim_dev_iw7027_probe();
#endif

		goto ldim_dev_add_driver_next;
	}

#else
	LDIMERR("%s: no AML_SPICC config\n", __func__);
	ret = -1;
#endif

	if (strcmp(ldev_conf->name, "ob3350") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_OB3350
		ret = ldim_dev_ob3350_probe();
#endif
		goto ldim_dev_add_driver_next;
	}

	if (strcmp(ldev_conf->name, "global") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_GLOBAL
		ret = ldim_dev_global_probe();
#endif
		goto ldim_dev_add_driver_next;
	}

	LDIMERR("invalid device name: %s\n", ldev_conf->name);
	ret = -1;

ldim_dev_add_driver_next:
	if (ret) {
		LDIMERR("add device driver failed %s(%d)\n",
			ldev_conf->name, index);
	} else {
		LDIMPR("add device driver %s(%d)\n", ldev_conf->name, index);
	}

	return ret;
}

static int ldim_dev_remove_driver(struct ldim_dev_config_s *ldev_conf,
		int index)
{
	int ret = -1;

#ifdef CONFIG_AML_SPICC
	if (strcmp(ldev_conf->name, "iw7019") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_IW7019
		ret = ldim_dev_iw7019_remove();
#endif
		goto ldim_dev_remove_driver_next;
	}

	if (strcmp(ldev_conf->name, "iw7027") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_IW7027
		ret = ldim_dev_iw7027_remove();
#endif
		goto ldim_dev_remove_driver_next;
	}

#else
	LDIMERR("%s: no AML_SPICC config\n", __func__);
	ret = -1;
#endif

	if (strcmp(ldev_conf->name, "ob3350") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_OB3350
		ret = ldim_dev_ob3350_remove();
#endif
		goto ldim_dev_remove_driver_next;
	}

	if (strcmp(ldev_conf->name, "global") == 0) {
#ifdef CONFIG_AML_LOCAL_DIMMING_GLOBAL
		ret = ldim_dev_global_remove();
#endif
		goto ldim_dev_remove_driver_next;
	}

	LDIMERR("invalid device name: %s\n", ldev_conf->name);
	ret = -1;

ldim_dev_remove_driver_next:
	if (ret) {
		LDIMERR("add device driver failed %s(%d)\n",
			ldev_conf->name, index);
	} else {
		LDIMPR("add device driver %s(%d)\n", ldev_conf->name, index);
	}

	return ret;
}

int aml_ldim_device_probe(char *dt_addr)
{
	struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
	int ret = 0;

	/* get configs */
	ldim_dev_config = &ldim_config_dft;
	ldim_drv->ldev_conf = ldim_dev_config;
	ldim_drv->pinmux_ctrl = ldim_pwm_pinmux_ctrl;

#ifdef CONFIG_OF_LIBFDT
	ret = ldim_dev_get_config_from_dts(dt_addr, ldim_drv->dev_index);
	if (ret)
		return -1;
#endif

	/* add device driver */
	ret = ldim_dev_add_driver(ldim_drv->ldev_conf, ldim_drv->dev_index);

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

	return ret;
}

int aml_ldim_device_remove(void)
{
	struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
	int ret = 0;

	ldim_dev_remove_driver(ldim_drv->ldev_conf, ldim_drv->dev_index);

	return ret;
}

