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 <evoke.zhang@amlogic.com>

Conflicts:
	drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c
	include/linux/amlogic/media/vout/lcd/aml_ldim.h
This commit is contained in:
Evoke Zhang
2019-01-14 20:56:01 +08:00
committed by Dongjin Kim
parent fd04ea8e4c
commit 6d4a452b14
3 changed files with 429 additions and 1 deletions

View File

@@ -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;
@@ -687,6 +718,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;
}

View File

@@ -83,8 +83,19 @@ struct ldim_dev_config_s ldim_dev_config = {
.pwm_duty_max = 100,
.pwm_duty_min = 1,
},
.analog_pwm_config = {
.pwm_method = BL_PWM_POSITIVE,
.pwm_port = BL_PWM_MAX,
.pwm_freq = 1000,
.pwm_duty_max = 100,
.pwm_duty_min = 10,
},
.bl_regnum = 0,
.dim_range_update = NULL,
.dev_reg_write = NULL,
.dev_reg_read = NULL,
};
static void ldim_gpio_probe(int index)
@@ -1159,6 +1170,384 @@ ldim_get_config_err:
return -1;
}
static ssize_t ldim_dev_show(struct class *class,
struct class_attribute *attr, char *buf)
{
int ret = 0;
ldim_dev_config_print();
return ret;
}
static ssize_t ldim_dev_pwm_ldim_show(struct class *class,
struct class_attribute *attr, char *buf)
{
struct bl_pwm_config_s *bl_pwm;
ssize_t len = 0;
bl_pwm = &ldim_dev_config.ldim_pwm_config;
if (bl_pwm->pwm_port < BL_PWM_MAX) {
len += sprintf(buf+len,
"ldim_pwm: freq=%d, pol=%d, duty_max=%d, duty_min=%d,",
bl_pwm->pwm_freq, bl_pwm->pwm_method,
bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min);
len += sprintf(buf+len, " duty_value=%d%%\n", bl_pwm->pwm_duty);
}
return len;
}
static ssize_t ldim_dev_pwm_ldim_store(struct class *class,
struct class_attribute *attr, const char *buf, size_t count)
{
unsigned int ret;
unsigned int val = 0;
struct bl_pwm_config_s *bl_pwm;
bl_pwm = &ldim_dev_config.ldim_pwm_config;
if (bl_pwm->pwm_port >= BL_PWM_MAX)
return count;
switch (buf[0]) {
case 'f': /* frequency */
ret = sscanf(buf, "freq %d", &val);
if (ret == 1) {
bl_pwm->pwm_freq = val;
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR("set ldim_pwm (port %d): freq = %dHz\n",
bl_pwm->pwm_port, bl_pwm->pwm_freq);
}
} else {
LDIMERR("invalid parameters\n");
}
break;
case 'd': /* duty */
ret = sscanf(buf, "duty %d", &val);
if (ret == 1) {
bl_pwm->pwm_duty = val;
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR("set ldim_pwm (port %d): duty = %d%%\n",
bl_pwm->pwm_port, bl_pwm->pwm_duty);
}
} else {
LDIMERR("invalid parameters\n");
}
break;
case 'p': /* polarity */
ret = sscanf(buf, "pol %d", &val);
if (ret == 1) {
bl_pwm->pwm_method = val;
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR("set ldim_pwm (port %d): method = %d\n",
bl_pwm->pwm_port, bl_pwm->pwm_method);
}
} else {
LDIMERR("invalid parameters\n");
}
break;
case 'm':
if (buf[1] == 'a') { /* max */
ret = sscanf(buf, "max %d", &val);
if (ret == 1) {
bl_pwm->pwm_duty_max = val;
if (ldim_dev_config.dim_range_update)
ldim_dev_config.dim_range_update();
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR(
"set ldim_pwm (port %d): duty_max = %d%%\n",
bl_pwm->pwm_port,
bl_pwm->pwm_duty_max);
}
} else {
LDIMERR("invalid parameters\n");
}
} else if (buf[1] == 'i') { /* min */
ret = sscanf(buf, "min %d", &val);
if (ret == 1) {
bl_pwm->pwm_duty_min = val;
if (ldim_dev_config.dim_range_update)
ldim_dev_config.dim_range_update();
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR(
"set ldim_pwm (port %d): duty_min = %d%%\n",
bl_pwm->pwm_port,
bl_pwm->pwm_duty_min);
}
} else {
LDIMERR("invalid parameters\n");
}
}
break;
default:
LDIMERR("wrong command\n");
break;
}
return count;
}
static ssize_t ldim_dev_pwm_analog_show(struct class *class,
struct class_attribute *attr, char *buf)
{
struct bl_pwm_config_s *bl_pwm;
ssize_t len = 0;
bl_pwm = &ldim_dev_config.analog_pwm_config;
if (bl_pwm->pwm_port < BL_PWM_VS) {
len += sprintf(buf+len,
"analog_pwm: freq=%d, pol=%d, duty_max=%d, duty_min=%d,",
bl_pwm->pwm_freq, bl_pwm->pwm_method,
bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min);
len += sprintf(buf+len, " duty_value=%d%%\n", bl_pwm->pwm_duty);
}
return len;
}
static ssize_t ldim_dev_pwm_analog_store(struct class *class,
struct class_attribute *attr, const char *buf, size_t count)
{
unsigned int ret;
unsigned int val = 0;
struct bl_pwm_config_s *bl_pwm;
bl_pwm = &ldim_dev_config.analog_pwm_config;
if (bl_pwm->pwm_port >= BL_PWM_VS)
return count;
switch (buf[0]) {
case 'f': /* frequency */
ret = sscanf(buf, "freq %d", &val);
if (ret == 1) {
bl_pwm->pwm_freq = val;
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR("set ldim_pwm (port %d): freq = %dHz\n",
bl_pwm->pwm_port, bl_pwm->pwm_freq);
}
} else {
LDIMERR("invalid parameters\n");
}
break;
case 'd': /* duty */
ret = sscanf(buf, "duty %d", &val);
if (ret == 1) {
bl_pwm->pwm_duty = val;
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR("set ldim_pwm (port %d): duty = %d%%\n",
bl_pwm->pwm_port, bl_pwm->pwm_duty);
}
} else {
LDIMERR("invalid parameters\n");
}
break;
case 'p': /* polarity */
ret = sscanf(buf, "pol %d", &val);
if (ret == 1) {
bl_pwm->pwm_method = val;
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR("set ldim_pwm (port %d): method = %d\n",
bl_pwm->pwm_port, bl_pwm->pwm_method);
}
} else {
LDIMERR("invalid parameters\n");
}
break;
case 'm':
if (buf[1] == 'a') { /* max */
ret = sscanf(buf, "max %d", &val);
if (ret == 1) {
bl_pwm->pwm_duty_max = val;
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR(
"set ldim_pwm (port %d): duty_max = %d%%\n",
bl_pwm->pwm_port,
bl_pwm->pwm_duty_max);
}
} else {
LDIMERR("invalid parameters\n");
}
} else if (buf[1] == 'i') { /* min */
ret = sscanf(buf, "min %d", &val);
if (ret == 1) {
bl_pwm->pwm_duty_min = val;
bl_pwm_config_init(bl_pwm);
ldim_set_duty_pwm(bl_pwm);
if (ldim_debug_print) {
LDIMPR(
"set ldim_pwm (port %d): duty_min = %d%%\n",
bl_pwm->pwm_port,
bl_pwm->pwm_duty_min);
}
} else {
LDIMERR("invalid parameters\n");
}
}
break;
default:
LDIMERR("wrong command\n");
break;
}
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", &reg, &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", &reg, &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
};
static void ldim_dev_class_create(void)
{
int ret;
ldim_dev_class.name = kzalloc(10, GFP_KERNEL);
if (ldim_dev_class.name == NULL) {
LDIMERR("%s: malloc failed\n", __func__);
return;
}
sprintf((char *)ldim_dev_class.name, "ldim_dev");
ldim_dev_class.class_attrs = ldim_dev_class_attrs;
ret = class_register(&ldim_dev_class);
if (ret < 0)
LDIMERR("register ldim_dev_class failed\n");
}
static int ldim_dev_add_driver(struct aml_ldim_driver_s *ldim_drv)
{
struct ldim_dev_config_s *ldev_conf = ldim_drv->ldev_conf;

View File

@@ -81,10 +81,15 @@ struct ldim_dev_config_s {
unsigned int init_on_cnt;
unsigned int init_off_cnt;
struct bl_pwm_config_s pwm_config;
struct bl_pwm_config_s ldim_pwm_config;
struct bl_pwm_config_s analog_pwm_config;
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******/