diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index b1af4a039fb4..1c685dd72016 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -39,6 +39,8 @@ #include #include +#include "panel-simple.h" + struct panel_cmd_header { u8 data_type; u8 delay; @@ -128,6 +130,7 @@ struct panel_simple { struct mipi_dsi_device *dsi; bool prepared; bool enabled; + bool power_invert; bool no_hpd; const struct panel_desc *desc; @@ -365,6 +368,57 @@ static int panel_simple_get_non_edid_modes(struct panel_simple *panel, return num; } +static int panel_simple_regulator_enable(struct panel_simple *p) +{ + int err; + + if (p->power_invert) { + if (regulator_is_enabled(p->supply) > 0) + regulator_disable(p->supply); + } else { + err = regulator_enable(p->supply); + if (err < 0) + return err; + } + + return 0; +} + +static int panel_simple_regulator_disable(struct panel_simple *p) +{ + int err; + + if (p->power_invert) { + if (!regulator_is_enabled(p->supply)) { + err = regulator_enable(p->supply); + if (err < 0) + return err; + } + } else { + regulator_disable(p->supply); + } + + return 0; +} + +int panel_simple_loader_protect(struct drm_panel *panel) +{ + struct panel_simple *p = to_panel_simple(panel); + int err; + + err = panel_simple_regulator_enable(p); + if (err < 0) { + dev_err(panel->dev, "failed to enable supply: %d\n", err); + return err; + } + + p->prepared = true; + p->enabled = true; + + return 0; +} +EXPORT_SYMBOL(panel_simple_loader_protect); + static int panel_simple_disable(struct drm_panel *panel) { struct panel_simple *p = to_panel_simple(panel); @@ -394,7 +448,7 @@ static int panel_simple_unprepare(struct drm_panel *panel) gpiod_set_value_cansleep(p->reset_gpio, 1); gpiod_set_value_cansleep(p->enable_gpio, 0); - regulator_disable(p->supply); + panel_simple_regulator_disable(p); if (p->desc->delay.unprepare) msleep(p->desc->delay.unprepare); @@ -439,7 +493,7 @@ static int panel_simple_prepare(struct drm_panel *panel) if (p->prepared) return 0; - err = regulator_enable(p->supply); + err = panel_simple_regulator_enable(p); if (err < 0) { dev_err(panel->dev, "failed to enable supply: %d\n", err); return err; @@ -708,6 +762,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) return err; } + panel->power_invert = of_property_read_bool(dev->of_node, "power-invert"); + ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0); if (ddc) { panel->ddc = of_find_i2c_adapter_by_node(ddc); diff --git a/drivers/gpu/drm/panel/panel-simple.h b/drivers/gpu/drm/panel/panel-simple.h new file mode 100644 index 000000000000..1958926d9738 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-simple.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + * Author: Sandy Huang + */ + +#ifndef PANEL_SIMPLE_H +#define PANEL_SIMPLE_H +#include + +#if IS_ENABLED(CONFIG_DRM_PANEL_SIMPLE) +int panel_simple_loader_protect(struct drm_panel *panel); +#else +static inline int panel_simple_loader_protect(struct drm_panel *panel) +{ + return 0; +} +#endif +#endif