diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c index e6cac94fb745..3bea1910cce2 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c @@ -58,7 +58,7 @@ static int iw7027_spi_op_flag; static DEFINE_MUTEX(iw7027_spi_mutex); -struct iw7027 { +struct iw7027_s { int test_mode; struct spi_device *spi; int cs_hold_delay; @@ -67,10 +67,11 @@ struct iw7027 { unsigned char *init_data; struct class cls; }; -struct iw7027 *bl_iw7027; +struct iw7027_s *bl_iw7027; -static int test_brightness[] = {0xfff, 0xfff, 0xfff, 0xfff, - 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff +static int test_brightness[] = { + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, }; static int iw7027_wreg(struct spi_device *spi, u8 addr, u8 val) @@ -99,13 +100,12 @@ static int iw7027_wreg(struct spi_device *spi, u8 addr, u8 val) static int iw7027_rreg(struct spi_device *spi, u8 addr, u8 *val) { - u8 tbuf[3]; + u8 tbuf[3], temp; int ret; - if (addr >= 0x80) - iw7027_wreg(bl_iw7027->spi, 0x78, 0x80); - else - iw7027_wreg(bl_iw7027->spi, 0x78, 0x0); + /* page select */ + temp = (addr >= 0x80) ? 0x80 : 0x0; + iw7027_wreg(spi, 0x78, temp); mutex_lock(&iw7027_spi_mutex); @@ -174,8 +174,8 @@ static int iw7027_power_on_init(int flag) } iw7027_spi_op_flag = 1; -iw7027_power_reset_p: +iw7027_power_reset_p: for (i = 0; i < LDIM_SPI_INIT_ON_SIZE; i += bl_iw7027->cmd_size) { if (bl_iw7027->init_data[i] == 0xff) { if (bl_iw7027->init_data[i+3] > 0) @@ -200,38 +200,56 @@ iw7027_power_reset_p: static int iw7027_hw_init_on(void) { - int i, j; - unsigned char temp, reg_chk, reg_duty_chk; - + int i; + unsigned char reg_chk, reg_duty_chk; struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); + /* step 1: system power_on */ ldim_gpio_set(ldim_drv->ldev_conf->en_gpio, ldim_drv->ldev_conf->en_gpio_on); - mdelay(2); - - iw7027_wreg(bl_iw7027->spi, 0x00, 0x06); - ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config)); - ldim_drv->pinmux_ctrl(ldim_drv->ldev_conf->pinmux_name); - mdelay(100); - iw7027_rreg(bl_iw7027->spi, 0x00, ®_chk); - for (i = 1; i < 10; i++) { - iw7027_rreg(bl_iw7027->spi, 0x00, &temp); - if (temp != reg_chk) - goto iw7027_smr_end; + /* step 2: delay for internal logic stable */ + mdelay(10); + + /* step 3: SPI communication check */ + LDIMPR("%s: SPI Communication Check\n", __func__); + for (i = 1; i <= 10; i++) { + iw7027_wreg(bl_iw7027->spi, 0x00, 0x06); + iw7027_rreg(bl_iw7027->spi, 0x00, ®_chk); + if (reg_chk == 0x06) + break; + if (i == 10) { + LDIMERR("%s: SPI communication check error\n", + __func__); } + } + /* step 4: configure initial registers */ iw7027_power_on_init(IW7027_POWER_ON); - mdelay(500); - iw7027_wreg(bl_iw7027->spi, 0x00, 0x07); - iw7027_rreg(bl_iw7027->spi, 0xb3, ®_duty_chk); - if (reg_duty_chk == 0x05) { - for (j = 0; j < 20; j++) - iw7027_wreg(bl_iw7027->spi, (0x40 + j), 0x1f); - } -iw7027_smr_end: + /* step 5: supply stable vsync */ + ldim_drv->pinmux_ctrl(ldim_drv->ldev_conf->pinmux_name); + + /* step 6: delay for system clock and light bar PSU stable */ + msleep(520); + + /* step 7: start calibration */ + iw7027_wreg(bl_iw7027->spi, 0x00, 0x07); + msleep(200); + + /* step 8: calibration done or not */ + i = 0; + while (i++ < 1000) { + iw7027_rreg(bl_iw7027->spi, 0xb3, ®_duty_chk); + /*VDAC statue reg :FB1=[0x5] FB2=[0x50]*/ + /*The current platform using FB1*/ + if ((reg_duty_chk & 0xf) == 0x05) + break; + mdelay(1); + } + LDIMPR("%s: calibration done: [%d] = %x\n", __func__, i, reg_duty_chk); + iw7027_spi_op_flag = 0; return 0; @@ -257,46 +275,59 @@ static int iw7027_hw_init_off(void) static int iw7027_spi_dump_low(char *buf) { - int ret = 0; + int len = 0; unsigned int i; unsigned char val; + if (buf == NULL) + return len; + + len += sprintf(buf, "iw7027 reg low:\n"); for (i = 0; i <= 0x7f; i++) { iw7027_rreg(bl_iw7027->spi, i, &val); - if (buf) { - int n = sprintf(buf+ret, - "iw7027 reg 0x%02x=0x%02x\n", i, val); - ret += n; - } - pr_info("iw7027 reg 0x%02x=0x%02x\n", i, val); + len += sprintf(buf+len, " 0x%02x=0x%02x\n", i, val); } - if (buf) - ret += sprintf(buf, "\n"); - pr_info("\n"); + len += sprintf(buf+len, "\n"); - return ret; + return len; } static int iw7027_spi_dump_high(char *buf) { - int ret = 0; + int len = 0; unsigned int i; unsigned char val; + if (buf == NULL) + return len; + + len += sprintf(buf, "iw7027 reg high:\n"); for (i = 0x80; i <= 0xff; i++) { iw7027_rreg(bl_iw7027->spi, i, &val); - if (buf) { - int n = sprintf(buf+ret, - "iw7027 reg 0x%02x=0x%02x\n", i, val); - ret += n; - } - pr_info("iw7027 reg 0x%02x=0x%02x\n", i, val); + len += sprintf(buf+len, " 0x%02x=0x%02x\n", i, val); } - if (buf) - ret += sprintf(buf, "\n"); - pr_info("\n"); + len += sprintf(buf+len, "\n"); - return ret; + return len; +} + +static int iw7027_spi_dump_dim(char *buf) +{ + int len = 0; + unsigned int i; + unsigned char val; + + if (buf == NULL) + return len; + + len += sprintf(buf, "iw7027 reg dimming:\n"); + for (i = 0x40; i <= 0x54; i++) { + iw7027_rreg(bl_iw7027->spi, i, &val); + len += sprintf(buf+len, " 0x%02x=0x%02x\n", i, val); + } + len += sprintf(buf+len, "\n"); + + return len; } static unsigned int iw7027_get_value(unsigned int level) @@ -317,7 +348,7 @@ static int iw7027_smr(unsigned short *buf, unsigned char len) { int i, j; unsigned int value_flag = 0; - unsigned char val_0[20]; + unsigned char val[20]; if (iw7027_on_flag == 0) { if (ldim_debug_print) @@ -343,76 +374,56 @@ static int iw7027_smr(unsigned short *buf, unsigned char len) if (value_flag) { if (bl_iw7027->test_mode) { - val_0[0] = (test_brightness[0] & 0xf00) >> 8; - val_0[1] = test_brightness[0] & 0xff; - val_0[2] = (test_brightness[1] & 0xf00) >> 8; - val_0[3] = test_brightness[1] & 0xff; - val_0[4] = (test_brightness[2] & 0xf00) >> 8; - val_0[5] = test_brightness[2] & 0xff; - val_0[6] = (test_brightness[3] & 0xf00) >> 8; - val_0[7] = test_brightness[3] & 0xff; - val_0[8] = (test_brightness[4] & 0xf00) >> 8; - val_0[9] = test_brightness[4] & 0xff; - val_0[10] = (test_brightness[5] & 0xf00) >> 8; - val_0[11] = test_brightness[5] & 0xff; - val_0[12] = (test_brightness[6] & 0xf00) >> 8; - val_0[13] = test_brightness[6] & 0xff; - val_0[14] = (test_brightness[7] & 0xf00) >> 8; - val_0[15] = test_brightness[7] & 0xff; - val_0[16] = (test_brightness[8] & 0xf00) >> 8; - val_0[17] = test_brightness[8] & 0xff; - val_0[18] = (test_brightness[9] & 0xf00) >> 8; - val_0[19] = test_brightness[9] & 0xff; + val[0] = (test_brightness[0] & 0xf00) >> 8; + val[1] = test_brightness[0] & 0xff; + val[2] = (test_brightness[1] & 0xf00) >> 8; + val[3] = test_brightness[1] & 0xff; + val[4] = (test_brightness[2] & 0xf00) >> 8; + val[5] = test_brightness[2] & 0xff; + val[6] = (test_brightness[3] & 0xf00) >> 8; + val[7] = test_brightness[3] & 0xff; + val[8] = (test_brightness[4] & 0xf00) >> 8; + val[9] = test_brightness[4] & 0xff; + val[10] = (test_brightness[5] & 0xf00) >> 8; + val[11] = test_brightness[5] & 0xff; + val[12] = (test_brightness[6] & 0xf00) >> 8; + val[13] = test_brightness[6] & 0xff; + val[14] = (test_brightness[7] & 0xf00) >> 8; + val[15] = test_brightness[7] & 0xff; + val[16] = (test_brightness[8] & 0xf00) >> 8; + val[17] = test_brightness[8] & 0xff; + val[18] = (test_brightness[9] & 0xf00) >> 8; + val[19] = test_brightness[9] & 0xff; - iw7027_wregs(bl_iw7027->spi, 0x40, val_0, 20); + iw7027_wregs(bl_iw7027->spi, 0x40, val, 20); } else { - val_0[0] = ((iw7027_get_value(buf[0]) - ) & 0xf00) >> 8; - val_0[1] = (iw7027_get_value(buf[0]) - ) & 0xff; - val_0[2] = ((iw7027_get_value(buf[1]) - ) & 0xf00) >> 8; - val_0[3] = (iw7027_get_value(buf[1]) - ) & 0xff; - val_0[4] = ((iw7027_get_value(buf[2]) - ) & 0xf00) >> 8; - val_0[5] = (iw7027_get_value(buf[2]) - ) & 0xff; - val_0[6] = ((iw7027_get_value(buf[3]) - ) & 0xf00) >> 8; - val_0[7] = (iw7027_get_value(buf[3]) - ) & 0xff; - val_0[8] = ((iw7027_get_value(buf[4]) - ) & 0xf00) >> 8; - val_0[9] = (iw7027_get_value(buf[4]) - ) & 0xff; - val_0[10] = ((iw7027_get_value(buf[5]) - ) & 0xf00) >> 8; - val_0[11] = (iw7027_get_value(buf[5]) - ) & 0xff; - val_0[12] = ((iw7027_get_value(buf[6]) - ) & 0xf00) >> 8; - val_0[13] = (iw7027_get_value(buf[6]) - ) & 0xff; - val_0[14] = ((iw7027_get_value(buf[7]) - ) & 0xf00) >> 8; - val_0[15] = (iw7027_get_value(buf[7]) - ) & 0xff; - val_0[16] = ((iw7027_get_value(buf[8]) - ) & 0xf00) >> 8; - val_0[17] = (iw7027_get_value(buf[8]) - ) & 0xff; - val_0[18] = ((iw7027_get_value(buf[9]) - ) & 0xf00) >> 8; - val_0[19] = (iw7027_get_value(buf[9]) - ) & 0xff; + val[0] = ((iw7027_get_value(buf[0])) & 0xf00) >> 8; + val[1] = (iw7027_get_value(buf[0])) & 0xff; + val[2] = ((iw7027_get_value(buf[1])) & 0xf00) >> 8; + val[3] = (iw7027_get_value(buf[1])) & 0xff; + val[4] = ((iw7027_get_value(buf[2])) & 0xf00) >> 8; + val[5] = (iw7027_get_value(buf[2])) & 0xff; + val[6] = ((iw7027_get_value(buf[3])) & 0xf00) >> 8; + val[7] = (iw7027_get_value(buf[3])) & 0xff; + val[8] = ((iw7027_get_value(buf[4])) & 0xf00) >> 8; + val[9] = (iw7027_get_value(buf[4])) & 0xff; + val[10] = ((iw7027_get_value(buf[5])) & 0xf00) >> 8; + val[11] = (iw7027_get_value(buf[5])) & 0xff; + val[12] = ((iw7027_get_value(buf[6])) & 0xf00) >> 8; + val[13] = (iw7027_get_value(buf[6])) & 0xff; + val[14] = ((iw7027_get_value(buf[7])) & 0xf00) >> 8; + val[15] = (iw7027_get_value(buf[7])) & 0xff; + val[16] = ((iw7027_get_value(buf[8])) & 0xf00) >> 8; + val[17] = (iw7027_get_value(buf[8])) & 0xff; + val[18] = ((iw7027_get_value(buf[9])) & 0xf00) >> 8; + val[19] = (iw7027_get_value(buf[9])) & 0xff; - iw7027_wregs(bl_iw7027->spi, 0x40, val_0, 20); + iw7027_wregs(bl_iw7027->spi, 0x40, val, 20); } } else { for (j = 0; j < 20; j++) - val_0[j] = 0; - iw7027_wregs(bl_iw7027->spi, 0x40, val_0, 20); + val[j] = 0; + iw7027_wregs(bl_iw7027->spi, 0x40, val, 20); } iw7027_spi_op_flag = 0; @@ -445,7 +456,7 @@ static ssize_t iw7027_show(struct class *class, struct class_attribute *attr, char *buf) { struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); - struct iw7027 *bl = container_of(class, struct iw7027, cls); + struct iw7027_s *bl = container_of(class, struct iw7027_s, cls); int ret = 0; int i; @@ -497,7 +508,6 @@ static ssize_t iw7027_show(struct class *class, } else { LDIMERR("%s: wait spi idle state failed\n", __func__); } - ret += sprintf(buf, "\n"); } else if (!strcmp(attr->attr.name, "dump_high")) { i = 1000; while ((iw7027_spi_op_flag) && (i > 0)) { @@ -511,7 +521,19 @@ static ssize_t iw7027_show(struct class *class, } else { LDIMERR("%s: wait spi idle state failed\n", __func__); } - ret += sprintf(buf, "\n"); + } else if (!strcmp(attr->attr.name, "dump_dim")) { + i = 1000; + while ((iw7027_spi_op_flag) && (i > 0)) { + i--; + udelay(10); + } + if (iw7027_spi_op_flag == 0) { + iw7027_spi_op_flag = 1; + ret = iw7027_spi_dump_dim(buf); + iw7027_spi_op_flag = 0; + } else { + LDIMERR("%s: wait spi idle state failed\n", __func__); + } } return ret; @@ -521,7 +543,7 @@ static ssize_t iw7027_show(struct class *class, static ssize_t iw7027_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { - struct iw7027 *bl = container_of(class, struct iw7027, cls); + struct iw7027_s *bl = container_of(class, struct iw7027_s, cls); unsigned int val, val2; unsigned char reg_addr, reg_val; int i; @@ -586,6 +608,7 @@ static struct class_attribute iw7027_class_attrs[] = { __ATTR(status, 0644, iw7027_show, NULL), __ATTR(dump_low, 0644, iw7027_show, NULL), __ATTR(dump_high, 0644, iw7027_show, NULL), + __ATTR(dump_dim, 0644, iw7027_show, NULL), __ATTR_NULL }; @@ -641,7 +664,7 @@ int ldim_dev_iw7027_probe(void) iw7027_on_flag = 0; iw7027_spi_op_flag = 0; - bl_iw7027 = kzalloc(sizeof(struct iw7027), GFP_KERNEL); + bl_iw7027 = kzalloc(sizeof(struct iw7027_s), GFP_KERNEL); if (bl_iw7027 == NULL) { LDIMERR("malloc bl_iw7027 failed\n"); return -1; diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.c b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.c index c9671c1fa599..3be0a1a98087 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.c @@ -56,6 +56,7 @@ const char ldim_dev_id[] = "ldim-dev"; static int ldim_on_flag; static unsigned int ldim_func_en; +static unsigned int ldim_remap_en; static unsigned int ldim_func_bypass; struct LDReg nPRM; @@ -2056,10 +2057,28 @@ static void ldim_set_matrix(unsigned int *data, unsigned int reg_sel, LDIM_WR_BASE_LUT(REG_LD_LUT_VDG_BASE, data, 16, cnt); } +static void ldim_remap_ctrl(int status) +{ + unsigned int temp; + + temp = ldim_matrix_update_en; + if (status) { + ldim_matrix_update_en = 0; + LDIM_WR_32Bits(0x0a, 0x706); + msleep(20); + ldim_matrix_update_en = temp; + } else { + ldim_matrix_update_en = 0; + LDIM_WR_32Bits(0x0a, 0x600); + msleep(20); + ldim_matrix_update_en = temp; + } + LDIMPR("%s: %d\n", __func__, status); +} + static void ldim_func_ctrl(int status) { if (status) { - /*ldim_remap_ctrl(ldim_matrix_update_en);*/ /* enable other flag */ ldim_top_en = 1; ldim_hist_en = 1; @@ -2067,7 +2086,11 @@ static void ldim_func_ctrl(int status) /* enable update */ ldim_avg_update_en = 1; /*ldim_matrix_update_en = 1;*/ + + ldim_remap_ctrl(ldim_remap_en); } else { + /* disable remap */ + ldim_remap_ctrl(0); /* disable update */ ldim_avg_update_en = 0; /*ldim_matrix_update_en = 0;*/ @@ -2075,12 +2098,11 @@ static void ldim_func_ctrl(int status) ldim_top_en = 0; ldim_hist_en = 0; ldim_alg_en = 0; - /* disable remap */ - /*ldim_remap_ctrl(0);*/ /* refresh system brightness */ ldim_level_update = 1; } + LDIMPR("%s: %d\n", __func__, status); } static int ldim_on_init(void) @@ -2382,19 +2404,19 @@ static ssize_t ldim_attr_store(struct class *cla, goto ldim_attr_store_end; } if (val1) { - ldim_matrix_update_en = 0; - LDIM_WR_32Bits(0x0a, 0x706); - msleep(20); - ldim_matrix_update_en = 1; + if (ldim_func_en) { + ldim_remap_en = 1; + ldim_remap_ctrl(1); + } else { + pr_info("error: ldim_func is disabled\n"); + } } else { - ldim_matrix_update_en = 0; - LDIM_WR_32Bits(0x0a, 0x600); - msleep(20); - ldim_matrix_update_en = 1; + ldim_remap_en = 0; + ldim_remap_ctrl(0); } - pr_info("ldim_remap_en: %d\n", (unsigned int)val1); + pr_info("ldim_remap_en: %d\n", ldim_remap_en); } else if (!strcmp(parm[0], "remap_get")) { - pr_info("ldim_remap_en: %d\n", ldim_matrix_update_en); + pr_info("ldim_remap_en: %d\n", ldim_remap_en); } else if (!strcmp(parm[0], "ldim_matrix_get")) { unsigned int data[32] = {0}; unsigned int k, g; @@ -2467,27 +2489,6 @@ static ssize_t ldim_attr_store(struct class *cla, ldim_data_min = (unsigned int)val1; ldim_set_level(ldim_brightness_level); pr_info("**********ldim brightness data_min update*********\n"); - } else if (!strcmp(parm[0], "ldim_info")) { - pr_info("ldim_on_flag = %d\n" - "ldim_func_en = %d\n" - "ldim_test_en = %d\n" - "ldim_avg_update_en = %d\n" - "ldim_matrix_update_en = %d\n" - "ldim_alg_en = %d\n" - "ldim_top_en = %d\n" - "ldim_hist_en = %d\n" - "ldim_data_min = %d\n" - "ldim_data_max = %d\n", - ldim_on_flag, ldim_func_en, ldim_test_en, - ldim_avg_update_en, ldim_matrix_update_en, - ldim_alg_en, ldim_top_en, ldim_hist_en, - ldim_data_min, LD_DATA_MAX); - pr_info("nPRM.reg_LD_BLK_Hnum = %d\n" - "nPRM.reg_LD_BLK_Vnum = %d\n" - "nPRM.reg_LD_pic_RowMax = %d\n" - "nPRM.reg_LD_pic_ColMax = %d\n", - nPRM.reg_LD_BLK_Hnum, nPRM.reg_LD_BLK_Vnum, - nPRM.reg_LD_pic_RowMax, nPRM.reg_LD_pic_ColMax); } else if (!strcmp(parm[0], "test_mode")) { if (parm[1] != NULL) { if (kstrtoul(parm[1], 10, &val1) < 0) @@ -2735,12 +2736,29 @@ static ssize_t ldim_attr_store(struct class *cla, pr_info("set avg_gain=%ld\n", avg_gain); } else if (!strcmp(parm[0], "info")) { ldim_driver.config_print(); - pr_info("ldim_on_flag = %d\n" + pr_info("\nldim_on_flag = %d\n" "ldim_func_en = %d\n" "ldim_remap_en = %d\n" - "ldim_test_en = %d\n\n", - ldim_on_flag, ldim_func_en, - ldim_matrix_update_en, ldim_test_en); + "ldim_func_bypass = %d\n" + "ldim_test_en = %d\n" + "ldim_avg_update_en = %d\n" + "ldim_matrix_update_en = %d\n" + "ldim_alg_en = %d\n" + "ldim_top_en = %d\n" + "ldim_hist_en = %d\n" + "ldim_data_min = %d\n" + "ldim_data_max = %d\n", + ldim_on_flag, ldim_func_en, ldim_remap_en, + ldim_func_bypass, ldim_test_en, + ldim_avg_update_en, ldim_matrix_update_en, + ldim_alg_en, ldim_top_en, ldim_hist_en, + ldim_data_min, LD_DATA_MAX); + pr_info("nPRM.reg_LD_BLK_Hnum = %d\n" + "nPRM.reg_LD_BLK_Vnum = %d\n" + "nPRM.reg_LD_pic_RowMax = %d\n" + "nPRM.reg_LD_pic_ColMax = %d\n", + nPRM.reg_LD_BLK_Hnum, nPRM.reg_LD_BLK_Vnum, + nPRM.reg_LD_pic_RowMax, nPRM.reg_LD_pic_ColMax); } else pr_info("no support cmd!!!\n"); @@ -2966,20 +2984,25 @@ int aml_ldim_probe(struct platform_device *pdev) unsigned int ldim_irq = 0, rdma_irq = 0; struct aml_bl_drv_s *bl_drv = aml_bl_get_driver(); - invalid_val_cnt = 0; - ldim_brightness_level = 0; - ldim_data_min = LD_DATA_MIN; + /* function flag */ ldim_on_flag = 0; ldim_func_en = 0; + ldim_remap_en = 0; ldim_func_bypass = 0; ldim_test_en = 0; + + ldim_brightness_level = 0; + ldim_data_min = LD_DATA_MIN; ldim_level_update = 0; + + /* alg flag */ ldim_avg_update_en = 0; ldim_matrix_update_en = 0; ldim_alg_en = 0; ldim_top_en = 0; ldim_hist_en = 0; avg_gain = LD_DATA_MAX; + invalid_val_cnt = 0; nPRM.val_1 = &val_1[0]; nPRM.bin_1 = &bin_1[0];