struct clk *isfr_clk;
struct clk *iahb_clk;
+ enum drm_connector_status connector_status;
+
struct hdmi_data_info hdmi_data;
int vic;
/* Clear Hotplug interrupts */
hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
- /* Unmute interrupts */
- hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
-
return 0;
}
static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
*connector, bool force)
{
- /* FIXME */
- return connector_status_connected;
+ struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+ connector);
+ return hdmi->connector_status;
}
static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
.best_encoder = imx_hdmi_connector_best_encoder,
};
+static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
+{
+ struct imx_hdmi *hdmi = dev_id;
+ u8 intr_stat;
+
+ intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
+ if (intr_stat)
+ hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+
+ return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
+}
+
static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
{
struct imx_hdmi *hdmi = dev_id;
hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
+ hdmi->connector_status = connector_status_connected;
imx_hdmi_poweron(hdmi);
} else {
dev_dbg(hdmi->dev, "EVENT=plugout\n");
hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD, HDMI_PHY_POL0);
+ hdmi->connector_status = connector_status_disconnected;
imx_hdmi_poweroff(hdmi);
}
+ drm_helper_hpd_irq_event(hdmi->connector.dev);
}
hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
+ hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
return IRQ_HANDLED;
}
if (ret)
return ret;
+ hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
+
drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
DRM_MODE_ENCODER_TMDS);
return -ENOMEM;
hdmi->dev = dev;
+ hdmi->connector_status = connector_status_disconnected;
hdmi->sample_rate = 48000;
hdmi->ratio = 100;
if (irq < 0)
return -EINVAL;
- ret = devm_request_irq(dev, irq, imx_hdmi_irq, 0,
- dev_name(dev), hdmi);
+ ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
+ imx_hdmi_irq, IRQF_SHARED,
+ dev_name(dev), hdmi);
if (ret)
return ret;
if (ret)
goto err_iahb;
+ /* Unmute interrupts */
+ hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+
dev_set_drvdata(dev, hdmi);
return 0;
{
struct imx_hdmi *hdmi = dev_get_drvdata(dev);
+ /* Disable all interrupts */
+ hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+
hdmi->connector.funcs->destroy(&hdmi->connector);
hdmi->encoder.funcs->destroy(&hdmi->encoder);