1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Samsung LTL106HL02-001 DSI panel driver 4 * 5 * Copyright (c) 2020 Anton Bambura <jenneron@protonmail.com> 6 * Copyright (c) 2023 Svyatoslav Ryhel <clamor95@gmail.com> 7 * Copyright (c) 2024 Jonas Schw��bel <jonasschwoebel@yahoo.de> 8 */ 9 10#include <backlight.h> 11#include <dm.h> 12#include <panel.h> 13#include <log.h> 14#include <mipi_dsi.h> 15#include <asm/gpio.h> 16#include <linux/delay.h> 17#include <power/regulator.h> 18 19struct samsung_ltl106hl02_priv { 20 struct udevice *vdd; 21 struct udevice *backlight; 22 23 struct gpio_desc reset_gpio; 24}; 25 26static struct display_timing default_timing = { 27 .pixelclock.typ = 137000000, 28 .hactive.typ = 1920, 29 .hfront_porch.typ = 32, 30 .hback_porch.typ = 64, 31 .hsync_len.typ = 32, 32 .vactive.typ = 1080, 33 .vfront_porch.typ = 2, 34 .vback_porch.typ = 26, 35 .vsync_len.typ = 3, 36}; 37 38static int samsung_ltl106hl02_enable_backlight(struct udevice *dev) 39{ 40 struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); 41 struct mipi_dsi_device *dsi = plat->device; 42 int ret; 43 44 ret = mipi_dsi_dcs_exit_sleep_mode(dsi); 45 if (ret < 0) { 46 log_debug("%s: failed to exit sleep mode: %d\n", 47 __func__, ret); 48 return ret; 49 } 50 mdelay(70); 51 52 ret = mipi_dsi_dcs_set_display_on(dsi); 53 if (ret < 0) { 54 log_debug("%s: failed to enable display: %d\n", 55 __func__, ret); 56 return ret; 57 } 58 mdelay(5); 59 60 return 0; 61} 62 63static int samsung_ltl106hl02_set_backlight(struct udevice *dev, int percent) 64{ 65 struct samsung_ltl106hl02_priv *priv = dev_get_priv(dev); 66 int ret; 67 68 ret = backlight_enable(priv->backlight); 69 if (ret) 70 return ret; 71 72 return backlight_set_brightness(priv->backlight, percent); 73} 74 75static int samsung_ltl106hl02_timings(struct udevice *dev, 76 struct display_timing *timing) 77{ 78 memcpy(timing, &default_timing, sizeof(*timing)); 79 return 0; 80} 81 82static int samsung_ltl106hl02_of_to_plat(struct udevice *dev) 83{ 84 struct samsung_ltl106hl02_priv *priv = dev_get_priv(dev); 85 int ret; 86 87 ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, 88 "backlight", &priv->backlight); 89 if (ret) { 90 log_debug("%s: cannot get backlight: ret = %d\n", 91 __func__, ret); 92 return ret; 93 } 94 95 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, 96 "vdd-supply", &priv->vdd); 97 if (ret) 98 log_debug("%s: cannot get vdd-supply: error %d\n", 99 __func__, ret); 100 101 ret = gpio_request_by_name(dev, "reset-gpios", 0, 102 &priv->reset_gpio, GPIOD_IS_OUT); 103 if (ret) 104 log_debug("%s: cannot get reset-gpios: error %d\n", 105 __func__, ret); 106 107 return 0; 108} 109 110static int samsung_ltl106hl02_hw_init(struct udevice *dev) 111{ 112 struct samsung_ltl106hl02_priv *priv = dev_get_priv(dev); 113 114 dm_gpio_set_value(&priv->reset_gpio, 1); 115 regulator_set_enable_if_allowed(priv->vdd, 1); 116 117 /* Dataheets states at least 8.5 msec for vdd stabilization */ 118 mdelay(10); 119 120 dm_gpio_set_value(&priv->reset_gpio, 0); 121 122 return 0; 123} 124 125static int samsung_ltl106hl02_probe(struct udevice *dev) 126{ 127 struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); 128 129 /* fill characteristics of DSI data link */ 130 plat->lanes = 4; 131 plat->format = MIPI_DSI_FMT_RGB888; 132 plat->mode_flags = MIPI_DSI_MODE_VIDEO; 133 134 return samsung_ltl106hl02_hw_init(dev); 135} 136 137static const struct panel_ops samsung_ltl106hl02_ops = { 138 .enable_backlight = samsung_ltl106hl02_enable_backlight, 139 .set_backlight = samsung_ltl106hl02_set_backlight, 140 .get_display_timing = samsung_ltl106hl02_timings, 141}; 142 143static const struct udevice_id samsung_ltl106hl02_ids[] = { 144 { .compatible = "samsung,ltl106hl02-001" }, 145 { } 146}; 147 148U_BOOT_DRIVER(samsung_ltl106hl02) = { 149 .name = "samsung_ltl106hl02", 150 .id = UCLASS_PANEL, 151 .of_match = samsung_ltl106hl02_ids, 152 .ops = &samsung_ltl106hl02_ops, 153 .of_to_plat = samsung_ltl106hl02_of_to_plat, 154 .probe = samsung_ltl106hl02_probe, 155 .plat_auto = sizeof(struct mipi_dsi_panel_plat), 156 .priv_auto = sizeof(struct samsung_ltl106hl02_priv), 157}; 158