167761Smsmith// SPDX-License-Identifier: GPL-2.0+
267761Smsmith/*
367761Smsmith * Copyright (c) 2022 Svyatoslav Ryhel <clamor95@gmail.com>
467761Smsmith */
567761Smsmith
667761Smsmith#define LOG_CATEGORY UCLASS_PANEL_BACKLIGHT
767761Smsmith
867761Smsmith#include <backlight.h>
967761Smsmith#include <common.h>
1067761Smsmith#include <dm.h>
1167761Smsmith#include <i2c.h>
1267761Smsmith#include <log.h>
1367761Smsmith#include <linux/delay.h>
1467761Smsmith#include <linux/err.h>
1567761Smsmith#include <asm/gpio.h>
1667761Smsmith
1767761Smsmith#define LM3533_BL_MIN_BRIGHTNESS			0x02
1867761Smsmith#define LM3533_BL_MAX_BRIGHTNESS			0xFF
1967761Smsmith
2067761Smsmith#define LM3533_SINK_OUTPUT_CONFIG_1			0x10
2167761Smsmith#define LM3533_CONTROL_BANK_A_PWM			0x14
2267761Smsmith#define LM3533_CONTROL_BANK_AB_BRIGHTNESS		0x1A
2367761Smsmith#define LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT		0x1F
2467761Smsmith#define LM3533_CONTROL_BANK_ENABLE			0x27
2567761Smsmith#define LM3533_OVP_FREQUENCY_PWM_POLARITY		0x2C
2667761Smsmith#define LM3533_BRIGHTNESS_REGISTER_A			0x40
2767761Smsmith
2867761Smsmithstruct lm3533_backlight_priv {
2967761Smsmith	struct gpio_desc enable_gpio;
30119418Sobrien	u32 def_bl_lvl;
31119418Sobrien};
32119418Sobrien
3367761Smsmithstatic int lm3533_backlight_enable(struct udevice *dev)
3467761Smsmith{
3567761Smsmith	struct lm3533_backlight_priv *priv = dev_get_priv(dev);
3667761Smsmith	int ret;
3774914Sjhb
3867761Smsmith	dm_gpio_set_value(&priv->enable_gpio, 1);
3967761Smsmith	mdelay(5);
4067761Smsmith
4167761Smsmith	/* HVLED 1 & 2 are controlled by Bank A */
42119529Snjl	ret = dm_i2c_reg_write(dev, LM3533_SINK_OUTPUT_CONFIG_1, 0x00);
4377432Smsmith	if (ret)
4491123Smsmith		return ret;
4569744Smsmith
4667761Smsmith	/* PWM input is disabled for CABC */
4767761Smsmith	ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_A_PWM, 0x00);
4867761Smsmith	if (ret)
4967761Smsmith		return ret;
5067761Smsmith
5167761Smsmith	/* Linear & Control Bank A is configured for register Current control */
5267761Smsmith	ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_AB_BRIGHTNESS, 0x02);
5367761Smsmith	if (ret)
54100497Siwasaki		return ret;
55100497Siwasaki
5667761Smsmith	/* Full-Scale Current (20.2mA) */
57121493Snjl	ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT, 0x13);
58121493Snjl	if (ret)
5967761Smsmith		return ret;
6067761Smsmith
6167761Smsmith	/* Control Bank A is enable */
6267761Smsmith	ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_ENABLE, 0x01);
6367761Smsmith	if (ret)
64100497Siwasaki		return ret;
65100497Siwasaki
6667761Smsmith	ret = dm_i2c_reg_write(dev, LM3533_OVP_FREQUENCY_PWM_POLARITY, 0x0A);
6767761Smsmith	if (ret)
6867761Smsmith		return ret;
6967761Smsmith
7067761Smsmith	return 0;
7167761Smsmith}
7267761Smsmith
7367761Smsmithstatic int lm3533_backlight_set_brightness(struct udevice *dev, int percent)
7467761Smsmith{
7567761Smsmith	struct lm3533_backlight_priv *priv = dev_get_priv(dev);
7689054Smsmith	int ret;
7767761Smsmith
7867761Smsmith	if (percent == BACKLIGHT_DEFAULT)
7967761Smsmith		percent = priv->def_bl_lvl;
8067761Smsmith
8167761Smsmith	if (percent < LM3533_BL_MIN_BRIGHTNESS)
82119529Snjl		percent = LM3533_BL_MIN_BRIGHTNESS;
8367761Smsmith
84119529Snjl	if (percent > LM3533_BL_MAX_BRIGHTNESS)
8567761Smsmith		percent = LM3533_BL_MAX_BRIGHTNESS;
86119529Snjl
8767761Smsmith	/* Set brightness level */
88119529Snjl	ret = dm_i2c_reg_write(dev, LM3533_BRIGHTNESS_REGISTER_A,
8967761Smsmith			       percent);
9067761Smsmith	if (ret)
9167761Smsmith		return ret;
9267761Smsmith
9367761Smsmith	return 0;
9467761Smsmith}
9567761Smsmith
9696926Speterstatic int lm3533_backlight_probe(struct udevice *dev)
9769744Smsmith{
9867761Smsmith	struct lm3533_backlight_priv *priv = dev_get_priv(dev);
9967761Smsmith	int ret;
10067761Smsmith
10167761Smsmith	if (device_get_uclass_id(dev->parent) != UCLASS_I2C)
102119529Snjl		return -EPROTONOSUPPORT;
103119529Snjl
104119529Snjl	ret = gpio_request_by_name(dev, "enable-gpios", 0,
105100497Siwasaki				   &priv->enable_gpio, GPIOD_IS_OUT);
106119529Snjl	if (ret) {
107119529Snjl		log_err("Could not decode enable-gpios (%d)\n", ret);
10867761Smsmith		return ret;
10967761Smsmith	}
110100497Siwasaki
111100497Siwasaki	priv->def_bl_lvl = dev_read_u32_default(dev, "default-brightness-level",
112100497Siwasaki						LM3533_BL_MAX_BRIGHTNESS);
113100497Siwasaki
114100497Siwasaki	return 0;
115100497Siwasaki}
116100497Siwasaki
117100497Siwasakistatic const struct backlight_ops lm3533_backlight_ops = {
118100497Siwasaki	.enable = lm3533_backlight_enable,
119100497Siwasaki	.set_brightness = lm3533_backlight_set_brightness,
120100497Siwasaki};
121100497Siwasaki
122100497Siwasakistatic const struct udevice_id lm3533_backlight_ids[] = {
123100497Siwasaki	{ .compatible = "ti,lm3533" },
124100497Siwasaki	{ }
125100497Siwasaki};
12667761Smsmith
12767761SmsmithU_BOOT_DRIVER(lm3533_backlight) = {
12867761Smsmith	.name		= "lm3533_backlight",
12967761Smsmith	.id		= UCLASS_PANEL_BACKLIGHT,
13067761Smsmith	.of_match	= lm3533_backlight_ids,
131119529Snjl	.probe		= lm3533_backlight_probe,
13267761Smsmith	.ops		= &lm3533_backlight_ops,
13396926Speter	.priv_auto	= sizeof(struct lm3533_backlight_priv),
13469744Smsmith};
13567761Smsmith