drivers/gpu/drm/bridge/thc63lvd1024.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/thc63lvd1024.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/bridge/thc63lvd1024.c
Extension
.c
Size
5559 bytes
Lines
244
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 thc63_dev {
	struct device *dev;

	struct regulator *vcc;

	struct gpio_desc *pdwn;
	struct gpio_desc *oe;

	struct drm_bridge bridge;

	struct drm_bridge_timings timings;
};

static inline struct thc63_dev *to_thc63(struct drm_bridge *bridge)
{
	return container_of(bridge, struct thc63_dev, bridge);
}

static int thc63_attach(struct drm_bridge *bridge,
			struct drm_encoder *encoder,
			enum drm_bridge_attach_flags flags)
{
	struct thc63_dev *thc63 = to_thc63(bridge);

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

static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
					const struct drm_display_info *info,
					const struct drm_display_mode *mode)
{
	struct thc63_dev *thc63 = to_thc63(bridge);
	unsigned int min_freq;
	unsigned int max_freq;

	/*
	 * The THC63LVD1024 pixel rate range is 8 to 135 MHz in all modes but
	 * dual-in, single-out where it is 40 to 150 MHz. As dual-in, dual-out
	 * isn't supported by the driver yet, simply derive the limits from the
	 * input mode.
	 */
	if (thc63->timings.dual_link) {
		min_freq = 40000;
		max_freq = 150000;
	} else {
		min_freq = 8000;
		max_freq = 135000;
	}

	if (mode->clock < min_freq)
		return MODE_CLOCK_LOW;

	if (mode->clock > max_freq)
		return MODE_CLOCK_HIGH;

	return MODE_OK;
}

static void thc63_enable(struct drm_bridge *bridge)
{
	struct thc63_dev *thc63 = to_thc63(bridge);
	int ret;

	ret = regulator_enable(thc63->vcc);
	if (ret) {
		dev_err(thc63->dev,
			"Failed to enable regulator \"vcc\": %d\n", ret);
		return;
	}

	gpiod_set_value(thc63->pdwn, 0);
	gpiod_set_value(thc63->oe, 1);
}

static void thc63_disable(struct drm_bridge *bridge)
{
	struct thc63_dev *thc63 = to_thc63(bridge);
	int ret;

	gpiod_set_value(thc63->oe, 0);
	gpiod_set_value(thc63->pdwn, 1);

	ret = regulator_disable(thc63->vcc);
	if (ret)
		dev_err(thc63->dev,
			"Failed to disable regulator \"vcc\": %d\n", ret);
}

static const struct drm_bridge_funcs thc63_bridge_func = {
	.attach	= thc63_attach,

Annotation

Implementation Notes