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