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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-samsung-s6d16d0.c
Extension
.c
Size
5702 bytes
Lines
241
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 s6d16d0 {
	struct device *dev;
	struct drm_panel panel;
	struct regulator *supply;
	struct gpio_desc *reset_gpio;
};

/*
 * The timings are not very helpful as the display is used in
 * command mode.
 */
static const struct drm_display_mode samsung_s6d16d0_mode = {
	/* HS clock, (htotal*vtotal*vrefresh)/1000 */
	.clock = 420160,
	.hdisplay = 864,
	.hsync_start = 864 + 154,
	.hsync_end = 864 + 154 + 16,
	.htotal = 864 + 154 + 16 + 32,
	.vdisplay = 480,
	.vsync_start = 480 + 1,
	.vsync_end = 480 + 1 + 1,
	.vtotal = 480 + 1 + 1 + 1,
	.width_mm = 84,
	.height_mm = 48,
};

static inline struct s6d16d0 *panel_to_s6d16d0(struct drm_panel *panel)
{
	return container_of(panel, struct s6d16d0, panel);
}

static int s6d16d0_unprepare(struct drm_panel *panel)
{
	struct s6d16d0 *s6 = panel_to_s6d16d0(panel);
	struct mipi_dsi_device *dsi = to_mipi_dsi_device(s6->dev);
	int ret;

	/* Enter sleep mode */
	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
	if (ret) {
		dev_err(s6->dev, "failed to enter sleep mode (%d)\n", ret);
		return ret;
	}

	/* Assert RESET */
	gpiod_set_value_cansleep(s6->reset_gpio, 1);
	regulator_disable(s6->supply);

	return 0;
}

static int s6d16d0_prepare(struct drm_panel *panel)
{
	struct s6d16d0 *s6 = panel_to_s6d16d0(panel);
	struct mipi_dsi_device *dsi = to_mipi_dsi_device(s6->dev);
	int ret;

	ret = regulator_enable(s6->supply);
	if (ret) {
		dev_err(s6->dev, "failed to enable supply (%d)\n", ret);
		return ret;
	}

	/* Assert RESET */
	gpiod_set_value_cansleep(s6->reset_gpio, 1);
	udelay(10);
	/* De-assert RESET */
	gpiod_set_value_cansleep(s6->reset_gpio, 0);
	msleep(120);

	/* Enabe tearing mode: send TE (tearing effect) at VBLANK */
	ret = mipi_dsi_dcs_set_tear_on(dsi,
				       MIPI_DSI_DCS_TEAR_MODE_VBLANK);
	if (ret) {
		dev_err(s6->dev, "failed to enable vblank TE (%d)\n", ret);
		return ret;
	}
	/* Exit sleep mode and power on */
	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
	if (ret) {
		dev_err(s6->dev, "failed to exit sleep mode (%d)\n", ret);
		return ret;
	}

	return 0;
}

static int s6d16d0_enable(struct drm_panel *panel)
{
	struct s6d16d0 *s6 = panel_to_s6d16d0(panel);

Annotation

Implementation Notes