- New Drivers

- Add support for KTD253
 
  - Fix-ups
    - Add Device Tree documentation; common, kinetic,ktd253
    - Use correct header(s); tosa_lcd, tosa_bl
 
  - Bug Fixes
    - Fix refcount imbalance; sky81452-backlight
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAl+GrnwACgkQUa+KL4f8
 d2FW1BAAkC9yeO2nfKP74ItegSgFBmNcQocmIU3G9o4jnvJdyEKPWkl973szrrD9
 SoiikF3qGfWIhLpR9yzB55pH5vrr3+eMsFGQAe2SOGB8+jeU7GHMXZZNEYaFxYSM
 L/yBaAqBewJym7xVpr7izCz6OAN7fcPeqtOxRcRFalyBLcn8Khp7M6N5LnyodqhN
 TjVveTCORo2URpLksT85MLIJLN7LmWEorX77vwl5bcH6N82A+TVsVRwzXWqdw2yC
 a6D9Sbvp6NrepH+g2vc08AVC7FKxfsPC3/SHVsMulXYyN5qREEv8jsz/91xromAG
 J4lBhK6MJTaUhdSUqEeryWDaAv7yqwLyTYSa8Ns8rLbzifUlC5evvCNpXDBbyj9i
 SMroVuExvchQlPPnnoYd9nWQjkjbmTFagwFZwoh6iVNH6ftqmFR505b+u9cDLw6f
 jMEcD7Qfmezw16XqoVNfQQom4HyURlgfor1ZkRX5vMCrA7lx2LeagI9pzdmwN4sO
 ngTDljw0pO9Z1OmFDcGp3NQmQj1Iq8R9628nJ/iqOam6oG9cAiRpayrHwKlJ6Idr
 pkSr0d9ayTQzd7IR2caM4LS+z34R3+5UG+7BOU2bn8RG4atyiPz0knDP7ILoWmoC
 1m9++xbBWvP8+yL3IOE2SBnaPSOeA4QDzVZajOuW9lY82IdlqeQ=
 =GZ+j
 -----END PGP SIGNATURE-----

Merge tag 'backlight-next-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight

Pull backlight updates from Lee Jones:
 "New Drivers:
   - Add support for KTD253

  Fix-ups:
   - Add Device Tree documentation; common, kinetic,ktd253
   - Use correct header(s); tosa_lcd, tosa_bl

  Bug Fixes:
   - Fix refcount imbalance; sky81452-backlight"

* tag 'backlight-next-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight:
  backlight: tosa_bl: Include the right header
  backlight: tosa_lcd: Include the right header
  backlight: Add Kinetic KTD253 backlight driver
  dt-bindings: backlight: Add Kinetic KTD253 bindings
  dt-bindings: backlight: Add some common backlight properties
  backlight: sky81452-backlight: Fix refcount imbalance on error
This commit is contained in:
Linus Torvalds 2020-10-14 15:59:42 -07:00
commit 6448cbf662
9 changed files with 296 additions and 2 deletions

View File

@ -0,0 +1,34 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/leds/backlight/common.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Common backlight properties
maintainers:
- Lee Jones <lee.jones@linaro.org>
- Daniel Thompson <daniel.thompson@linaro.org>
- Jingoo Han <jingoohan1@gmail.com>
description:
Backlight devices provide backlight for different types of graphical
displays. They are typically but not necessarily implemented using a white
LED powered by a boost converter.
properties:
default-brightness:
description:
The default brightness that should be applied to the LED by the operating
system on start-up. The brightness should not exceed the brightness the
LED can provide.
$ref: /schemas/types.yaml#definitions/uint32
max-brightness:
description:
Normally the maximum brightness is determined by the hardware and this
property is not required. This property is used to put a software limit
on the brightness apart from what the driver says, as it could happen
that a LED can be made so bright that it gets damaged or causes damage
due to restrictions in a specific system, such as mounting conditions.
$ref: /schemas/types.yaml#definitions/uint32

View File

