diff options
Diffstat (limited to 'drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c')
| -rw-r--r-- | drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c | 132 |
1 files changed, 39 insertions, 93 deletions
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c index 9d843fcc3a22..ca5cad41ff1d 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c @@ -18,8 +18,6 @@ struct s6e88a0_ams452ef01 { struct mipi_dsi_device *dsi; struct regulator_bulk_data supplies[2]; struct gpio_desc *reset_gpio; - - bool prepared; }; static inline struct @@ -28,14 +26,6 @@ s6e88a0_ams452ef01 *to_s6e88a0_ams452ef01(struct drm_panel *panel) return container_of(panel, struct s6e88a0_ams452ef01, panel); } -#define dsi_dcs_write_seq(dsi, seq...) do { \ - static const u8 d[] = { seq }; \ - int ret; \ - ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ - if (ret < 0) \ - return ret; \ - } while (0) - static void s6e88a0_ams452ef01_reset(struct s6e88a0_ams452ef01 *ctx) { gpiod_set_value_cansleep(ctx->reset_gpio, 1); @@ -49,121 +39,84 @@ static void s6e88a0_ams452ef01_reset(struct s6e88a0_ams452ef01 *ctx) static int s6e88a0_ams452ef01_on(struct s6e88a0_ams452ef01 *ctx) { struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi }; dsi->mode_flags |= MIPI_DSI_MODE_LPM; - dsi_dcs_write_seq(dsi, 0xf0, 0x5a, 0x5a); // enable LEVEL2 commands - dsi_dcs_write_seq(dsi, 0xcc, 0x4c); // set Pixel Clock Divider polarity + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a); // enable LEVEL2 commands + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xcc, 0x4c); // set Pixel Clock Divider polarity - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to exit sleep mode: %d\n", ret); - return ret; - } - msleep(120); + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); // set default brightness/gama - dsi_dcs_write_seq(dsi, 0xca, - 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, // V255 RR,GG,BB - 0x80, 0x80, 0x80, // V203 R,G,B - 0x80, 0x80, 0x80, // V151 R,G,B - 0x80, 0x80, 0x80, // V87 R,G,B - 0x80, 0x80, 0x80, // V51 R,G,B - 0x80, 0x80, 0x80, // V35 R,G,B - 0x80, 0x80, 0x80, // V23 R,G,B - 0x80, 0x80, 0x80, // V11 R,G,B - 0x6b, 0x68, 0x71, // V3 R,G,B - 0x00, 0x00, 0x00); // V1 R,G,B + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xca, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,// V255 RR,GG,BB + 0x80, 0x80, 0x80, // V203 R,G,B + 0x80, 0x80, 0x80, // V151 R,G,B + 0x80, 0x80, 0x80, // V87 R,G,B + 0x80, 0x80, 0x80, // V51 R,G,B + 0x80, 0x80, 0x80, // V35 R,G,B + 0x80, 0x80, 0x80, // V23 R,G,B + 0x80, 0x80, 0x80, // V11 R,G,B + 0x6b, 0x68, 0x71, // V3 R,G,B + 0x00, 0x00, 0x00); // V1 R,G,B // set default Amoled Off Ratio - dsi_dcs_write_seq(dsi, 0xb2, 0x40, 0x0a, 0x17, 0x00, 0x0a); - dsi_dcs_write_seq(dsi, 0xb6, 0x2c, 0x0b); // set default elvss voltage - dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00); - dsi_dcs_write_seq(dsi, 0xf7, 0x03); // gamma/aor update - dsi_dcs_write_seq(dsi, 0xf0, 0xa5, 0xa5); // disable LEVEL2 commands + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb2, 0x40, 0x0a, 0x17, 0x00, 0x0a); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb6, 0x2c, 0x0b); // set default elvss voltage + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00); + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf7, 0x03); // gamma/aor update + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5); // disable LEVEL2 commands - ret = mipi_dsi_dcs_set_display_on(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display on: %d\n", ret); - return ret; - } + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx); - return 0; + return dsi_ctx.accum_err; } -static int s6e88a0_ams452ef01_off(struct s6e88a0_ams452ef01 *ctx) +static void s6e88a0_ams452ef01_off(struct s6e88a0_ams452ef01 *ctx) { struct mipi_dsi_device *dsi = ctx->dsi; - struct device *dev = &dsi->dev; - int ret; + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi}; dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; - ret = mipi_dsi_dcs_set_display_off(dsi); - if (ret < 0) { - dev_err(dev, "Failed to set display off: %d\n", ret); - return ret; - } - msleep(35); - - ret = mipi_dsi_dcs_enter_sleep_mode(dsi); - if (ret < 0) { - dev_err(dev, "Failed to enter sleep mode: %d\n", ret); - return ret; - } - msleep(120); - - return 0; + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 35); + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx); + mipi_dsi_msleep(&dsi_ctx, 120); } static int s6e88a0_ams452ef01_prepare(struct drm_panel *panel) { struct s6e88a0_ams452ef01 *ctx = to_s6e88a0_ams452ef01(panel); - struct device *dev = &ctx->dsi->dev; int ret; - if (ctx->prepared) - return 0; - ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - if (ret < 0) { - dev_err(dev, "Failed to enable regulators: %d\n", ret); + if (ret < 0) return ret; - } s6e88a0_ams452ef01_reset(ctx); ret = s6e88a0_ams452ef01_on(ctx); if (ret < 0) { - dev_err(dev, "Failed to initialize panel: %d\n", ret); gpiod_set_value_cansleep(ctx->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); return ret; } - ctx->prepared = true; return 0; } static int s6e88a0_ams452ef01_unprepare(struct drm_panel *panel) { struct s6e88a0_ams452ef01 *ctx = to_s6e88a0_ams452ef01(panel); - struct device *dev = &ctx->dsi->dev; - int ret; - if (!ctx->prepared) - return 0; - - ret = s6e88a0_ams452ef01_off(ctx); - if (ret < 0) - dev_err(dev, "Failed to un-initialize panel: %d\n", ret); + s6e88a0_ams452ef01_off(ctx); gpiod_set_value_cansleep(ctx->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); - ctx->prepared = false; return 0; } @@ -177,7 +130,6 @@ static const struct drm_display_mode s6e88a0_ams452ef01_mode = { .vsync_start = 960 + 14, .vsync_end = 960 + 14 + 2, .vtotal = 960 + 14 + 2 + 8, - .vrefresh = 60, .width_mm = 56, .height_mm = 100, }; @@ -213,9 +165,11 @@ static int s6e88a0_ams452ef01_probe(struct mipi_dsi_device *dsi) struct s6e88a0_ams452ef01 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; + ctx = devm_drm_panel_alloc(dev, struct s6e88a0_ams452ef01, panel, + &s6e88a0_ams452ef01_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); ctx->supplies[0].supply = "vdd3"; ctx->supplies[1].supply = "vci"; @@ -240,25 +194,19 @@ static int s6e88a0_ams452ef01_probe(struct mipi_dsi_device *dsi) dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; - drm_panel_init(&ctx->panel, dev, &s6e88a0_ams452ef01_panel_funcs, - DRM_MODE_CONNECTOR_DSI); - - ret = drm_panel_add(&ctx->panel); - if (ret < 0) { - dev_err(dev, "Failed to add panel: %d\n", ret); - return ret; - } + drm_panel_add(&ctx->panel); ret = mipi_dsi_attach(dsi); if (ret < 0) { dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&ctx->panel); return ret; } return 0; } -static int s6e88a0_ams452ef01_remove(struct mipi_dsi_device *dsi) +static void s6e88a0_ams452ef01_remove(struct mipi_dsi_device *dsi) { struct s6e88a0_ams452ef01 *ctx = mipi_dsi_get_drvdata(dsi); int ret; @@ -268,8 +216,6 @@ static int s6e88a0_ams452ef01_remove(struct mipi_dsi_device *dsi) dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); drm_panel_remove(&ctx->panel); - - return 0; } static const struct of_device_id s6e88a0_ams452ef01_of_match[] = { |
