drivers/gpu/drm/panel/panel-lg-ld070wx3.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-lg-ld070wx3.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-lg-ld070wx3.c
Extension
.c
Size
4861 bytes
Lines
185
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct lg_ld070wx3 {
	struct drm_panel panel;
	struct mipi_dsi_device *dsi;

	struct regulator_bulk_data *supplies;
};

static inline struct lg_ld070wx3 *to_lg_ld070wx3(struct drm_panel *panel)
{
	return container_of(panel, struct lg_ld070wx3, panel);
}

static int lg_ld070wx3_prepare(struct drm_panel *panel)
{
	struct lg_ld070wx3 *priv = to_lg_ld070wx3(panel);
	struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi };
	struct device *dev = panel->dev;
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(lg_ld070wx3_supplies), priv->supplies);
	if (ret < 0) {
		dev_err(dev, "failed to enable power supplies: %d\n", ret);
		return ret;
	}

	/*
	 * According to spec delay between enabling supply is 0,
	 * for regulators to reach required voltage ~5ms needed.
	 * MIPI interface signal for setup requires additional
	 * 110ms which in total results in 115ms.
	 */
	mdelay(115);

	mipi_dsi_dcs_soft_reset_multi(&ctx);
	mipi_dsi_msleep(&ctx, 20);

	/* Differential input impedance selection */
	mipi_dsi_dcs_write_seq_multi(&ctx, 0xae, 0x0b);

	/* Enter test mode 1 and 2*/
	mipi_dsi_dcs_write_seq_multi(&ctx, 0xee, 0xea);
	mipi_dsi_dcs_write_seq_multi(&ctx, 0xef, 0x5f);

	/* Increased MIPI CLK driving ability */
	mipi_dsi_dcs_write_seq_multi(&ctx, 0xf2, 0x68);

	/* Exit test mode 1 and 2 */
	mipi_dsi_dcs_write_seq_multi(&ctx, 0xee, 0x00);
	mipi_dsi_dcs_write_seq_multi(&ctx, 0xef, 0x00);

	return ctx.accum_err;
}

static int lg_ld070wx3_unprepare(struct drm_panel *panel)
{
	struct lg_ld070wx3 *priv = to_lg_ld070wx3(panel);
	struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi };

	mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);

	msleep(50);

	regulator_bulk_disable(ARRAY_SIZE(lg_ld070wx3_supplies), priv->supplies);

	/* power supply must be off for at least 1s after panel disable */
	msleep(1000);

	return 0;
}

static const struct drm_display_mode lg_ld070wx3_mode = {
	.clock = (800 + 32 + 48 + 8) * (1280 + 5 + 3 + 1) * 60 / 1000,
	.hdisplay = 800,
	.hsync_start = 800 + 32,
	.hsync_end = 800 + 32 + 48,
	.htotal = 800 + 32 + 48 + 8,
	.vdisplay = 1280,
	.vsync_start = 1280 + 5,
	.vsync_end = 1280 + 5 + 3,
	.vtotal = 1280 + 5 + 3 + 1,
	.width_mm = 94,
	.height_mm = 151,
	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
};

static int lg_ld070wx3_get_modes(struct drm_panel *panel,
				 struct drm_connector *connector)
{
	return drm_connector_helper_get_modes_fixed(connector, &lg_ld070wx3_mode);
}

Annotation

Implementation Notes