@ -0,0 +1,46 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/leds/backlight/kinetic,ktd253.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Kinetic Technologies KTD253 one-wire backlight
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
description: |
The Kinetic Technologies KTD253 is a white LED backlight that is
controlled by a single GPIO line. If you just turn on the backlight
it goes to maximum backlight then you can set the level of backlight
using pulses on the enable wire. This is sometimes referred to as
"expresswire".
allOf:
- $ref: common.yaml#
properties:
compatible:
const: kinetic,ktd253
enable-gpios:
description: GPIO to use to enable/disable and dim the backlight.
maxItems: 1
default-brightness: true
max-brightness: true
required:
- compatible
- enable-gpios
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
backlight {
compatible = "kinetic,ktd253";
enable-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
default-brightness = <13>;
};

View File

@ -9760,6 +9760,12 @@ F: Documentation/admin-guide/auxdisplay/ks0108.rst
F: drivers/auxdisplay/ks0108.c
F: include/linux/ks0108.h
KTD253 BACKLIGHT DRIVER
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
F: Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml
F: drivers/video/backlight/ktd253-backlight.c
L3MDEV
M: David Ahern <dsahern@kernel.org>
L: netdev@vger.kernel.org

View File

@ -182,6 +182,14 @@ config BACKLIGHT_IPAQ_MICRO
computers. Say yes if you have one of the h3100/h3600/h3700
machines.
config BACKLIGHT_KTD253
tristate "Backlight Driver for Kinetic KTD253"
depends on GPIOLIB || COMPILE_TEST
help
Say y to enabled the backlight driver for the Kinetic KTD253
which is a 1-wire GPIO-controlled backlight found in some mobile
phones.
config BACKLIGHT_LM3533
tristate "Backlight Driver for LM3533"
depends on MFD_LM3533

View File

@ -35,6 +35,7 @@ obj-$(CONFIG_BACKLIGHT_GPIO) += gpio_backlight.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO) += ipaq_micro_bl.o
obj-$(CONFIG_BACKLIGHT_KTD253) += ktd253-backlight.o
obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o
obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o

View File

