summaryrefslogtreecommitdiff
authorEvoke Zhang <evoke.zhang@amlogic.com>2018-06-15 09:23:24 (GMT)
committer Jianxin Pan <jianxin.pan@amlogic.com>2018-08-01 11:07:52 (GMT)
commit31c9040d47ccda0f69dc260c6ae8ba8a9edd6893 (patch)
treecba49bbaad484ea588432f4d07ee8bc024a1c826
parent7ff97417010946a571dae391f9489429ff07dfa1 (diff)
downloadcommon-31c9040d47ccda0f69dc260c6ae8ba8a9edd6893.zip
common-31c9040d47ccda0f69dc260c6ae8ba8a9edd6893.tar.gz
common-31c9040d47ccda0f69dc260c6ae8ba8a9edd6893.tar.bz2
backlight: optimize pwm level step calculation
PD#168569: backlight: optimize pwm level step calculation Change-Id: I570c12cc44af399a861ca54ad98180314924c180 Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
Diffstat
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_bl.c174
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c25
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c2
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c257
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.h7
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.c10
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h6
-rw-r--r--drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c28
-rw-r--r--include/linux/amlogic/media/vout/lcd/aml_ldim.h7
9 files changed, 289 insertions, 227 deletions
diff --git a/drivers/amlogic/media/vout/backlight/aml_bl.c b/drivers/amlogic/media/vout/backlight/aml_bl.c
index b966ade..f9d8a2b 100644
--- a/drivers/amlogic/media/vout/backlight/aml_bl.c
+++ b/drivers/amlogic/media/vout/backlight/aml_bl.c
@@ -329,6 +329,14 @@ static void bl_gpio_set(int index, int value)
}
}
+static inline unsigned int bl_do_div(unsigned long num, unsigned int den)
+{
+ unsigned long ret = num;
+
+ do_div(ret, den);
+ return (unsigned int)ret;
+}
+
/* ****************************************************** */
#define BL_PINMUX_MAX 6
static char *bl_pinmux_str[BL_PINMUX_MAX] = {
@@ -441,8 +449,6 @@ static void bl_set_pwm_vs(struct bl_pwm_config_s *bl_pwm,
ve[i] = 0x1fff;
}
} else {
- bl_pwm->pwm_level =
- (((bl_pwm->pwm_cnt * bl_pwm->pwm_duty / 10) + 5) / 10);
pwm_hi = bl_pwm->pwm_level;
n = bl_pwm->pwm_freq;
sw = (bl_pwm->pwm_cnt * 10 / n + 5) / 10;
@@ -486,15 +492,13 @@ static void bl_set_pwm_vs(struct bl_pwm_config_s *bl_pwm,
static void bl_set_pwm_normal(struct bl_pwm_config_s *bl_pwm,
unsigned int pol, unsigned int out_level)
{
- unsigned int pwm_period, pwm_duty, port_index;
+ unsigned int port_index;
if (IS_ERR_OR_NULL(bl_pwm->pwm_data.pwm)) {
BLERR("%s: invalid bl_pwm_ch\n", __func__);
return;
}
- pwm_period = 1000000000 / bl_pwm->pwm_freq;
- pwm_duty = (pwm_period * bl_pwm->pwm_duty) / 100;
port_index = bl_pwm->pwm_data.port_index;
if (bl_debug_print_flag) {
pr_info("pwm: pwm=0x%p, port_index=%d, meson_index=%d\n",
@@ -503,8 +507,8 @@ static void bl_set_pwm_normal(struct bl_pwm_config_s *bl_pwm,
if (((port_index % 2) == bl_pwm->pwm_data.meson_index) &&
(port_index == bl_pwm->pwm_port)) {
bl_pwm->pwm_data.state.polarity = pol;
- bl_pwm->pwm_data.state.duty_cycle = pwm_duty;
- bl_pwm->pwm_data.state.period = pwm_period;
+ bl_pwm->pwm_data.state.duty_cycle = bl_pwm->pwm_level;
+ bl_pwm->pwm_data.state.period = bl_pwm->pwm_cnt;
bl_pwm->pwm_data.state.enabled = true;
if (bl_debug_print_flag) {
BLPR(
@@ -934,6 +938,8 @@ static unsigned int bl_level_mapping(unsigned int level)
static void bl_set_duty_pwm(struct bl_pwm_config_s *bl_pwm)
{
+ unsigned long temp;
+
if (bl_pwm_bypass)
return;
@@ -958,10 +964,16 @@ static void bl_set_duty_pwm(struct bl_pwm_config_s *bl_pwm)
}
}
+ temp = bl_pwm->pwm_cnt;
+ bl_pwm->pwm_level = bl_do_div(((temp * bl_pwm->pwm_duty) + 50), 100);
+
if (bl_debug_print_flag) {
BLPR("pwm port %d: duty=%d%%, duty_max=%d%%, duty_min=%d%%\n",
bl_pwm->pwm_port, bl_pwm->pwm_duty,
bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min);
+ BLPR("pwm port %d: pwm_max=%d, pwm_min=%d, pwm_level=%d\n",
+ bl_pwm->pwm_port,
+ bl_pwm->pwm_max, bl_pwm->pwm_min, bl_pwm->pwm_level);
}
bl_set_pwm(bl_pwm);
}
@@ -970,8 +982,9 @@ static void bl_set_level_pwm(struct bl_pwm_config_s *bl_pwm, unsigned int level)
{
unsigned int min = bl_pwm->level_min;
unsigned int max = bl_pwm->level_max;
- unsigned int pwm_max = bl_pwm->pwm_duty_max;
- unsigned int pwm_min = bl_pwm->pwm_duty_min;
+ unsigned int pwm_max = bl_pwm->pwm_max;
+ unsigned int pwm_min = bl_pwm->pwm_min;
+ unsigned long temp;
if (bl_pwm_bypass)
return;
@@ -980,17 +993,23 @@ static void bl_set_level_pwm(struct bl_pwm_config_s *bl_pwm, unsigned int level)
max = bl_level_mapping(max);
min = bl_level_mapping(min);
if ((max <= min) || (level < min)) {
- bl_pwm->pwm_duty = pwm_min;
+ bl_pwm->pwm_level = pwm_min;
} else {
- bl_pwm->pwm_duty = ((pwm_max - pwm_min) * (level - min) *
- 10 / (max - min) + 5) / 10 + pwm_min;
+ temp = pwm_max - pwm_min;
+ bl_pwm->pwm_level =
+ bl_do_div((temp * (level - min)), (max - min)) +
+ pwm_min;
}
+ temp = bl_pwm->pwm_level;
+ bl_pwm->pwm_duty = (bl_do_div((temp * 1000), bl_pwm->pwm_cnt) + 5) / 10;
if (bl_debug_print_flag) {
- BLPR("port %d mapping: level=%d, level_max=%d, level_min=%d\n",
+ BLPR("pwm port %d: level=%d, level_max=%d, level_min=%d\n",
bl_pwm->pwm_port, level, max, min);
- BLPR("port %d: duty=%d%%, duty_max=%d%%, duty_min=%d%%\n",
- bl_pwm->pwm_port, bl_pwm->pwm_duty, pwm_max, pwm_min);
+ BLPR(
+ "pwm port %d: duty=%d%%, pwm_max=%d, pwm_min=%d, pwm_level=%d\n",
+ bl_pwm->pwm_port, bl_pwm->pwm_duty,
+ bl_pwm->pwm_max, bl_pwm->pwm_min, bl_pwm->pwm_level);
}
bl_set_pwm(bl_pwm);
@@ -1196,6 +1215,7 @@ enum bl_pwm_port_e bl_pwm_str_to_pwm(const char *str)
void bl_pwm_config_init(struct bl_pwm_config_s *bl_pwm)
{
unsigned int cnt;
+ unsigned long temp;
if (bl_debug_print_flag) {
BLPR("%s pwm_port %d: freq = %u\n",
@@ -1206,19 +1226,21 @@ void bl_pwm_config_init(struct bl_pwm_config_s *bl_pwm)
case BL_PWM_VS:
cnt = bl_vcbus_read(ENCL_VIDEO_MAX_LNCNT) + 1;
bl_pwm->pwm_cnt = cnt;
- bl_pwm->pwm_max = (bl_pwm->pwm_cnt *
- bl_pwm->pwm_duty_max / 100);
- bl_pwm->pwm_min = (bl_pwm->pwm_cnt *
- bl_pwm->pwm_duty_min / 100);
- if (bl_debug_print_flag)
- BLPR("pwm_cnt = %u, pwm_max = %u, pwm_min = %u\n",
- bl_pwm->pwm_cnt,
- bl_pwm->pwm_max,
- bl_pwm->pwm_min);
break;
default:
+ /* for pwm api: pwm_period */
+ bl_pwm->pwm_cnt = 1000000000 / bl_pwm->pwm_freq;
break;
}
+
+ temp = bl_pwm->pwm_cnt;
+ bl_pwm->pwm_max = bl_do_div((temp * bl_pwm->pwm_duty_max), 100);
+ bl_pwm->pwm_min = bl_do_div((temp * bl_pwm->pwm_duty_min), 100);
+
+ if (bl_debug_print_flag) {
+ BLPR("pwm_cnt = %u, pwm_max = %u, pwm_min = %u\n",
+ bl_pwm->pwm_cnt, bl_pwm->pwm_max, bl_pwm->pwm_min);
+ }
}
static void aml_bl_config_print(struct bl_config_s *bconf)
@@ -1258,23 +1280,20 @@ static void aml_bl_config_print(struct bl_config_s *bconf)
if (bconf->bl_pwm) {
bl_pwm = bconf->bl_pwm;
BLPR("pwm_index = %d\n", bl_pwm->index);
- BLPR("pwm_method = %d\n", bl_pwm->pwm_method);
BLPR("pwm_port = %d\n", bl_pwm->pwm_port);
+ BLPR("pwm_method = %d\n", bl_pwm->pwm_method);
if (bl_pwm->pwm_port == BL_PWM_VS) {
BLPR("pwm_freq = %d x vfreq\n",
bl_pwm->pwm_freq);
- BLPR("pwm_cnt = %u\n", bl_pwm->pwm_cnt);
} else {
BLPR("pwm_freq = %uHz\n",
bl_pwm->pwm_freq);
- BLPR("pwm_cnt = %u\n", bl_pwm->pwm_cnt);
- BLPR("pwm_pre_div = %u\n",
- bl_pwm->pwm_pre_div);
}
BLPR("pwm_level_max = %u\n", bl_pwm->level_max);
BLPR("pwm_level_min = %u\n", bl_pwm->level_min);
BLPR("pwm_duty_max = %d%%\n", bl_pwm->pwm_duty_max);
BLPR("pwm_duty_min = %d%%\n", bl_pwm->pwm_duty_min);
+ BLPR("pwm_cnt = %u\n", bl_pwm->pwm_cnt);
BLPR("pwm_max = %u\n", bl_pwm->pwm_max);
BLPR("pwm_min = %u\n", bl_pwm->pwm_min);
}
@@ -1288,20 +1307,14 @@ static void aml_bl_config_print(struct bl_config_s *bconf)
if (bconf->bl_pwm_combo0) {
bl_pwm = bconf->bl_pwm_combo0;
BLPR("pwm_combo0_index = %d\n", bl_pwm->index);
- BLPR("pwm_combo0_method = %d\n", bl_pwm->pwm_method);
BLPR("pwm_combo0_port = %d\n", bl_pwm->pwm_port);
+ BLPR("pwm_combo0_method = %d\n", bl_pwm->pwm_method);
if (bl_pwm->pwm_port == BL_PWM_VS) {
BLPR("pwm_combo0_freq = %d x vfreq\n",
bl_pwm->pwm_freq);
- BLPR("pwm_combo0_cnt = %u\n",
- bl_pwm->pwm_cnt);
} else {
BLPR("pwm_combo0_freq = %uHz\n",
bl_pwm->pwm_freq);
- BLPR("pwm_combo0_cnt = %u\n",
- bl_pwm->pwm_cnt);
- BLPR("pwm_combo0_pre_div = %u\n",
- bl_pwm->pwm_pre_div);
}
BLPR("pwm_combo0_level_max = %u\n", bl_pwm->level_max);
BLPR("pwm_combo0_level_min = %u\n", bl_pwm->level_min);
@@ -1309,27 +1322,22 @@ static void aml_bl_config_print(struct bl_config_s *bconf)
bl_pwm->pwm_duty_max);
BLPR("pwm_combo0_duty_min = %d\n",
bl_pwm->pwm_duty_min);
- BLPR("pwm_combo0_max = %u\n", bl_pwm->pwm_max);
- BLPR("pwm_combo0_min = %u\n", bl_pwm->pwm_min);
+ BLPR("pwm_combo0_pwm_cnt = %u\n", bl_pwm->pwm_cnt);
+ BLPR("pwm_combo0_pwm_max = %u\n", bl_pwm->pwm_max);
+ BLPR("pwm_combo0_pwm_min = %u\n", bl_pwm->pwm_min);
}
/* pwm_combo_1 */
if (bconf->bl_pwm_combo1) {
bl_pwm = bconf->bl_pwm_combo1;
BLPR("pwm_combo1_index = %d\n", bl_pwm->index);
- BLPR("pwm_combo1_method = %d\n", bl_pwm->pwm_method);
BLPR("pwm_combo1_port = %d\n", bl_pwm->pwm_port);
+ BLPR("pwm_combo1_method = %d\n", bl_pwm->pwm_method);
if (bl_pwm->pwm_port == BL_PWM_VS) {
BLPR("pwm_combo1_freq = %d x vfreq\n",
bl_pwm->pwm_freq);
- BLPR("pwm_combo1_cnt = %u\n",
- bl_pwm->pwm_cnt);
} else {
BLPR("pwm_combo1_freq = %uHz\n",
bl_pwm->pwm_freq);
- BLPR("pwm_combo1_cnt = %u\n",
- bl_pwm->pwm_cnt);
- BLPR("pwm_combo1_pre_div = %u\n",
- bl_pwm->pwm_pre_div);
}
BLPR("pwm_combo1_level_max = %u\n", bl_pwm->level_max);
BLPR("pwm_combo1_level_min = %u\n", bl_pwm->level_min);
@@ -1337,8 +1345,9 @@ static void aml_bl_config_print(struct bl_config_s *bconf)
bl_pwm->pwm_duty_max);
BLPR("pwm_combo1_duty_min = %d\n",
bl_pwm->pwm_duty_min);
- BLPR("pwm_combo1_max = %u\n", bl_pwm->pwm_max);
- BLPR("pwm_combo1_min = %u\n", bl_pwm->pwm_min);
+ BLPR("pwm_combo1_pwm_cnt = %u\n", bl_pwm->pwm_cnt);
+ BLPR("pwm_combo1_pwm_max = %u\n", bl_pwm->pwm_max);
+ BLPR("pwm_combo1_pwm_min = %u\n", bl_pwm->pwm_min);
}
break;
default:
@@ -1946,13 +1955,12 @@ static int aml_bl_config_load_from_unifykey(struct bl_config_s *bconf)
}
static int aml_bl_pwm_channel_register(struct bl_config_s *bconf,
- struct platform_device *pdev)
+ struct device_node *blnode)
{
int ret = 0;
int index0 = BL_PWM_MAX;
int index1 = BL_PWM_MAX;
phandle pwm_phandle;
- struct device_node *blnode = pdev->dev.of_node;
struct device_node *pnode = NULL;
struct device_node *child;
struct bl_pwm_config_s *bl_pwm = NULL;
@@ -1960,43 +1968,42 @@ static int aml_bl_pwm_channel_register(struct bl_config_s *bconf,
ret = of_property_read_u32(blnode, "bl_pwm_config", &pwm_phandle);
if (ret) {
BLERR("not match bl_pwm_config node\n");
- } else {
- pnode = of_find_node_by_phandle(pwm_phandle);
- if (!pnode) {
- BLERR("can't find bl_pwm_config node\n");
- return -1;
- }
+ return -1;
+ }
+ pnode = of_find_node_by_phandle(pwm_phandle);
+ if (!pnode) {
+ BLERR("can't find bl_pwm_config node\n");
+ return -1;
}
/*request for pwm device */
for_each_child_of_node(pnode, child) {
ret = of_property_read_u32(child, "pwm_port_index", &index0);
if (ret) {
- BLERR("invalid %d pwm_port_index parameters\n", index0);
+ BLERR("failed to get pwm_port_index\n");
return ret;
}
ret = of_property_read_u32_index(child, "pwms", 1, &index1);
if (ret) {
- BLERR("invalid %d meson_pwm_index\n", index1);
+ BLERR("failed to get meson_pwm_index\n");
return ret;
}
if (index0 >= BL_PWM_VS)
continue;
+ if ((index0 % 2) != index1)
+ continue;
bl_pwm = NULL;
switch (bconf->method) {
case BL_CTRL_PWM:
- if ((index0 == bconf->bl_pwm->pwm_port) &&
- ((index0 % 2) == index1))
+ if (index0 == bconf->bl_pwm->pwm_port)
bl_pwm = bconf->bl_pwm;
break;
case BL_CTRL_PWM_COMBO:
- if ((index0 == bconf->bl_pwm_combo0->pwm_port) &&
- ((index0 % 2) == index1))
+ if (index0 == bconf->bl_pwm_combo0->pwm_port)
bl_pwm = bconf->bl_pwm_combo0;
- if ((index0 == bconf->bl_pwm_combo1->pwm_port) &&
- ((index0 % 2) == index1))
+ if (index0 == bconf->bl_pwm_combo1->pwm_port)
bl_pwm = bconf->bl_pwm_combo1;
break;
default:
@@ -2078,7 +2085,7 @@ static int aml_bl_config_load(struct bl_config_s *bconf,
switch (bconf->method) {
case BL_CTRL_PWM:
case BL_CTRL_PWM_COMBO:
- ret = aml_bl_pwm_channel_register(bconf, pdev);
+ ret = aml_bl_pwm_channel_register(bconf, pdev->dev.of_node);
bl_pwm_pinmux_set(bconf);
break;
#ifdef CONFIG_AMLOGIC_BL_EXTERN
@@ -2440,17 +2447,22 @@ static ssize_t bl_debug_pwm_show(struct class *class,
bl_pwm = bconf->bl_pwm;
len += sprintf(buf+len,
"pwm_index: %d\n"
- "pwm_method: %d\n"
"pwm_port: %d\n"
+ "pwm_method: %d\n"
"pwm_freq: %d\n"
"pwm_duty_max: %d\n"
"pwm_duty_min: %d\n"
"pwm_cnt: %d\n"
+ "pwm_max: %d\n"
+ "pwm_min: %d\n"
+ "pwm_level: %d\n"
"pwm_duty: %d%%\n",
- bl_pwm->index, bl_pwm->pwm_method,
- bl_pwm->pwm_port, bl_pwm->pwm_freq,
+ bl_pwm->index, bl_pwm->pwm_port,
+ bl_pwm->pwm_method, bl_pwm->pwm_freq,
bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min,
- bl_pwm->pwm_cnt, bl_pwm->pwm_duty);
+ bl_pwm->pwm_cnt,
+ bl_pwm->pwm_max, bl_pwm->pwm_min,
+ bl_pwm->pwm_level, bl_pwm->pwm_duty);
switch (bl_pwm->pwm_port) {
case BL_PWM_A:
case BL_PWM_B:
@@ -2503,17 +2515,22 @@ static ssize_t bl_debug_pwm_show(struct class *class,
bl_pwm = bconf->bl_pwm_combo0;
len += sprintf(buf+len,
"pwm_0_index: %d\n"
- "pwm_0_method: %d\n"
"pwm_0_port: %d\n"
+ "pwm_0_method: %d\n"
"pwm_0_freq: %d\n"
"pwm_0_duty_max: %d\n"
"pwm_0_duty_min: %d\n"
"pwm_0_cnt: %d\n"
+ "pwm_0_max: %d\n"
+ "pwm_0_min: %d\n"
+ "pwm_0_level: %d\n"
"pwm_0_duty: %d%%\n",
- bl_pwm->index, bl_pwm->pwm_method,
- bl_pwm->pwm_port, bl_pwm->pwm_freq,
+ bl_pwm->index, bl_pwm->pwm_port,
+ bl_pwm->pwm_method, bl_pwm->pwm_freq,
bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min,
- bl_pwm->pwm_cnt, bl_pwm->pwm_duty);
+ bl_pwm->pwm_cnt,
+ bl_pwm->pwm_max, bl_pwm->pwm_min,
+ bl_pwm->pwm_level, bl_pwm->pwm_duty);
switch (bl_pwm->pwm_port) {
case BL_PWM_A:
case BL_PWM_B:
@@ -2561,17 +2578,22 @@ static ssize_t bl_debug_pwm_show(struct class *class,
len += sprintf(buf+len,
"\n"
"pwm_1_index: %d\n"
- "pwm_1_method: %d\n"
"pwm_1_port: %d\n"
+ "pwm_1_method: %d\n"
"pwm_1_freq: %d\n"
"pwm_1_duty_max: %d\n"
"pwm_1_duty_min: %d\n"
"pwm_1_cnt: %d\n"
+ "pwm_1_max: %d\n"
+ "pwm_1_min: %d\n"
+ "pwm_1_level: %d\n"
"pwm_1_duty: %d%%\n",
- bl_pwm->index, bl_pwm->pwm_method,
- bl_pwm->pwm_port, bl_pwm->pwm_freq,
+ bl_pwm->index, bl_pwm->pwm_port,
+ bl_pwm->pwm_method, bl_pwm->pwm_freq,
bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min,
- bl_pwm->pwm_cnt, bl_pwm->pwm_duty);
+ bl_pwm->pwm_cnt,
+ bl_pwm->pwm_max, bl_pwm->pwm_min,
+ bl_pwm->pwm_level, bl_pwm->pwm_duty);
switch (bl_pwm->pwm_port) {
case BL_PWM_A:
case BL_PWM_B:
diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c b/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c
index 4835aed..ad81ac4 100644
--- a/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c
+++ b/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c
@@ -44,7 +44,6 @@ static int global_hw_init_on(void)
{
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
- ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config));
ldim_drv->pinmux_ctrl(ldim_drv->ldev_conf->pinmux_name);
mdelay(2);
ldim_gpio_set(ldim_drv->ldev_conf->en_gpio,
@@ -60,29 +59,16 @@ static int global_hw_init_off(void)
ldim_gpio_set(ldim_drv->ldev_conf->en_gpio,
ldim_drv->ldev_conf->en_gpio_off);
+ ldim_pwm_off(&(ldim_drv->ldev_conf->pwm_config));
return 0;
}
-static unsigned int global_get_value(unsigned int level)
-{
- struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
-
- unsigned int val;
- unsigned int dim_max, dim_min;
-
- dim_max = ldim_drv->ldev_conf->dim_max;
- dim_min = ldim_drv->ldev_conf->dim_min;
-
- val = dim_min + ((level * (dim_max - dim_min)) / LD_DATA_MAX);
-
- return val;
-}
-
static int global_smr(unsigned short *buf, unsigned char len)
{
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
- unsigned short val;
+ unsigned int dim_max, dim_min;
+ unsigned int level, val;
if (global_on_flag == 0) {
if (ldim_debug_print)
@@ -95,7 +81,10 @@ static int global_smr(unsigned short *buf, unsigned char len)
return -1;
}
- val = global_get_value(buf[0]);
+ dim_max = ldim_drv->ldev_conf->dim_max;
+ dim_min = ldim_drv->ldev_conf->dim_min;
+ level = buf[0];
+ val = dim_min + ((level * (dim_max - dim_min)) / LD_DATA_MAX);
ldim_drv->ldev_conf->pwm_config.pwm_duty = val;
ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config));
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 d3317fb..d9cbc5f 100644
--- a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c
+++ b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c
@@ -204,7 +204,6 @@ static int iw7027_hw_init_on(void)
/* step 1: system power_on */
ldim_gpio_set(ldim_drv->ldev_conf->en_gpio,
ldim_drv->ldev_conf->en_gpio_on);
- ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config));
/* step 2: delay for internal logic stable */
mdelay(10);
@@ -266,6 +265,7 @@ static int iw7027_hw_init_off(void)
ldim_gpio_set(ldim_drv->ldev_conf->en_gpio,
ldim_drv->ldev_conf->en_gpio_off);
+ ldim_pwm_off(&(ldim_drv->ldev_conf->pwm_config));
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 3e06167..d7fe8dd 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
@@ -273,101 +273,33 @@ unsigned int ldim_gpio_get(int index)
return gpiod_get_value(ld_gpio->gpio);
}
-static unsigned int pwm_reg[6] = {
- PWM_PWM_A,
- PWM_PWM_B,
- PWM_PWM_C,
- PWM_PWM_D,
- PWM_PWM_E,
- PWM_PWM_F,
-};
-
-static unsigned int pwm_reg_txlx[6] = {
- PWM_PWM_A_TXLX,
- PWM_PWM_B_TXLX,
- PWM_PWM_C_TXLX,
- PWM_PWM_D_TXLX,
- PWM_PWM_E_TXLX,
- PWM_PWM_F_TXLX,
-};
-
-void ldim_set_duty_pwm(struct bl_pwm_config_s *ld_pwm)
+void ldim_set_duty_pwm(struct bl_pwm_config_s *bl_pwm)
{
- unsigned int pwm_hi = 0, pwm_lo = 0;
- unsigned int port = ld_pwm->pwm_port;
- unsigned int vs[4], ve[4], sw, n, i;
- struct aml_bl_drv_s *bl_drv = aml_bl_get_driver();
+ unsigned long temp;
- if (ld_pwm->pwm_port >= BL_PWM_MAX)
+ if (bl_pwm->pwm_port >= BL_PWM_MAX)
return;
- ld_pwm->pwm_level = ld_pwm->pwm_cnt * ld_pwm->pwm_duty / 100;
- if (ldim_debug_print) {
- LDIMPR("pwm port %d: duty=%d%%, duty_max=%d, duty_min=%d\n",
- ld_pwm->pwm_port, ld_pwm->pwm_duty,
- ld_pwm->pwm_duty_max, ld_pwm->pwm_duty_min);
- }
+ temp = bl_pwm->pwm_cnt;
+ temp = (((temp * bl_pwm->pwm_duty) + 50) / 100);
+ bl_pwm->pwm_level = (unsigned int)temp;
- switch (ld_pwm->pwm_method) {
- case BL_PWM_POSITIVE:
- pwm_hi = ld_pwm->pwm_level;
- pwm_lo = ld_pwm->pwm_cnt - ld_pwm->pwm_level;
- break;
- case BL_PWM_NEGATIVE:
- pwm_lo = ld_pwm->pwm_level;
- pwm_hi = ld_pwm->pwm_cnt - ld_pwm->pwm_level;
- break;
- default:
- LDIMERR("port %d: invalid pwm_method %d\n",
- port, ld_pwm->pwm_method);
- break;
- }
if (ldim_debug_print) {
- LDIMPR("port %d: pwm_cnt=%d, pwm_hi=%d, pwm_lo=%d\n",
- port, ld_pwm->pwm_cnt, pwm_hi, pwm_lo);
- }
-
- switch (port) {
- case BL_PWM_A:
- case BL_PWM_B:
- case BL_PWM_C:
- case BL_PWM_D:
- case BL_PWM_E:
- case BL_PWM_F:
- if (bl_drv->data->chip_type == BL_CHIP_TXLX)
- bl_cbus_write(pwm_reg_txlx[port],
- (pwm_hi << 16) | pwm_lo);
- else
- bl_cbus_write(pwm_reg[port], (pwm_hi << 16) | pwm_lo);
- break;
- case BL_PWM_VS:
- n = ld_pwm->pwm_freq;
- sw = (ld_pwm->pwm_cnt * 10 / n + 5) / 10;
- pwm_hi = (pwm_hi * 10 / n + 5) / 10;
- pwm_hi = (pwm_hi > 1) ? pwm_hi : 1;
- if (ldim_debug_print)
- LDIMPR("n=%d, sw=%d, pwm_high=%d\n", n, sw, pwm_hi);
- for (i = 0; i < n; i++) {
- vs[i] = 1 + (sw * i);
- ve[i] = vs[i] + pwm_hi - 1;
- if (ldim_debug_print) {
- LDIMPR("vs[%d]=%d, ve[%d]=%d\n",
- i, vs[i], i, ve[i]);
- }
- }
- for (i = n; i < 4; i++) {
- vs[i] = 0xffff;
- ve[i] = 0xffff;
- }
- bl_vcbus_write(VPU_VPU_PWM_V0, (2 << 14) | /* vsync latch */
- (ve[0] << 16) | (vs[0]));
- bl_vcbus_write(VPU_VPU_PWM_V1, (ve[1] << 16) | (vs[1]));
- bl_vcbus_write(VPU_VPU_PWM_V2, (ve[2] << 16) | (vs[2]));
- bl_vcbus_write(VPU_VPU_PWM_V3, (ve[3] << 16) | (vs[3]));
- break;
- default:
- break;
+ LDIMPR(
+ "pwm port %d: duty=%d%%, pwm_max=%d, pwm_min=%d, pwm_level=%d\n",
+ bl_pwm->pwm_port, bl_pwm->pwm_duty,
+ bl_pwm->pwm_max, bl_pwm->pwm_min, bl_pwm->pwm_level);
}
+
+ bl_pwm_ctrl(bl_pwm, 1);
+}
+
+void ldim_pwm_off(struct bl_pwm_config_s *bl_pwm)
+{
+ if (bl_pwm->pwm_port >= BL_PWM_MAX)
+ return;
+
+ bl_pwm_ctrl(bl_pwm, 0);
}
/* ****************************************************** */
@@ -381,19 +313,23 @@ static char *ldim_pinmux_str[] = {
static int ldim_pwm_pinmux_ctrl(char *pin_str)
{
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
- struct bl_pwm_config_s *ld_pwm;
+ struct bl_pwm_config_s *bl_pwm;
int ret = 0;
if (strcmp(pin_str, "invalid") == 0)
return 0;
- ld_pwm = &ldim_drv->ldev_conf->pwm_config;
- if (ld_pwm->pwm_port >= BL_PWM_MAX)
+ bl_pwm = &ldim_drv->ldev_conf->pwm_config;
+ if (bl_pwm->pwm_port >= BL_PWM_MAX)
+ return 0;
+
+ ldim_set_duty_pwm(bl_pwm);
+
+ if (ldim_drv->pinmux_flag)
return 0;
- bl_pwm_ctrl(ld_pwm, 1);
/* request pwm pinmux */
- if (ld_pwm->pwm_port == BL_PWM_VS) {
+ if (bl_pwm->pwm_port == BL_PWM_VS) {
ldim_drv->pin = devm_pinctrl_get_select(ldim_drv->dev,
ldim_pinmux_str[1]);
if (IS_ERR(ldim_drv->pin)) {
@@ -414,6 +350,7 @@ static int ldim_pwm_pinmux_ctrl(char *pin_str)
ldim_pinmux_str[0], ldim_drv->pin);
}
}
+ ldim_drv->pinmux_flag = 1;
return ret;
}
@@ -433,7 +370,10 @@ static int ldim_pwm_vs_update(void)
static void ldim_config_print(void)
{
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
- struct bl_pwm_config_s *ld_pwm;
+ struct aml_bl_drv_s *bl_drv = aml_bl_get_driver();
+ struct bl_pwm_config_s *bl_pwm;
+ struct pwm_state pstate;
+ unsigned int value;
int i, n, len = 0;
char *str = NULL;
@@ -444,7 +384,7 @@ static void ldim_config_print(void)
ldim_drv->valid_flag,
ldim_drv->dev_index);
if (ldim_drv->ldev_conf) {
- ld_pwm = &ldim_drv->ldev_conf->pwm_config;
+ bl_pwm = &ldim_drv->ldev_conf->pwm_config;
pr_info("dev_name = %s\n"
"type = %d\n"
"en_gpio = %d\n"
@@ -508,21 +448,125 @@ static void ldim_config_print(void)
default:
break;
}
- if (ld_pwm->pwm_port < BL_PWM_MAX) {
- pr_info("pwm_port = %d\n"
- "pwm_pol = %d\n"
- "pwm_freq = %d\n"
- "pwm_duty = %d%%\n"
- "pwm_pointer = %p\n",
- ld_pwm->pwm_port, ld_pwm->pwm_method,
- ld_pwm->pwm_freq, ld_pwm->pwm_duty,
- ld_pwm->pwm_data.pwm);
+ if (bl_pwm->pwm_port < BL_PWM_MAX) {
+ pr_info("pwm_port: %d\n"
+ "pwm_pol: %d\n"
+ "pwm_freq: %d\n"
+ "pwm_cnt: %d\n"
+ "pwm_level: %d\n"
+ "pwm_duty: %d%%\n",
+ bl_pwm->pwm_port, bl_pwm->pwm_method,
+ bl_pwm->pwm_freq, bl_pwm->pwm_cnt,
+ bl_pwm->pwm_level, bl_pwm->pwm_duty);
+ switch (bl_pwm->pwm_port) {
+ case BL_PWM_A:
+ case BL_PWM_B:
+ case BL_PWM_C:
+ case BL_PWM_D:
+ case BL_PWM_E:
+ case BL_PWM_F:
+ if (IS_ERR_OR_NULL(bl_pwm->pwm_data.pwm)) {
+ pr_info("pwm invalid\n");
+ break;
+ }
+ pr_info("pwm_pointer: %p\n",
+ bl_pwm->pwm_data.pwm);
+ pwm_get_state(bl_pwm->pwm_data.pwm, &pstate);
+ pr_info("pwm state:\n"
+ " period: %d\n"
+ " duty_cycle: %d\n"
+ " polarity: %d\n"
+ " enabled: %d\n",
+ pstate.period, pstate.duty_cycle,
+ pstate.polarity, pstate.enabled);
+ value = bl_cbus_read(bl_drv->data->pwm_reg[
+ bl_pwm->pwm_port]);
+ pr_info("pwm_reg: 0x%08x\n",
+ value);
+ break;
+ case BL_PWM_VS:
+ pr_info("pwm_reg0: 0x%08x\n"
+ "pwm_reg1: 0x%08x\n"
+ "pwm_reg2: 0x%08x\n"
+ "pwm_reg3: 0x%08x\n",
+ bl_vcbus_read(VPU_VPU_PWM_V0),
+ bl_vcbus_read(VPU_VPU_PWM_V1),
+ bl_vcbus_read(VPU_VPU_PWM_V2),
+ bl_vcbus_read(VPU_VPU_PWM_V3));
+ break;
+ default:
+ break;
+ }
}
} else {
pr_info("device config is null\n");
}
}
+static int ldim_dev_pwm_channel_register(struct bl_pwm_config_s *bl_pwm,
+ struct device_node *blnode)
+{
+ int ret = 0;
+ int index0 = BL_PWM_MAX;
+ int index1 = BL_PWM_MAX;
+ phandle pwm_phandle;
+ struct device_node *pnode = NULL;
+ struct device_node *child;
+ struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
+
+ ret = of_property_read_u32(blnode, "bl_pwm_config", &pwm_phandle);
+ if (ret) {
+ LDIMERR("not match bl_pwm_config node\n");
+ return -1;
+ }
+ pnode = of_find_node_by_phandle(pwm_phandle);
+ if (!pnode) {
+ LDIMERR("can't find bl_pwm_config node\n");
+ return -1;
+ }
+
+ /*request for pwm device */
+ for_each_child_of_node(pnode, child) {
+ ret = of_property_read_u32(child, "pwm_port_index", &index0);
+ if (ret) {
+ LDIMERR("failed to get pwm_port_index\n");
+ return ret;
+ }
+ ret = of_property_read_u32_index(child, "pwms", 1, &index1);
+ if (ret) {
+ LDIMERR("failed to get meson_pwm_index\n");
+ return ret;
+ }
+
+ if (index0 >= BL_PWM_VS)
+ continue;
+ if ((index0 % 2) != index1)
+ continue;
+ if (index0 != bl_pwm->pwm_port)
+ continue;
+
+ bl_pwm->pwm_data.port_index = index0;
+ bl_pwm->pwm_data.meson_index = index1;
+ bl_pwm->pwm_data.pwm = devm_of_pwm_get(
+ ldim_drv->dev, child, NULL);
+ if (IS_ERR_OR_NULL(bl_pwm->pwm_data.pwm)) {
+ ret = PTR_ERR(bl_pwm->pwm_data.pwm);
+ LDIMERR("unable to request bl_pwm\n");
+ return ret;
+ }
+ bl_pwm->pwm_data.meson = to_meson_pwm(
+ bl_pwm->pwm_data.pwm->chip);
+ pwm_init_state(bl_pwm->pwm_data.pwm, &(bl_pwm->pwm_data.state));
+ LDIMPR("register pwm_ch(%d) 0x%p\n",
+ bl_pwm->pwm_data.port_index, bl_pwm->pwm_data.pwm);
+ }
+
+ LDIMPR("%s ok\n", __func__);
+
+ return ret;
+
+}
+
static int ldim_dev_get_config_from_dts(struct device_node *np, int index)
{
char ld_propname[20];
@@ -598,6 +642,11 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index)
ldim_dev_config.pwm_config.pwm_duty);
bl_pwm_config_init(&ldim_dev_config.pwm_config);
+
+ if (ldim_dev_config.pwm_config.pwm_port < BL_PWM_VS) {
+ ldim_dev_pwm_channel_register(
+ &ldim_dev_config.pwm_config, np);
+ }
}
ret = of_property_read_u32_array(child, "en_gpio_on_off", temp, 3);
diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.h b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.h
index 690969c..6d5a111 100644
--- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.h
+++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.h
@@ -18,14 +18,19 @@
#ifndef __LDIM_DEV_DRV_H
#define __LDIM_DEV_DRV_H
+/* ldim global api */
extern void ldim_gpio_set(int index, int value);
extern unsigned int ldim_gpio_get(int index);
+extern void ldim_set_duty_pwm(struct bl_pwm_config_s *ld_pwm);
+extern void ldim_pwm_off(struct bl_pwm_config_s *ld_pwm);
+/* ldim dev api */
extern int ldim_dev_iw7027_probe(void);
extern int ldim_dev_iw7027_remove(void);
+
extern int ldim_dev_ob3350_probe(void);
extern int ldim_dev_ob3350_remove(void);
-extern void ldim_set_duty_pwm(struct bl_pwm_config_s *ld_pwm);
+
extern int ldim_dev_global_probe(void);
extern int ldim_dev_global_remove(void);
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 409848b..440f364 100644
--- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.c
+++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.c
@@ -3172,6 +3172,7 @@ static struct aml_ldim_driver_s ldim_driver = {
.valid_flag = 0, /* default invalid, active when bl_ctrl_method=ldim */
.dev_index = 0xff,
.static_pic_flag = 0,
+ .pinmux_flag = 0,
.ldim_conf = &ldim_config,
.ldev_conf = NULL,
.ldim_matrix_buf = NULL,
@@ -3999,8 +4000,7 @@ static ssize_t ldim_attr_store(struct class *cla,
fw_print_frequent,
Dbprint_lv);
} else if (!strcmp(parm[0], "info")) {
- pr_info("ldim_drv_ver = %s\n",
- LDIM_DRV_VER);
+ pr_info("ldim_drv_ver: %s\n", LDIM_DRV_VER);
ldim_driver.config_print();
pr_info("\nldim_blk_row = %d\n"
"ldim_blk_col = %d\n"
@@ -4134,7 +4134,7 @@ int aml_ldim_get_config_dts(struct device_node *child)
if (ret)
LDIMERR("failed to get ldim_dev_index\n");
else
- ldim_driver.dev_index = para[0];
+ ldim_driver.dev_index = (unsigned char)para[0];
LDIMPR("get ldim_dev_index = %d\n", ldim_driver.dev_index);
return 0;
@@ -4269,6 +4269,10 @@ int aml_ldim_probe(struct platform_device *pdev)
struct ldim_dev_s *devp = &ldim_dev;
struct aml_bl_drv_s *bl_drv = aml_bl_get_driver();
+#ifdef LDIM_DEBUG_INFO
+ ldim_debug_print = 1;
+#endif
+
/* function flag */
ldim_on_flag = 0;
ldim_func_en = 0;
diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h
index 56fb088..1e08047 100644
--- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h
+++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h
@@ -28,11 +28,13 @@
#define Wr(reg, val) aml_write_vcbus(reg, val)
#define Rd(adr) aml_read_vcbus(adr)
-/*#define LDIM_EXT_DEBUG_INFO*/
+/*#define LDIM_DEBUG_INFO*/
#define LDIMPR(fmt, args...) pr_info("ldim: "fmt"", ## args)
#define LDIMERR(fmt, args...) pr_err("ldim: error: "fmt"", ## args)
-#define LDIM_DRV_VER "20180629"
+/*20180629: initial version */
+/*20180725: new pwm control flow support */
+#define LDIM_DRV_VER "20180725"
extern unsigned char ldim_debug_print;
diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c b/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c
index 5b64f47..7f5e91c 100644
--- a/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c
+++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c
@@ -47,7 +47,7 @@ static int ob3350_hw_init_on(void)
ldim_gpio_set(ldim_drv->ldev_conf->en_gpio,
ldim_drv->ldev_conf->en_gpio_on);
mdelay(2);
- ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config));
+
ldim_drv->pinmux_ctrl(ldim_drv->ldev_conf->pinmux_name);
mdelay(20);
@@ -60,42 +60,32 @@ static int ob3350_hw_init_off(void)
ldim_gpio_set(ldim_drv->ldev_conf->en_gpio,
ldim_drv->ldev_conf->en_gpio_off);
+ ldim_pwm_off(&(ldim_drv->ldev_conf->pwm_config));
return 0;
}
-static unsigned int ob3350_get_value(unsigned int level)
-{
- struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
-
- unsigned int val;
- unsigned int dim_max, dim_min;
-
- dim_max = ldim_drv->ldev_conf->dim_max;
- dim_min = ldim_drv->ldev_conf->dim_min;
-
- val = dim_min + ((level * (dim_max - dim_min)) / LD_DATA_MAX);
-
- return val;
-}
-
static int ob3350_smr(unsigned short *buf, unsigned char len)
{
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
- unsigned short val;
+ unsigned int dim_max, dim_min;
+ unsigned int level, val;
if (ob3350_on_flag == 0) {
if (ldim_debug_print)
LDIMPR("%s: on_flag=%d\n", __func__, ob3350_on_flag);
return 0;
- }
+ }
if (len != 1) {
LDIMERR("%s: data len %d invalid\n", __func__, len);
return -1;
}
- val = ob3350_get_value(buf[0]);
+ dim_max = ldim_drv->ldev_conf->dim_max;
+ dim_min = ldim_drv->ldev_conf->dim_min;
+ level = buf[0];
+ val = dim_min + ((level * (dim_max - dim_min)) / LD_DATA_MAX);
ldim_drv->ldev_conf->pwm_config.pwm_duty = val;
ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config));
diff --git a/include/linux/amlogic/media/vout/lcd/aml_ldim.h b/include/linux/amlogic/media/vout/lcd/aml_ldim.h
index c672e41..dac5acc 100644
--- a/include/linux/amlogic/media/vout/lcd/aml_ldim.h
+++ b/include/linux/amlogic/media/vout/lcd/aml_ldim.h
@@ -80,9 +80,10 @@ struct ldim_dev_config_s {
/*******global API******/
struct aml_ldim_driver_s {
- int valid_flag;
- int dev_index;
- int static_pic_flag;
+ unsigned char valid_flag;
+ unsigned char dev_index;
+ unsigned char static_pic_flag;
+ unsigned char pinmux_flag;
struct ldim_config_s *ldim_conf;
struct ldim_dev_config_s *ldev_conf;