drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c
Extension
.c
Size
12169 bytes
Lines
478
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 jdi_panel {
	struct drm_panel base;
	struct mipi_dsi_device *link1;
	struct mipi_dsi_device *link2;

	struct regulator *supply;
	struct regulator *ddi_supply;
	struct backlight_device *backlight;

	struct gpio_desc *enable_gpio;
	struct gpio_desc *reset_gpio;

	const struct drm_display_mode *mode;
};

static inline struct jdi_panel *to_panel_jdi(struct drm_panel *panel)
{
	return container_of(panel, struct jdi_panel, base);
}

static void jdi_wait_frames(struct jdi_panel *jdi, unsigned int frames)
{
	unsigned int refresh = drm_mode_vrefresh(jdi->mode);

	if (WARN_ON(frames > refresh))
		return;

	msleep(1000 / (refresh / frames));
}

static int jdi_panel_disable(struct drm_panel *panel)
{
	struct jdi_panel *jdi = to_panel_jdi(panel);

	backlight_disable(jdi->backlight);

	jdi_wait_frames(jdi, 2);

	return 0;
}

static int jdi_panel_unprepare(struct drm_panel *panel)
{
	struct jdi_panel *jdi = to_panel_jdi(panel);

	/*
	 * One context per panel since we'll continue trying to shut down the
	 * other panel even if one isn't responding.
	 */
	struct mipi_dsi_multi_context dsi_ctx1 = { .dsi = jdi->link1 };
	struct mipi_dsi_multi_context dsi_ctx2 = { .dsi = jdi->link2 };

	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx1);
	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx2);

	/* Specified by JDI @ 50ms, subject to change */
	msleep(50);

	/* Doesn't hurt to try sleep mode even if display off fails */
	dsi_ctx1.accum_err = 0;
	dsi_ctx2.accum_err = 0;
	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx1);
	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx2);

	/* Specified by JDI @ 150ms, subject to change */
	msleep(150);

	gpiod_set_value(jdi->reset_gpio, 1);

	/* T4 = 1ms */
	usleep_range(1000, 3000);

	gpiod_set_value(jdi->enable_gpio, 0);

	/* T5 = 2ms */
	usleep_range(2000, 4000);

	regulator_disable(jdi->ddi_supply);

	/* T6 = 2ms plus some time to discharge capacitors */
	usleep_range(7000, 9000);

	regulator_disable(jdi->supply);
	/* Specified by JDI @ 20ms, subject to change */
	msleep(20);

	return 0;
}

static void jdi_setup_symmetrical_split(struct mipi_dsi_multi_context *dsi_ctx,

Annotation

Implementation Notes