drivers/gpu/drm/panel/panel-auo-a030jtn01.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panel/panel-auo-a030jtn01.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-auo-a030jtn01.c
Extension
.c
Size
7769 bytes
Lines
308
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 a030jtn01_info {
	const struct drm_display_mode *display_modes;
	unsigned int num_modes;
	u16 width_mm, height_mm;
	u32 bus_format, bus_flags;
};

struct a030jtn01 {
	struct drm_panel panel;
	struct spi_device *spi;
	struct regmap *map;

	const struct a030jtn01_info *panel_info;

	struct regulator *supply;
	struct gpio_desc *reset_gpio;
};

static inline struct a030jtn01 *to_a030jtn01(struct drm_panel *panel)
{
	return container_of(panel, struct a030jtn01, panel);
}

static int a030jtn01_prepare(struct drm_panel *panel)
{
	struct a030jtn01 *priv = to_a030jtn01(panel);
	struct device *dev = &priv->spi->dev;
	unsigned int dummy;
	int err;

	err = regulator_enable(priv->supply);
	if (err) {
		dev_err(dev, "Failed to enable power supply: %d\n", err);
		return err;
	}

	usleep_range(1000, 8000);

	/* Reset the chip */
	gpiod_set_value_cansleep(priv->reset_gpio, 1);
	usleep_range(100, 8000);
	gpiod_set_value_cansleep(priv->reset_gpio, 0);
	usleep_range(2000, 8000);

	/*
	 * No idea why, but a register read (doesn't matter which) is needed to
	 * properly initialize the chip after a reset; otherwise, the colors
	 * will be wrong. It doesn't seem to be timing-related as a msleep(200)
	 * doesn't fix it.
	 */
	err = regmap_read(priv->map, REG05, &dummy);
	if (err)
		goto err_disable_regulator;

	/* Use (24 + 6) == 0x1e as the vertical back porch */
	err = regmap_write(priv->map, REG06, FIELD_PREP(REG06_VBLK, 0x1e));
	if (err)
		goto err_disable_regulator;

	/* Use (42 + 30) * 3 == 0xd8 as the horizontal back porch */
	err = regmap_write(priv->map, REG07, FIELD_PREP(REG07_HBLK, 0xd8));
	if (err)
		goto err_disable_regulator;

	return 0;

err_disable_regulator:
	gpiod_set_value_cansleep(priv->reset_gpio, 1);
	regulator_disable(priv->supply);
	return err;
}

static int a030jtn01_unprepare(struct drm_panel *panel)
{
	struct a030jtn01 *priv = to_a030jtn01(panel);

	gpiod_set_value_cansleep(priv->reset_gpio, 1);
	regulator_disable(priv->supply);

	return 0;
}

static int a030jtn01_enable(struct drm_panel *panel)
{
	struct a030jtn01 *priv = to_a030jtn01(panel);
	int ret;

	ret = regmap_set_bits(priv->map, REG05, REG05_STDBY);
	if (ret)
		return ret;

Annotation

Implementation Notes