drivers/gpu/drm/meson/meson_encoder_cvbs.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/meson/meson_encoder_cvbs.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/meson/meson_encoder_cvbs.c
Extension
.c
Size
8893 bytes
Lines
296
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 meson_encoder_cvbs {
	struct drm_encoder	encoder;
	struct drm_bridge	bridge;
	struct meson_drm	*priv;
};

#define bridge_to_meson_encoder_cvbs(x) \
	container_of(x, struct meson_encoder_cvbs, bridge)

/* Supported Modes */

struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
	{ /* PAL */
		.enci = &meson_cvbs_enci_pal,
		.mode = {
			DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
				 720, 732, 795, 864, 0, 576, 580, 586, 625, 0,
				 DRM_MODE_FLAG_INTERLACE),
			.picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
		},
	},
	{ /* NTSC */
		.enci = &meson_cvbs_enci_ntsc,
		.mode = {
			DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
				720, 739, 801, 858, 0, 480, 488, 494, 525, 0,
				DRM_MODE_FLAG_INTERLACE),
			.picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
		},
	},
};

static const struct meson_cvbs_mode *
meson_cvbs_get_mode(const struct drm_display_mode *req_mode)
{
	int i;

	for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
		struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];

		if (drm_mode_match(req_mode, &meson_mode->mode,
				   DRM_MODE_MATCH_TIMINGS |
				   DRM_MODE_MATCH_CLOCK |
				   DRM_MODE_MATCH_FLAGS |
				   DRM_MODE_MATCH_3D_FLAGS))
			return meson_mode;
	}

	return NULL;
}

static int meson_encoder_cvbs_attach(struct drm_bridge *bridge,
				     struct drm_encoder *encoder,
				     enum drm_bridge_attach_flags flags)
{
	struct meson_encoder_cvbs *meson_encoder_cvbs =
					bridge_to_meson_encoder_cvbs(bridge);

	return drm_bridge_attach(encoder, meson_encoder_cvbs->bridge.next_bridge,
				 &meson_encoder_cvbs->bridge, flags);
}

static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge,
					struct drm_connector *connector)
{
	struct meson_encoder_cvbs *meson_encoder_cvbs =
					bridge_to_meson_encoder_cvbs(bridge);
	struct meson_drm *priv = meson_encoder_cvbs->priv;
	struct drm_display_mode *mode;
	int i;

	for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
		struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];

		mode = drm_mode_duplicate(priv->drm, &meson_mode->mode);
		if (!mode) {
			dev_err(priv->dev, "Failed to create a new display mode\n");
			return 0;
		}

		drm_mode_probed_add(connector, mode);
	}

	return i;
}

static enum drm_mode_status
meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge,
			      const struct drm_display_info *display_info,
			      const struct drm_display_mode *mode)

Annotation

Implementation Notes