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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-samsung-ld9040.c
Extension
.c
Size
12244 bytes
Lines
423
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 ld9040 {
	struct device *dev;
	struct drm_panel panel;

	struct regulator_bulk_data supplies[2];
	struct gpio_desc *reset_gpio;
	u32 power_on_delay;
	u32 reset_delay;
	struct videomode vm;
	u32 width_mm;
	u32 height_mm;

	int brightness;

	/* 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 inline struct ld9040 *panel_to_ld9040(struct drm_panel *panel)
{
	return container_of(panel, struct ld9040, panel);
}

static int ld9040_clear_error(struct ld9040 *ctx)
{
	int ret = ctx->error;

	ctx->error = 0;
	return ret;
}

static int ld9040_spi_write_word(struct ld9040 *ctx, u16 data)
{
	struct spi_device *spi = to_spi_device(ctx->dev);
	struct spi_transfer xfer = {
		.len		= 2,
		.tx_buf		= &data,
	};
	struct spi_message msg;

	spi_message_init(&msg);
	spi_message_add_tail(&xfer, &msg);

	return spi_sync(spi, &msg);
}

static void ld9040_dcs_write(struct ld9040 *ctx, const u8 *data, size_t len)
{
	int ret = 0;

	if (ctx->error < 0 || len == 0)
		return;

	dev_dbg(ctx->dev, "writing dcs seq: %*ph\n", (int)len, data);
	ret = ld9040_spi_write_word(ctx, *data);

	while (!ret && --len) {
		++data;
		ret = ld9040_spi_write_word(ctx, *data | 0x100);
	}

	if (ret) {
		dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret,
			(int)len, data);
		ctx->error = ret;
	}

	usleep_range(300, 310);
}

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

static void ld9040_brightness_set(struct ld9040 *ctx)
{
	ld9040_dcs_write(ctx, ld9040_gammas[ctx->brightness],
			 ARRAY_SIZE(ld9040_gammas[ctx->brightness]));

	ld9040_dcs_write_seq_static(ctx, MCS_GAMMA_CTRL, 0x02, 0x5a);
}

static void ld9040_init(struct ld9040 *ctx)

Annotation

Implementation Notes