drivers/gpu/drm/panel/panel-sitronix-st7789v.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-sitronix-st7789v.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-sitronix-st7789v.c
Extension
.c
Size
21235 bytes
Lines
698
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 st7789_panel_info {
	const struct drm_display_mode *mode;
	u32 bus_format;
	u32 bus_flags;
	bool invert_mode;
	bool partial_mode;
	u16 partial_start;
	u16 partial_end;
};

struct st7789v {
	struct drm_panel panel;
	const struct st7789_panel_info *info;
	struct spi_device *spi;
	struct gpio_desc *reset;
	struct regulator *power;
	enum drm_panel_orientation orientation;
};

enum st7789v_prefix {
	ST7789V_COMMAND = 0,
	ST7789V_DATA = 1,
};

static inline struct st7789v *panel_to_st7789v(struct drm_panel *panel)
{
	return container_of(panel, struct st7789v, panel);
}

static int st7789v_spi_write(struct st7789v *ctx, enum st7789v_prefix prefix,
			     u8 data)
{
	struct spi_transfer xfer = { };
	u16 txbuf = ((prefix & 1) << 8) | data;

	xfer.tx_buf = &txbuf;
	xfer.len = sizeof(txbuf);

	return spi_sync_transfer(ctx->spi, &xfer, 1);
}

static int st7789v_write_command(struct st7789v *ctx, u8 cmd)
{
	return st7789v_spi_write(ctx, ST7789V_COMMAND, cmd);
}

static int st7789v_write_data(struct st7789v *ctx, u8 cmd)
{
	return st7789v_spi_write(ctx, ST7789V_DATA, cmd);
}

static int st7789v_read_data(struct st7789v *ctx, u8 cmd, u8 *buf,
			     unsigned int len)
{
	struct spi_transfer xfer[2] = { };
	struct spi_message msg;
	u16 txbuf = ((ST7789V_COMMAND & 1) << 8) | cmd;
	u16 rxbuf[4] = {};
	u8 bit9 = 0;
	int ret, i;

	switch (len) {
	case 1:
	case 3:
	case 4:
		break;
	default:
		return -EOPNOTSUPP;
	}

	spi_message_init(&msg);

	xfer[0].tx_buf = &txbuf;
	xfer[0].len = sizeof(txbuf);
	spi_message_add_tail(&xfer[0], &msg);

	xfer[1].rx_buf = rxbuf;
	xfer[1].len = len * 2;
	spi_message_add_tail(&xfer[1], &msg);

	ret = spi_sync(ctx->spi, &msg);
	if (ret)
		return ret;

	for (i = 0; i < len; i++) {
		buf[i] = rxbuf[i] >> i | (bit9 << (9 - i));
		if (i)
			bit9 = rxbuf[i] & GENMASK(i - 1, 0);
	}

Annotation

Implementation Notes