Skip to content

Commit 4ede9c5

Browse files
author
Jyri Sarha
committed
Merge branch 'peter/ti-linux-4.4.y/topic/display' of https://github.com/omap-audio/linux-audio into audio-display-ti-linux-4.4.y
Hotplug detection for 2016.04 * 'peter/ti-linux-4.4.y/topic/display' of https://github.com/omap-audio/linux-audio: ARM: dts: am437x-gp-evm-hdmi: Add interrupt information for sii9022 drm/omap: displays: encoder-sii9022: Support for omapdrm HPD detection drm/omap: displays: encoder-sii9022: Clean up hpd and interrupt handling drm/omap: displays: encoder-sii9022: Simplify the HPD/RXsense reading drm/omap: displays: encoder-sii9022: Enable host interrupts when needed drm/omap: displays: encoder-sii9022: Add bit definition for IRQ EN/STAT drm/omap: displays: dra7-evm-encoder-tpd12s015: Support for hot plug detection drm/omap: displays: encoder-tpd12s015: Support for hot plug detection drm/omap: displays: connector-hdmi: Support for hot plug detection drm/omap: Support for HDMI hot plug detection omap/drm: omap_drv: connector type translation for DSI drm/omap: poll only connectors where the connect/disconnect can be checked
2 parents 0e4f1fc + cc08d44 commit 4ede9c5

File tree

9 files changed

+323
-30
lines changed

9 files changed

+323
-30
lines changed

arch/arm/boot/dts/am437x-gp-evm-hdmi.dts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
compatible = "sil,sii9022";
6363
reg = <0x3b>;
6464

65+
interrupt-parent = <&gpio3>;
66+
interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
67+
6568
i2s-fifo-routing = <
6669
(ENABLE_BIT|CONNECT_SD0)
6770
0

drivers/gpu/drm/omapdrm/displays/connector-hdmi.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/platform_device.h>
1515
#include <linux/of.h>
1616
#include <linux/of_gpio.h>
17+
#include <linux/spinlock.h>
1718

1819
#include <drm/drm_edid.h>
1920

