summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-04-26 14:48:32 +0300
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-07 20:01:49 +0300
commitcca35017ca0dadae632ced71a11a7e0b7083af6c (patch)
treebe103d24062e0f3539b909e3381a79903e20d02a /drivers/video
parentc50e86ce7c2961a41f2f7aa6e4fd6c99229ba205 (diff)
downloadlinux-cca35017ca0dadae632ced71a11a7e0b7083af6c.tar.gz
linux-cca35017ca0dadae632ced71a11a7e0b7083af6c.tar.bz2
linux-cca35017ca0dadae632ced71a11a7e0b7083af6c.zip
OMAPDSS: HDMI: Move GPIO handling to HDMI driver
We currently manage HDMI GPIOs in the board files via platform_enable/disable calls. This won't work with device tree, and in any case the correct place to manage the GPIOs is in the HDMI driver. This patch moves the handling of the GPIOs to the HDMI driver. The GPIO handling is moved to the common hdmi.c file, and this probably needs to be revisited when adding OMAP5 HDMI support to see if the GPIO handling needs to be moved to IP specific files. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/hdmi.c75
1 files changed, 55 insertions, 20 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf24673d48..4fbe27191de5 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -32,6 +32,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
+#include <linux/gpio.h>
#include <video/omapdss.h>
#include "ti_hdmi.h"
@@ -61,6 +62,10 @@ static struct {
struct hdmi_ip_data ip_data;
struct clk *sys_clk;
+
+ int ct_cp_hpd_gpio;
+ int ls_oe_gpio;
+ int hpd_gpio;
} hdmi;
/*
@@ -314,12 +319,34 @@ static void hdmi_runtime_put(void)
static int __init hdmi_init_display(struct omap_dss_device *dssdev)
{
+ int r;
+
+ struct gpio gpios[] = {
+ { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
+ { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
+ { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
+ };
+
DSSDBG("init_display\n");
dss_init_hdmi_ip_ops(&hdmi.ip_data);
+
+ r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+ if (r)
+ return r;
+
return 0;
}
+static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
+{
+ DSSDBG("uninit_display\n");
+
+ gpio_free(hdmi.ct_cp_hpd_gpio);
+ gpio_free(hdmi.ls_oe_gpio);
+ gpio_free(hdmi.hpd_gpio);
+}
+
static const struct hdmi_config *hdmi_find_timing(
const struct hdmi_config *timings_arr,
int len)
@@ -462,9 +489,12 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
struct omap_video_timings *p;
unsigned long phy;
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
+ gpio_set_value(hdmi.ls_oe_gpio, 1);
+
r = hdmi_runtime_get();
if (r)
- return r;
+ goto err_runtime_get;
dss_mgr_disable(dssdev->manager);
@@ -482,7 +512,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
if (r) {
DSSDBG("Failed to lock PLL\n");
- goto err;
+ goto err_pll_enable;
}
r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
@@ -526,8 +556,11 @@ err_vid_enable:
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
err_phy_enable:
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
-err:
+err_pll_enable:
hdmi_runtime_put();
+err_runtime_get:
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
return -EIO;
}
@@ -539,6 +572,9 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
hdmi_runtime_put();
+
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
}
int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -637,7 +673,6 @@ bool omapdss_hdmi_detect(void)
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_hdmi_data *priv = dssdev->data;
int r = 0;
DSSDBG("ENTER hdmi_display_enable\n");
@@ -650,7 +685,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
- hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
+ hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
r = omap_dss_start_device(dssdev);
if (r) {
@@ -658,26 +693,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
- if (dssdev->platform_enable) {
- r = dssdev->platform_enable(dssdev);
- if (r) {
- DSSERR("failed to enable GPIO's\n");
- goto err1;
- }
- }
-
r = hdmi_power_on(dssdev);
if (r) {
DSSERR("failed to power on device\n");
- goto err2;
+ goto err1;
}
mutex_unlock(&hdmi.lock);
return 0;
-err2:
- if (dssdev->platform_disable)
- dssdev->platform_disable(dssdev);
err1:
omap_dss_stop_device(dssdev);
err0:
@@ -693,9 +717,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
hdmi_power_off(dssdev);
- if (dssdev->platform_disable)
- dssdev->platform_disable(dssdev);
-
omap_dss_stop_device(dssdev);
mutex_unlock(&hdmi.lock);
@@ -873,10 +894,15 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
for (i = 0; i < pdata->num_devices; ++i) {
struct omap_dss_device *dssdev = pdata->devices[i];
+ struct omap_dss_hdmi_data *priv = dssdev->data;
if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
continue;
+ hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
+ hdmi.ls_oe_gpio = priv->ls_oe_gpio;
+ hdmi.hpd_gpio = priv->hpd_gpio;
+
r = hdmi_init_display(dssdev);
if (r) {
DSSERR("device %s init failed: %d\n", dssdev->name, r);
@@ -938,8 +964,17 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
return 0;
}
+static int __exit hdmi_remove_child(struct device *dev, void *data)
+{
+ struct omap_dss_device *dssdev = to_dss_device(dev);
+ hdmi_uninit_display(dssdev);
+ return 0;
+}
+
static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
{
+ device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
+
omap_dss_unregister_child_devices(&pdev->dev);
hdmi_panel_exit();