From 02ac0eb37639e9f0669f50c8b32db201be0e5fc5 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Mon, 14 Jan 2019 20:56:01 +0800 Subject: [PATCH] backlight: ldim: add dev reg access api support [1/1] PD#TV-1481 Problem: need ldim_dev reg access uniform api Solution: add ldim_dev reg access uniform api Verify: x301 Change-Id: I72756d178ef70aac1f8b7fef842468f2e27a0ffe Signed-off-by: Evoke Zhang --- .../media/vout/backlight/aml_ldim/iw7027_bl.c | 34 +++++ .../vout/backlight/aml_ldim/ldim_dev_drv.c | 121 +++++++++++++++++- .../linux/amlogic/media/vout/lcd/aml_ldim.h | 5 +- 3 files changed, 158 insertions(+), 2 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 054f3d2cf78c..c1536128e3c0 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c @@ -116,6 +116,37 @@ static int iw7027_wregs(struct spi_device *spi, unsigned char addr, return ret; } +static int iw7027_reg_write(unsigned char *buf, unsigned int len) +{ + int ret; + + if (len > 28) { + LDIMERR("%s: unsupport len: %d\n", __func__, len); + return -1; + } + + if (len > 1) + ret = iw7027_wreg(bl_iw7027->spi, buf[0], buf[1]); + else + ret = iw7027_wregs(bl_iw7027->spi, buf[0], &buf[1], (len - 1)); + + return ret; +} + +static int iw7027_reg_read(unsigned char *buf, unsigned int len) +{ + int ret; + + if (len > 1) { + LDIMERR("%s: unsupport len: %d\n", __func__, len); + return -1; + } + + ret = iw7027_rreg(bl_iw7027->spi, buf[0], &buf[0]); + + return ret; +} + static int ldim_power_cmd_dynamic_size(void) { unsigned char *table; @@ -693,6 +724,9 @@ static int iw7027_ldim_driver_update(struct aml_ldim_driver_s *ldim_drv) ldim_drv->device_power_off = iw7027_power_off; ldim_drv->device_bri_update = iw7027_smr; ldim_drv->device_bri_check = iw7027_check; + + ldim_drv->ldev_conf->dev_reg_write = iw7027_reg_write; + ldim_drv->ldev_conf->dev_reg_read = iw7027_reg_read; return 0; } 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 db5a10a7f31c..9dab744e1622 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 @@ -91,9 +91,12 @@ struct ldim_dev_config_s ldim_dev_config = { .pwm_duty_max = 100, .pwm_duty_min = 10, }, - .dim_range_update = NULL, .bl_regnum = 0, + + .dim_range_update = NULL, + .dev_reg_write = NULL, + .dev_reg_read = NULL, }; static void ldim_gpio_probe(int index) @@ -1498,11 +1501,127 @@ static ssize_t ldim_dev_pwm_analog_store(struct class *class, return count; } +static unsigned char ldim_dev_reg; +static unsigned char ldim_dev_reg_dump_cnt; +static ssize_t ldim_dev_reg_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + unsigned char data; + ssize_t len = 0; + int ret; + + if (ldim_dev_config.dev_reg_read == NULL) + return sprintf(buf, "ldim dev_reg_read is null\n"); + + data = ldim_dev_reg; + ret = ldim_dev_config.dev_reg_read(&data, 1); + if (ret) { + len = sprintf(buf, "reg[0x%02x] read error\n", ldim_dev_reg); + } else { + len = sprintf(buf, "reg[0x%02x] = 0x%02x\n", + ldim_dev_reg, data); + } + + return len; +} + +static ssize_t ldim_dev_reg_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + unsigned int reg = 0, val = 0; + unsigned char data[2]; + unsigned int ret; + + ret = sscanf(buf, "%x %x", ®, &val); + if (ret == 1) { + if (reg > 0xff) { + LDIMERR("invalid reg address: 0x%x\n", reg); + return count; + } + ldim_dev_reg = (unsigned char)reg; + } else if (ret == 2) { + if (ldim_dev_config.dev_reg_write == NULL) { + LDIMERR("ldim dev_reg_write is null\n"); + return count; + } + if (reg > 0xff) { + LDIMERR("invalid reg address: 0x%x\n", reg); + return count; + } + ldim_dev_reg = (unsigned char)reg; + data[0] = ldim_dev_reg; + data[1] = (unsigned char)val; + ldim_dev_config.dev_reg_write(data, 2); + LDIMPR("write reg[0x%02x] = 0x%02x\n", data[0], data[1]); + } else { + LDIMERR("invalid parameters\n"); + } + + return count; +} + +static ssize_t ldim_dev_reg_dump_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + unsigned char *data; + ssize_t len = 0; + int i, ret; + + if (ldim_dev_config.dev_reg_read == NULL) + return sprintf(buf, "ldim dev_reg_read is null\n"); + + if (ldim_dev_reg_dump_cnt == 0) + return sprintf(buf, "ldim reg_dump_cnt is zero\n"); + + data = kcalloc(ldim_dev_reg_dump_cnt, + sizeof(unsigned char), GFP_KERNEL); + ret = ldim_dev_config.dev_reg_read(data, ldim_dev_reg_dump_cnt); + if (ret) { + len = sprintf(buf, "reg[0x%02x] read error\n", ldim_dev_reg); + } else { + len += sprintf(buf+len, "reg[0x%02x] = ", ldim_dev_reg); + for (i = 0; i < (ldim_dev_reg_dump_cnt - 1); i++) + len += sprintf(buf+len, "0x%02x,", data[i]); + len += sprintf(buf+len, "0x%02x\n", + data[ldim_dev_reg_dump_cnt - 1]); + } + kfree(data); + + return len; +} + +static ssize_t ldim_dev_reg_dump_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + unsigned int reg = 0, cnt = 0; + unsigned int ret; + + ret = sscanf(buf, "%x %d", ®, &cnt); + if (ret == 2) { + if (reg > 0xff) { + LDIMERR("invalid reg address: 0x%x\n", reg); + return count; + } + if (cnt > 0xff) { + LDIMERR("invalid reg cnt: %d\n", cnt); + return count; + } + ldim_dev_reg = (unsigned char)reg; + ldim_dev_reg_dump_cnt = (unsigned char)cnt; + } else { + LDIMERR("invalid parameters\n"); + } + + return count; +} + static struct class_attribute ldim_dev_class_attrs[] = { __ATTR(status, 0644, ldim_dev_show, NULL), __ATTR(pwm_ldim, 0644, ldim_dev_pwm_ldim_show, ldim_dev_pwm_ldim_store), __ATTR(pwm_analog, 0644, ldim_dev_pwm_analog_show, ldim_dev_pwm_analog_store), + __ATTR(reg, 0644, ldim_dev_reg_show, ldim_dev_reg_store), + __ATTR(reg_dump, 0644, ldim_dev_reg_dump_show, ldim_dev_reg_dump_store), __ATTR_NULL }; diff --git a/include/linux/amlogic/media/vout/lcd/aml_ldim.h b/include/linux/amlogic/media/vout/lcd/aml_ldim.h index c7578e9e28a6..c066b0539e6e 100644 --- a/include/linux/amlogic/media/vout/lcd/aml_ldim.h +++ b/include/linux/amlogic/media/vout/lcd/aml_ldim.h @@ -83,10 +83,13 @@ struct ldim_dev_config_s { struct bl_pwm_config_s ldim_pwm_config; struct bl_pwm_config_s analog_pwm_config; - void (*dim_range_update)(void); unsigned short bl_regnum; unsigned short bl_mapping[LD_BLKREGNUM]; + + void (*dim_range_update)(void); + int (*dev_reg_write)(unsigned char *buf, unsigned int len); + int (*dev_reg_read)(unsigned char *buf, unsigned int len); }; /*******global API******/