@@ -39,6 +40,9 @@ static const struct omap_video_timings hdmic_default_timings = {
3940
struct panel_drv_data {
4041
struct omap_dss_device dssdev;
4142
struct omap_dss_device *in;
43+
void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
44+
void *hpd_cb_data;
45+
struct mutex hpd_lock;
4246

4347
struct device *dev;
4448

@@ -169,6 +173,32 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
169173
return in->ops.hdmi->detect(in);
170174
}
171175

176+
static int hdmic_enable_hpd(struct omap_dss_device *dssdev,
177+
void (*cb)(void *cb_data,
178+
enum drm_connector_status status),
179+
void *cb_data)
180+
{
181+
struct panel_drv_data *ddata = to_panel_data(dssdev);
182+
struct omap_dss_device *in = ddata->in;
183+
184+
if (gpio_is_valid(ddata->hpd_gpio)) {
185+
mutex_lock(&ddata->hpd_lock);
186+
ddata->hpd_cb = cb;
187+
ddata->hpd_cb_data = cb_data;
188+
mutex_unlock(&ddata->hpd_lock);
189+
return 0;
190+
} else if (in->ops.hdmi->enable_hpd) {
191+
return in->ops.hdmi->enable_hpd(in, cb, cb_data);
192+
}
193+
194+
return -ENOTSUPP;
195+
}
196+
197+
static void hdmic_disable_hpd(struct omap_dss_device *dssdev)
198+
{
199+
hdmic_enable_hpd(dssdev, NULL, NULL);
200+
}
201+
172202
static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
173203
{
174204
struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -201,10 +231,32 @@ static struct omap_dss_driver hdmic_driver = {
201231

202232
.read_edid = hdmic_read_edid,
203233
.detect = hdmic_detect,
234+
.enable_hpd = hdmic_enable_hpd,
235+
.disable_hpd = hdmic_disable_hpd,
204236
.set_hdmi_mode = hdmic_set_hdmi_mode,
205237
.set_hdmi_infoframe = hdmic_set_infoframe,
206238
};
207239

240+
static irqreturn_t hdmic_hpd_isr(int irq, void *data)
241+
{
242+
struct panel_drv_data *ddata = data;
243+
244+
mutex_lock(&ddata->hpd_lock);
245+
if (ddata->hpd_cb) {
246+
enum drm_connector_status status;
247+
248+
if (hdmic_detect(&ddata->dssdev))
249+
status = connector_status_connected;
250+
else
251+
status = connector_status_disconnected;
252+
253+
ddata->hpd_cb(ddata->hpd_cb_data, status);
254+
}
255+
mutex_unlock(&ddata->hpd_lock);
256+
257+
return IRQ_HANDLED;
258+
}
259+
208260
static int hdmic_probe_of(struct platform_device *pdev)
209261
{
210262
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
@@ -250,11 +302,22 @@ static int hdmic_probe(struct platform_device *pdev)
250302
if (r)
251303
return r;
252304

305+
mutex_init(&ddata->hpd_lock);
306+
253307
if (gpio_is_valid(ddata->hpd_gpio)) {
254308
r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
255309
GPIOF_DIR_IN, "hdmi_hpd");
256310
if (r)
257311
goto err_reg;
312+
313+
r = devm_request_threaded_irq(&pdev->dev,
314+
gpio_to_irq(ddata->hpd_gpio),
315+
NULL, hdmic_hpd_isr,
316+
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
317+
IRQF_ONESHOT,
318+
"hdmic hpd", ddata);
319+
if (r)
320+
goto err_reg;
258321
}
259322

260323
ddata->timings = hdmic_default_timings;

drivers/gpu/drm/omapdrm/displays/dra7-evm-encoder-tpd12s015.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/suspend.h>
2222
#include <linux/of_platform.h>
2323
#include <linux/pinctrl/consumer.h>
24+
#include <linux/spinlock.h>
2425

2526
#include "../dss/omapdss.h"
2627

@@ -37,6 +38,9 @@ int dra7_mcasp_hdmi_gpio_set(struct platform_device *pdev, bool high);
3738
struct panel_drv_data {
3839
struct omap_dss_device dssdev;
3940
struct omap_dss_device *in;
41+
void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
42+
void *hpd_cb_data;
43+
struct mutex hpd_lock;
4044

4145
int ct_cp_hpd_gpio;
4246
int ls_oe_gpio;
@@ -271,7 +275,26 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
271275
struct panel_drv_data *ddata = to_panel_data(dssdev);
272276

273277
return gpio_get_value_cansleep(ddata->hpd_gpio);
278+
}
279+
280+
static int tpd_enable_hpd(struct omap_dss_device *dssdev,
281+
void (*cb)(void *cb_data,
282+
enum drm_connector_status status),
283+
void *cb_data)
284+
{
285+
struct panel_drv_data *ddata = to_panel_data(dssdev);
286+
287+
mutex_lock(&ddata->hpd_lock);
288+
ddata->hpd_cb = cb;
289+
ddata->hpd_cb_data = cb_data;
290+
mutex_unlock(&ddata->hpd_lock);
274291

292+
return 0;
293+
}
294+
295+
static void tpd_disable_hpd(struct omap_dss_device *dssdev)
296+
{
297+
tpd_enable_hpd(dssdev, NULL, NULL);
275298
}
276299

277300
static int tpd_set_infoframe(struct omap_dss_device *dssdev,
@@ -305,10 +328,32 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
305328

306329
.read_edid = tpd_read_edid,
307330
.detect = tpd_detect,
331+
.enable_hpd = tpd_enable_hpd,
332+
.disable_hpd = tpd_disable_hpd,
308333
.set_infoframe = tpd_set_infoframe,
309334
.set_hdmi_mode = tpd_set_hdmi_mode,
310335
};
311336

337+
static irqreturn_t tpd_hpd_isr(int irq, void *data)
338+
{
339+
struct panel_drv_data *ddata = data;
340+
341+
mutex_lock(&ddata->hpd_lock);
342+
if (ddata->hpd_cb) {
343+
enum drm_connector_status status;
344+
345+
if (tpd_detect(&ddata->dssdev))
346+
status = connector_status_connected;
347+
else
348+
status = connector_status_disconnected;
349+
350+
ddata->hpd_cb(ddata->hpd_cb_data, status);
351+
}
352+
mutex_unlock(&ddata->hpd_lock);
353+
354+
return IRQ_HANDLED;
355+
}
356+
312357
static int tpd_probe_of(struct platform_device *pdev)
313358
{
314359
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
@@ -457,6 +502,15 @@ static int tpd_probe(struct platform_device *pdev)
457502
if (r)
458503
goto err_debounce;
459504

505+
mutex_init(&ddata->hpd_lock);
506+
507+
r = devm_request_threaded_irq(&pdev->dev, gpio_to_irq(ddata->hpd_gpio),
508+
NULL, tpd_hpd_isr,
509+
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
510+
"tpd12s015 hpd", ddata);
511+
if (r)
512+
goto err_debounce;
513+
460514
dssdev = &ddata->dssdev;
461515
dssdev->ops.hdmi = &tpd_hdmi_ops;
462516
dssdev->dev = &pdev->dev;

0 commit comments

Comments
 (0)