drivers/gpu/drm/panel/panel-orisetech-otm8009a.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
Extension
.c
Size
14883 bytes
Lines
476
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 otm8009a {
	struct device *dev;
	struct drm_panel panel;
	struct backlight_device *bl_dev;
	struct gpio_desc *reset_gpio;
	struct regulator *supply;
	bool prepared;
};

static const struct drm_display_mode modes[] = {
	{ /* 50 Hz, preferred */
		.clock = 29700,
		.hdisplay = 480,
		.hsync_start = 480 + 98,
		.hsync_end = 480 + 98 + 32,
		.htotal = 480 + 98 + 32 + 98,
		.vdisplay = 800,
		.vsync_start = 800 + 15,
		.vsync_end = 800 + 15 + 10,
		.vtotal = 800 + 15 + 10 + 14,
		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
		.width_mm = 52,
		.height_mm = 86,
	},
	{ /* 60 Hz */
		.clock = 33000,
		.hdisplay = 480,
		.hsync_start = 480 + 70,
		.hsync_end = 480 + 70 + 32,
		.htotal = 480 + 70 + 32 + 72,
		.vdisplay = 800,
		.vsync_start = 800 + 15,
		.vsync_end = 800 + 15 + 10,
		.vtotal = 800 + 15 + 10 + 16,
		.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
		.width_mm = 52,
		.height_mm = 86,
	},
};

static inline struct otm8009a *panel_to_otm8009a(struct drm_panel *panel)
{
	return container_of(panel, struct otm8009a, panel);
}

#define dcs_write_cmd_at(ctx, cmd, seq...)		\
({							\
	mipi_dsi_dcs_write_seq_multi(ctx, MCS_ADRSFT, (cmd) & 0xFF);	\
	mipi_dsi_dcs_write_seq_multi(ctx, (cmd) >> 8, seq);		\
})

static int otm8009a_init_sequence(struct otm8009a *ctx)
{
	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
	struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };

	/* Enter CMD2 */
	dcs_write_cmd_at(&dsi_ctx, MCS_CMD2_ENA1, 0x80, 0x09, 0x01);

	/* Enter Orise Command2 */
	dcs_write_cmd_at(&dsi_ctx, MCS_CMD2_ENA2, 0x80, 0x09);

	dcs_write_cmd_at(&dsi_ctx, MCS_SD_PCH_CTRL, 0x30);
	mipi_dsi_msleep(&dsi_ctx, 10);

	dcs_write_cmd_at(&dsi_ctx, MCS_NO_DOC1, 0x40);
	mipi_dsi_msleep(&dsi_ctx, 10);

	dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL4 + 1, 0xA9);
	dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 1, 0x34);
	dcs_write_cmd_at(&dsi_ctx, MCS_P_DRV_M, 0x50);
	dcs_write_cmd_at(&dsi_ctx, MCS_VCOMDC, 0x4E);
	dcs_write_cmd_at(&dsi_ctx, MCS_OSC_ADJ, 0x66); /* 65Hz */
	dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 2, 0x01);
	dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 5, 0x34);
	dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL2 + 4, 0x33);
	dcs_write_cmd_at(&dsi_ctx, MCS_GVDDSET, 0x79, 0x79);
	dcs_write_cmd_at(&dsi_ctx, MCS_SD_CTRL + 1, 0x1B);
	dcs_write_cmd_at(&dsi_ctx, MCS_PWR_CTRL1 + 2, 0x83);
	dcs_write_cmd_at(&dsi_ctx, MCS_SD_PCH_CTRL + 1, 0x83);
	dcs_write_cmd_at(&dsi_ctx, MCS_RGB_VID_SET, 0x0E);
	dcs_write_cmd_at(&dsi_ctx, MCS_PANSET, 0x00, 0x01);

	dcs_write_cmd_at(&dsi_ctx, MCS_GOAVST, 0x85, 0x01, 0x00, 0x84, 0x01, 0x00);
	dcs_write_cmd_at(&dsi_ctx, MCS_GOACLKA1, 0x18, 0x04, 0x03, 0x39, 0x00, 0x00,
			 0x00, 0x18, 0x03, 0x03, 0x3A, 0x00, 0x00, 0x00);
	dcs_write_cmd_at(&dsi_ctx, MCS_GOACLKA3, 0x18, 0x02, 0x03, 0x3B, 0x00, 0x00,
			 0x00, 0x18, 0x01, 0x03, 0x3C, 0x00, 0x00, 0x00);
	dcs_write_cmd_at(&dsi_ctx, MCS_GOAECLK, 0x01, 0x01, 0x20, 0x20, 0x00, 0x00,
			 0x01, 0x02, 0x00, 0x00);

Annotation

Implementation Notes