mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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", ®, &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
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@@ -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******/
|
||||
|
||||
Reference in New Issue
Block a user