drivers/gpu/drm/bridge/tc358762.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/tc358762.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/bridge/tc358762.c
Extension
.c
Size
8486 bytes
Lines
334
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 tc358762 {
	struct device *dev;
	struct drm_bridge bridge;
	struct regulator *regulator;
	struct drm_bridge *panel_bridge;
	struct gpio_desc *reset_gpio;
	struct drm_display_mode mode;
	bool pre_enabled;
	int error;
};

static int tc358762_clear_error(struct tc358762 *ctx)
{
	int ret = ctx->error;

	ctx->error = 0;
	return ret;
}

static void tc358762_write(struct tc358762 *ctx, u16 addr, u32 val)
{
	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
	ssize_t ret;
	u8 data[6];

	if (ctx->error)
		return;

	data[0] = addr;
	data[1] = addr >> 8;
	data[2] = val;
	data[3] = val >> 8;
	data[4] = val >> 16;
	data[5] = val >> 24;

	ret = mipi_dsi_generic_write(dsi, data, sizeof(data));
	if (ret < 0)
		ctx->error = ret;
}

static inline struct tc358762 *bridge_to_tc358762(struct drm_bridge *bridge)
{
	return container_of(bridge, struct tc358762, bridge);
}

static int tc358762_init(struct tc358762 *ctx)
{
	u32 lcdctrl;

	tc358762_write(ctx, DSI_LANEENABLE,
		       LANEENABLE_L0EN | LANEENABLE_CLEN);
	tc358762_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5);
	tc358762_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5);
	tc358762_write(ctx, PPI_D0S_ATMR, 0);
	tc358762_write(ctx, PPI_D1S_ATMR, 0);
	tc358762_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD);

	tc358762_write(ctx, SPICMR, 0x00);

	lcdctrl = LCDCTRL_VSDELAY(1) | LCDCTRL_RGB888 |
		  LCDCTRL_UNK6 | LCDCTRL_VTGEN;

	if (ctx->mode.flags & DRM_MODE_FLAG_NHSYNC)
		lcdctrl |= LCDCTRL_HSPOL;

	if (ctx->mode.flags & DRM_MODE_FLAG_NVSYNC)
		lcdctrl |= LCDCTRL_VSPOL;

	tc358762_write(ctx, LCDCTRL, lcdctrl);

	tc358762_write(ctx, SYSCTRL, 0x040f);
	msleep(100);

	tc358762_write(ctx, PPI_STARTPPI, PPI_START_FUNCTION);
	tc358762_write(ctx, DSI_STARTDSI, DSI_RX_START);

	msleep(100);

	return tc358762_clear_error(ctx);
}

static void tc358762_post_disable(struct drm_bridge *bridge,
				  struct drm_atomic_commit *state)
{
	struct tc358762 *ctx = bridge_to_tc358762(bridge);
	int ret;

	/*
	 * The post_disable hook might be called multiple times.
	 * We want to avoid regulator imbalance below.

Annotation

Implementation Notes