From bd02e116145798daa5d1c7a415d2d9b225af5014 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Tue, 24 Jul 2018 11:17:55 +0800 Subject: [PATCH] backlight: ldim: add custome bl region num support for iw7027 PD#170488: ldim: add custome bl region num support for iw7027 Change-Id: If57cc7dd77f6143ce6c904716750c3edbfcbd546 Signed-off-by: Evoke Zhang --- .../media/vout/backlight/aml_ldim/iw7027_bl.c | 114 ++++++++++++++------- .../media/vout/backlight/aml_ldim/ldim_dev_drv.c | 9 +- include/linux/amlogic/media/vout/lcd/aml_ldim.h | 1 + 3 files changed, 86 insertions(+), 38 deletions(-) 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 53e572e..d3317fb 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c @@ -68,10 +68,8 @@ struct iw7027_s { }; struct iw7027_s *bl_iw7027; -static int test_brightness[] = { - 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, - 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, -}; +static unsigned short *test_brightness; +static unsigned char *val_brightness; static int iw7027_wreg(struct spi_device *spi, u8 addr, u8 val) { @@ -313,14 +311,16 @@ static int iw7027_spi_dump_high(char *buf) static int iw7027_spi_dump_dim(char *buf) { int len = 0; - unsigned int i; + unsigned int i, num; unsigned char val; + struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); if (buf == NULL) return len; len += sprintf(buf, "iw7027 reg dimming:\n"); - for (i = 0x40; i <= 0x54; i++) { + num = ldim_drv->ldev_conf->bl_regnum; + for (i = 0x40; i <= (0x40 + (num * 2)); i++) { iw7027_rreg(bl_iw7027->spi, i, &val); len += sprintf(buf+len, " 0x%02x=0x%02x\n", i, val); } @@ -339,25 +339,35 @@ static inline unsigned int iw7027_get_value(unsigned int level) return val; } +static int smr_cnt; static int iw7027_smr(unsigned short *buf, unsigned char len) { int i; unsigned int value_flag = 0, temp; - unsigned char val[20]; - unsigned short *mapping; + unsigned short *mapping, num; struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); + if (smr_cnt++ >= 30) + smr_cnt = 0; + if (iw7027_on_flag == 0) { - if (ldim_debug_print) + if (smr_cnt == 0) LDIMPR("%s: on_flag=%d\n", __func__, iw7027_on_flag); return 0; } - if (len != 10) { - LDIMERR("%s: data len %d invalid\n", __func__, len); + num = ldim_drv->ldev_conf->bl_regnum; + if (len != num) { + if (smr_cnt == 0) + LDIMERR("%s: data len %d invalid\n", __func__, len); + return -1; + } + if (val_brightness == NULL) { + if (smr_cnt == 0) + LDIMERR("%s: val_brightness is null\n", __func__); return -1; } if (iw7027_spi_op_flag) { - if (ldim_debug_print) { + if (smr_cnt == 0) { LDIMPR("%s: spi_op_flag=%d\n", __func__, iw7027_spi_op_flag); } @@ -371,26 +381,31 @@ static int iw7027_smr(unsigned short *buf, unsigned char len) dim_min = ldim_drv->ldev_conf->dim_min; if (bl_iw7027->test_mode) { - for (i = 0; i < 10; i++) { - val[2*i] = (test_brightness[i] >> 8) & 0xf; - val[2*i+1] = test_brightness[i] & 0xff; + if (test_brightness == NULL) { + if (smr_cnt == 0) + LDIMERR("test_brightness is null\n"); + return 0; + } + for (i = 0; i < num; i++) { + val_brightness[2*i] = (test_brightness[i] >> 8) & 0xf; + val_brightness[2*i+1] = test_brightness[i] & 0xff; } } else { - for (i = 0; i < 10; i++) + for (i = 0; i < num; i++) value_flag += buf[i]; if (value_flag == 0) { - for (i = 0; i < 20; i++) - val[i] = 0; + for (i = 0; i < (num * 2); i++) + val_brightness[i] = 0; } else { - for (i = 0; i < 10; i++) { + for (i = 0; i < num; i++) { temp = iw7027_get_value(buf[mapping[i]]); - val[2*i] = (temp >> 8) & 0xf; - val[2*i+1] = temp & 0xff; + val_brightness[2*i] = (temp >> 8) & 0xf; + val_brightness[2*i+1] = temp & 0xff; } } } - iw7027_wregs(bl_iw7027->spi, 0x40, val, 20); + iw7027_wregs(bl_iw7027->spi, 0x40, val_brightness, (num * 2)); iw7027_spi_op_flag = 0; return 0; @@ -433,15 +448,14 @@ static ssize_t iw7027_show(struct class *class, } else if (!strcmp(attr->attr.name, "test")) { ret = sprintf(buf, "test mode=%d\n", bl->test_mode); } else if (!strcmp(attr->attr.name, "brightness")) { - ret = sprintf(buf, "0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n", - test_brightness[0], - test_brightness[1], - test_brightness[2], - test_brightness[3], - test_brightness[4], - test_brightness[5], - test_brightness[6], - test_brightness[7]); + if (test_brightness == NULL) { + ret = sprintf(buf, "test_brightness is null\n"); + return ret; + } + ret = sprintf(buf, "test_brightness: "); + for (i = 0; i < ldim_drv->ldev_conf->bl_regnum; i++) + ret += sprintf(buf+ret, " 0x%x", test_brightness[i]); + ret += sprintf(buf+ret, "\n"); } else if (!strcmp(attr->attr.name, "status")) { ret = sprintf(buf, "iw7027 status:\n" "dev_index = %d\n" @@ -509,6 +523,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 aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); struct iw7027_s *bl = container_of(class, struct iw7027_s, cls); unsigned int val, val2; unsigned char reg_addr, reg_val; @@ -556,9 +571,14 @@ static ssize_t iw7027_store(struct class *class, } else if (!strcmp(attr->attr.name, "brightness")) { i = sscanf(buf, "%d %d", &val, &val2); val &= 0xfff; - LDIMPR("brightness=%d, index=%d\n", val, val2); - if ((i == 2) && (val2 < ARRAY_SIZE(test_brightness))) - test_brightness[val2] = val; + if (test_brightness == NULL) { + LDIMERR("test_brightness is null\n"); + return count; + } + if ((i == 2) && (val2 < ldim_drv->ldev_conf->bl_regnum)) { + test_brightness[val2] = (unsigned short)val; + LDIMPR("brightness=%d, index=%d\n", val, val2); + } } else LDIMERR("LDIM argment error!\n"); return count; @@ -625,7 +645,7 @@ static struct spi_driver ldim_spi_dev_driver = { int ldim_dev_iw7027_probe(void) { struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); - int ret; + int ret, i; iw7027_on_flag = 0; iw7027_spi_op_flag = 0; @@ -640,6 +660,7 @@ int ldim_dev_iw7027_probe(void) ret = spi_register_driver(&ldim_spi_dev_driver); if (ret) { LDIMERR("register ldim_dev spi driver failed\n"); + kfree(bl_iw7027); return -1; } @@ -650,6 +671,22 @@ int ldim_dev_iw7027_probe(void) bl_iw7027->cmd_size = ldim_drv->ldev_conf->cmd_size; bl_iw7027->init_data = ldim_drv->ldev_conf->init_on; + val_brightness = kcalloc(ldim_drv->ldev_conf->bl_regnum * 2, + sizeof(unsigned char), GFP_KERNEL); + if (val_brightness == NULL) { + LDIMERR("malloc val_brightness failed\n"); + kfree(bl_iw7027); + return -1; + } + test_brightness = kcalloc(ldim_drv->ldev_conf->bl_regnum, + sizeof(unsigned short), GFP_KERNEL); + if (test_brightness == NULL) { + LDIMERR("malloc test_brightness failed\n"); + } else { + for (i = 0; i < ldim_drv->ldev_conf->bl_regnum; i++) + test_brightness[i] = 0xfff; + } + iw7027_ldim_driver_update(); bl_iw7027->cls.name = kzalloc(10, GFP_KERNEL); @@ -657,7 +694,7 @@ int ldim_dev_iw7027_probe(void) bl_iw7027->cls.class_attrs = iw7027_class_attrs; ret = class_register(&bl_iw7027->cls); if (ret < 0) - pr_err("register iw7027 class failed\n"); + LDIMERR("register iw7027 class failed\n"); iw7027_on_flag = 1; /* default enable in uboot */ @@ -667,6 +704,11 @@ int ldim_dev_iw7027_probe(void) int ldim_dev_iw7027_remove(void) { + kfree(val_brightness); + val_brightness = NULL; + kfree(test_brightness); + test_brightness = NULL; + spi_unregister_driver(&ldim_spi_dev_driver); kfree(bl_iw7027); bl_iw7027 = NULL; diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c index 72a4cb1..3e06167 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c @@ -79,6 +79,8 @@ struct ldim_dev_config_s ldim_dev_config = { .pwm_duty_max = 100, .pwm_duty_min = 1, }, + + .bl_regnum = 0, }; #if 0 @@ -457,7 +459,9 @@ static void ldim_config_print(void) ldim_drv->ldev_conf->en_gpio_off, ldim_drv->ldev_conf->dim_min, ldim_drv->ldev_conf->dim_max); - n = ldim_drv->ldim_conf->row * ldim_drv->ldim_conf->col; + pr_info("region_num = %d\n", + ldim_drv->ldev_conf->bl_regnum); + n = ldim_drv->ldev_conf->bl_regnum; len = (n * 4) + 50; str = kcalloc(len, sizeof(char), GFP_KERNEL); if (str == NULL) { @@ -466,7 +470,7 @@ static void ldim_config_print(void) len = sprintf(str, "region_mapping:\n "); for (i = 0; i < n; i++) { len += sprintf(str+len, "%d,", - ldim_dev_config.bl_mapping[i]); + ldim_drv->ldev_conf->bl_mapping[i]); } pr_info("%s\n\n", str); kfree(str); @@ -634,6 +638,7 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index) for (i = 0; i < val; i++) ldim_dev_config.bl_mapping[i] = (unsigned short)temp[i]; } + ldim_dev_config.bl_regnum = (unsigned short)val; ret = of_property_read_u32(child, "type", &val); if (ret) { diff --git a/include/linux/amlogic/media/vout/lcd/aml_ldim.h b/include/linux/amlogic/media/vout/lcd/aml_ldim.h index 6840be9..c672e41 100644 --- a/include/linux/amlogic/media/vout/lcd/aml_ldim.h +++ b/include/linux/amlogic/media/vout/lcd/aml_ldim.h @@ -74,6 +74,7 @@ struct ldim_dev_config_s { struct bl_pwm_config_s pwm_config; + unsigned short bl_regnum; unsigned short bl_mapping[LD_BLKREGNUM]; }; -- 2.7.4