Skip to content

Commit 706dc68

Browse files
brglLee Jones
authored andcommitted
backlight: gpio: Explicitly set the direction of the GPIO
The GPIO backlight driver currently requests the line 'as is', without acively setting its direction. This can lead to problems: if the line is in input mode by default, we won't be able to drive it later when updating the status and also reading its initial value doesn't make sense for backlight setting. Request the line 'as is' initially, so that we can read its value without affecting it but then change the direction to output explicitly when setting the initial brightness. Also: check the current direction and only read the value if it's output. Signed-off-by: Bartosz Golaszewski <[email protected]> Reviewed-by: Daniel Thompson <[email protected]> Signed-off-by: Lee Jones <[email protected]>
1 parent 3cfc291 commit 706dc68

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

drivers/video/backlight/gpio_backlight.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,23 @@ struct gpio_backlight {
2525
int def_value;
2626
};
2727

28-
static int gpio_backlight_update_status(struct backlight_device *bl)
28+
static int gpio_backlight_get_next_brightness(struct backlight_device *bl)
2929
{
30-
struct gpio_backlight *gbl = bl_get_data(bl);
3130
int brightness = bl->props.brightness;
3231

3332
if (bl->props.power != FB_BLANK_UNBLANK ||
3433
bl->props.fb_blank != FB_BLANK_UNBLANK ||
3534
bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
3635
brightness = 0;
3736

37+
return brightness;
38+
}
39+
40+
static int gpio_backlight_update_status(struct backlight_device *bl)
41+
{
42+
struct gpio_backlight *gbl = bl_get_data(bl);
43+
int brightness = gpio_backlight_get_next_brightness(bl);
44+
3845
gpiod_set_value_cansleep(gbl->gpiod, brightness);
3946

4047
return 0;
@@ -85,7 +92,8 @@ static int gpio_backlight_initial_power_state(struct gpio_backlight *gbl)
8592
return gbl->def_value ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
8693

8794
/* if the enable GPIO is disabled, do not enable the backlight */
88-
if (gpiod_get_value_cansleep(gbl->gpiod) == 0)
95+
if (gpiod_get_direction(gbl->gpiod) == 0 &&
96+
gpiod_get_value_cansleep(gbl->gpiod) == 0)
8997
return FB_BLANK_POWERDOWN;
9098

9199
return FB_BLANK_UNBLANK;
@@ -98,7 +106,7 @@ static int gpio_backlight_probe(struct platform_device *pdev)
98106
struct backlight_properties props;
99107
struct backlight_device *bl;
100108
struct gpio_backlight *gbl;
101-
int ret;
109+
int ret, init_brightness;
102110

103111
gbl = devm_kzalloc(&pdev->dev, sizeof(*gbl), GFP_KERNEL);
104112
if (gbl == NULL)
@@ -151,7 +159,12 @@ static int gpio_backlight_probe(struct platform_device *pdev)
151159
bl->props.power = gpio_backlight_initial_power_state(gbl);
152160
bl->props.brightness = 1;
153161

154-
backlight_update_status(bl);
162+
init_brightness = gpio_backlight_get_next_brightness(bl);
163+
ret = gpiod_direction_output(gbl->gpiod, init_brightness);
164+
if (ret) {
165+
dev_err(&pdev->dev, "failed to set initial brightness\n");
166+
return ret;
167+
}
155168

156169
platform_set_drvdata(pdev, bl);
157170
return 0;

0 commit comments

Comments
 (0)