drivers/gpu/drm/panel/panel-himax-hx83121a.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-himax-hx83121a.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-himax-hx83121a.c
Extension
.c
Size
27005 bytes
Lines
750
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 himax {
	struct drm_panel panel;
	struct mipi_dsi_device *dsi[2];
	const struct panel_desc *desc;
	struct drm_dsc_config dsc;
	struct gpio_desc *reset_gpio;
	struct regulator_bulk_data *supplies;
	struct backlight_device *backlight;
};

struct panel_desc {
	unsigned int width_mm;
	unsigned int height_mm;
	unsigned int bpc;
	unsigned int lanes;
	enum mipi_dsi_pixel_format format;
	unsigned long mode_flags;
	const struct drm_dsc_config *dsc_cfg;
	const struct drm_display_mode *dsc_modes;
	unsigned int num_dsc_modes;

	const struct drm_display_mode *modes;
	unsigned int num_modes;

	int (*init_sequence_dsc)(struct mipi_dsi_multi_context *dsi_ctx);
	int (*init_sequence)(struct mipi_dsi_multi_context *dsi_ctx);

	bool is_dual_dsi;
	bool has_dcs_backlight;
};

static const struct regulator_bulk_data himax_supplies[] = {
	{ .supply = "vddi" },
	{ .supply = "avdd" },
	{ .supply = "avee" },
};

static inline struct himax *to_himax(struct drm_panel *panel)
{
	return container_of(panel, struct himax, panel);
}

static inline struct mipi_dsi_device *to_primary_dsi(struct himax *ctx)
{
	/* Sync on DSI1 for dual dsi */
	return ctx->desc->is_dual_dsi ? ctx->dsi[1] : ctx->dsi[0];
}

static void himax_reset(struct himax *ctx)
{
	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
	usleep_range(4000, 4100);
	gpiod_set_value_cansleep(ctx->reset_gpio, 0);
	msleep(20);
}

static int himax_prepare(struct drm_panel *panel)
{
	struct himax *ctx = to_himax(panel);
	struct mipi_dsi_device *dsi = to_primary_dsi(ctx);
	struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
	struct drm_dsc_picture_parameter_set pps;
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(himax_supplies),
				    ctx->supplies);
	if (ret < 0)
		return ret;

	himax_reset(ctx);

	if (enable_dsc && ctx->desc->init_sequence_dsc)
		ret = ctx->desc->init_sequence_dsc(&dsi_ctx);
	else if (ctx->desc->init_sequence)
		ret = ctx->desc->init_sequence(&dsi_ctx);
	else
		ret = -EOPNOTSUPP;

	if (ret < 0) {
		gpiod_set_value_cansleep(ctx->reset_gpio, 1);
		regulator_bulk_disable(ARRAY_SIZE(himax_supplies),
				       ctx->supplies);
		return ret;
	}

	if (enable_dsc) {
		drm_dsc_pps_payload_pack(&pps, &ctx->dsc);
		mipi_dsi_picture_parameter_set_multi(&dsi_ctx, &pps);
		mipi_dsi_compression_mode_multi(&dsi_ctx, true);
	}

Annotation

Implementation Notes