aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/omap2/dss/Makefile3
-rw-r--r--drivers/video/omap2/dss/dss.h20
-rw-r--r--drivers/video/omap2/dss/hdmi.c303
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c414
4 files changed, 44 insertions, 696 deletions
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 61949ff7940c..e022ed103804 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -10,6 +10,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
10omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o 10omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
11omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 11omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
12omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 12omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
13omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ 13omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o ti_hdmi_4xxx_ip.o
14 hdmi_panel.o ti_hdmi_4xxx_ip.o
15ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG 14ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 146349f6ae91..6142885751e0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -452,26 +452,6 @@ void venc_panel_exit(void);
452/* HDMI */ 452/* HDMI */
453int hdmi_init_platform_driver(void) __init; 453int hdmi_init_platform_driver(void) __init;
454void hdmi_uninit_platform_driver(void) __exit; 454void hdmi_uninit_platform_driver(void) __exit;
455int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
456void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
457int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev);
458void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev);
459void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
460 struct omap_video_timings *timings);
461int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
462 struct omap_video_timings *timings);
463int omapdss_hdmi_read_edid(u8 *buf, int len);
464bool omapdss_hdmi_detect(void);
465int hdmi_panel_init(void);
466void hdmi_panel_exit(void);
467#ifdef CONFIG_OMAP4_DSS_HDMI_AUDIO
468int hdmi_audio_enable(void);
469void hdmi_audio_disable(void);
470int hdmi_audio_start(void);
471void hdmi_audio_stop(void);
472bool hdmi_mode_has_audio(void);
473int hdmi_audio_config(struct omap_dss_audio *audio);
474#endif
475 455
476/* RFBI */ 456/* RFBI */
477int rfbi_init_platform_driver(void) __init; 457int rfbi_init_platform_driver(void) __init;
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 44a885b92825..0b8e4dec2c0e 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -66,10 +66,6 @@ static struct {
66 struct clk *sys_clk; 66 struct clk *sys_clk;
67 struct regulator *vdda_hdmi_dac_reg; 67 struct regulator *vdda_hdmi_dac_reg;
68 68
69 int ct_cp_hpd_gpio;
70 int ls_oe_gpio;
71 int hpd_gpio;
72
73 bool core_enabled; 69 bool core_enabled;
74 70
75 struct omap_dss_device output; 71 struct omap_dss_device output;
@@ -353,40 +349,6 @@ static int hdmi_init_regulator(void)
353 return 0; 349 return 0;
354} 350}
355 351
356static int hdmi_init_display(struct omap_dss_device *dssdev)
357{
358 int r;
359
360 struct gpio gpios[] = {
361 { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
362 { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
363 { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
364 };
365
366 DSSDBG("init_display\n");
367
368 dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
369
370 r = hdmi_init_regulator();
371 if (r)
372 return r;
373
374 r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
375 if (r)
376 return r;
377
378 return 0;
379}
380
381static void hdmi_uninit_display(struct omap_dss_device *dssdev)
382{
383 DSSDBG("uninit_display\n");
384
385 gpio_free(hdmi.ct_cp_hpd_gpio);
386 gpio_free(hdmi.ls_oe_gpio);
387 gpio_free(hdmi.hpd_gpio);
388}
389
390static const struct hdmi_config *hdmi_find_timing( 352static const struct hdmi_config *hdmi_find_timing(
391 const struct hdmi_config *timings_arr, 353 const struct hdmi_config *timings_arr,
392 int len) 354 int len)
@@ -517,17 +479,9 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
517{ 479{
518 int r; 480 int r;
519 481
520 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
521 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
522 if (gpio_is_valid(hdmi.ls_oe_gpio))
523 gpio_set_value(hdmi.ls_oe_gpio, 1);
524
525 /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
526 udelay(300);
527
528 r = regulator_enable(hdmi.vdda_hdmi_dac_reg); 482 r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
529 if (r) 483 if (r)
530 goto err_vdac_enable; 484 return r;
531 485
532 r = hdmi_runtime_get(); 486 r = hdmi_runtime_get();
533 if (r) 487 if (r)
@@ -542,11 +496,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
542 496
543err_runtime_get: 497err_runtime_get:
544 regulator_disable(hdmi.vdda_hdmi_dac_reg); 498 regulator_disable(hdmi.vdda_hdmi_dac_reg);
545err_vdac_enable: 499
546 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
547 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
548 if (gpio_is_valid(hdmi.ls_oe_gpio))
549 gpio_set_value(hdmi.ls_oe_gpio, 0);
550 return r; 500 return r;
551} 501}
552 502
@@ -556,10 +506,6 @@ static void hdmi_power_off_core(struct omap_dss_device *dssdev)
556 506
557 hdmi_runtime_put(); 507 hdmi_runtime_put();
558 regulator_disable(hdmi.vdda_hdmi_dac_reg); 508 regulator_disable(hdmi.vdda_hdmi_dac_reg);
559 if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
560 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
561 if (gpio_is_valid(hdmi.ls_oe_gpio))
562 gpio_set_value(hdmi.ls_oe_gpio, 0);
563} 509}
564 510
565static int hdmi_power_on_full(struct omap_dss_device *dssdev) 511static int hdmi_power_on_full(struct omap_dss_device *dssdev)
@@ -640,7 +586,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
640 hdmi_power_off_core(dssdev); 586 hdmi_power_off_core(dssdev);
641} 587}
642 588
643int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 589static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
644 struct omap_video_timings *timings) 590 struct omap_video_timings *timings)
645{ 591{
646 struct hdmi_cm cm; 592 struct hdmi_cm cm;
@@ -654,7 +600,7 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
654 600
655} 601}
656 602
657void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, 603static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
658 struct omap_video_timings *timings) 604 struct omap_video_timings *timings)
659{ 605{
660 struct hdmi_cm cm; 606 struct hdmi_cm cm;
@@ -674,7 +620,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
674 mutex_unlock(&hdmi.lock); 620 mutex_unlock(&hdmi.lock);
675} 621}
676 622
677static void omapdss_hdmi_display_get_timings(struct omap_dss_device *dssdev, 623static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
678 struct omap_video_timings *timings) 624 struct omap_video_timings *timings)
679{ 625{
680 const struct hdmi_config *cfg; 626 const struct hdmi_config *cfg;
@@ -704,7 +650,7 @@ static void hdmi_dump_regs(struct seq_file *s)
704 mutex_unlock(&hdmi.lock); 650 mutex_unlock(&hdmi.lock);
705} 651}
706 652
707int omapdss_hdmi_read_edid(u8 *buf, int len) 653static int read_edid(u8 *buf, int len)
708{ 654{
709 int r; 655 int r;
710 656
@@ -721,24 +667,7 @@ int omapdss_hdmi_read_edid(u8 *buf, int len)
721 return r; 667 return r;
722} 668}
723 669
724bool omapdss_hdmi_detect(void) 670static int hdmi_display_enable(struct omap_dss_device *dssdev)
725{
726 int r;
727
728 mutex_lock(&hdmi.lock);
729
730 r = hdmi_runtime_get();
731 BUG_ON(r);
732
733 r = gpio_get_value(hdmi.hpd_gpio);
734
735 hdmi_runtime_put();
736 mutex_unlock(&hdmi.lock);
737
738 return r == 1;
739}
740
741int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
742{ 671{
743 struct omap_dss_device *out = &hdmi.output; 672 struct omap_dss_device *out = &hdmi.output;
744 int r = 0; 673 int r = 0;
@@ -767,7 +696,7 @@ err0:
767 return r; 696 return r;
768} 697}
769 698
770void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) 699static void hdmi_display_disable(struct omap_dss_device *dssdev)
771{ 700{
772 DSSDBG("Enter hdmi_display_disable\n"); 701 DSSDBG("Enter hdmi_display_disable\n");
773 702
@@ -778,7 +707,7 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
778 mutex_unlock(&hdmi.lock); 707 mutex_unlock(&hdmi.lock);
779} 708}
780 709
781int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev) 710static int hdmi_core_enable(struct omap_dss_device *dssdev)
782{ 711{
783 int r = 0; 712 int r = 0;
784 713
@@ -800,7 +729,7 @@ err0:
800 return r; 729 return r;
801} 730}
802 731
803void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev) 732static void hdmi_core_disable(struct omap_dss_device *dssdev)
804{ 733{
805 DSSDBG("Enter omapdss_hdmi_core_disable\n"); 734 DSSDBG("Enter omapdss_hdmi_core_disable\n");
806 735
@@ -927,35 +856,7 @@ int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts)
927 return 0; 856 return 0;
928} 857}
929 858
930int hdmi_audio_enable(void) 859static bool hdmi_mode_has_audio(void)
931{
932 DSSDBG("audio_enable\n");
933
934 return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data);
935}
936
937void hdmi_audio_disable(void)
938{
939 DSSDBG("audio_disable\n");
940
941 hdmi.ip_data.ops->audio_disable(&hdmi.ip_data);
942}
943
944int hdmi_audio_start(void)
945{
946 DSSDBG("audio_start\n");
947
948 return hdmi.ip_data.ops->audio_start(&hdmi.ip_data);
949}
950
951void hdmi_audio_stop(void)
952{
953 DSSDBG("audio_stop\n");
954
955 hdmi.ip_data.ops->audio_stop(&hdmi.ip_data);
956}
957
958bool hdmi_mode_has_audio(void)
959{ 860{
960 if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) 861 if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI)
961 return true; 862 return true;
@@ -963,92 +864,8 @@ bool hdmi_mode_has_audio(void)
963 return false; 864 return false;
964} 865}
965 866
966int hdmi_audio_config(struct omap_dss_audio *audio)
967{
968 return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio);
969}
970
971#endif 867#endif
972 868
973static struct omap_dss_device *hdmi_find_dssdev(struct platform_device *pdev)
974{
975 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
976 const char *def_disp_name = omapdss_get_default_display_name();
977 struct omap_dss_device *def_dssdev;
978 int i;
979
980 def_dssdev = NULL;
981
982 for (i = 0; i < pdata->num_devices; ++i) {
983 struct omap_dss_device *dssdev = pdata->devices[i];
984
985 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
986 continue;
987
988 if (def_dssdev == NULL)
989 def_dssdev = dssdev;
990
991 if (def_disp_name != NULL &&
992 strcmp(dssdev->name, def_disp_name) == 0) {
993 def_dssdev = dssdev;
994 break;
995 }
996 }
997
998 return def_dssdev;
999}
1000
1001static int hdmi_probe_pdata(struct platform_device *pdev)
1002{
1003 struct omap_dss_device *plat_dssdev;
1004 struct omap_dss_device *dssdev;
1005 struct omap_dss_hdmi_data *priv;
1006 int r;
1007
1008 plat_dssdev = hdmi_find_dssdev(pdev);
1009
1010 if (!plat_dssdev)
1011 return 0;
1012
1013 dssdev = dss_alloc_and_init_device(&pdev->dev);
1014 if (!dssdev)
1015 return -ENOMEM;
1016
1017 dss_copy_device_pdata(dssdev, plat_dssdev);
1018
1019 priv = dssdev->data;
1020
1021 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
1022 hdmi.ls_oe_gpio = priv->ls_oe_gpio;
1023 hdmi.hpd_gpio = priv->hpd_gpio;
1024
1025 r = hdmi_init_display(dssdev);
1026 if (r) {
1027 DSSERR("device %s init failed: %d\n", dssdev->name, r);
1028 dss_put_device(dssdev);
1029 return r;
1030 }
1031
1032 r = omapdss_output_set_device(&hdmi.output, dssdev);
1033 if (r) {
1034 DSSERR("failed to connect output to new device: %s\n",
1035 dssdev->name);
1036 dss_put_device(dssdev);
1037 return r;
1038 }
1039
1040 r = dss_add_device(dssdev);
1041 if (r) {
1042 DSSERR("device %s register failed: %d\n", dssdev->name, r);
1043 omapdss_output_unset_device(&hdmi.output);
1044 hdmi_uninit_display(dssdev);
1045 dss_put_device(dssdev);
1046 return r;
1047 }
1048
1049 return 0;
1050}
1051
1052static int hdmi_connect(struct omap_dss_device *dssdev, 869static int hdmi_connect(struct omap_dss_device *dssdev,
1053 struct omap_dss_device *dst) 870 struct omap_dss_device *dst)
1054{ 871{
@@ -1103,21 +920,21 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
1103 need_enable = hdmi.core_enabled == false; 920 need_enable = hdmi.core_enabled == false;
1104 921
1105 if (need_enable) { 922 if (need_enable) {
1106 r = omapdss_hdmi_core_enable(dssdev); 923 r = hdmi_core_enable(dssdev);
1107 if (r) 924 if (r)
1108 return r; 925 return r;
1109 } 926 }
1110 927
1111 r = omapdss_hdmi_read_edid(edid, len); 928 r = read_edid(edid, len);
1112 929
1113 if (need_enable) 930 if (need_enable)
1114 omapdss_hdmi_core_disable(dssdev); 931 hdmi_core_disable(dssdev);
1115 932
1116 return r; 933 return r;
1117} 934}
1118 935
1119#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 936#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
1120static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) 937static int hdmi_audio_enable(struct omap_dss_device *dssdev)
1121{ 938{
1122 int r; 939 int r;
1123 940
@@ -1128,7 +945,8 @@ static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
1128 goto err; 945 goto err;
1129 } 946 }
1130 947
1131 r = hdmi_audio_enable(); 948
949 r = hdmi.ip_data.ops->audio_enable(&hdmi.ip_data);
1132 if (r) 950 if (r)
1133 goto err; 951 goto err;
1134 952
@@ -1140,22 +958,22 @@ err:
1140 return r; 958 return r;
1141} 959}
1142 960
1143static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev) 961static void hdmi_audio_disable(struct omap_dss_device *dssdev)
1144{ 962{
1145 hdmi_audio_disable(); 963 hdmi.ip_data.ops->audio_disable(&hdmi.ip_data);
1146} 964}
1147 965
1148static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev) 966static int hdmi_audio_start(struct omap_dss_device *dssdev)
1149{ 967{
1150 return hdmi_audio_start(); 968 return hdmi.ip_data.ops->audio_start(&hdmi.ip_data);
1151} 969}
1152 970
1153static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev) 971static void hdmi_audio_stop(struct omap_dss_device *dssdev)
1154{ 972{
1155 hdmi_audio_stop(); 973 hdmi.ip_data.ops->audio_stop(&hdmi.ip_data);
1156} 974}
1157 975
1158static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) 976static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
1159{ 977{
1160 bool r; 978 bool r;
1161 979
@@ -1167,7 +985,7 @@ static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
1167 return r; 985 return r;
1168} 986}
1169 987
1170static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, 988static int hdmi_audio_config(struct omap_dss_device *dssdev,
1171 struct omap_dss_audio *audio) 989 struct omap_dss_audio *audio)
1172{ 990{
1173 int r; 991 int r;
@@ -1179,7 +997,7 @@ static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
1179 goto err; 997 goto err;
1180 } 998 }
1181 999
1182 r = hdmi_audio_config(audio); 1000 r = hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio);
1183 if (r) 1001 if (r)
1184 goto err; 1002 goto err;
1185 1003
@@ -1191,30 +1009,30 @@ err:
1191 return r; 1009 return r;
1192} 1010}
1193#else 1011#else
1194static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) 1012static int hdmi_audio_enable(struct omap_dss_device *dssdev)
1195{ 1013{
1196 return -EPERM; 1014 return -EPERM;
1197} 1015}
1198 1016
1199static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev) 1017static void hdmi_audio_disable(struct omap_dss_device *dssdev)
1200{ 1018{
1201} 1019}
1202 1020
1203static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev) 1021static int hdmi_audio_start(struct omap_dss_device *dssdev)
1204{ 1022{
1205 return -EPERM; 1023 return -EPERM;
1206} 1024}
1207 1025
1208static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev) 1026static void hdmi_audio_stop(struct omap_dss_device *dssdev)
1209{ 1027{
1210} 1028}
1211 1029
1212static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) 1030static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
1213{ 1031{
1214 return false; 1032 return false;
1215} 1033}
1216 1034
1217static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, 1035static int hdmi_audio_config(struct omap_dss_device *dssdev,
1218 struct omap_dss_audio *audio) 1036 struct omap_dss_audio *audio)
1219{ 1037{
1220 return -EPERM; 1038 return -EPERM;
@@ -1225,21 +1043,21 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
1225 .connect = hdmi_connect, 1043 .connect = hdmi_connect,
1226 .disconnect = hdmi_disconnect, 1044 .disconnect = hdmi_disconnect,
1227 1045
1228 .enable = omapdss_hdmi_display_enable, 1046 .enable = hdmi_display_enable,
1229 .disable = omapdss_hdmi_display_disable, 1047 .disable = hdmi_display_disable,
1230 1048
1231 .check_timings = omapdss_hdmi_display_check_timing, 1049 .check_timings = hdmi_display_check_timing,
1232 .set_timings = omapdss_hdmi_display_set_timing, 1050 .set_timings = hdmi_display_set_timing,
1233 .get_timings = omapdss_hdmi_display_get_timings, 1051 .get_timings = hdmi_display_get_timings,
1234 1052
1235 .read_edid = hdmi_read_edid, 1053 .read_edid = hdmi_read_edid,
1236 1054
1237 .audio_enable = omapdss_hdmi_audio_enable, 1055 .audio_enable = hdmi_audio_enable,
1238 .audio_disable = omapdss_hdmi_audio_disable, 1056 .audio_disable = hdmi_audio_disable,
1239 .audio_start = omapdss_hdmi_audio_start, 1057 .audio_start = hdmi_audio_start,
1240 .audio_stop = omapdss_hdmi_audio_stop, 1058 .audio_stop = hdmi_audio_stop,
1241 .audio_supported = omapdss_hdmi_audio_supported, 1059 .audio_supported = hdmi_audio_supported,
1242 .audio_config = omapdss_hdmi_audio_config, 1060 .audio_config = hdmi_audio_config,
1243}; 1061};
1244 1062
1245static void hdmi_init_output(struct platform_device *pdev) 1063static void hdmi_init_output(struct platform_device *pdev)
@@ -1301,50 +1119,15 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1301 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1119 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1302 hdmi.ip_data.phy_offset = HDMI_PHY; 1120 hdmi.ip_data.phy_offset = HDMI_PHY;
1303 1121
1304 hdmi.ct_cp_hpd_gpio = -1;
1305 hdmi.ls_oe_gpio = -1;
1306 hdmi.hpd_gpio = -1;
1307
1308 hdmi_init_output(pdev); 1122 hdmi_init_output(pdev);
1309 1123
1310 r = hdmi_panel_init();
1311 if (r) {
1312 DSSERR("can't init panel\n");
1313 return r;
1314 }
1315
1316 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1124 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1317 1125
1318 if (pdev->dev.platform_data) {
1319 r = hdmi_probe_pdata(pdev);
1320 if (r)
1321 goto err_probe;
1322 }
1323
1324 return 0;
1325
1326err_probe:
1327 hdmi_panel_exit();
1328 hdmi_uninit_output(pdev);
1329 pm_runtime_disable(&pdev->dev);
1330 return r;
1331}
1332
1333static int __exit hdmi_remove_child(struct device *dev, void *data)
1334{
1335 struct omap_dss_device *dssdev = to_dss_device(dev);
1336 hdmi_uninit_display(dssdev);
1337 return 0; 1126 return 0;
1338} 1127}
1339 1128
1340static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 1129static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1341{ 1130{
1342 device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
1343
1344 dss_unregister_child_devices(&pdev->dev);
1345
1346 hdmi_panel_exit();
1347
1348 hdmi_uninit_output(pdev); 1131 hdmi_uninit_output(pdev);
1349 1132
1350 pm_runtime_disable(&pdev->dev); 1133 pm_runtime_disable(&pdev->dev);
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
deleted file mode 100644
index dfb8eda81b61..000000000000
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ /dev/null
@@ -1,414 +0,0 @@
1/*
2 * hdmi_panel.c
3 *
4 * HDMI library support functions for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 * Authors: Mythri P k <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/mutex.h>
26#include <linux/module.h>
27#include <video/omapdss.h>
28#include <linux/slab.h>
29
30#include "dss.h"
31
32static struct {
33 /* This protects the panel ops, mainly when accessing the HDMI IP. */
34 struct mutex lock;
35#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
36 /* This protects the audio ops, specifically. */
37 spinlock_t audio_lock;
38#endif
39} hdmi;
40
41
42static int hdmi_panel_probe(struct omap_dss_device *dssdev)
43{
44 /* Initialize default timings to VGA in DVI mode */
45 const struct omap_video_timings default_timings = {
46 .x_res = 640,
47 .y_res = 480,
48 .pixel_clock = 25175,
49 .hsw = 96,
50 .hfp = 16,
51 .hbp = 48,
52 .vsw = 2,
53 .vfp = 11,
54 .vbp = 31,
55
56 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
57 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
58
59 .interlace = false,
60 };
61
62 DSSDBG("ENTER hdmi_panel_probe\n");
63
64 dssdev->panel.timings = default_timings;
65
66 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
67 dssdev->panel.timings.x_res,
68 dssdev->panel.timings.y_res);
69
70 omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
71
72 return 0;
73}
74
75static void hdmi_panel_remove(struct omap_dss_device *dssdev)
76{
77
78}
79
80#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
81static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev)
82{
83 unsigned long flags;
84 int r;
85
86 mutex_lock(&hdmi.lock);
87 spin_lock_irqsave(&hdmi.audio_lock, flags);
88
89 /* enable audio only if the display is active and supports audio */
90 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE ||
91 !hdmi_mode_has_audio()) {
92 DSSERR("audio not supported or display is off\n");
93 r = -EPERM;
94 goto err;
95 }
96
97 r = hdmi_audio_enable();
98
99 if (!r)
100 dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
101
102err:
103 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
104 mutex_unlock(&hdmi.lock);
105 return r;
106}
107
108static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev)
109{
110 unsigned long flags;
111
112 spin_lock_irqsave(&hdmi.audio_lock, flags);
113
114 hdmi_audio_disable();
115
116 dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
117
118 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
119}
120
121static int hdmi_panel_audio_start(struct omap_dss_device *dssdev)
122{
123 unsigned long flags;
124 int r;
125
126 spin_lock_irqsave(&hdmi.audio_lock, flags);
127 /*
128 * No need to check the panel state. It was checked when trasitioning
129 * to AUDIO_ENABLED.
130 */
131 if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED) {
132 DSSERR("audio start from invalid state\n");
133 r = -EPERM;
134 goto err;
135 }
136
137 r = hdmi_audio_start();
138
139 if (!r)
140 dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
141
142err:
143 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
144 return r;
145}
146
147static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev)
148{
149 unsigned long flags;
150
151 spin_lock_irqsave(&hdmi.audio_lock, flags);
152
153 hdmi_audio_stop();
154 dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
155
156 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
157}
158
159static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev)
160{
161 bool r = false;
162
163 mutex_lock(&hdmi.lock);
164
165 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
166 goto err;
167
168 if (!hdmi_mode_has_audio())
169 goto err;
170
171 r = true;
172err:
173 mutex_unlock(&hdmi.lock);
174 return r;
175}
176
177static int hdmi_panel_audio_config(struct omap_dss_device *dssdev,
178 struct omap_dss_audio *audio)
179{
180 unsigned long flags;
181 int r;
182
183 mutex_lock(&hdmi.lock);
184 spin_lock_irqsave(&hdmi.audio_lock, flags);
185
186 /* config audio only if the display is active and supports audio */
187 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE ||
188 !hdmi_mode_has_audio()) {
189 DSSERR("audio not supported or display is off\n");
190 r = -EPERM;
191 goto err;
192 }
193
194 r = hdmi_audio_config(audio);
195
196 if (!r)
197 dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
198
199err:
200 spin_unlock_irqrestore(&hdmi.audio_lock, flags);
201 mutex_unlock(&hdmi.lock);
202 return r;
203}
204
205#else
206static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev)
207{
208 return -EPERM;
209}
210
211static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev)
212{
213}
214
215static int hdmi_panel_audio_start(struct omap_dss_device *dssdev)
216{
217 return -EPERM;
218}
219
220static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev)
221{
222}
223
224static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev)
225{
226 return false;
227}
228
229static int hdmi_panel_audio_config(struct omap_dss_device *dssdev,
230 struct omap_dss_audio *audio)
231{
232 return -EPERM;
233}
234#endif
235
236static int hdmi_panel_enable(struct omap_dss_device *dssdev)
237{
238 int r = 0;
239 DSSDBG("ENTER hdmi_panel_enable\n");
240
241 mutex_lock(&hdmi.lock);
242
243 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
244 r = -EINVAL;
245 goto err;
246 }
247
248 omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
249
250 r = omapdss_hdmi_display_enable(dssdev);
251 if (r) {
252 DSSERR("failed to power on\n");
253 goto err;
254 }
255
256 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
257
258err:
259 mutex_unlock(&hdmi.lock);
260
261 return r;
262}
263
264static void hdmi_panel_disable(struct omap_dss_device *dssdev)
265{
266 mutex_lock(&hdmi.lock);
267
268 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
269 /*
270 * TODO: notify audio users that the display was disabled. For
271 * now, disable audio locally to not break our audio state
272 * machine.
273 */
274 hdmi_panel_audio_disable(dssdev);
275 omapdss_hdmi_display_disable(dssdev);
276 }
277
278 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
279
280 mutex_unlock(&hdmi.lock);
281}
282
283static void hdmi_get_timings(struct omap_dss_device *dssdev,
284 struct omap_video_timings *timings)
285{
286 mutex_lock(&hdmi.lock);
287
288 *timings = dssdev->panel.timings;
289
290 mutex_unlock(&hdmi.lock);
291}
292
293static void hdmi_set_timings(struct omap_dss_device *dssdev,
294 struct omap_video_timings *timings)
295{
296 DSSDBG("hdmi_set_timings\n");
297
298 mutex_lock(&hdmi.lock);
299
300 /*
301 * TODO: notify audio users that there was a timings change. For
302 * now, disable audio locally to not break our audio state machine.
303 */
304 hdmi_panel_audio_disable(dssdev);
305
306 omapdss_hdmi_display_set_timing(dssdev, timings);
307 dssdev->panel.timings = *timings;
308
309 mutex_unlock(&hdmi.lock);
310}
311
312static int hdmi_check_timings(struct omap_dss_device *dssdev,
313 struct omap_video_timings *timings)
314{
315 int r = 0;
316
317 DSSDBG("hdmi_check_timings\n");
318
319 mutex_lock(&hdmi.lock);
320
321 r = omapdss_hdmi_display_check_timing(dssdev, timings);
322
323 mutex_unlock(&hdmi.lock);
324 return r;
325}
326
327static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
328{
329 int r;
330 bool need_enable;
331
332 mutex_lock(&hdmi.lock);
333
334 need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
335
336 if (need_enable) {
337 r = omapdss_hdmi_core_enable(dssdev);
338 if (r)
339 goto err;
340 }
341
342 r = omapdss_hdmi_read_edid(buf, len);
343
344 if (need_enable)
345 omapdss_hdmi_core_disable(dssdev);
346err:
347 mutex_unlock(&hdmi.lock);
348
349 return r;
350}
351
352static bool hdmi_detect(struct omap_dss_device *dssdev)
353{
354 int r;
355 bool need_enable;
356
357 mutex_lock(&hdmi.lock);
358
359 need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED;
360
361 if (need_enable) {
362 r = omapdss_hdmi_core_enable(dssdev);
363 if (r)
364 goto err;
365 }
366
367 r = omapdss_hdmi_detect();
368
369 if (need_enable)
370 omapdss_hdmi_core_disable(dssdev);
371err:
372 mutex_unlock(&hdmi.lock);
373
374 return r;
375}
376
377static struct omap_dss_driver hdmi_driver = {
378 .probe = hdmi_panel_probe,
379 .remove = hdmi_panel_remove,
380 .enable = hdmi_panel_enable,
381 .disable = hdmi_panel_disable,
382 .get_timings = hdmi_get_timings,
383 .set_timings = hdmi_set_timings,
384 .check_timings = hdmi_check_timings,
385 .read_edid = hdmi_read_edid,
386 .detect = hdmi_detect,
387 .audio_enable = hdmi_panel_audio_enable,
388 .audio_disable = hdmi_panel_audio_disable,
389 .audio_start = hdmi_panel_audio_start,
390 .audio_stop = hdmi_panel_audio_stop,
391 .audio_supported = hdmi_panel_audio_supported,
392 .audio_config = hdmi_panel_audio_config,
393 .driver = {
394 .name = "hdmi_panel",
395 .owner = THIS_MODULE,
396 },
397};
398
399int hdmi_panel_init(void)
400{
401 mutex_init(&hdmi.lock);
402
403#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
404 spin_lock_init(&hdmi.audio_lock);
405#endif
406
407 return omap_dss_register_driver(&hdmi_driver);
408}
409
410void hdmi_panel_exit(void)
411{
412 omap_dss_unregister_driver(&hdmi_driver);
413
414}