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;
return0;
}
/* construct hdmi at bind/probe time, grab all the resources. If *wearetoEPROBE_DEFERwewanttodoithere,ratherthanlater *atmodeset_init()time
*/ staticint msm_hdmi_init(struct hdmi *hdmi)
{ struct platform_device *pdev = hdmi->pdev; int ret;
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0); if (!hdmi->workq) {
ret = -ENOMEM; goto fail;
}
hdmi->i2c = msm_hdmi_i2c_init(hdmi); if (IS_ERR(hdmi->i2c)) {
ret = PTR_ERR(hdmi->i2c);
DRM_DEV_ERROR(&pdev->dev, "failed to get i2c: %d\n", ret);
hdmi->i2c = NULL; goto fail;
}
hdmi->hdcp_ctrl = msm_hdmi_hdcp_init(hdmi); if (IS_ERR(hdmi->hdcp_ctrl)) {
dev_warn(&pdev->dev, "failed to init hdcp: disabled\n");
hdmi->hdcp_ctrl = NULL;
}
return0;
fail:
msm_hdmi_destroy(hdmi);
return ret;
}
/* Second part of initialization, the drm/kms level modeset_init, *constructs/initializesmodeobjects,etc,iscalledfrommaster *driver(nothdmisub-device'sprobe/bind!) * *Anyresource(regulator/clk/etc)whichcouldbemissingatboot *shouldbehandledinmsm_hdmi_init()sothatfailurehappensfrom *hdmisub-device'sprobe.
*/ int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, struct drm_encoder *encoder)
{ int ret;
hdmi->dev = dev;
hdmi->encoder = encoder;
ret = msm_hdmi_bridge_init(hdmi); if (ret) {
DRM_DEV_ERROR(dev->dev, "failed to create HDMI bridge: %d\n", ret); goto fail;
}
if (hdmi->next_bridge) {
ret = drm_bridge_attach(hdmi->encoder, hdmi->next_bridge, hdmi->bridge,
DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (ret) {
DRM_DEV_ERROR(dev->dev, "failed to attach next HDMI bridge: %d\n", ret); goto fail;
}
}
hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder); if (IS_ERR(hdmi->connector)) {
ret = PTR_ERR(hdmi->connector);
DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n", ret);
hdmi->connector = NULL; goto fail;
}
hdmi->irq = platform_get_irq(pdev, 0); if (hdmi->irq < 0) return hdmi->irq;
hdmi->pwr_regs = devm_kcalloc(&pdev->dev,
config->pwr_reg_cnt, sizeof(hdmi->pwr_regs[0]),
GFP_KERNEL); if (!hdmi->pwr_regs) return -ENOMEM;
for (i = 0; i < config->pwr_reg_cnt; i++)
hdmi->pwr_regs[i].supply = config->pwr_reg_names[i];
ret = devm_regulator_bulk_get(&pdev->dev, config->pwr_reg_cnt, hdmi->pwr_regs); if (ret) return dev_err_probe(dev, ret, "failed to get pwr regulators\n");
hdmi->pwr_clks = devm_kcalloc(&pdev->dev,
config->pwr_clk_cnt, sizeof(hdmi->pwr_clks[0]),
GFP_KERNEL); if (!hdmi->pwr_clks) return -ENOMEM;
for (i = 0; i < config->pwr_clk_cnt; i++)
hdmi->pwr_clks[i].id = config->pwr_clk_names[i];
ret = devm_clk_bulk_get(&pdev->dev, config->pwr_clk_cnt, hdmi->pwr_clks); if (ret) return ret;
hdmi->extp_clk = devm_clk_get_optional(&pdev->dev, "extp"); if (IS_ERR(hdmi->extp_clk)) return dev_err_probe(dev, PTR_ERR(hdmi->extp_clk), "failed to get extp clock\n");
hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN); /* This will catch e.g. -EPROBE_DEFER */ if (IS_ERR(hdmi->hpd_gpiod)) return dev_err_probe(dev, PTR_ERR(hdmi->hpd_gpiod), "failed to get hpd gpio\n");
if (!hdmi->hpd_gpiod)
DBG("failed to get HPD gpio");
if (hdmi->hpd_gpiod)
gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
ret = msm_hdmi_get_phy(hdmi); if (ret) {
DRM_DEV_ERROR(&pdev->dev, "failed to get phy\n"); return ret;
}
ret = devm_pm_runtime_enable(&pdev->dev); if (ret) goto err_put_phy;
platform_set_drvdata(pdev, hdmi);
ret = component_add(&pdev->dev, &msm_hdmi_ops); if (ret) goto err_put_phy;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.