blob: 00297a09b7fcee613e723d34fa2c14462266d3fa [file] [log] [blame]
Svyatoslav Ryhel3e9488a2023-04-25 10:51:42 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2022 Svyatoslav Ryhel <clamor95@gmail.com>
4 */
5
6#define LOG_CATEGORY UCLASS_PANEL_BACKLIGHT
7
8#include <backlight.h>
9#include <common.h>
10#include <dm.h>
11#include <i2c.h>
12#include <log.h>
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <asm/gpio.h>
16
17#define LM3533_BL_MIN_BRIGHTNESS 0x02
18#define LM3533_BL_MAX_BRIGHTNESS 0xFF
19
20#define LM3533_SINK_OUTPUT_CONFIG_1 0x10
21#define LM3533_CONTROL_BANK_A_PWM 0x14
22#define LM3533_CONTROL_BANK_AB_BRIGHTNESS 0x1A
23#define LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT 0x1F
24#define LM3533_CONTROL_BANK_ENABLE 0x27
25#define LM3533_OVP_FREQUENCY_PWM_POLARITY 0x2C
26#define LM3533_BRIGHTNESS_REGISTER_A 0x40
27
28struct lm3533_backlight_priv {
29 struct gpio_desc enable_gpio;
30 u32 def_bl_lvl;
31};
32
33static int lm3533_backlight_enable(struct udevice *dev)
34{
35 struct lm3533_backlight_priv *priv = dev_get_priv(dev);
36 int ret;
37
38 dm_gpio_set_value(&priv->enable_gpio, 1);
39 mdelay(5);
40
41 /* HVLED 1 & 2 are controlled by Bank A */
42 ret = dm_i2c_reg_write(dev, LM3533_SINK_OUTPUT_CONFIG_1, 0x00);
43 if (ret)
44 return ret;
45
46 /* PWM input is disabled for CABC */
47 ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_A_PWM, 0x00);
48 if (ret)
49 return ret;
50
51 /* Linear & Control Bank A is configured for register Current control */
52 ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_AB_BRIGHTNESS, 0x02);
53 if (ret)
54 return ret;
55
56 /* Full-Scale Current (20.2mA) */
57 ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT, 0x13);
58 if (ret)
59 return ret;
60
61 /* Control Bank A is enable */
62 ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_ENABLE, 0x01);
63 if (ret)
64 return ret;
65
66 ret = dm_i2c_reg_write(dev, LM3533_OVP_FREQUENCY_PWM_POLARITY, 0x0A);
67 if (ret)
68 return ret;
69
70 return 0;
71}
72
73static int lm3533_backlight_set_brightness(struct udevice *dev, int percent)
74{
75 struct lm3533_backlight_priv *priv = dev_get_priv(dev);
76 int ret;
77
78 if (percent == BACKLIGHT_DEFAULT)
79 percent = priv->def_bl_lvl;
80
81 if (percent < LM3533_BL_MIN_BRIGHTNESS)
82 percent = LM3533_BL_MIN_BRIGHTNESS;
83
84 if (percent > LM3533_BL_MAX_BRIGHTNESS)
85 percent = LM3533_BL_MAX_BRIGHTNESS;
86
87 /* Set brightness level */
88 ret = dm_i2c_reg_write(dev, LM3533_BRIGHTNESS_REGISTER_A,
89 percent);
90 if (ret)
91 return ret;
92
93 return 0;
94}
95
96static int lm3533_backlight_probe(struct udevice *dev)
97{
98 struct lm3533_backlight_priv *priv = dev_get_priv(dev);
99 int ret;
100
101 if (device_get_uclass_id(dev->parent) != UCLASS_I2C)
102 return -EPROTONOSUPPORT;
103
104 ret = gpio_request_by_name(dev, "enable-gpios", 0,
105 &priv->enable_gpio, GPIOD_IS_OUT);
106 if (ret) {
107 log_err("Could not decode enable-gpios (%d)\n", ret);
108 return ret;
109 }
110
111 priv->def_bl_lvl = dev_read_u32_default(dev, "default-brightness-level",
112 LM3533_BL_MAX_BRIGHTNESS);
113
114 return 0;
115}
116
117static const struct backlight_ops lm3533_backlight_ops = {
118 .enable = lm3533_backlight_enable,
119 .set_brightness = lm3533_backlight_set_brightness,
120};
121
122static const struct udevice_id lm3533_backlight_ids[] = {
123 { .compatible = "ti,lm3533" },
124 { }
125};
126
127U_BOOT_DRIVER(lm3533_backlight) = {
128 .name = "lm3533_backlight",
129 .id = UCLASS_PANEL_BACKLIGHT,
130 .of_match = lm3533_backlight_ids,
131 .probe = lm3533_backlight_probe,
132 .ops = &lm3533_backlight_ops,
133 .priv_auto = sizeof(struct lm3533_backlight_priv),
134};