summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c')
-rw-r--r--drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c75
1 files changed, 60 insertions, 15 deletions
diff --git a/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c b/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c
index 6dcb692c4701..b9109922397f 100644
--- a/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c
+++ b/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c
@@ -15,6 +15,7 @@
#include <linux/gpio/consumer.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
+#include <linux/regulator/consumer.h>
#include <video/display_timing.h>
#include <video/mipi_display.h>
@@ -33,6 +34,7 @@
#define ST7703_CMD_SETEXTC 0xB9
#define ST7703_CMD_SETMIPI 0xBA
#define ST7703_CMD_SETVDC 0xBC
+#define ST7703_CMD_UNKNOWN0 0xBF
#define ST7703_CMD_SETSCR 0xC0
#define ST7703_CMD_SETPOWER 0xC1
#define ST7703_CMD_SETPANEL 0xCC
@@ -46,6 +48,8 @@ struct jh057n {
struct drm_panel panel;
struct gpio_desc *reset_gpio;
struct backlight_device *backlight;
+ struct regulator *vcc;
+ struct regulator *iovcc;
bool prepared;
struct dentry *debugfs;
@@ -94,7 +98,7 @@ static int jh057n_init_sequence(struct jh057n *ctx)
msleep(20);
dsi_generic_write_seq(dsi, ST7703_CMD_SETVCOM, 0x3F, 0x3F);
- dsi_generic_write_seq(dsi, 0xBF, 0x02, 0x11, 0x00);
+ dsi_generic_write_seq(dsi, ST7703_CMD_UNKNOWN0, 0x02, 0x11, 0x00);
dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP1,
0x82, 0x10, 0x06, 0x05, 0x9E, 0x0A, 0xA5, 0x12,
0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38,
@@ -123,7 +127,7 @@ static int jh057n_init_sequence(struct jh057n *ctx)
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
if (ret < 0) {
- DRM_DEV_ERROR(dev, "Failed to exit sleep mode\n");
+ DRM_DEV_ERROR(dev, "Failed to exit sleep mode: %d\n", ret);
return ret;
}
/* Panel is operational 120 msec after reset */
@@ -139,6 +143,14 @@ static int jh057n_init_sequence(struct jh057n *ctx)
static int jh057n_enable(struct drm_panel *panel)
{
struct jh057n *ctx = panel_to_jh057n(panel);
+ int ret;
+
+ ret = jh057n_init_sequence(ctx);
+ if (ret < 0) {
+ DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",
+ ret);
+ return ret;
+ }
return backlight_enable(ctx->backlight);
}
@@ -146,19 +158,21 @@ static int jh057n_enable(struct drm_panel *panel)
static int jh057n_disable(struct drm_panel *panel)
{
struct jh057n *ctx = panel_to_jh057n(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
- return backlight_disable(ctx->backlight);
+ backlight_disable(ctx->backlight);
+ return mipi_dsi_dcs_set_display_off(dsi);
}
static int jh057n_unprepare(struct drm_panel *panel)
{
struct jh057n *ctx = panel_to_jh057n(panel);
- struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
if (!ctx->prepared)
return 0;
- mipi_dsi_dcs_set_display_off(dsi);
+ regulator_disable(ctx->iovcc);
+ regulator_disable(ctx->vcc);
ctx->prepared = false;
return 0;
@@ -173,21 +187,31 @@ static int jh057n_prepare(struct drm_panel *panel)
return 0;
DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");
+ ret = regulator_enable(ctx->vcc);
+ if (ret < 0) {
+ DRM_DEV_ERROR(ctx->dev,
+ "Failed to enable vcc supply: %d\n", ret);
+ return ret;
+ }
+ ret = regulator_enable(ctx->iovcc);
+ if (ret < 0) {
+ DRM_DEV_ERROR(ctx->dev,
+ "Failed to enable iovcc supply: %d\n", ret);
+ goto disable_vcc;
+ }
+
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
usleep_range(20, 40);
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
msleep(20);
- ret = jh057n_init_sequence(ctx);
- if (ret < 0) {
- DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",
- ret);
- return ret;
- }
-
ctx->prepared = true;
return 0;
+
+disable_vcc:
+ regulator_disable(ctx->vcc);
+ return ret;
}
static const struct drm_display_mode default_mode = {
@@ -300,6 +324,25 @@ static int jh057n_probe(struct mipi_dsi_device *dsi)
if (IS_ERR(ctx->backlight))
return PTR_ERR(ctx->backlight);
+ ctx->vcc = devm_regulator_get(dev, "vcc");
+ if (IS_ERR(ctx->vcc)) {
+ ret = PTR_ERR(ctx->vcc);
+ if (ret != -EPROBE_DEFER)
+ DRM_DEV_ERROR(dev,
+ "Failed to request vcc regulator: %d\n",
+ ret);
+ return ret;
+ }
+ ctx->iovcc = devm_regulator_get(dev, "iovcc");
+ if (IS_ERR(ctx->iovcc)) {
+ ret = PTR_ERR(ctx->iovcc);
+ if (ret != -EPROBE_DEFER)
+ DRM_DEV_ERROR(dev,
+ "Failed to request iovcc regulator: %d\n",
+ ret);
+ return ret;
+ }
+
drm_panel_init(&ctx->panel);
ctx->panel.dev = dev;
ctx->panel.funcs = &jh057n_drm_funcs;
@@ -308,7 +351,9 @@ static int jh057n_probe(struct mipi_dsi_device *dsi)
ret = mipi_dsi_attach(dsi);
if (ret < 0) {
- DRM_DEV_ERROR(dev, "mipi_dsi_attach failed. Is host ready?\n");
+ DRM_DEV_ERROR(dev,
+ "mipi_dsi_attach failed (%d). Is host ready?\n",
+ ret);
drm_panel_remove(&ctx->panel);
return ret;
}
@@ -327,12 +372,12 @@ static void jh057n_shutdown(struct mipi_dsi_device *dsi)
struct jh057n *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
- ret = jh057n_unprepare(&ctx->panel);
+ ret = drm_panel_unprepare(&ctx->panel);
if (ret < 0)
DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",
ret);
- ret = jh057n_disable(&ctx->panel);
+ ret = drm_panel_disable(&ctx->panel);
if (ret < 0)
DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",
ret);