aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2')
-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 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
34#include <linux/clk.h> 34#include <linux/clk.h>
35#include <linux/gpio.h>
35#include <video/omapdss.h> 36#include <video/omapdss.h>
36 37
37#include "ti_hdmi.h" 38#include "ti_hdmi.h"
@@ -61,6 +62,10 @@ static struct {
61 struct hdmi_ip_data ip_data; 62 struct hdmi_ip_data ip_data;
62 63
63 struct clk *sys_clk; 64 struct clk *sys_clk;
65
66 int ct_cp_hpd_gpio;
67 int ls_oe_gpio;
68 int hpd_gpio;
64} hdmi; 69} hdmi;
65 70
66/* 71/*
@@ -314,12 +319,34 @@ static void hdmi_runtime_put(void)
314 319
315static int __init hdmi_init_display(struct omap_dss_device *dssdev) 320static int __init hdmi_init_display(struct omap_dss_device *dssdev)
316{ 321{
322 int r;
323
324 struct gpio gpios[] = {
325 { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
326 { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
327 { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
328 };
329
317 DSSDBG("init_display\n"); 330 DSSDBG("init_display\n");
318 331
319 dss_init_hdmi_ip_ops(&hdmi.ip_data); 332 dss_init_hdmi_ip_ops(&hdmi.ip_data);
333
334 r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
335 if (r)
336 return r;
337
320 return 0; 338 return 0;
321} 339}
322 340
341static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
342{
343 DSSDBG("uninit_display\n");
344
345 gpio_free(hdmi.ct_cp_hpd_gpio);
346 gpio_free(hdmi.ls_oe_gpio);
347 gpio_free(hdmi.hpd_gpio);
348}
349
323static const struct hdmi_config *hdmi_find_timing( 350static const struct hdmi_config *hdmi_find_timing(
324 const struct hdmi_config *timings_arr, 351 const struct hdmi_config *timings_arr,
325 int len) 352 int len)
@@ -462,9 +489,12 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
462 struct omap_video_timings *p; 489 struct omap_video_timings *p;
463 unsigned long phy; 490 unsigned long phy;
464 491
492 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
493 gpio_set_value(hdmi.ls_oe_gpio, 1);
494
465 r = hdmi_runtime_get(); 495 r = hdmi_runtime_get();
466 if (r) 496 if (r)
467 return r; 497 goto err_runtime_get;
468 498
469 dss_mgr_disable(dssdev->manager); 499 dss_mgr_disable(dssdev->manager);
470 500
@@ -482,7 +512,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
482 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); 512 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
483 if (r) { 513 if (r) {
484 DSSDBG("Failed to lock PLL\n"); 514 DSSDBG("Failed to lock PLL\n");
485 goto err; 515 goto err_pll_enable;
486 } 516 }
487 517
488 r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); 518 r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
@@ -526,8 +556,11 @@ err_vid_enable:
526 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 556 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
527err_phy_enable: 557err_phy_enable:
528 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 558 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
529err: 559err_pll_enable:
530 hdmi_runtime_put(); 560 hdmi_runtime_put();
561err_runtime_get:
562 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
563 gpio_set_value(hdmi.ls_oe_gpio, 0);
531 return -EIO; 564 return -EIO;
532} 565}
533 566
@@ -539,6 +572,9 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
539 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 572 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
540 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 573 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
541 hdmi_runtime_put(); 574 hdmi_runtime_put();
575
576 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
577 gpio_set_value(hdmi.ls_oe_gpio, 0);
542} 578}
543 579
544int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 580int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -637,7 +673,6 @@ bool omapdss_hdmi_detect(void)
637 673
638int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) 674int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
639{ 675{
640 struct omap_dss_hdmi_data *priv = dssdev->data;
641 int r = 0; 676 int r = 0;
642 677
643 DSSDBG("ENTER hdmi_display_enable\n"); 678 DSSDBG("ENTER hdmi_display_enable\n");
@@ -650,7 +685,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
650 goto err0; 685 goto err0;
651 } 686 }
652 687
653 hdmi.ip_data.hpd_gpio = priv->hpd_gpio; 688 hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
654 689
655 r = omap_dss_start_device(dssdev); 690 r = omap_dss_start_device(dssdev);
656 if (r) { 691 if (r) {
@@ -658,26 +693,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
658 goto err0; 693 goto err0;
659 } 694 }
660 695
661 if (dssdev->platform_enable) {
662 r = dssdev->platform_enable(dssdev);
663 if (r) {
664 DSSERR("failed to enable GPIO's\n");
665 goto err1;
666 }
667 }
668
669 r = hdmi_power_on(dssdev); 696 r = hdmi_power_on(dssdev);
670 if (r) { 697 if (r) {
671 DSSERR("failed to power on device\n"); 698 DSSERR("failed to power on device\n");
672 goto err2; 699 goto err1;
673 } 700 }
674 701
675 mutex_unlock(&hdmi.lock); 702 mutex_unlock(&hdmi.lock);
676 return 0; 703 return 0;
677 704
678err2:
679 if (dssdev->platform_disable)
680 dssdev->platform_disable(dssdev);
681err1: 705err1:
682 omap_dss_stop_device(dssdev); 706 omap_dss_stop_device(dssdev);
683err0: 707err0:
@@ -693,9 +717,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
693 717
694 hdmi_power_off(dssdev); 718 hdmi_power_off(dssdev);
695 719
696 if (dssdev->platform_disable)
697 dssdev->platform_disable(dssdev);
698
699 omap_dss_stop_device(dssdev); 720 omap_dss_stop_device(dssdev);
700 721
701 mutex_unlock(&hdmi.lock); 722 mutex_unlock(&hdmi.lock);
@@ -873,10 +894,15 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
873 894
874 for (i = 0; i < pdata->num_devices; ++i) { 895 for (i = 0; i < pdata->num_devices; ++i) {
875 struct omap_dss_device *dssdev = pdata->devices[i]; 896 struct omap_dss_device *dssdev = pdata->devices[i];
897 struct omap_dss_hdmi_data *priv = dssdev->data;
876 898
877 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) 899 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
878 continue; 900 continue;
879 901
902 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
903 hdmi.ls_oe_gpio = priv->ls_oe_gpio;
904 hdmi.hpd_gpio = priv->hpd_gpio;
905
880 r = hdmi_init_display(dssdev); 906 r = hdmi_init_display(dssdev);
881 if (r) { 907 if (r) {
882 DSSERR("device %s init failed: %d\n", dssdev->name, r); 908 DSSERR("device %s init failed: %d\n", dssdev->name, r);
@@ -938,8 +964,17 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
938 return 0; 964 return 0;
939} 965}
940 966
967static int __exit hdmi_remove_child(struct device *dev, void *data)
968{
969 struct omap_dss_device *dssdev = to_dss_device(dev);
970 hdmi_uninit_display(dssdev);
971 return 0;
972}
973
941static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 974static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
942{ 975{
976 device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
977
943 omap_dss_unregister_child_devices(&pdev->dev); 978 omap_dss_unregister_child_devices(&pdev->dev);
944 979
945 hdmi_panel_exit(); 980 hdmi_panel_exit();