drivers/gpu/drm/msm/hdmi/hdmi.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/hdmi/hdmi.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/msm/hdmi/hdmi.c
Extension
.c
Size
11676 bytes
Lines
485
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

if (!hdmi->connector->display_info.is_hdmi) {
			ctrl |= HDMI_CTRL_HDMI;
			hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
			ctrl &= ~HDMI_CTRL_HDMI;
		} else {
			ctrl |= HDMI_CTRL_HDMI;
		}
	} else {
		ctrl = HDMI_CTRL_HDMI;
	}

	hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
	DBG("HDMI Core: %s, HDMI_CTRL=0x%08x",
			power_on ? "Enable" : "Disable", ctrl);
}

static irqreturn_t msm_hdmi_irq(int irq, void *dev_id)
{
	struct hdmi *hdmi = dev_id;

	/* Process HPD: */
	msm_hdmi_hpd_irq(hdmi->bridge);

	/* Process DDC: */
	msm_hdmi_i2c_irq(hdmi->i2c);

	/* Process HDCP: */
	if (hdmi->hdcp_ctrl)
		msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl);

	/* TODO audio.. */

	return IRQ_HANDLED;
}

static void msm_hdmi_destroy(struct hdmi *hdmi)
{
	/*
	 * at this point, hpd has been disabled,
	 * after flush workq, it's safe to deinit hdcp
	 */
	if (hdmi->workq)
		destroy_workqueue(hdmi->workq);
	msm_hdmi_hdcp_destroy(hdmi);

	if (hdmi->i2c)
		msm_hdmi_i2c_destroy(hdmi->i2c);
}

static void msm_hdmi_put_phy(struct hdmi *hdmi)
{
	if (hdmi->phy_dev) {
		put_device(hdmi->phy_dev);
		hdmi->phy = NULL;
		hdmi->phy_dev = NULL;
	}
}

static int msm_hdmi_get_phy(struct hdmi *hdmi)
{
	struct platform_device *pdev = hdmi->pdev;
	struct platform_device *phy_pdev;
	struct device_node *phy_node;

	phy_node = of_parse_phandle(dev_of_node(&pdev->dev), "phys", 0);
	if (!phy_node) {
		DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n");
		return -ENXIO;
	}

	phy_pdev = of_find_device_by_node(phy_node);
	of_node_put(phy_node);

	if (!phy_pdev)
		return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "phy driver is not ready\n");

	hdmi->phy = platform_get_drvdata(phy_pdev);
	if (!hdmi->phy) {
		put_device(&phy_pdev->dev);
		return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "phy driver is not ready\n");
	}

	hdmi->phy_dev = &phy_pdev->dev;

	return 0;
}

/* construct hdmi at bind/probe time, grab all the resources.  If
 * we are to EPROBE_DEFER we want to do it here, rather than later

Annotation

Implementation Notes