Skip to content

Commit 15da270

Browse files
committed
video: backlight: Add support for Richtek RT8555 Backlight
The Richtek RT8555 is a 6 channel LED driver that supports up to 35mA/LED. This is a backlight driver that drives ILED1. Signed-off-by: Michael Abood <[email protected]>
1 parent edd4ec0 commit 15da270

File tree

3 files changed

+177
-0
lines changed

3 files changed

+177
-0
lines changed

drivers/video/backlight/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,15 @@ config BACKLIGHT_RT4831
297297
It's commonly used to drive the display WLED. There're four channels
298298
inisde, and each channel can provide up to 30mA current.
299299

300+
config BACKLIGHT_RT8555
301+
tristate "Richtek RT8555 Backlight Driver"
302+
depends on I2C
303+
select REGMAP_I2C
304+
help
305+
This enables support for Richtek RT8555 Backlight driver.
306+
It's commonly used to drive the display WLED. There are six channels
307+
inisde, and each channel can provide up to 35mA current.
308+
300309
config BACKLIGHT_SAHARA
301310
tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
302311
depends on X86

drivers/video/backlight/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
5050
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
5151
obj-$(CONFIG_BACKLIGHT_QCOM_WLED) += qcom-wled.o
5252
obj-$(CONFIG_BACKLIGHT_RT4831) += rt4831-backlight.o
53+
obj-$(CONFIG_BACKLIGHT_RT8555) += rt8555-backlight.o
5354
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
5455
obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
5556
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
3+
#include <dt-bindings/leds/rt4831-backlight.h>
4+
#include <linux/backlight.h>
5+
#include <linux/bitops.h>
6+
#include <linux/kernel.h>
7+
#include <linux/module.h>
8+
#include <linux/gpio/consumer.h>
9+
#include <linux/platform_device.h>
10+
#include <linux/property.h>
11+
#include <linux/regmap.h>
12+
13+
#define RT8555_MAX_BRIGHTNESS 1023
14+
15+
#define RT8555_REG_CFG1 0x01
16+
#define RT8555_REG_ILED1_LSB 0x04
17+
#define RT8555_REG_ILED1_MSB 0x05
18+
19+
#define RT8555_EN10BIT_MASK BIT(7)
20+
#define RT8555_LSB_MASK GENMASK(7, 0)
21+
22+
struct rt8555_priv {
23+
struct device *dev;
24+
struct regmap *regmap;
25+
struct backlight_device *bl;
26+
struct gpio_desc *enable;
27+
};
28+
29+
static int rt8555_bl_update_status(struct backlight_device *bl_dev)
30+
{
31+
struct rt8555_priv *priv = bl_get_data(bl_dev);
32+
unsigned int brightness = min(backlight_get_brightness(bl_dev), RT8555_MAX_BRIGHTNESS);
33+
int ret;
34+
35+
/* Enable the IC before setting the brightness */
36+
if (brightness)
37+
if (!IS_ERR(priv->enable))
38+
gpiod_set_value(priv->enable, 1);
39+
40+
41+
ret = regmap_write(priv->regmap, RT8555_REG_ILED1_LSB, (brightness & RT8555_LSB_MASK));
42+
if (ret)
43+
return ret;
44+
45+
ret = regmap_write(priv->regmap, RT8555_REG_ILED1_MSB, (brightness >> 8));
46+
if (ret)
47+
return ret;
48+
49+
/* Disable the IC after setting it to 0 */
50+
if (brightness == 0)
51+
if (!IS_ERR(priv->enable))
52+
gpiod_set_value(priv->enable, 0);
53+
54+
return 0;
55+
}
56+
57+
static int rt8555_bl_get_brightness(struct backlight_device *bl_dev)
58+
{
59+
struct rt8555_priv *priv = bl_get_data(bl_dev);
60+
int ret, msb, lsb;
61+
62+
/* If the RT8555 is disabled, there's no reason to turn it on just to read
63+
* it back */
64+
if (!IS_ERR(priv->enable))
65+
if (gpiod_get_value(priv->enable) == 0)
66+
return 0;
67+
68+
ret = regmap_read(priv->regmap, RT8555_REG_ILED1_MSB, &msb);
69+
if (ret)
70+
return ret;
71+
72+
ret = regmap_read(priv->regmap, RT8555_REG_ILED1_LSB, &lsb);
73+
if (ret)
74+
return ret;
75+
76+
ret = (lsb >> 8) & msb;
77+
return ret;
78+
}
79+
80+
static const struct backlight_ops rt8555_bl_ops = {
81+
.options = BL_CORE_SUSPENDRESUME,
82+
.update_status = rt8555_bl_update_status,
83+
.get_brightness = rt8555_bl_get_brightness,
84+
};
85+
86+
static const struct regmap_config rt8555_regmap_config = {
87+
.reg_bits = 8,
88+
.val_bits = 8,
89+
};
90+
91+
static int rt8555_bl_probe(struct i2c_client *client)
92+
{
93+
struct rt8555_priv *priv;
94+
struct backlight_properties bl_props = { .type = BACKLIGHT_RAW,
95+
.scale = BACKLIGHT_SCALE_LINEAR };
96+
int ret;
97+
u32 brightness;
98+
99+
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
100+
if (!priv)
101+
return -ENOMEM;
102+
103+
priv->dev = &client->dev;
104+
105+
priv->enable = devm_gpiod_get_optional(&client->dev, NULL, GPIOD_OUT_HIGH);
106+
if (!IS_ERR(priv->enable))
107+
gpiod_set_value(priv->enable, 1);
108+
109+
ret = device_property_read_u32(&client->dev, "max-brightness", &brightness);
110+
if (ret)
111+
brightness = RT8555_MAX_BRIGHTNESS;
112+
113+
bl_props.max_brightness = min_t(u32, brightness, RT8555_MAX_BRIGHTNESS);
114+
115+
ret = device_property_read_u32(&client->dev, "default-brightness", &brightness);
116+
if (ret)
117+
brightness = bl_props.max_brightness;
118+
119+
bl_props.brightness = min_t(u32, brightness, bl_props.max_brightness);
120+
121+
priv->bl = devm_backlight_device_register(&client->dev, client->name, &client->dev, priv,
122+
&rt8555_bl_ops, &bl_props);
123+
if (IS_ERR(priv->bl)) {
124+
dev_err(&client->dev, "Failed to register backlight\n");
125+
return PTR_ERR(priv->bl);
126+
}
127+
128+
/* Set 10 bit mode */
129+
ret = regmap_update_bits(priv->regmap, RT8555_REG_CFG1, RT8555_EN10BIT_MASK, BIT(7));
130+
if (ret)
131+
return ret;
132+
133+
backlight_update_status(priv->bl);
134+
i2c_set_clientdata(client, priv);
135+
136+
return 0;
137+
}
138+
139+
static void rt8555_bl_remove(struct i2c_client *client)
140+
{
141+
struct rt8555_priv *priv = i2c_get_clientdata(client);
142+
struct backlight_device *bl_dev = priv->bl;
143+
144+
bl_dev->props.brightness = 0;
145+
backlight_update_status(priv->bl);
146+
147+
if (!IS_ERR(priv->enable))
148+
gpiod_set_value(priv->enable, 0);
149+
}
150+
151+
static const struct of_device_id __maybe_unused rt8555_bl_of_match[] = {
152+
{ .compatible = "richtek,rt8555-backlight", },
153+
{}
154+
};
155+
MODULE_DEVICE_TABLE(of, rt8555_bl_of_match);
156+
157+
static struct i2c_driver rt8555_bl_driver = {
158+
.driver = {
159+
.name = "rt8555-backlight",
160+
.of_match_table = rt8555_bl_of_match
161+
},
162+
.probe_new = rt8555_bl_probe,
163+
.shutdown = rt8555_bl_remove
164+
};
165+
module_i2c_driver(rt8555_bl_driver);
166+
MODULE_AUTHOR("Michael Abood <[email protected]>");
167+
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)