mirror of https://gitee.com/openkylin/linux.git
- Core Frameworks
- Obtain scale type through sysfs - New Functionality - Provide Device Tree functionality; rave-sp-backlight - Calculate if scale type is (non-)linear; pwm_bl - Fix-ups - Simplify code; lm3630a_bl - Trivial rename/whitespace/typo fixes; lms283gf05 - Remove superfluous NULL check; tosa_lcd - Fix power state initialisation; gpio_backlight - List supported file; MAINTAINERS - Bug Fixes - Kconfig - default to not building unless requested; {LED,BACKLIGHT}_CLASS_DEVICE -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAl2JTwMACgkQUa+KL4f8 d2EC7g/+Pliuvx8dgW+MPX8K6cnap+m7xV8Z9OyyEYHroz+MX7TsBGmJeChoOz9K RoFCap5VCtEEyiobDbe8HKpxivY88CdweegYxxBx+Uo9qJRogDv93kqVz3BmHxBm v2ShTY+8r2nf6YNN30FXZJSM4WkFqAg2MvM6LXP3R4rPSQ/u2Xp6L5VnzVETl23b /ZsP71axvwDNpi437ekUSoraUl9GZnHaINc7/0R/SnRPvZ2aakko7IRNYU0z+NQ+ unImiBpFjuC1UXDaebd2Bt9ayrM47QkBGLu6LgOTUSg9tFlosvF6Z3TDLo3L2ptD Td5SWuTXALFaOv1xmMaylcsA/36D/KRhwnmQMVn/Ld5c/M+l4vOm4YDNgS1G8JY4 i7KzoD7Z2yhyI3OHYoBGXI8+fmj2qQs+VGThtdhb96LlaHVUibfSlA0i5OjeMKO+ ddiTy9ksiH+pBcn0YPvHJRNOI0uVmqBMSPkJ1Bdwz6HS58QcL3LvBzHtMVNoGkCK iWPPn90hveZmbXAxFIb8a2KRjFz531sReSZh+9dIZ/zOOF5OdyOotMk1zacWCUrt Jre1paR4W1VPXf4cE3IcpE6dJeA9DN9niz+9bsMgbr6cYG6xhB7xELrTUCXZn5CR C9tNMWuiqUlv0NZHb7CsifQW1bwzw8hTPhDk9VpBb0cFCucLYV0= =DSnC -----END PGP SIGNATURE----- Merge tag 'backlight-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight Pull backlight updates from Lee Jones: "Core Frameworks - Obtain scale type through sysfs New Functionality: - Provide Device Tree functionality in rave-sp-backlight - Calculate if scale type is (non-)linear in pwm_bl Fix-ups: - Simplify code in lm3630a_bl - Trivial rename/whitespace/typo fixes in lms283gf05 - Remove superfluous NULL check in tosa_lcd - Fix power state initialisation in gpio_backlight - List supported file in MAINTAINERS Bug Fixes: - Kconfig - default to not building unless requested in {LED,BACKLIGHT}_CLASS_DEVICE" * tag 'backlight-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight: backlight: pwm_bl: Set scale type for brightness curves specified in the DT backlight: pwm_bl: Set scale type for CIE 1931 curves backlight: Expose brightness curve type through sysfs MAINTAINERS: Add entry for stable backlight sysfs ABI documentation backlight: gpio-backlight: Correct initial power state handling video: backlight: tosa_lcd: drop check because i2c_unregister_device() is NULL safe video: backlight: Drop default m for {LCD,BACKLIGHT_CLASS_DEVICE} backlight: lms283gf05: Fix a typo in the description passed to 'devm_gpio_request_one()' backlight: lm3630a: Switch to use fwnode_property_count_uXX() backlight: rave-sp: Leave initial state and register with correct device
This commit is contained in:
commit
d0b3cfee33
|
@ -0,0 +1,26 @@
|
||||||
|
What: /sys/class/backlight/<backlight>/scale
|
||||||
|
Date: July 2019
|
||||||
|
KernelVersion: 5.4
|
||||||
|
Contact: Daniel Thompson <daniel.thompson@linaro.org>
|
||||||
|
Description:
|
||||||
|
Description of the scale of the brightness curve.
|
||||||
|
|
||||||
|
The human eye senses brightness approximately logarithmically,
|
||||||
|
hence linear changes in brightness are perceived as being
|
||||||
|
non-linear. To achieve a linear perception of brightness changes
|
||||||
|
controls like sliders need to apply a logarithmic mapping for
|
||||||
|
backlights with a linear brightness curve.
|
||||||
|
|
||||||
|
Possible values of the attribute are:
|
||||||
|
|
||||||
|
unknown
|
||||||
|
The scale of the brightness curve is unknown.
|
||||||
|
|
||||||
|
linear
|
||||||
|
The brightness changes linearly with each step. Brightness
|
||||||
|
controls should apply a logarithmic mapping for a linear
|
||||||
|
perception.
|
||||||
|
|
||||||
|
non-linear
|
||||||
|
The brightness changes non-linearly with each step. Brightness
|
||||||
|
controls should use a linear mapping for a linear perception.
|
|
@ -2921,6 +2921,8 @@ F: drivers/video/backlight/
|
||||||
F: include/linux/backlight.h
|
F: include/linux/backlight.h
|
||||||
F: include/linux/pwm_backlight.h
|
F: include/linux/pwm_backlight.h
|
||||||
F: Documentation/devicetree/bindings/leds/backlight
|
F: Documentation/devicetree/bindings/leds/backlight
|
||||||
|
F: Documentation/ABI/stable/sysfs-class-backlight
|
||||||
|
F: Documentation/ABI/testing/sysfs-class-backlight
|
||||||
|
|
||||||
BATMAN ADVANCED
|
BATMAN ADVANCED
|
||||||
M: Marek Lindner <mareklindner@neomailbox.ch>
|
M: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
|
|
@ -10,7 +10,6 @@ menu "Backlight & LCD device support"
|
||||||
#
|
#
|
||||||
config LCD_CLASS_DEVICE
|
config LCD_CLASS_DEVICE
|
||||||
tristate "Lowlevel LCD controls"
|
tristate "Lowlevel LCD controls"
|
||||||
default m
|
|
||||||
help
|
help
|
||||||
This framework adds support for low-level control of LCD.
|
This framework adds support for low-level control of LCD.
|
||||||
Some framebuffer devices connect to platform-specific LCD modules
|
Some framebuffer devices connect to platform-specific LCD modules
|
||||||
|
@ -143,7 +142,6 @@ endif # LCD_CLASS_DEVICE
|
||||||
#
|
#
|
||||||
config BACKLIGHT_CLASS_DEVICE
|
config BACKLIGHT_CLASS_DEVICE
|
||||||
tristate "Lowlevel Backlight controls"
|
tristate "Lowlevel Backlight controls"
|
||||||
default m
|
|
||||||
help
|
help
|
||||||
This framework adds support for low-level control of the LCD
|
This framework adds support for low-level control of the LCD
|
||||||
backlight. This includes support for brightness and power.
|
backlight. This includes support for brightness and power.
|
||||||
|
|
|
@ -32,6 +32,12 @@ static const char *const backlight_types[] = {
|
||||||
[BACKLIGHT_FIRMWARE] = "firmware",
|
[BACKLIGHT_FIRMWARE] = "firmware",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *const backlight_scale_types[] = {
|
||||||
|
[BACKLIGHT_SCALE_UNKNOWN] = "unknown",
|
||||||
|
[BACKLIGHT_SCALE_LINEAR] = "linear",
|
||||||
|
[BACKLIGHT_SCALE_NON_LINEAR] = "non-linear",
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
|
#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
|
||||||
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
|
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
|
||||||
/* This callback gets called when something important happens inside a
|
/* This callback gets called when something important happens inside a
|
||||||
|
@ -246,6 +252,18 @@ static ssize_t actual_brightness_show(struct device *dev,
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR_RO(actual_brightness);
|
static DEVICE_ATTR_RO(actual_brightness);
|
||||||
|
|
||||||
|
static ssize_t scale_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct backlight_device *bd = to_backlight_device(dev);
|
||||||
|
|
||||||
|
if (WARN_ON(bd->props.scale > BACKLIGHT_SCALE_NON_LINEAR))
|
||||||
|
return sprintf(buf, "unknown\n");
|
||||||
|
|
||||||
|
return sprintf(buf, "%s\n", backlight_scale_types[bd->props.scale]);
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(scale);
|
||||||
|
|
||||||
static struct class *backlight_class;
|
static struct class *backlight_class;
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
@ -292,6 +310,7 @@ static struct attribute *bl_device_attrs[] = {
|
||||||
&dev_attr_brightness.attr,
|
&dev_attr_brightness.attr,
|
||||||
&dev_attr_actual_brightness.attr,
|
&dev_attr_actual_brightness.attr,
|
||||||
&dev_attr_max_brightness.attr,
|
&dev_attr_max_brightness.attr,
|
||||||
|
&dev_attr_scale.attr,
|
||||||
&dev_attr_type.attr,
|
&dev_attr_type.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,13 +59,11 @@ static int gpio_backlight_probe_dt(struct platform_device *pdev,
|
||||||
struct gpio_backlight *gbl)
|
struct gpio_backlight *gbl)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
enum gpiod_flags flags;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
gbl->def_value = device_property_read_bool(dev, "default-on");
|
gbl->def_value = device_property_read_bool(dev, "default-on");
|
||||||
flags = gbl->def_value ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
|
|
||||||
|
|
||||||
gbl->gpiod = devm_gpiod_get(dev, NULL, flags);
|
gbl->gpiod = devm_gpiod_get(dev, NULL, GPIOD_ASIS);
|
||||||
if (IS_ERR(gbl->gpiod)) {
|
if (IS_ERR(gbl->gpiod)) {
|
||||||
ret = PTR_ERR(gbl->gpiod);
|
ret = PTR_ERR(gbl->gpiod);
|
||||||
|
|
||||||
|
@ -79,6 +77,22 @@ static int gpio_backlight_probe_dt(struct platform_device *pdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gpio_backlight_initial_power_state(struct gpio_backlight *gbl)
|
||||||
|
{
|
||||||
|
struct device_node *node = gbl->dev->of_node;
|
||||||
|
|
||||||
|
/* Not booted with device tree or no phandle link to the node */
|
||||||
|
if (!node || !node->phandle)
|
||||||
|
return gbl->def_value ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
|
||||||
|
|
||||||
|
/* if the enable GPIO is disabled, do not enable the backlight */
|
||||||
|
if (gpiod_get_value_cansleep(gbl->gpiod) == 0)
|
||||||
|
return FB_BLANK_POWERDOWN;
|
||||||
|
|
||||||
|
return FB_BLANK_UNBLANK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int gpio_backlight_probe(struct platform_device *pdev)
|
static int gpio_backlight_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct gpio_backlight_platform_data *pdata =
|
struct gpio_backlight_platform_data *pdata =
|
||||||
|
@ -136,7 +150,9 @@ static int gpio_backlight_probe(struct platform_device *pdev)
|
||||||
return PTR_ERR(bl);
|
return PTR_ERR(bl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bl->props.brightness = gbl->def_value;
|
bl->props.power = gpio_backlight_initial_power_state(gbl);
|
||||||
|
bl->props.brightness = 1;
|
||||||
|
|
||||||
backlight_update_status(bl);
|
backlight_update_status(bl);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, bl);
|
platform_set_drvdata(pdev, bl);
|
||||||
|
|
|
@ -377,8 +377,7 @@ static int lm3630a_parse_led_sources(struct fwnode_handle *node,
|
||||||
u32 sources[LM3630A_NUM_SINKS];
|
u32 sources[LM3630A_NUM_SINKS];
|
||||||
int ret, num_sources, i;
|
int ret, num_sources, i;
|
||||||
|
|
||||||
num_sources = fwnode_property_read_u32_array(node, "led-sources", NULL,
|
num_sources = fwnode_property_count_u32(node, "led-sources");
|
||||||
0);
|
|
||||||
if (num_sources < 0)
|
if (num_sources < 0)
|
||||||
return default_led_sources;
|
return default_led_sources;
|
||||||
else if (num_sources > ARRAY_SIZE(sources))
|
else if (num_sources > ARRAY_SIZE(sources))
|
||||||
|
|
|
@ -158,7 +158,7 @@ static int lms283gf05_probe(struct spi_device *spi)
|
||||||
ret = devm_gpio_request_one(&spi->dev, pdata->reset_gpio,
|
ret = devm_gpio_request_one(&spi->dev, pdata->reset_gpio,
|
||||||
GPIOF_DIR_OUT | (!pdata->reset_inverted ?
|
GPIOF_DIR_OUT | (!pdata->reset_inverted ?
|
||||||
GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
|
GPIOF_INIT_HIGH : GPIOF_INIT_LOW),
|
||||||
"LMS285GF05 RESET");
|
"LMS283GF05 RESET");
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,6 +387,31 @@ int pwm_backlight_brightness_default(struct device *dev,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool pwm_backlight_is_linear(struct platform_pwm_backlight_data *data)
|
||||||
|
{
|
||||||
|
unsigned int nlevels = data->max_brightness + 1;
|
||||||
|
unsigned int min_val = data->levels[0];
|
||||||
|
unsigned int max_val = data->levels[nlevels - 1];
|
||||||
|
/*
|
||||||
|
* Multiplying by 128 means that even in pathological cases such
|
||||||
|
* as (max_val - min_val) == nlevels the error at max_val is less
|
||||||
|
* than 1%.
|
||||||
|
*/
|
||||||
|
unsigned int slope = (128 * (max_val - min_val)) / nlevels;
|
||||||
|
unsigned int margin = (max_val - min_val) / 20; /* 5% */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < nlevels; i++) {
|
||||||
|
unsigned int linear_value = min_val + ((i * slope) / 128);
|
||||||
|
unsigned int delta = abs(linear_value - data->levels[i]);
|
||||||
|
|
||||||
|
if (delta > margin)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
|
static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
|
||||||
{
|
{
|
||||||
struct device_node *node = pb->dev->of_node;
|
struct device_node *node = pb->dev->of_node;
|
||||||
|
@ -536,6 +561,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&props, 0, sizeof(struct backlight_properties));
|
||||||
|
|
||||||
if (data->levels) {
|
if (data->levels) {
|
||||||
/*
|
/*
|
||||||
* For the DT case, only when brightness levels is defined
|
* For the DT case, only when brightness levels is defined
|
||||||
|
@ -548,6 +575,11 @@ static int pwm_backlight_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
pb->levels = data->levels;
|
pb->levels = data->levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pwm_backlight_is_linear(data))
|
||||||
|
props.scale = BACKLIGHT_SCALE_LINEAR;
|
||||||
|
else
|
||||||
|
props.scale = BACKLIGHT_SCALE_NON_LINEAR;
|
||||||
} else if (!data->max_brightness) {
|
} else if (!data->max_brightness) {
|
||||||
/*
|
/*
|
||||||
* If no brightness levels are provided and max_brightness is
|
* If no brightness levels are provided and max_brightness is
|
||||||
|
@ -574,6 +606,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
pb->levels = data->levels;
|
pb->levels = data->levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props.scale = BACKLIGHT_SCALE_NON_LINEAR;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* That only happens for the non-DT case, where platform data
|
* That only happens for the non-DT case, where platform data
|
||||||
|
@ -584,7 +618,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
pb->lth_brightness = data->lth_brightness * (state.period / pb->scale);
|
pb->lth_brightness = data->lth_brightness * (state.period / pb->scale);
|
||||||
|
|
||||||
memset(&props, 0, sizeof(struct backlight_properties));
|
|
||||||
props.type = BACKLIGHT_RAW;
|
props.type = BACKLIGHT_RAW;
|
||||||
props.max_brightness = data->max_brightness;
|
props.max_brightness = data->max_brightness;
|
||||||
bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
|
bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
|
||||||
|
|
|
@ -48,14 +48,20 @@ static int rave_sp_backlight_probe(struct platform_device *pdev)
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct backlight_device *bd;
|
struct backlight_device *bd;
|
||||||
|
|
||||||
bd = devm_backlight_device_register(dev, pdev->name, dev->parent,
|
bd = devm_backlight_device_register(dev, pdev->name, dev,
|
||||||
dev_get_drvdata(dev->parent),
|
dev_get_drvdata(dev->parent),
|
||||||
&rave_sp_backlight_ops,
|
&rave_sp_backlight_ops,
|
||||||
&rave_sp_backlight_props);
|
&rave_sp_backlight_props);
|
||||||
if (IS_ERR(bd))
|
if (IS_ERR(bd))
|
||||||
return PTR_ERR(bd);
|
return PTR_ERR(bd);
|
||||||
|
|
||||||
backlight_update_status(bd);
|
/*
|
||||||
|
* If there is a phandle pointing to the device node we can
|
||||||
|
* assume that another device will manage the status changes.
|
||||||
|
* If not we make sure the backlight is in a consistent state.
|
||||||
|
*/
|
||||||
|
if (!dev->of_node->phandle)
|
||||||
|
backlight_update_status(bd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,8 +222,7 @@ static int tosa_lcd_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
struct tosa_lcd_data *data = spi_get_drvdata(spi);
|
struct tosa_lcd_data *data = spi_get_drvdata(spi);
|
||||||
|
|
||||||
if (data->i2c)
|
i2c_unregister_device(data->i2c);
|
||||||
i2c_unregister_device(data->i2c);
|
|
||||||
|
|
||||||
tosa_lcd_tg_off(data);
|
tosa_lcd_tg_off(data);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,12 @@ enum backlight_notification {
|
||||||
BACKLIGHT_UNREGISTERED,
|
BACKLIGHT_UNREGISTERED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum backlight_scale {
|
||||||
|
BACKLIGHT_SCALE_UNKNOWN = 0,
|
||||||
|
BACKLIGHT_SCALE_LINEAR,
|
||||||
|
BACKLIGHT_SCALE_NON_LINEAR,
|
||||||
|
};
|
||||||
|
|
||||||
struct backlight_device;
|
struct backlight_device;
|
||||||
struct fb_info;
|
struct fb_info;
|
||||||
|
|
||||||
|
@ -80,6 +86,8 @@ struct backlight_properties {
|
||||||
enum backlight_type type;
|
enum backlight_type type;
|
||||||
/* Flags used to signal drivers of state changes */
|
/* Flags used to signal drivers of state changes */
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
|
/* Type of the brightness scale (linear, non-linear, ...) */
|
||||||
|
enum backlight_scale scale;
|
||||||
|
|
||||||
#define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */
|
#define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */
|
||||||
#define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */
|
#define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */
|
||||||
|
|
Loading…
Reference in New Issue