]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/blob - drivers/video/fbdev/omap2/dss/hdmi5.c
OMAPDSS: Adapt DSS driver for skipping initialization during bootup
[android-sdk/kernel-video.git] / drivers / video / fbdev / omap2 / dss / hdmi5.c
1 /*
2  * HDMI driver for OMAP5
3  *
4  * Copyright (C) 2014 Texas Instruments Incorporated
5  *
6  * Authors:
7  *      Yong Zhi
8  *      Mythri pk
9  *      Archit Taneja <archit@ti.com>
10  *      Tomi Valkeinen <tomi.valkeinen@ti.com>
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License version 2 as published by
14  * the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19  * more details.
20  *
21  * You should have received a copy of the GNU General Public License along with
22  * this program.  If not, see <http://www.gnu.org/licenses/>.
23  */
25 #define DSS_SUBSYS_NAME "HDMI"
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/err.h>
30 #include <linux/io.h>
31 #include <linux/interrupt.h>
32 #include <linux/mutex.h>
33 #include <linux/delay.h>
34 #include <linux/string.h>
35 #include <linux/platform_device.h>
36 #include <linux/pm_runtime.h>
37 #include <linux/clk.h>
38 #include <linux/gpio.h>
39 #include <linux/regulator/consumer.h>
40 #include <video/omapdss.h>
41 #include <sound/omap-hdmi-audio.h>
43 #include "hdmi5_core.h"
44 #include "dss.h"
45 #include "dss_features.h"
47 static struct omap_hdmi hdmi;
49 static int hdmi_runtime_get(void)
50 {
51         int r;
53         DSSDBG("hdmi_runtime_get\n");
55         r = pm_runtime_get_sync(&hdmi.pdev->dev);
56         WARN_ON(r < 0);
57         if (r < 0)
58                 return r;
60         return 0;
61 }
63 static void hdmi_runtime_put(void)
64 {
65         int r;
67         DSSDBG("hdmi_runtime_put\n");
69         r = pm_runtime_put_sync(&hdmi.pdev->dev);
70         WARN_ON(r < 0 && r != -ENOSYS);
71 }
73 static irqreturn_t hdmi_irq_handler(int irq, void *data)
74 {
75         struct hdmi_wp_data *wp = data;
76         u32 irqstatus;
78         irqstatus = hdmi_wp_get_irqstatus(wp);
79         hdmi_wp_set_irqstatus(wp, irqstatus);
81         if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
82                         irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
83                 u32 v;
84                 /*
85                  * If we get both connect and disconnect interrupts at the same
86                  * time, turn off the PHY, clear interrupts, and restart, which
87                  * raises connect interrupt if a cable is connected, or nothing
88                  * if cable is not connected.
89                  */
91                 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
93                 /*
94                  * We always get bogus CONNECT & DISCONNECT interrupts when
95                  * setting the PHY to LDOON. To ignore those, we force the RXDET
96                  * line to 0 until the PHY power state has been changed.
97                  */
98                 v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
99                 v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
100                 v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
101                 hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
103                 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
104                                 HDMI_IRQ_LINK_DISCONNECT);
106                 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
108                 REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
110         } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
111                 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
112                 extcon_set_state(&hdmi.edev, 1);
113         } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
114                 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
115                 extcon_set_state(&hdmi.edev, 0);
116         }
118         return IRQ_HANDLED;
121 static int hdmi_init_regulator(void)
123         int r;
124         struct regulator *reg;
126         if (hdmi.vdda_reg != NULL)
127                 return 0;
129         reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
130         if (IS_ERR(reg)) {
131                 DSSERR("can't get VDDA regulator\n");
132                 return PTR_ERR(reg);
133         }
135         if (regulator_can_change_voltage(reg)) {
136                 r = regulator_set_voltage(reg, 1800000, 1800000);
137                 if (r) {
138                         devm_regulator_put(reg);
139                         DSSWARN("can't set the regulator voltage\n");
140                         return r;
141                 }
142         }
144         hdmi.vdda_reg = reg;
146         return 0;
149 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp,
150                 struct pll_params *p)
152         u16 r = 0;
154         dss_ctrl_hdmi_pll_enable(true);
156         r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
157         if (r)
158                 return r;
160         r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
161         if (r)
162                 return r;
164         pll_sysreset(pll);
166         r = pll_wait_reset(pll);
167         if (r)
168                 return r;
170         r = pll_calc_and_check_clock_rates(pll, p);
171         if (r)
172                 return r;
174         r = pll_set_clock_div(pll, p);
175         if (r)
176                 return r;
178         return 0;
181 static void hdmi_pll_disable(struct hdmi_wp_data *wp)
183         hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
185         dss_ctrl_hdmi_pll_enable(false);
188 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
190         int r;
192         r = regulator_enable(hdmi.vdda_reg);
193         if (r)
194                 return r;
196         r = hdmi_runtime_get();
197         if (r)
198                 goto err_runtime_get;
200         /* Make selection of HDMI in DSS */
201         dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
203         hdmi.core_enabled = true;
205         return 0;
207 err_runtime_get:
208         regulator_disable(hdmi.vdda_reg);
210         return r;
213 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
215         hdmi.core_enabled = false;
217         hdmi_runtime_put();
218         regulator_disable(hdmi.vdda_reg);
221 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
223         int r;
224         struct omap_video_timings *p;
225         struct omap_overlay_manager *mgr = hdmi.output.manager;
226         unsigned long phy;
227         struct pll_params param;
228         bool ok;
230         r = hdmi_power_on_core(dssdev);
231         if (r)
232                 return r;
234         p = &hdmi.cfg.timings;
236         DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
238         phy = p->pixelclock * 10;
240         memset(&param, 0, sizeof(param));
242         ok = pll_calc(hdmi.pll, phy, phy, NULL, &param);
243         if (!ok) {
244                 DSSDBG("Failed to calculate PLL settings\n");
245                 goto err_pll_enable;
246         }
248         /* disable and clear irqs */
249         hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
250         hdmi_wp_set_irqstatus(&hdmi.wp,
251                         hdmi_wp_get_irqstatus(&hdmi.wp));
253         /* config the PLL and PHY hdmi_set_pll_pwrfirst */
254         r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param);
255         if (r) {
256                 DSSDBG("Failed to lock PLL\n");
257                 goto err_pll_enable;
258         }
260         r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
261         if (r) {
262                 DSSDBG("Failed to start PHY\n");
263                 goto err_phy_cfg;
264         }
266         r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON);
267         if (r)
268                 goto err_phy_pwr;
270         hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
272         /* bypass TV gamma table */
273         dispc_enable_gamma_table(0);
275         /* tv size */
276         dss_mgr_set_timings(mgr, p);
278         r = dss_mgr_enable(mgr);
279         if (r)
280                 goto err_mgr_enable;
282         r = hdmi_wp_video_start(&hdmi.wp);
283         if (r)
284                 goto err_vid_enable;
286         hdmi_wp_set_irqenable(&hdmi.wp,
287                         HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
289         return 0;
291 err_vid_enable:
292         dss_mgr_disable(mgr);
293 err_mgr_enable:
294         hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
295 err_phy_pwr:
296 err_phy_cfg:
297         hdmi_pll_disable(&hdmi.wp);
298 err_pll_enable:
299         hdmi_power_off_core(dssdev);
300         return -EIO;
303 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
305         struct omap_overlay_manager *mgr = hdmi.output.manager;
307         hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
309         hdmi_wp_video_stop(&hdmi.wp);
311         dss_mgr_disable(mgr);
313         hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
315         hdmi_pll_disable(&hdmi.wp);
317         hdmi_power_off_core(dssdev);
320 static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
321                                         struct omap_video_timings *timings)
323         struct omap_dss_device *out = &hdmi.output;
325         if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
326                 return -EINVAL;
328         return 0;
331 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
332                 struct omap_video_timings *timings)
334         mutex_lock(&hdmi.lock);
336         hdmi.cfg.timings = *timings;
338         dispc_set_tv_pclk(timings->pixelclock);
340         mutex_unlock(&hdmi.lock);
343 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
344                 struct omap_video_timings *timings)
346         *timings = hdmi.cfg.timings;
349 static void hdmi_dump_regs(struct seq_file *s)
351         mutex_lock(&hdmi.lock);
353         if (hdmi_runtime_get()) {
354                 mutex_unlock(&hdmi.lock);
355                 return;
356         }
358         hdmi_wp_dump(&hdmi.wp, s);
359         pll_dump(hdmi.pll, s);
360         hdmi_phy_dump(&hdmi.phy, s);
361         hdmi5_core_dump(&hdmi.core, s);
363         hdmi_runtime_put();
364         mutex_unlock(&hdmi.lock);
367 static int read_edid(u8 *buf, int len)
369         int r;
370         int idlemode;
372         mutex_lock(&hdmi.lock);
374         r = hdmi_runtime_get();
375         BUG_ON(r);
377         idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
378         /* No-idle mode */
379         REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
381         r = hdmi5_read_edid(&hdmi.core,  buf, len);
383         REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
385         hdmi_runtime_put();
386         mutex_unlock(&hdmi.lock);
388         return r;
391 static int hdmi_display_enable(struct omap_dss_device *dssdev)
393         struct omap_dss_device *out = &hdmi.output;
394         int r = 0;
396         DSSDBG("ENTER hdmi_display_enable\n");
398         mutex_lock(&hdmi.lock);
400         if (out == NULL || out->manager == NULL) {
401                 DSSERR("failed to enable display: no output/manager\n");
402                 r = -ENODEV;
403                 goto err0;
404         }
406         r = hdmi_power_on_full(dssdev);
407         if (r) {
408                 DSSERR("failed to power on device\n");
409                 goto err0;
410         }
412         hdmi.display_enabled = true;
414         mutex_unlock(&hdmi.lock);
415         return 0;
417 err0:
418         mutex_unlock(&hdmi.lock);
419         return r;
422 static void hdmi_display_disable(struct omap_dss_device *dssdev)
424         DSSDBG("Enter hdmi_display_disable\n");
426         mutex_lock(&hdmi.lock);
428         /* If set hdmi.audio_abort_cb(&hdmi.pdev->dev) should be
429          * called here, if audio abort functionality is needed. */
431         hdmi_power_off_full(dssdev);
433         hdmi.display_enabled = false;
435         mutex_unlock(&hdmi.lock);
438 static int hdmi_core_enable(struct omap_dss_device *dssdev)
440         int r = 0;
442         DSSDBG("ENTER omapdss_hdmi_core_enable\n");
444         mutex_lock(&hdmi.lock);
446         r = hdmi_power_on_core(dssdev);
447         if (r) {
448                 DSSERR("failed to power on device\n");
449                 goto err0;
450         }
452         mutex_unlock(&hdmi.lock);
453         return 0;
455 err0:
456         mutex_unlock(&hdmi.lock);
457         return r;
460 static void hdmi_core_disable(struct omap_dss_device *dssdev)
462         DSSDBG("Enter omapdss_hdmi_core_disable\n");
464         mutex_lock(&hdmi.lock);
466         hdmi_power_off_core(dssdev);
468         mutex_unlock(&hdmi.lock);
471 static int hdmi_connect(struct omap_dss_device *dssdev,
472                 struct omap_dss_device *dst)
474         struct omap_overlay_manager *mgr;
475         int r;
477         r = hdmi_init_regulator();
478         if (r)
479                 return r;
481         mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
482         if (!mgr)
483                 return -ENODEV;
485         r = dss_mgr_connect(mgr, dssdev);
486         if (r)
487                 return r;
489         r = omapdss_output_set_device(dssdev, dst);
490         if (r) {
491                 DSSERR("failed to connect output to new device: %s\n",
492                                 dst->name);
493                 dss_mgr_disconnect(mgr, dssdev);
494                 return r;
495         }
497         return 0;
500 static void hdmi_disconnect(struct omap_dss_device *dssdev,
501                 struct omap_dss_device *dst)
503         WARN_ON(dst != dssdev->dst);
505         if (dst != dssdev->dst)
506                 return;
508         omapdss_output_unset_device(dssdev);
510         if (dssdev->manager)
511                 dss_mgr_disconnect(dssdev->manager, dssdev);
514 static int hdmi_read_edid(struct omap_dss_device *dssdev,
515                 u8 *edid, int len)
517         bool need_enable;
518         int r;
520         need_enable = hdmi.core_enabled == false;
522         if (need_enable) {
523                 r = hdmi_core_enable(dssdev);
524                 if (r)
525                         return r;
526         }
528         r = read_edid(edid, len);
530         if (need_enable)
531                 hdmi_core_disable(dssdev);
533         return r;
536 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
537                 const struct hdmi_avi_infoframe *avi)
539         hdmi.cfg.infoframe = *avi;
540         return 0;
543 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
544                 bool hdmi_mode)
546         hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
547         return 0;
550 static const struct omapdss_hdmi_ops hdmi_ops = {
551         .connect                = hdmi_connect,
552         .disconnect             = hdmi_disconnect,
554         .enable                 = hdmi_display_enable,
555         .disable                = hdmi_display_disable,
557         .check_timings          = hdmi_display_check_timing,
558         .set_timings            = hdmi_display_set_timing,
559         .get_timings            = hdmi_display_get_timings,
561         .read_edid              = hdmi_read_edid,
562         .set_infoframe          = hdmi_set_infoframe,
563         .set_hdmi_mode          = hdmi_set_hdmi_mode,
564 };
566 static void hdmi_init_output(struct platform_device *pdev)
568         struct omap_dss_device *out = &hdmi.output;
570         out->dev = &pdev->dev;
571         out->id = OMAP_DSS_OUTPUT_HDMI;
572         out->output_type = OMAP_DISPLAY_TYPE_HDMI;
573         out->name = "hdmi.0";
574         out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
575         out->ops.hdmi = &hdmi_ops;
576         out->owner = THIS_MODULE;
578         omapdss_register_output(out);
581 static void __exit hdmi_uninit_output(struct platform_device *pdev)
583         struct omap_dss_device *out = &hdmi.output;
585         omapdss_unregister_output(out);
588 static int hdmi_probe_of(struct platform_device *pdev)
590         struct device_node *node = pdev->dev.of_node;
591         struct device_node *ep;
592         int r;
594         ep = omapdss_of_get_first_endpoint(node);
595         if (!ep)
596                 return 0;
598         r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
599         if (r)
600                 goto err;
602         of_node_put(ep);
603         return 0;
605 err:
606         of_node_put(ep);
607         return r;
610 #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
611 static int audio_startup(struct device *dev,
612                          void (*abort_cb)(struct device *dev))
614         struct omap_hdmi *hd = dev_get_drvdata(dev);
615         int ret = 0;
617         mutex_lock(&hd->lock);
619         if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
620                 ret = -EPERM;
621                 goto out;
622         }
624         hd->audio_abort_cb = abort_cb;
626 out:
627         mutex_unlock(&hd->lock);
629         return ret;
632 static int audio_enable(struct device *dev, bool enable)
634         struct omap_hdmi *hd = dev_get_drvdata(dev);
635         int ret;
637         mutex_lock(&hd->lock);
639         if (enable) {
640                 /* No idle while playing audio */
641                 hd->wp_idlemode =
642                         REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
643                 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
644         }
646         ret = hdmi_wp_audio_enable(&hd->wp, enable);
648         if (!enable) {
649                 /* Playback stopped, restore original idlemode */
650                 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode,
651                             3, 2);
653                 hd->audio_abort_cb = NULL;
654         }
656         mutex_unlock(&hd->lock);
658         return ret;
661 static int audio_start(struct device *dev, bool enable)
663         struct omap_hdmi *hd = dev_get_drvdata(dev);
665         return hdmi_wp_audio_core_req_enable(&hd->wp, enable);
668 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio)
670         struct omap_hdmi *hd = dev_get_drvdata(dev);
671         int ret;
673         mutex_lock(&hd->lock);
674         if (!hdmi_mode_has_audio(&hd->cfg))
675                 ret = -EPERM;
676         else
677                 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
678                                          hd->cfg.timings.pixelclock);
679         mutex_unlock(&hd->lock);
681         return ret;
684 static int hdmi_audio_register(struct device *dev)
686         struct omap_hdmi_audio ha = {
687                 .dev = dev,
688                 .hw_version = OMAP5_HDMI,
689                 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
690                 .audio_startup = audio_startup,
691                 .audio_enable = audio_enable,
692                 .audio_start = audio_start,
693                 .audio_config = audio_config,
694         };
696         return omap_hdmi_audio_register(&ha);
698 #else /* CONFIG_OMAP5_DSS_HDMI_AUDIO */
699 static int hdmi_audio_register(struct device *dev)
701         return 0;
703 #endif
705 /* HDMI HW IP initialisation */
706 static int omapdss_hdmihw_probe(struct platform_device *pdev)
708         int r;
709         int irq;
711         hdmi.pdev = pdev;
712         dev_set_drvdata(&pdev->dev, &hdmi);
714         mutex_init(&hdmi.lock);
716         if (pdev->dev.of_node) {
717                 r = hdmi_probe_of(pdev);
718                 if (r)
719                         return r;
720         }
722         r = hdmi_wp_init(pdev, &hdmi.wp);
723         if (r)
724                 return r;
726         hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI,
727                         NULL, 0);
728         if (!hdmi.pll)
729                 return -ENODEV;
731         r = hdmi_phy_init(pdev, &hdmi.phy);
732         if (r)
733                 return r;
735         r = hdmi5_core_init(pdev, &hdmi.core);
736         if (r)
737                 return r;
739         irq = platform_get_irq(pdev, 0);
740         if (irq < 0) {
741                 DSSERR("platform_get_irq failed\n");
742                 return -ENODEV;
743         }
745         r = devm_request_threaded_irq(&pdev->dev, irq,
746                         NULL, hdmi_irq_handler,
747                         IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
748         if (r) {
749                 DSSERR("HDMI IRQ request failed\n");
750                 return r;
751         }
753         hdmi.edev.name = "hdmi";
754         hdmi.edev.print_state = NULL;
756         r = extcon_dev_register(&hdmi.edev);
757         if (r)
758                 return r;
760         /* Init extcon state to zero */
761         extcon_set_state(&hdmi.edev, 0);
763         pm_runtime_enable(&pdev->dev);
765         hdmi_init_output(pdev);
767         r = hdmi_audio_register(&pdev->dev);
768         if (r) {
769                 DSSERR("Registering HDMI audio failed\n");
770                 hdmi_uninit_output(pdev);
771                 pm_runtime_disable(&pdev->dev);
772                 extcon_dev_unregister(&hdmi.edev);
773                 return r;
774         }
776         dss_debugfs_create_file("hdmi", hdmi_dump_regs);
778         return 0;
781 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
783         omap_hdmi_audio_unregister(&pdev->dev);
785         hdmi_uninit_output(pdev);
787         pm_runtime_disable(&pdev->dev);
789         extcon_dev_unregister(&hdmi.edev);
791         return 0;
794 static int hdmi_runtime_suspend(struct device *dev)
796         pll_enable_clock(hdmi.pll, false);
798         dispc_runtime_put();
800         return 0;
803 static int hdmi_runtime_resume(struct device *dev)
805         int r;
807         r = dispc_runtime_get();
808         if (r < 0)
809                 return r;
811         pll_enable_clock(hdmi.pll, true);
813         return 0;
816 static const struct dev_pm_ops hdmi_pm_ops = {
817         .runtime_suspend = hdmi_runtime_suspend,
818         .runtime_resume = hdmi_runtime_resume,
819 };
821 static const struct of_device_id hdmi_of_match[] = {
822         { .compatible = "ti,omap5-hdmi", },
823         { .compatible = "ti,dra7-hdmi", },
824         {},
825 };
827 static struct platform_driver omapdss_hdmihw_driver = {
828         .probe          = omapdss_hdmihw_probe,
829         .remove         = __exit_p(omapdss_hdmihw_remove),
830         .driver         = {
831                 .name   = "omapdss_hdmi5",
832                 .owner  = THIS_MODULE,
833                 .pm     = &hdmi_pm_ops,
834                 .of_match_table = hdmi_of_match,
835         },
836 };
838 int __init hdmi5_init_platform_driver(void)
840         return platform_driver_register(&omapdss_hdmihw_driver);
843 void __exit hdmi5_uninit_platform_driver(void)
845         platform_driver_unregister(&omapdss_hdmihw_driver);