@ -0,0 +1,198 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Backlight driver for the Kinetic KTD253
* Based on code and know-how from the Samsung GT-S7710
* Gareth Phillips <gareth.phillips@samsung.com>
*/
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
/* Current ratio is n/32 from 1/32 to 32/32 */
#define KTD253_MIN_RATIO 1
#define KTD253_MAX_RATIO 32
#define KTD253_DEFAULT_RATIO 13
#define KTD253_T_LOW_NS (200 + 10) /* Additional 10ns as safety factor */
#define KTD253_T_HIGH_NS (200 + 10) /* Additional 10ns as safety factor */
#define KTD253_T_OFF_MS 3
struct ktd253_backlight {
struct device *dev;
struct backlight_device *bl;
struct gpio_desc *gpiod;
u16 ratio;
};
static int ktd253_backlight_update_status(struct backlight_device *bl)
{
struct ktd253_backlight *ktd253 = bl_get_data(bl);
int brightness = backlight_get_brightness(bl);
u16 target_ratio;
u16 current_ratio = ktd253->ratio;
unsigned long flags;
dev_dbg(ktd253->dev, "new brightness/ratio: %d/32\n", brightness);
target_ratio = brightness;
if (target_ratio == current_ratio)
/* This is already right */
return 0;
if (target_ratio == 0) {
gpiod_set_value_cansleep(ktd253->gpiod, 0);
/*
* We need to keep the GPIO low for at least this long
* to actually switch the KTD253 off.
*/
msleep(KTD253_T_OFF_MS);
ktd253->ratio = 0;
return 0;
}
if (current_ratio == 0) {
gpiod_set_value_cansleep(ktd253->gpiod, 1);
ndelay(KTD253_T_HIGH_NS);
/* We always fall back to this when we power on */
current_ratio = KTD253_MAX_RATIO;
}
/*
* WARNING:
* The loop to set the correct current level is performed
* with interrupts disabled as it is timing critical.
* The maximum number of cycles of the loop is 32
* so the time taken will be (T_LOW_NS + T_HIGH_NS + loop_time) * 32,
*/
local_irq_save(flags);
while (current_ratio != target_ratio) {
/*
* These GPIO operations absolutely can NOT sleep so no
* _cansleep suffixes, and no using GPIO expanders on
* slow buses for this!
*/
gpiod_set_value(ktd253->gpiod, 0);
ndelay(KTD253_T_LOW_NS);
gpiod_set_value(ktd253->gpiod, 1);
ndelay(KTD253_T_HIGH_NS);
/* After 1/32 we loop back to 32/32 */
if (current_ratio == KTD253_MIN_RATIO)
current_ratio = KTD253_MAX_RATIO;
else
current_ratio--;
}
local_irq_restore(flags);
ktd253->ratio = current_ratio;
dev_dbg(ktd253->dev, "new ratio set to %d/32\n", target_ratio);
return 0;
}
static const struct backlight_ops ktd253_backlight_ops = {
.options = BL_CORE_SUSPENDRESUME,
.update_status = ktd253_backlight_update_status,
};
static int ktd253_backlight_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct backlight_device *bl;
struct ktd253_backlight *ktd253;
u32 max_brightness;
u32 brightness;
int ret;
ktd253 = devm_kzalloc(dev, sizeof(*ktd253), GFP_KERNEL);
if (!ktd253)
return -ENOMEM;
ktd253->dev = dev;
ret = device_property_read_u32(dev, "max-brightness", &max_brightness);
if (ret)
max_brightness = KTD253_MAX_RATIO;
if (max_brightness > KTD253_MAX_RATIO) {
/* Clamp brightness to hardware max */
dev_err(dev, "illegal max brightness specified\n");
max_brightness = KTD253_MAX_RATIO;
}
ret = device_property_read_u32(dev, "default-brightness", &brightness);
if (ret)
brightness = KTD253_DEFAULT_RATIO;
if (brightness > max_brightness) {
/* Clamp default brightness to max brightness */
dev_err(dev, "default brightness exceeds max brightness\n");
brightness = max_brightness;
}
if (brightness)
/* This will be the default ratio when the KTD253 is enabled */
ktd253->ratio = KTD253_MAX_RATIO;
else
ktd253->ratio = 0;
ktd253->gpiod = devm_gpiod_get(dev, "enable",
brightness ? GPIOD_OUT_HIGH :
GPIOD_OUT_LOW);
if (IS_ERR(ktd253->gpiod)) {
ret = PTR_ERR(ktd253->gpiod);
if (ret != -EPROBE_DEFER)
dev_err(dev, "gpio line missing or invalid.\n");
return ret;
}
gpiod_set_consumer_name(ktd253->gpiod, dev_name(dev));
bl = devm_backlight_device_register(dev, dev_name(dev), dev, ktd253,
&ktd253_backlight_ops, NULL);
if (IS_ERR(bl)) {
dev_err(dev, "failed to register backlight\n");
return PTR_ERR(bl);
}
bl->props.max_brightness = max_brightness;
/* When we just enable the GPIO line we set max brightness */
if (brightness) {
bl->props.brightness = brightness;
bl->props.power = FB_BLANK_UNBLANK;
} else {
bl->props.brightness = 0;
bl->props.power = FB_BLANK_POWERDOWN;
}
ktd253->bl = bl;
platform_set_drvdata(pdev, bl);
backlight_update_status(bl);
return 0;
}
static const struct of_device_id ktd253_backlight_of_match[] = {
{ .compatible = "kinetic,ktd253" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ktd253_backlight_of_match);
static struct platform_driver ktd253_backlight_driver = {
.driver = {
.name = "ktd253-backlight",
.of_match_table = ktd253_backlight_of_match,
},
.probe = ktd253_backlight_probe,
};
module_platform_driver(ktd253_backlight_driver);
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_DESCRIPTION("Kinetic KTD253 Backlight Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ktd253-backlight");

View File

@ -217,6 +217,7 @@ static struct sky81452_bl_platform_data *sky81452_bl_parse_dt(
num_entry);
if (ret < 0) {
dev_err(dev, "led-sources node is invalid.\n");
of_node_put(np);
return ERR_PTR(-EINVAL);
}

View File

@ -11,7 +11,7 @@
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/slab.h>

View File

@ -12,7 +12,7 @@
#include <linux/spi/spi.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/lcd.h>
#include <linux/fb.h>