drivers/gpu/drm/panel/panel-lvds.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/panel/panel-lvds.c
Extension
.c
Size
6033 bytes
Lines
257
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 panel_lvds {
	struct drm_panel panel;
	struct device *dev;

	const char *label;
	struct drm_display_mode dmode;
	u32 bus_flags;
	unsigned int bus_format;

	struct regulator *supply;

	struct gpio_desc *enable_gpio;
	struct gpio_desc *reset_gpio;

	enum drm_panel_orientation orientation;
};

static inline struct panel_lvds *to_panel_lvds(struct drm_panel *panel)
{
	return container_of(panel, struct panel_lvds, panel);
}

static int panel_lvds_unprepare(struct drm_panel *panel)
{
	struct panel_lvds *lvds = to_panel_lvds(panel);

	if (lvds->enable_gpio)
		gpiod_set_value_cansleep(lvds->enable_gpio, 0);

	if (lvds->supply)
		regulator_disable(lvds->supply);

	return 0;
}

static int panel_lvds_prepare(struct drm_panel *panel)
{
	struct panel_lvds *lvds = to_panel_lvds(panel);

	if (lvds->supply) {
		int err;

		err = regulator_enable(lvds->supply);
		if (err < 0) {
			dev_err(lvds->dev, "failed to enable supply: %d\n",
				err);
			return err;
		}
	}

	if (lvds->enable_gpio)
		gpiod_set_value_cansleep(lvds->enable_gpio, 1);

	return 0;
}

static int panel_lvds_get_modes(struct drm_panel *panel,
				struct drm_connector *connector)
{
	struct panel_lvds *lvds = to_panel_lvds(panel);
	struct drm_display_mode *mode;

	mode = drm_mode_duplicate(connector->dev, &lvds->dmode);
	if (!mode)
		return 0;

	mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
	drm_mode_probed_add(connector, mode);

	connector->display_info.width_mm = lvds->dmode.width_mm;
	connector->display_info.height_mm = lvds->dmode.height_mm;
	drm_display_info_set_bus_formats(&connector->display_info,
					 &lvds->bus_format, 1);
	connector->display_info.bus_flags = lvds->bus_flags;

	/*
	 * TODO: Remove once all drm drivers call
	 * drm_connector_set_orientation_from_panel()
	 */
	drm_connector_set_panel_orientation(connector, lvds->orientation);

	return 1;
}

static enum drm_panel_orientation panel_lvds_get_orientation(struct drm_panel *panel)
{
	struct panel_lvds *lvds = to_panel_lvds(panel);

	return lvds->orientation;
}

Annotation

Implementation Notes