drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-sharp-lq079l1sx01.c
Extension
.c
Size
6504 bytes
Lines
226
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 sharp_panel {
	struct drm_panel panel;
	struct mipi_dsi_device *dsi[2];

	struct gpio_desc *reset_gpio;
	struct regulator_bulk_data *supplies;

	const struct drm_display_mode *mode;
};

static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel)
{
	return container_of(panel, struct sharp_panel, panel);
}

static void sharp_panel_reset(struct sharp_panel *sharp)
{
	gpiod_set_value_cansleep(sharp->reset_gpio, 1);
	usleep_range(2000, 3000);
	gpiod_set_value_cansleep(sharp->reset_gpio, 0);
	usleep_range(2000, 3000);
}

static int sharp_panel_prepare(struct drm_panel *panel)
{
	struct sharp_panel *sharp = to_sharp_panel(panel);
	struct device *dev = panel->dev;
	struct mipi_dsi_device *dsi0 = sharp->dsi[0];
	struct mipi_dsi_device *dsi1 = sharp->dsi[1];
	struct mipi_dsi_multi_context dsi_ctx = { .dsi = NULL };
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(sharp_supplies), sharp->supplies);
	if (ret) {
		dev_err(dev, "error enabling regulators (%d)\n", ret);
		return ret;
	}

	msleep(24);

	if (sharp->reset_gpio)
		sharp_panel_reset(sharp);

	msleep(32);

	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_EXIT_SLEEP_MODE);
	mipi_dsi_msleep(&dsi_ctx, 120);

	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1,
					  MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0xff);
	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1,
					  MIPI_DCS_WRITE_POWER_SAVE, 0x01);
	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1,
					  MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x2c);

	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_SET_DISPLAY_ON);

	return 0;
}

static int sharp_panel_unprepare(struct drm_panel *panel)
{
	struct sharp_panel *sharp = to_sharp_panel(panel);
	struct mipi_dsi_device *dsi0 = sharp->dsi[0];
	struct mipi_dsi_device *dsi1 = sharp->dsi[1];
	struct mipi_dsi_multi_context dsi_ctx = { .dsi = NULL };

	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_SET_DISPLAY_OFF);
	mipi_dsi_msleep(&dsi_ctx, 100);
	mipi_dsi_dual_dcs_write_seq_multi(&dsi_ctx, dsi0, dsi1, MIPI_DCS_ENTER_SLEEP_MODE);
	mipi_dsi_msleep(&dsi_ctx, 150);

	if (sharp->reset_gpio)
		gpiod_set_value_cansleep(sharp->reset_gpio, 1);

	return regulator_bulk_disable(ARRAY_SIZE(sharp_supplies), sharp->supplies);
}

static const struct drm_display_mode default_mode = {
	.clock = (1536 + 136 + 28 + 28) * (2048 + 14 + 8 + 2) * 60 / 1000,
	.hdisplay = 1536,
	.hsync_start = 1536 + 136,
	.hsync_end = 1536 + 136 + 28,
	.htotal = 1536 + 136 + 28 + 28,
	.vdisplay = 2048,
	.vsync_start = 2048 + 14,
	.vsync_end = 2048 + 14 + 8,
	.vtotal = 2048 + 14 + 8 + 2,
	.width_mm = 120,
	.height_mm = 160,

Annotation

Implementation Notes