video: rockchip: hdmi: 3288/3368: phy pll support more vesa dmt clock
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmiv2 / rockchip_hdmiv2.c
1 #include <linux/kernel.h>
2 #include <linux/delay.h>
3 #include <linux/module.h>
4 #include <linux/platform_device.h>
5 #include <linux/interrupt.h>
6 #include <linux/clk.h>
7 #include <linux/rockchip/grf.h>
8 #include <linux/rockchip/iomap.h>
9 #include <linux/mfd/syscon.h>
10 #if defined(CONFIG_DEBUG_FS)
11 #include <linux/uaccess.h>
12 #include <linux/fs.h>
13 #include <linux/debugfs.h>
14 #include <linux/seq_file.h>
15 #endif
16
17 #include "rockchip_hdmiv2.h"
18 #include "rockchip_hdmiv2_hw.h"
19
20 #define HDMI_SEL_LCDC(x)        ((((x)&1)<<4)|(1<<20))
21 #define grf_writel(v, offset)   writel_relaxed(v, RK_GRF_VIRT + offset)
22
23 static struct hdmi_dev *hdmi_dev;
24
25 static struct hdmi_property rk_hdmi_property = {
26         .videosrc = DISPLAY_SOURCE_LCDC0,
27         .display = DISPLAY_MAIN,
28 };
29
30 #if defined(CONFIG_DEBUG_FS)
31 static const struct rockchip_hdmiv2_reg_table hdmi_reg_table[] = {
32         {IDENTIFICATION_BASE, CONFIG3_ID},
33         {INTERRUPT_BASE, IH_MUTE},
34         {VIDEO_SAMPLER_BASE, TX_BCBDATA1},
35         {VIDEO_PACKETIZER_BASE, VP_MASK},
36         {FRAME_COMPOSER_BASE, FC_DBGTMDS2},
37         {HDMI_SOURCE_PHY_BASE, PHY_PLLCFGFREQ2},
38         {I2C_MASTER_PHY_BASE, PHY_I2CM_SDA_HOLD},
39         {AUDIO_SAMPLER_BASE, AHB_DMA_STPADDR_SET1_0},
40         {MAIN_CONTROLLER_BASE, MC_SWRSTZREQ_2},
41         {COLOR_SPACE_CONVERTER_BASE, CSC_SPARE_2},
42         {HDCP_ENCRYPTION_ENGINE_BASE, HDCP_REVOC_LIST},
43         {HDCP_BKSV_BASE, HDCPREG_BKSV4},
44         {HDCP_AN_BASE, HDCPREG_AN7},
45         {HDCP2REG_BASE, HDCP2REG_MUTE},
46         {ENCRYPTED_DPK_EMBEDDED_BASE, HDCPREG_DPK6},
47         {CEC_ENGINE_BASE, CEC_WKUPCTRL},
48         {I2C_MASTER_BASE, I2CM_SCDC_UPDATE1},
49 };
50
51 static int hdmi_regs_ctrl_show(struct seq_file *s, void *v)
52 {
53         u32 i = 0, j = 0, val = 0;
54
55         seq_puts(s, "\n>>>hdmi_ctl reg ");
56         for (i = 0; i < 16; i++)
57                 seq_printf(s, " %2x", i);
58         seq_puts(s, "\n-----------------------------------------------------------------");
59
60         for (i = 0; i < ARRAY_SIZE(hdmi_reg_table); i++) {
61                 for (j = hdmi_reg_table[i].reg_base;
62                      j <= hdmi_reg_table[i].reg_end; j++) {
63                         val = hdmi_readl(hdmi_dev, j);
64                         if ((j - hdmi_reg_table[i].reg_base)%16 == 0)
65                                 seq_printf(s, "\n>>>hdmi_ctl %04x:", j);
66                         seq_printf(s, " %02x", val);
67                 }
68         }
69         seq_puts(s, "\n-----------------------------------------------------------------\n");
70
71         return 0;
72 }
73
74 static ssize_t hdmi_regs_ctrl_write(struct file *file,
75                                     const char __user *buf,
76                                     size_t count, loff_t *ppos)
77 {
78         u32 reg, val;
79         char kbuf[25];
80
81         if (copy_from_user(kbuf, buf, count))
82                 return -EFAULT;
83         if (sscanf(kbuf, "%x%x", &reg, &val) == -1)
84                 return -EFAULT;
85         if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) {
86                 dev_info(hdmi_dev->hdmi->dev, "it is no hdmi reg\n");
87                 return count;
88         }
89         dev_info(hdmi_dev->hdmi->dev,
90                  "/**********hdmi reg config******/");
91         dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
92         hdmi_writel(hdmi_dev, reg, val);
93
94         return count;
95 }
96
97 static int hdmi_regs_phy_show(struct seq_file *s, void *v)
98 {
99         u32 i;
100
101         seq_puts(s, "\n>>>hdmi_phy reg ");
102         for (i = 0; i < 0x28; i++)
103                 seq_printf(s, "regs %02x val %04x\n",
104                            i, rockchip_hdmiv2_read_phy(hdmi_dev, i));
105         return 0;
106 }
107
108 static ssize_t hdmi_regs_phy_write(struct file *file,
109                                    const char __user *buf,
110                                    size_t count, loff_t *ppos)
111 {
112         u32 reg, val;
113         char kbuf[25];
114
115         if (copy_from_user(kbuf, buf, count))
116                 return -EFAULT;
117         if (sscanf(kbuf, "%x%x", &reg, &val) == -1)
118                 return -EFAULT;
119         dev_info(hdmi_dev->hdmi->dev,
120                  "/**********hdmi reg phy config******/");
121         dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
122         rockchip_hdmiv2_write_phy(hdmi_dev, reg, val);
123         return count;
124 }
125
126 #define HDMI_DEBUG_ENTRY(name) \
127 static int hdmi_##name##_open(struct inode *inode, struct file *file) \
128 { \
129         return single_open(file, hdmi_##name##_show, inode->i_private); \
130 } \
131 \
132 static const struct file_operations hdmi_##name##_fops = { \
133         .owner = THIS_MODULE, \
134         .open = hdmi_##name##_open, \
135         .read = seq_read, \
136         .write = hdmi_##name##_write,   \
137         .llseek = seq_lseek, \
138         .release = single_release, \
139 }
140
141 HDMI_DEBUG_ENTRY(regs_phy);
142 HDMI_DEBUG_ENTRY(regs_ctrl);
143 #endif
144
145 #ifdef CONFIG_HAS_EARLYSUSPEND
146 static void rockchip_hdmiv2_early_suspend(struct early_suspend *h)
147 {
148         struct hdmi *hdmi = hdmi_dev->hdmi;
149         struct pinctrl_state *gpio_state;
150
151         HDMIDBG("hdmi enter early suspend\n");
152         hdmi_submit_work(hdmi, HDMI_SUSPEND_CTL, 0, 1);
153         /* iomux to gpio and pull down when suspend */
154         gpio_state = pinctrl_lookup_state(hdmi_dev->dev->pins->p, "gpio");
155         pinctrl_select_state(hdmi_dev->dev->pins->p, gpio_state);
156         rockchip_hdmiv2_clk_disable(hdmi_dev);
157 }
158
159 static void rockchip_hdmiv2_early_resume(struct early_suspend *h)
160 {
161         struct hdmi *hdmi = hdmi_dev->hdmi;
162
163         HDMIDBG("hdmi exit early resume\n");
164         /* iomux to default state for hdmi use when resume */
165         pinctrl_select_state(hdmi_dev->dev->pins->p,
166                              hdmi_dev->dev->pins->default_state);
167         rockchip_hdmiv2_clk_enable(hdmi_dev);
168         hdmi_dev_initial(hdmi_dev);
169         if (hdmi->ops->hdcp_power_on_cb)
170                 hdmi->ops->hdcp_power_on_cb();
171         hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, 0);
172 }
173 #endif
174
175 #define HDMI_PD_ON                      (1 << 0)
176 #define HDMI_PCLK_ON            (1 << 1)
177 #define HDMI_HDCPCLK_ON         (1 << 2)
178 #define HDMI_CECCLK_ON          (1 << 3)
179
180 static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev)
181 {
182         if ((hdmi_dev->clk_on & HDMI_PD_ON) &&
183             (hdmi_dev->clk_on & HDMI_PCLK_ON) &&
184             (hdmi_dev->clk_on & HDMI_HDCPCLK_ON))
185                 return 0;
186
187         if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) {
188                 if (hdmi_dev->pd == NULL) {
189                         hdmi_dev->pd = devm_clk_get(hdmi_dev->dev, "pd_hdmi");
190                         if (IS_ERR(hdmi_dev->pd)) {
191                                 dev_err(hdmi_dev->dev,
192                                         "Unable to get hdmi pd\n");
193                                 return -1;
194                         }
195                 }
196                 clk_prepare_enable(hdmi_dev->pd);
197                 hdmi_dev->clk_on |= HDMI_PD_ON;
198         }
199
200         if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
201                 if (hdmi_dev->pclk == NULL) {
202                         hdmi_dev->pclk =
203                                 devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
204                         if (IS_ERR(hdmi_dev->pclk)) {
205                                 dev_err(hdmi_dev->dev,
206                                         "Unable to get hdmi pclk\n");
207                                 return -1;
208                         }
209                 }
210                 clk_prepare_enable(hdmi_dev->pclk);
211                 hdmi_dev->clk_on |= HDMI_PCLK_ON;
212         }
213
214         if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
215                 if (hdmi_dev->hdcp_clk == NULL) {
216                         hdmi_dev->hdcp_clk =
217                                 devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi");
218                         if (IS_ERR(hdmi_dev->hdcp_clk)) {
219                                 dev_err(hdmi_dev->dev,
220                                         "Unable to get hdmi hdcp_clk\n");
221                                 return -1;
222                         }
223                 }
224                 clk_prepare_enable(hdmi_dev->hdcp_clk);
225                 hdmi_dev->clk_on |= HDMI_HDCPCLK_ON;
226         }
227
228         if ((rk_hdmi_property.feature & SUPPORT_CEC) &&
229             (hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) {
230                 if (hdmi_dev->cec_clk == NULL) {
231                         hdmi_dev->cec_clk =
232                                 devm_clk_get(hdmi_dev->dev, "cec_clk_hdmi");
233                         if (IS_ERR(hdmi_dev->cec_clk)) {
234                                 dev_err(hdmi_dev->dev,
235                                         "Unable to get hdmi cec_clk\n");
236                                 return -1;
237                         }
238                 }
239                 clk_prepare_enable(hdmi_dev->cec_clk);
240                 hdmi_dev->clk_on |= HDMI_CECCLK_ON;
241         }
242         return 0;
243 }
244
245 static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev)
246 {
247         if (hdmi_dev->clk_on == 0)
248                 return 0;
249
250         if ((hdmi_dev->clk_on & HDMI_PD_ON) && (hdmi_dev->pd != NULL)) {
251                 clk_disable_unprepare(hdmi_dev->pd);
252                 hdmi_dev->clk_on &= ~HDMI_PD_ON;
253         }
254
255         if ((hdmi_dev->clk_on & HDMI_PCLK_ON) &&
256             (hdmi_dev->pclk != NULL)) {
257                 clk_disable_unprepare(hdmi_dev->pclk);
258                 hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
259         }
260
261         if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) &&
262             (hdmi_dev->hdcp_clk != NULL)) {
263                 clk_disable_unprepare(hdmi_dev->hdcp_clk);
264                 hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON;
265         }
266
267         return 0;
268 }
269
270 static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self,
271                                            unsigned long action, void *data)
272 {
273         struct fb_event *event = data;
274         int blank_mode = *((int *)event->data);
275         struct hdmi *hdmi = hdmi_dev->hdmi;
276         struct pinctrl_state *gpio_state;
277 #ifdef CONFIG_PINCTRL
278         struct dev_pin_info *pins = hdmi_dev->dev->pins;
279 #endif
280
281         if (action == FB_EARLY_EVENT_BLANK) {
282                 switch (blank_mode) {
283                 case FB_BLANK_UNBLANK:
284                         break;
285                 default:
286                         HDMIDBG("suspend hdmi\n");
287                         if (!hdmi->sleep) {
288                                 hdmi_submit_work(hdmi,
289                                                  HDMI_SUSPEND_CTL,
290                                                  0, 1);
291                                 if (hdmi_dev->hdcp2_en)
292                                         hdmi_dev->hdcp2_en(0);
293                                 rockchip_hdmiv2_clk_disable(hdmi_dev);
294                                 #ifdef CONFIG_PINCTRL
295                                 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
296                                         gpio_state =
297                                         pinctrl_lookup_state(pins->p,
298                                                              "sleep");
299                                 else
300                                         gpio_state =
301                                         pinctrl_lookup_state(pins->p,
302                                                              "gpio");
303                                 pinctrl_select_state(pins->p,
304                                                      gpio_state);
305                                 #endif
306                         }
307                         break;
308                 }
309         } else if (action == FB_EVENT_BLANK) {
310                 switch (blank_mode) {
311                 case FB_BLANK_UNBLANK:
312                         HDMIDBG("resume hdmi\n");
313                         if (hdmi->sleep) {
314                                 #ifdef CONFIG_PINCTRL
315                                 pinctrl_select_state(pins->p,
316                                                      pins->default_state);
317                                 #endif
318                                 rockchip_hdmiv2_clk_enable(hdmi_dev);
319                                 rockchip_hdmiv2_dev_initial(hdmi_dev);
320                                 if (hdmi->ops->hdcp_power_on_cb)
321                                         hdmi->ops->hdcp_power_on_cb();
322                                 if (hdmi_dev->hdcp2_reset)
323                                         hdmi_dev->hdcp2_reset();
324                                 if (hdmi_dev->hdcp2_en)
325                                         hdmi_dev->hdcp2_en(1);
326                                 hdmi_submit_work(hdmi, HDMI_RESUME_CTL,
327                                                  0, 0);
328                         }
329                         break;
330                 default:
331                         break;
332                 }
333         }
334         return NOTIFY_OK;
335 }
336
337 static struct notifier_block rockchip_hdmiv2_fb_notifier = {
338         .notifier_call = rockchip_hdmiv2_fb_event_notify,
339 };
340 #ifdef HDMI_INT_USE_POLL
341 static void rockchip_hdmiv2_irq_work_func(struct work_struct *work)
342 {
343         if (hdmi_dev->enable) {
344                 rockchip_hdmiv2_dev_irq(0, hdmi_dev);
345                 queue_delayed_work(hdmi_dev->workqueue,
346                                    &(hdmi_dev->delay_work),
347                                    msecs_to_jiffies(50));
348         }
349 }
350 #endif
351
352 static struct hdmi_ops rk_hdmi_ops;
353
354
355 #if defined(CONFIG_OF)
356 static const struct of_device_id rk_hdmi_dt_ids[] = {
357         {.compatible = "rockchip,rk3288-hdmi",},
358         {.compatible = "rockchip,rk3368-hdmi",},
359         {}
360 };
361
362 static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev)
363 {
364         int val = 0;
365         struct device_node *np = hdmi_dev->dev->of_node;
366         const struct of_device_id *match;
367
368         match = of_match_node(rk_hdmi_dt_ids, np);
369         if (!match)
370                 return PTR_ERR(match);
371
372         if (!strcmp(match->compatible, "rockchip,rk3288-hdmi")) {
373                 hdmi_dev->soctype = HDMI_SOC_RK3288;
374         } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) {
375                 hdmi_dev->soctype = HDMI_SOC_RK3368;
376         } else {
377                 pr_err("It is not a valid rockchip soc!");
378                 return -ENOMEM;
379         }
380
381         if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val))
382                 rk_hdmi_property.videosrc = val;
383
384         if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val))
385                 hdmi_dev->audiosrc = val;
386
387         if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
388             (val == 1)) {
389                 pr_debug("hdmi support cec\n");
390                 rk_hdmi_property.feature |= SUPPORT_CEC;
391         }
392         if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
393             (val == 1)) {
394                 pr_debug("hdmi support hdcp\n");
395                 rk_hdmi_property.feature |= SUPPORT_HDCP;
396         }
397         if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
398             (val > 0)) {
399                 pr_debug("default mode is %d\n", val);
400                 rk_hdmi_property.defaultmode = val;
401         } else {
402                 rk_hdmi_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE;
403         }
404         #ifdef CONFIG_MFD_SYSCON
405         hdmi_dev->grf_base =
406                 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
407         #endif
408         return 0;
409 }
410 #endif
411
412 static int rockchip_hdmiv2_probe(struct platform_device *pdev)
413 {
414         int ret = -1;
415         struct resource *res;
416
417         HDMIDBG("%s\n", __func__);
418         hdmi_dev = kmalloc(sizeof(*hdmi_dev), GFP_KERNEL);
419         if (!hdmi_dev) {
420                 dev_err(&pdev->dev, ">>rockchip hdmiv2 kmalloc fail!");
421                 return -ENOMEM;
422         }
423         memset(hdmi_dev, 0, sizeof(struct hdmi_dev));
424         platform_set_drvdata(pdev, hdmi_dev);
425         hdmi_dev->dev = &pdev->dev;
426
427         rockchip_hdmiv2_parse_dt(hdmi_dev);
428
429         /*request and remap iomem*/
430         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
431         if (!res) {
432                 dev_err(&pdev->dev, "Unable to get register resource\n");
433                 ret = -ENXIO;
434                 goto failed;
435         }
436         hdmi_dev->regbase_phy = res->start;
437         hdmi_dev->regsize_phy = resource_size(res);
438         hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
439         if (IS_ERR(hdmi_dev->regbase)) {
440                 ret = PTR_ERR(hdmi_dev->regbase);
441                 dev_err(&pdev->dev,
442                         "cannot ioremap registers,err=%d\n", ret);
443                 goto failed;
444         }
445
446         /*enable pd and pclk and hdcp_clk*/
447         if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) {
448                 ret = -ENXIO;
449                 goto failed1;
450         }
451         /*lcdc source select*/
452         if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
453                 grf_writel(HDMI_SEL_LCDC(rk_hdmi_property.videosrc),
454                            RK3288_GRF_SOC_CON6);
455                 /* select GPIO7_C0 as cec pin */
456                 grf_writel(((1 << 12) | (1 << 28)), RK3288_GRF_SOC_CON8);
457         }
458         rockchip_hdmiv2_dev_init_ops(&rk_hdmi_ops);
459         /* Register HDMI device */
460         rk_hdmi_property.name = (char *)pdev->name;
461         rk_hdmi_property.priv = hdmi_dev;
462         if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
463                 rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;
464                 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
465                         rk_hdmi_property.feature |=
466                                                 SUPPORT_4K |
467                                                 SUPPORT_TMDS_600M;
468         } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
469                 rk_hdmi_property.feature |=
470                                 SUPPORT_4K |
471                                 SUPPORT_4K_4096 |
472                                 SUPPORT_YUV420 |
473                                 SUPPORT_YCBCR_INPUT;
474         }
475         hdmi_dev->hdmi =
476                 rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops);
477         if (hdmi_dev->hdmi == NULL) {
478                 dev_err(&pdev->dev, "register hdmi device failed\n");
479                 ret = -ENOMEM;
480                 goto failed1;
481         }
482         mutex_init(&hdmi_dev->ddc_lock);
483         hdmi_dev->hdmi->dev = &pdev->dev;
484         hdmi_dev->hdmi->soctype = hdmi_dev->soctype;
485         fb_register_client(&rockchip_hdmiv2_fb_notifier);
486         rockchip_hdmiv2_dev_initial(hdmi_dev);
487         pinctrl_select_state(hdmi_dev->dev->pins->p,
488                              hdmi_dev->dev->pins->default_state);
489 #if defined(CONFIG_DEBUG_FS)
490         hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv2", NULL);
491         if (IS_ERR(hdmi_dev->debugfs_dir))
492                 dev_err(hdmi_dev->hdmi->dev,
493                         "failed to create debugfs dir for rockchip hdmiv2!\n");
494         else {
495                 debugfs_create_file("regs_ctrl", S_IRUSR,
496                                     hdmi_dev->debugfs_dir,
497                                     hdmi_dev, &hdmi_regs_ctrl_fops);
498                 debugfs_create_file("regs_phy", S_IRUSR,
499                                     hdmi_dev->debugfs_dir,
500                                     hdmi_dev, &hdmi_regs_phy_fops);
501         }
502 #endif
503         rk_display_device_enable(hdmi_dev->hdmi->ddev);
504
505 #ifndef HDMI_INT_USE_POLL
506         /* get and request the IRQ */
507         hdmi_dev->irq = platform_get_irq(pdev, 0);
508         if (hdmi_dev->irq <= 0) {
509                 dev_err(hdmi_dev->dev,
510                         "failed to get hdmi irq resource (%d).\n",
511                         hdmi_dev->irq);
512                 ret = -ENXIO;
513                 goto failed1;
514         }
515
516         ret =
517             devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
518                              rockchip_hdmiv2_dev_irq,
519                              IRQF_TRIGGER_HIGH,
520                              dev_name(hdmi_dev->dev), hdmi_dev);
521         if (ret) {
522                 dev_err(hdmi_dev->dev, "hdmi request_irq failed (%d).\n", ret);
523                 goto failed1;
524         }
525 #else
526         hdmi_dev->workqueue =
527                 create_singlethread_workqueue("rockchip hdmiv2 irq");
528         INIT_DELAYED_WORK(&(hdmi_dev->delay_work),
529                           rockchip_hdmiv2_irq_work_func);
530         rockchip_hdmiv2_irq_work_func(NULL);
531
532 #endif
533         dev_info(&pdev->dev, "rockchip hdmiv2 probe sucess.\n");
534         return 0;
535
536 failed1:
537         rockchip_hdmi_unregister(hdmi_dev->hdmi);
538 failed:
539         kfree(hdmi_dev);
540         hdmi_dev = NULL;
541         dev_err(&pdev->dev, "rk3288 hdmi probe error.\n");
542         return ret;
543 }
544
545 static int rockchip_hdmiv2_remove(struct platform_device *pdev)
546 {
547         dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n");
548         return 0;
549 }
550
551 static void rockchip_hdmiv2_shutdown(struct platform_device *pdev)
552 {
553         struct hdmi *hdmi;
554
555         if (hdmi_dev) {
556                 #ifdef CONFIG_HAS_EARLYSUSPEND
557                 unregister_early_suspend(&hdmi_dev->early_suspend);
558                 #endif
559                 hdmi = hdmi_dev->hdmi;
560                 if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
561                     hdmi->ops->setmute)
562                         hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE);
563         }
564 }
565
566 static struct platform_driver rockchip_hdmiv2_driver = {
567         .probe          = rockchip_hdmiv2_probe,
568         .remove         = rockchip_hdmiv2_remove,
569         .driver         = {
570                 .name   = "rockchip-hdmiv2",
571                 .owner  = THIS_MODULE,
572                 #if defined(CONFIG_OF)
573                 .of_match_table = of_match_ptr(rk_hdmi_dt_ids),
574                 #endif
575         },
576         .shutdown   = rockchip_hdmiv2_shutdown,
577 };
578
579 static int __init rockchip_hdmiv2_init(void)
580 {
581         return platform_driver_register(&rockchip_hdmiv2_driver);
582 }
583
584 static void __exit rockchip_hdmiv2_exit(void)
585 {
586         platform_driver_unregister(&rockchip_hdmiv2_driver);
587 }
588
589 module_init(rockchip_hdmiv2_init);
590 module_exit(rockchip_hdmiv2_exit);