aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/venc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/venc.c')
-rw-r--r--drivers/video/omap2/dss/venc.c133
1 files changed, 101 insertions, 32 deletions
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 9c3daf71750c..2b8973931ff4 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -415,6 +415,7 @@ static const struct venc_config *venc_timings_to_config(
415 return &venc_config_ntsc_trm; 415 return &venc_config_ntsc_trm;
416 416
417 BUG(); 417 BUG();
418 return NULL;
418} 419}
419 420
420static int venc_power_on(struct omap_dss_device *dssdev) 421static int venc_power_on(struct omap_dss_device *dssdev)
@@ -440,10 +441,11 @@ static int venc_power_on(struct omap_dss_device *dssdev)
440 441
441 venc_write_reg(VENC_OUTPUT_CONTROL, l); 442 venc_write_reg(VENC_OUTPUT_CONTROL, l);
442 443
443 dispc_set_digit_size(dssdev->panel.timings.x_res, 444 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
444 dssdev->panel.timings.y_res/2);
445 445
446 regulator_enable(venc.vdda_dac_reg); 446 r = regulator_enable(venc.vdda_dac_reg);
447 if (r)
448 goto err;
447 449
448 if (dssdev->platform_enable) 450 if (dssdev->platform_enable)
449 dssdev->platform_enable(dssdev); 451 dssdev->platform_enable(dssdev);
@@ -485,16 +487,68 @@ unsigned long venc_get_pixel_clock(void)
485 return 13500000; 487 return 13500000;
486} 488}
487 489
490static ssize_t display_output_type_show(struct device *dev,
491 struct device_attribute *attr, char *buf)
492{
493 struct omap_dss_device *dssdev = to_dss_device(dev);
494 const char *ret;
495
496 switch (dssdev->phy.venc.type) {
497 case OMAP_DSS_VENC_TYPE_COMPOSITE:
498 ret = "composite";
499 break;
500 case OMAP_DSS_VENC_TYPE_SVIDEO:
501 ret = "svideo";
502 break;
503 default:
504 return -EINVAL;
505 }
506
507 return snprintf(buf, PAGE_SIZE, "%s\n", ret);
508}
509
510static ssize_t display_output_type_store(struct device *dev,
511 struct device_attribute *attr, const char *buf, size_t size)
512{
513 struct omap_dss_device *dssdev = to_dss_device(dev);
514 enum omap_dss_venc_type new_type;
515
516 if (sysfs_streq("composite", buf))
517 new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
518 else if (sysfs_streq("svideo", buf))
519 new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
520 else
521 return -EINVAL;
522
523 mutex_lock(&venc.venc_lock);
524
525 if (dssdev->phy.venc.type != new_type) {
526 dssdev->phy.venc.type = new_type;
527 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
528 venc_power_off(dssdev);
529 venc_power_on(dssdev);
530 }
531 }
532
533 mutex_unlock(&venc.venc_lock);
534
535 return size;
536}
537
538static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
539 display_output_type_show, display_output_type_store);
540
488/* driver */ 541/* driver */
489static int venc_panel_probe(struct omap_dss_device *dssdev) 542static int venc_panel_probe(struct omap_dss_device *dssdev)
490{ 543{
491 dssdev->panel.timings = omap_dss_pal_timings; 544 dssdev->panel.timings = omap_dss_pal_timings;
492 545
493 return 0; 546 return device_create_file(&dssdev->dev, &dev_attr_output_type);
494} 547}
495 548
496static void venc_panel_remove(struct omap_dss_device *dssdev) 549static void venc_panel_remove(struct omap_dss_device *dssdev)
497{ 550{
551 device_remove_file(&dssdev->dev, &dev_attr_output_type);
498} 552}
499 553
500static int venc_panel_enable(struct omap_dss_device *dssdev) 554static int venc_panel_enable(struct omap_dss_device *dssdev)
@@ -577,12 +631,6 @@ static int venc_panel_resume(struct omap_dss_device *dssdev)
577 return venc_panel_enable(dssdev); 631 return venc_panel_enable(dssdev);
578} 632}
579 633
580static void venc_get_timings(struct omap_dss_device *dssdev,
581 struct omap_video_timings *timings)
582{
583 *timings = dssdev->panel.timings;
584}
585
586static void venc_set_timings(struct omap_dss_device *dssdev, 634static void venc_set_timings(struct omap_dss_device *dssdev,
587 struct omap_video_timings *timings) 635 struct omap_video_timings *timings)
588{ 636{
@@ -597,6 +645,8 @@ static void venc_set_timings(struct omap_dss_device *dssdev,
597 /* turn the venc off and on to get new timings to use */ 645 /* turn the venc off and on to get new timings to use */
598 venc_panel_disable(dssdev); 646 venc_panel_disable(dssdev);
599 venc_panel_enable(dssdev); 647 venc_panel_enable(dssdev);
648 } else {
649 dss_mgr_set_timings(dssdev->manager, timings);
600 } 650 }
601} 651}
602 652
@@ -661,7 +711,6 @@ static struct omap_dss_driver venc_driver = {
661 .get_resolution = omapdss_default_get_resolution, 711 .get_resolution = omapdss_default_get_resolution,
662 .get_recommended_bpp = omapdss_default_get_recommended_bpp, 712 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
663 713
664 .get_timings = venc_get_timings,
665 .set_timings = venc_set_timings, 714 .set_timings = venc_set_timings,
666 .check_timings = venc_check_timings, 715 .check_timings = venc_check_timings,
667 716
@@ -675,7 +724,7 @@ static struct omap_dss_driver venc_driver = {
675}; 724};
676/* driver end */ 725/* driver end */
677 726
678int venc_init_display(struct omap_dss_device *dssdev) 727static int __init venc_init_display(struct omap_dss_device *dssdev)
679{ 728{
680 DSSDBG("init_display\n"); 729 DSSDBG("init_display\n");
681 730
@@ -695,7 +744,7 @@ int venc_init_display(struct omap_dss_device *dssdev)
695 return 0; 744 return 0;
696} 745}
697 746
698void venc_dump_regs(struct seq_file *s) 747static void venc_dump_regs(struct seq_file *s)
699{ 748{
700#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) 749#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
701 750
@@ -779,8 +828,32 @@ static void venc_put_clocks(void)
779 clk_put(venc.tv_dac_clk); 828 clk_put(venc.tv_dac_clk);
780} 829}
781 830
831static void __init venc_probe_pdata(struct platform_device *pdev)
832{
833 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
834 int r, i;
835
836 for (i = 0; i < pdata->num_devices; ++i) {
837 struct omap_dss_device *dssdev = pdata->devices[i];
838
839 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
840 continue;
841
842 r = venc_init_display(dssdev);
843 if (r) {
844 DSSERR("device %s init failed: %d\n", dssdev->name, r);
845 continue;
846 }
847
848 r = omap_dss_register_device(dssdev, &pdev->dev, i);
849 if (r)
850 DSSERR("device %s register failed: %d\n",
851 dssdev->name, r);
852 }
853}
854
782/* VENC HW IP initialisation */ 855/* VENC HW IP initialisation */
783static int omap_venchw_probe(struct platform_device *pdev) 856static int __init omap_venchw_probe(struct platform_device *pdev)
784{ 857{
785 u8 rev_id; 858 u8 rev_id;
786 struct resource *venc_mem; 859 struct resource *venc_mem;
@@ -824,6 +897,10 @@ static int omap_venchw_probe(struct platform_device *pdev)
824 if (r) 897 if (r)
825 goto err_reg_panel_driver; 898 goto err_reg_panel_driver;
826 899
900 dss_debugfs_create_file("venc", venc_dump_regs);
901
902 venc_probe_pdata(pdev);
903
827 return 0; 904 return 0;
828 905
829err_reg_panel_driver: 906err_reg_panel_driver:
@@ -833,12 +910,15 @@ err_runtime_get:
833 return r; 910 return r;
834} 911}
835 912
836static int omap_venchw_remove(struct platform_device *pdev) 913static int __exit omap_venchw_remove(struct platform_device *pdev)
837{ 914{
915 omap_dss_unregister_child_devices(&pdev->dev);
916
838 if (venc.vdda_dac_reg != NULL) { 917 if (venc.vdda_dac_reg != NULL) {
839 regulator_put(venc.vdda_dac_reg); 918 regulator_put(venc.vdda_dac_reg);
840 venc.vdda_dac_reg = NULL; 919 venc.vdda_dac_reg = NULL;
841 } 920 }
921
842 omap_dss_unregister_driver(&venc_driver); 922 omap_dss_unregister_driver(&venc_driver);
843 923
844 pm_runtime_disable(&pdev->dev); 924 pm_runtime_disable(&pdev->dev);
@@ -853,7 +933,6 @@ static int venc_runtime_suspend(struct device *dev)
853 clk_disable(venc.tv_dac_clk); 933 clk_disable(venc.tv_dac_clk);
854 934
855 dispc_runtime_put(); 935 dispc_runtime_put();
856 dss_runtime_put();
857 936
858 return 0; 937 return 0;
859} 938}
@@ -862,23 +941,14 @@ static int venc_runtime_resume(struct device *dev)
862{ 941{
863 int r; 942 int r;
864 943
865 r = dss_runtime_get();
866 if (r < 0)
867 goto err_get_dss;
868
869 r = dispc_runtime_get(); 944 r = dispc_runtime_get();
870 if (r < 0) 945 if (r < 0)
871 goto err_get_dispc; 946 return r;
872 947
873 if (venc.tv_dac_clk) 948 if (venc.tv_dac_clk)
874 clk_enable(venc.tv_dac_clk); 949 clk_enable(venc.tv_dac_clk);
875 950
876 return 0; 951 return 0;
877
878err_get_dispc:
879 dss_runtime_put();
880err_get_dss:
881 return r;
882} 952}
883 953
884static const struct dev_pm_ops venc_pm_ops = { 954static const struct dev_pm_ops venc_pm_ops = {
@@ -887,8 +957,7 @@ static const struct dev_pm_ops venc_pm_ops = {
887}; 957};
888 958
889static struct platform_driver omap_venchw_driver = { 959static struct platform_driver omap_venchw_driver = {
890 .probe = omap_venchw_probe, 960 .remove = __exit_p(omap_venchw_remove),
891 .remove = omap_venchw_remove,
892 .driver = { 961 .driver = {
893 .name = "omapdss_venc", 962 .name = "omapdss_venc",
894 .owner = THIS_MODULE, 963 .owner = THIS_MODULE,
@@ -896,18 +965,18 @@ static struct platform_driver omap_venchw_driver = {
896 }, 965 },
897}; 966};
898 967
899int venc_init_platform_driver(void) 968int __init venc_init_platform_driver(void)
900{ 969{
901 if (cpu_is_omap44xx()) 970 if (cpu_is_omap44xx())
902 return 0; 971 return 0;
903 972
904 return platform_driver_register(&omap_venchw_driver); 973 return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
905} 974}
906 975
907void venc_uninit_platform_driver(void) 976void __exit venc_uninit_platform_driver(void)
908{ 977{
909 if (cpu_is_omap44xx()) 978 if (cpu_is_omap44xx())
910 return; 979 return;
911 980
912 return platform_driver_unregister(&omap_venchw_driver); 981 platform_driver_unregister(&omap_venchw_driver);
913} 982}