Skip to content
Snippets Groups Projects
Commit a7056983 authored by Gianfranco Mariotti's avatar Gianfranco Mariotti
Browse files

[DRIVER] pwm_bl: add dts property enable-delay

Add a DT property for configurable delay on the backlight enable GPIO.
parent 9487adc7
No related branches found
No related tags found
No related merge requests found
......@@ -18,6 +18,7 @@
#include <linux/pwm_backlight.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
struct pwm_bl_data {
struct pwm_device *pwm;
......@@ -31,6 +32,9 @@ struct pwm_bl_data {
bool legacy;
unsigned int post_pwm_on_delay;
unsigned int pwm_off_delay;
struct delayed_work pwmg_oneshot_work;
struct workqueue_struct *pwmg_workq;
unsigned int enable_delay;
int (*notify)(struct device *,
int brightness);
void (*notify_after)(struct device *,
......@@ -40,6 +44,15 @@ struct pwm_bl_data {
char fb_id[16];
};
#define PWMG_WORK_POLLING_JIFFIES msecs_to_jiffies(pb->enable_delay)
static void pwmg_oneshot_work_handler(struct work_struct *work)
{
struct pwm_bl_data *pb = container_of(work, struct pwm_bl_data, pwmg_oneshot_work.work);
gpiod_set_value_cansleep(pb->enable_gpio, 1);
return;
}
static void pwm_backlight_power_on(struct pwm_bl_data *pb)
{
struct pwm_state state;
......@@ -60,7 +73,8 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb)
msleep(pb->post_pwm_on_delay);
if (pb->enable_gpio)
gpiod_set_value_cansleep(pb->enable_gpio, 1);
if (pb->pwmg_workq)
queue_delayed_work(pb->pwmg_workq, &pb->pwmg_oneshot_work, PWMG_WORK_POLLING_JIFFIES);
pb->enabled = true;
}
......@@ -270,6 +284,10 @@ static int pwm_backlight_parse_dt(struct device *dev,
&data->post_pwm_on_delay);
of_property_read_u32(node, "pwm-off-delay-ms", &data->pwm_off_delay);
ret = of_property_read_u32(node, "enable-delay", &data->enable_delay);
if ( data->enable_delay < 0 )
data->enable_delay = 0;
/*
* Determine the number of brightness levels, if this property is not
* set a default table of brightness levels will be used.
......@@ -515,14 +533,23 @@ static int pwm_backlight_probe(struct platform_device *pdev)
/*
* If the GPIO is not known to be already configured as output, that
* is, if gpiod_get_direction returns either 1 or -EINVAL, change the
* direction to output and set the GPIO as active.
* Do not force the GPIO to active when it was already output as it
* could cause backlight flickering or we would enable the backlight too
* early. Leave the decision of the initial backlight state for later.
* direction to output and set the GPIO to low.
* Do not force the GPIO value if it was already output as it
* could cause backlight flickering and leave the decision
* of the backlight state for later.
*/
if (pb->enable_gpio &&
gpiod_get_direction(pb->enable_gpio) != 0)
gpiod_direction_output(pb->enable_gpio, 1);
gpiod_direction_output(pb->enable_gpio, 0);
pb->enable_delay = data->enable_delay;
pb->pwmg_workq = create_singlethread_workqueue("pwmg_oneshot");
if (pb->pwmg_workq == NULL) {
ret = -ENOMEM;
goto err_alloc;
}
INIT_DELAYED_WORK(&pb->pwmg_oneshot_work, pwmg_oneshot_work_handler);
pb->power_supply = devm_regulator_get(&pdev->dev, "power");
if (IS_ERR(pb->power_supply)) {
......
......@@ -16,6 +16,7 @@ struct platform_pwm_backlight_data {
unsigned int *levels;
unsigned int post_pwm_on_delay;
unsigned int pwm_off_delay;
unsigned int enable_delay;
/* TODO remove once all users are switched to gpiod_* API */
int enable_gpio;
int (*init)(struct device *dev);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment