drivers/gpu/drm/panel/panel-samsung-s6e63m0.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
Extension
.c
Size
20937 bytes
Lines
740
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 s6e63m0 {
	struct device *dev;
	void *transport_data;
	int (*dcs_read)(struct device *dev, void *trsp, const u8 cmd, u8 *val);
	int (*dcs_write)(struct device *dev, void *trsp, const u8 *data, size_t len);
	struct drm_panel panel;
	struct backlight_device *bl_dev;
	u8 lcd_type;
	u8 elvss_pulse;
	bool dsi_mode;

	struct regulator_bulk_data supplies[2];
	struct gpio_desc *reset_gpio;

	/*
	 * This field is tested by functions directly accessing bus before
	 * transfer, transfer is skipped if it is set. In case of transfer
	 * failure or unexpected response the field is set to error value.
	 * Such construct allows to eliminate many checks in higher level
	 * functions.
	 */
	int error;
};

static const struct drm_display_mode default_mode = {
	.clock		= 25628,
	.hdisplay	= 480,
	.hsync_start	= 480 + 16,
	.hsync_end	= 480 + 16 + 2,
	.htotal		= 480 + 16 + 2 + 16,
	.vdisplay	= 800,
	.vsync_start	= 800 + 28,
	.vsync_end	= 800 + 28 + 2,
	.vtotal		= 800 + 28 + 2 + 1,
	.width_mm	= 53,
	.height_mm	= 89,
	.flags		= DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

static inline struct s6e63m0 *panel_to_s6e63m0(struct drm_panel *panel)
{
	return container_of(panel, struct s6e63m0, panel);
}

static int s6e63m0_clear_error(struct s6e63m0 *ctx)
{
	int ret = ctx->error;

	ctx->error = 0;
	return ret;
}

static void s6e63m0_dcs_read(struct s6e63m0 *ctx, const u8 cmd, u8 *data)
{
	if (ctx->error < 0)
		return;

	ctx->error = ctx->dcs_read(ctx->dev, ctx->transport_data, cmd, data);
}

static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len)
{
	if (ctx->error < 0 || len == 0)
		return;

	ctx->error = ctx->dcs_write(ctx->dev, ctx->transport_data, data, len);
}

#define s6e63m0_dcs_write_seq_static(ctx, seq ...) \
	({ \
		static const u8 d[] = { seq }; \
		s6e63m0_dcs_write(ctx, d, ARRAY_SIZE(d)); \
	})

static int s6e63m0_check_lcd_type(struct s6e63m0 *ctx)
{
	u8 id1, id2, id3;
	int ret;

	s6e63m0_dcs_read(ctx, MCS_READ_ID1, &id1);
	s6e63m0_dcs_read(ctx, MCS_READ_ID2, &id2);
	s6e63m0_dcs_read(ctx, MCS_READ_ID3, &id3);

	ret = s6e63m0_clear_error(ctx);
	if (ret) {
		dev_err(ctx->dev, "error checking LCD type (%d)\n", ret);
		ctx->lcd_type = 0x00;
		return ret;
	}

Annotation

Implementation Notes