1 #include <linux/kernel.h>
2 #include <linux/delay.h>
3 #include <linux/module.h>
4 #include <linux/platform_device.h>
5 #include <linux/pm_runtime.h>
6 #include <linux/interrupt.h>
8 #include <linux/of_gpio.h>
9 #include <linux/rockchip/cpu.h>
10 #include <linux/rockchip/grf.h>
11 #include <linux/rockchip/iomap.h>
12 #include <linux/mfd/syscon.h>
13 #if defined(CONFIG_DEBUG_FS)
14 #include <linux/uaccess.h>
16 #include <linux/debugfs.h>
17 #include <linux/seq_file.h>
20 #include "rockchip_hdmiv2.h"
21 #include "rockchip_hdmiv2_hw.h"
23 #define HDMI_SEL_LCDC(x, bit) ((((x) & 1) << bit) | (1 << (16 + bit)))
24 #define grf_writel(v, offset) writel_relaxed(v, RK_GRF_VIRT + offset)
25 #define GRF_SOC_CON20 0x6250
27 static struct hdmi_dev *hdmi_dev;
29 static struct hdmi_property rk_hdmi_property = {
30 .videosrc = DISPLAY_SOURCE_LCDC0,
31 .display = DISPLAY_MAIN,
34 #if defined(CONFIG_DEBUG_FS)
35 static const struct rockchip_hdmiv2_reg_table hdmi_reg_table[] = {
36 {IDENTIFICATION_BASE, CONFIG3_ID},
37 {INTERRUPT_BASE, IH_MUTE},
38 {VIDEO_SAMPLER_BASE, TX_BCBDATA1},
39 {VIDEO_PACKETIZER_BASE, VP_MASK},
40 {FRAME_COMPOSER_BASE, FC_DBGTMDS2},
41 {HDMI_SOURCE_PHY_BASE, PHY_PLLCFGFREQ2},
42 {I2C_MASTER_PHY_BASE, PHY_I2CM_SDA_HOLD},
43 {AUDIO_SAMPLER_BASE, AHB_DMA_STPADDR_SET1_0},
44 {MAIN_CONTROLLER_BASE, MC_SWRSTZREQ_2},
45 {COLOR_SPACE_CONVERTER_BASE, CSC_SPARE_2},
46 {HDCP_ENCRYPTION_ENGINE_BASE, HDCP_REVOC_LIST},
47 {HDCP_BKSV_BASE, HDCPREG_BKSV4},
48 {HDCP_AN_BASE, HDCPREG_AN7},
49 {HDCP2REG_BASE, HDCP2REG_MUTE},
50 {ENCRYPTED_DPK_EMBEDDED_BASE, HDCPREG_DPK6},
51 {CEC_ENGINE_BASE, CEC_WKUPCTRL},
52 {I2C_MASTER_BASE, I2CM_SCDC_UPDATE1},
55 static int hdmi_regs_ctrl_show(struct seq_file *s, void *v)
57 u32 i = 0, j = 0, val = 0;
59 seq_puts(s, "\n>>>hdmi_ctl reg ");
60 for (i = 0; i < 16; i++)
61 seq_printf(s, " %2x", i);
62 seq_puts(s, "\n-----------------------------------------------------------------");
64 for (i = 0; i < ARRAY_SIZE(hdmi_reg_table); i++) {
65 for (j = hdmi_reg_table[i].reg_base;
66 j <= hdmi_reg_table[i].reg_end; j++) {
67 val = hdmi_readl(hdmi_dev, j);
68 if ((j - hdmi_reg_table[i].reg_base) % 16 == 0)
69 seq_printf(s, "\n>>>hdmi_ctl %04x:", j);
70 seq_printf(s, " %02x", val);
73 seq_puts(s, "\n-----------------------------------------------------------------\n");
78 static ssize_t hdmi_regs_ctrl_write(struct file *file,
79 const char __user *buf,
80 size_t count, loff_t *ppos)
85 if (copy_from_user(kbuf, buf, count))
87 if (sscanf(kbuf, "%x%x", ®, &val) == -1)
89 if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) {
90 dev_info(hdmi_dev->hdmi->dev, "it is no hdmi reg\n");
93 dev_info(hdmi_dev->hdmi->dev,
94 "/**********hdmi reg config******/");
95 dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
96 hdmi_writel(hdmi_dev, reg, val);
101 static int hdmi_regs_phy_show(struct seq_file *s, void *v)
105 if (hdmi_dev->soctype == HDMI_SOC_RK322X)
109 seq_puts(s, "\n>>>hdmi_phy reg ");
110 for (i = 0; i < count; i++)
111 seq_printf(s, "regs %02x val %04x\n",
112 i, rockchip_hdmiv2_read_phy(hdmi_dev, i));
116 static ssize_t hdmi_regs_phy_write(struct file *file,
117 const char __user *buf,
118 size_t count, loff_t *ppos)
123 if (copy_from_user(kbuf, buf, count))
125 if (sscanf(kbuf, "%x%x", ®, &val) == -1)
127 dev_info(hdmi_dev->hdmi->dev,
128 "/**********hdmi reg phy config******/");
129 dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
130 rockchip_hdmiv2_write_phy(hdmi_dev, reg, val);
134 #define HDMI_DEBUG_ENTRY(name) \
135 static int hdmi_##name##_open(struct inode *inode, struct file *file) \
137 return single_open(file, hdmi_##name##_show, inode->i_private); \
140 static const struct file_operations hdmi_##name##_fops = { \
141 .owner = THIS_MODULE, \
142 .open = hdmi_##name##_open, \
144 .write = hdmi_##name##_write, \
145 .llseek = seq_lseek, \
146 .release = single_release, \
149 HDMI_DEBUG_ENTRY(regs_phy);
150 HDMI_DEBUG_ENTRY(regs_ctrl);
153 #ifdef CONFIG_HAS_EARLYSUSPEND
154 static void rockchip_hdmiv2_early_suspend(struct early_suspend *h)
156 struct hdmi *hdmi = hdmi_dev->hdmi;
157 struct pinctrl_state *gpio_state;
159 HDMIDBG("hdmi enter early suspend\n");
160 hdmi_submit_work(hdmi, HDMI_SUSPEND_CTL, 0, 1);
161 /* iomux to gpio and pull down when suspend */
162 gpio_state = pinctrl_lookup_state(hdmi_dev->dev->pins->p, "gpio");
163 pinctrl_select_state(hdmi_dev->dev->pins->p, gpio_state);
164 rockchip_hdmiv2_clk_disable(hdmi_dev);
167 static void rockchip_hdmiv2_early_resume(struct early_suspend *h)
169 struct hdmi *hdmi = hdmi_dev->hdmi;
171 HDMIDBG("hdmi exit early resume\n");
172 /* iomux to default state for hdmi use when resume */
173 pinctrl_select_state(hdmi_dev->dev->pins->p,
174 hdmi_dev->dev->pins->default_state);
175 rockchip_hdmiv2_clk_enable(hdmi_dev);
176 hdmi_dev_initial(hdmi_dev);
177 if (hdmi->ops->hdcp_power_on_cb)
178 hdmi->ops->hdcp_power_on_cb();
179 hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, 0);
183 void ext_pll_set_27m_out(void)
185 if (!hdmi_dev || hdmi_dev->soctype != HDMI_SOC_RK322X)
187 /* PHY PLL VCO is 1080MHz, output pclk is 27MHz */
188 rockchip_hdmiv2_write_phy(hdmi_dev,
189 EXT_PHY_PLL_PRE_DIVIDER,
191 rockchip_hdmiv2_write_phy(hdmi_dev,
192 EXT_PHY_PLL_FB_DIVIDER,
194 rockchip_hdmiv2_write_phy(hdmi_dev,
195 EXT_PHY_PCLK_DIVIDER1,
197 rockchip_hdmiv2_write_phy(hdmi_dev,
198 EXT_PHY_PCLK_DIVIDER2,
200 rockchip_hdmiv2_write_phy(hdmi_dev,
201 EXT_PHY_TMDSCLK_DIVIDER,
205 #define HDMI_PD_ON BIT(0)
206 #define HDMI_PCLK_ON BIT(1)
207 #define HDMI_HDCPCLK_ON BIT(2)
208 #define HDMI_CECCLK_ON BIT(3)
209 #define HDMI_EXT_PHY_CLK_ON BIT(4)
211 static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev)
213 if (hdmi_dev->soctype == HDMI_SOC_RK322X ||
214 hdmi_dev->soctype == HDMI_SOC_RK3366 ||
215 hdmi_dev->soctype == HDMI_SOC_RK3399) {
216 if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) == 0) {
217 if (!hdmi_dev->pclk_phy) {
218 if (hdmi_dev->soctype == HDMI_SOC_RK322X)
220 devm_clk_get(hdmi_dev->dev,
224 devm_clk_get(hdmi_dev->dev,
226 if (IS_ERR(hdmi_dev->pclk_phy)) {
227 dev_err(hdmi_dev->dev,
228 "get hdmi phy pclk error\n");
232 clk_prepare_enable(hdmi_dev->pclk_phy);
233 hdmi_dev->clk_on |= HDMI_EXT_PHY_CLK_ON;
235 } else if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) {
236 pm_runtime_get_sync(hdmi_dev->dev);
237 hdmi_dev->clk_on |= HDMI_PD_ON;
240 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
241 if (!hdmi_dev->pclk) {
243 devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
244 if (IS_ERR(hdmi_dev->pclk)) {
245 dev_err(hdmi_dev->dev,
246 "Unable to get hdmi pclk\n");
250 clk_prepare_enable(hdmi_dev->pclk);
251 hdmi_dev->clk_on |= HDMI_PCLK_ON;
254 if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
255 if (!hdmi_dev->hdcp_clk) {
257 devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi");
258 if (IS_ERR(hdmi_dev->hdcp_clk)) {
259 dev_err(hdmi_dev->dev,
260 "Unable to get hdmi hdcp_clk\n");
264 clk_prepare_enable(hdmi_dev->hdcp_clk);
265 hdmi_dev->clk_on |= HDMI_HDCPCLK_ON;
268 if ((rk_hdmi_property.feature & SUPPORT_CEC) &&
269 (hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) {
270 if (!hdmi_dev->cec_clk) {
272 devm_clk_get(hdmi_dev->dev, "cec_clk_hdmi");
273 if (IS_ERR(hdmi_dev->cec_clk)) {
274 dev_err(hdmi_dev->dev,
275 "Unable to get hdmi cec_clk\n");
279 clk_prepare_enable(hdmi_dev->cec_clk);
280 hdmi_dev->clk_on |= HDMI_CECCLK_ON;
285 static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev)
287 if (hdmi_dev->clk_on == 0)
290 if ((hdmi_dev->clk_on & HDMI_PD_ON)) {
291 pm_runtime_put(hdmi_dev->dev);
292 hdmi_dev->clk_on &= ~HDMI_PD_ON;
295 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) &&
297 clk_disable_unprepare(hdmi_dev->pclk);
298 hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
301 if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) &&
302 (hdmi_dev->hdcp_clk)) {
303 clk_disable_unprepare(hdmi_dev->hdcp_clk);
304 hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON;
307 if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) &&
308 hdmi_dev->pclk_phy) {
309 clk_disable_unprepare(hdmi_dev->pclk_phy);
310 hdmi_dev->clk_on &= ~HDMI_EXT_PHY_CLK_ON;
315 static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self,
316 unsigned long action, void *data)
318 struct fb_event *event = data;
319 int blank_mode = *((int *)event->data);
320 struct hdmi *hdmi = hdmi_dev->hdmi;
321 struct pinctrl_state *gpio_state;
322 #ifdef CONFIG_PINCTRL
323 struct dev_pin_info *pins = hdmi_dev->dev->pins;
326 if (action == FB_EARLY_EVENT_BLANK) {
327 switch (blank_mode) {
328 case FB_BLANK_UNBLANK:
331 HDMIDBG("suspend hdmi\n");
333 hdmi_submit_work(hdmi,
336 if (hdmi_dev->hdcp2_en)
337 hdmi_dev->hdcp2_en(0);
338 rockchip_hdmiv2_clk_disable(hdmi_dev);
339 #ifdef CONFIG_PINCTRL
340 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
342 pinctrl_lookup_state(pins->p,
346 pinctrl_lookup_state(pins->p,
348 pinctrl_select_state(pins->p,
354 } else if (action == FB_EVENT_BLANK) {
355 switch (blank_mode) {
356 case FB_BLANK_UNBLANK:
357 HDMIDBG("resume hdmi\n");
359 #ifdef CONFIG_PINCTRL
360 pinctrl_select_state(pins->p,
361 pins->default_state);
363 rockchip_hdmiv2_clk_enable(hdmi_dev);
364 rockchip_hdmiv2_dev_initial(hdmi_dev);
365 if (hdmi->ops->hdcp_power_on_cb)
366 hdmi->ops->hdcp_power_on_cb();
367 if (hdmi_dev->hdcp2_reset)
368 hdmi_dev->hdcp2_reset();
369 if (hdmi_dev->hdcp2_en)
370 hdmi_dev->hdcp2_en(1);
371 hdmi_submit_work(hdmi, HDMI_RESUME_CTL,
382 static struct notifier_block rockchip_hdmiv2_fb_notifier = {
383 .notifier_call = rockchip_hdmiv2_fb_event_notify,
386 #ifdef HDMI_INT_USE_POLL
387 static void rockchip_hdmiv2_irq_work_func(struct work_struct *work)
389 if (hdmi_dev->enable) {
390 rockchip_hdmiv2_dev_irq(0, hdmi_dev);
391 queue_delayed_work(hdmi_dev->workqueue,
392 &hdmi_dev->delay_work,
393 msecs_to_jiffies(50));
398 static struct hdmi_ops rk_hdmi_ops;
400 #if defined(CONFIG_OF)
401 static const struct of_device_id rk_hdmi_dt_ids[] = {
402 {.compatible = "rockchip,rk322x-hdmi",},
403 {.compatible = "rockchip,rk3288-hdmi",},
404 {.compatible = "rockchip,rk3366-hdmi",},
405 {.compatible = "rockchip,rk3368-hdmi",},
406 {.compatible = "rockchip,rk3399-hdmi",},
410 static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev)
413 struct device_node *np = hdmi_dev->dev->of_node;
414 const struct of_device_id *match;
416 match = of_match_node(rk_hdmi_dt_ids, np);
418 return PTR_ERR(match);
420 if (!strcmp(match->compatible, "rockchip,rk3288-hdmi")) {
421 hdmi_dev->soctype = HDMI_SOC_RK3288;
422 } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) {
423 hdmi_dev->soctype = HDMI_SOC_RK3368;
424 } else if (!strcmp(match->compatible, "rockchip,rk322x-hdmi")) {
425 hdmi_dev->soctype = HDMI_SOC_RK322X;
426 } else if (!strcmp(match->compatible, "rockchip,rk3366-hdmi")) {
427 hdmi_dev->soctype = HDMI_SOC_RK3366;
428 } else if (!strcmp(match->compatible, "rockchip,rk3399-hdmi")) {
429 hdmi_dev->soctype = HDMI_SOC_RK3399;
431 pr_err("It is not a valid rockchip soc!");
435 if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val))
436 rk_hdmi_property.videosrc = val;
438 if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val))
439 hdmi_dev->audiosrc = val;
441 if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
443 pr_debug("hdmi support cec\n");
444 rk_hdmi_property.feature |= SUPPORT_CEC;
446 if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
448 pr_debug("hdmi support hdcp\n");
449 rk_hdmi_property.feature |= SUPPORT_HDCP;
451 if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
453 pr_debug("default mode is %d\n", val);
454 rk_hdmi_property.defaultmode = val;
456 rk_hdmi_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE;
458 if (of_get_property(np, "rockchip,phy_table", &val)) {
459 hdmi_dev->phy_table = kmalloc(val, GFP_KERNEL);
460 if (!hdmi_dev->phy_table) {
461 pr_err("kmalloc phy table %d error\n", val);
464 hdmi_dev->phy_table_size =
465 val / sizeof(struct hdmi_dev_phy_para);
466 of_property_read_u32_array(np, "rockchip,phy_table",
467 (u32 *)hdmi_dev->phy_table,
470 pr_info("hdmi phy_table not exist\n");
473 of_property_read_string(np, "rockchip,vendor",
474 &hdmi_dev->vendor_name);
475 of_property_read_string(np, "rockchip,product",
476 &hdmi_dev->product_name);
477 if (!of_property_read_u32(np, "rockchip,deviceinfo", &val))
478 hdmi_dev->deviceinfo = val & 0xff;
480 #ifdef CONFIG_MFD_SYSCON
482 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
483 if (IS_ERR(hdmi_dev->grf_base)) {
484 hdmi_dev->grf_base = NULL;
491 static int rockchip_hdmiv2_probe(struct platform_device *pdev)
494 struct resource *res;
496 HDMIDBG("%s\n", __func__);
497 hdmi_dev = kmalloc(sizeof(*hdmi_dev), GFP_KERNEL);
499 dev_err(&pdev->dev, ">>rockchip hdmiv2 kmalloc fail!");
502 memset(hdmi_dev, 0, sizeof(struct hdmi_dev));
503 platform_set_drvdata(pdev, hdmi_dev);
504 hdmi_dev->dev = &pdev->dev;
506 if (rockchip_hdmiv2_parse_dt(hdmi_dev))
509 /*request and remap iomem*/
510 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
512 dev_err(&pdev->dev, "Unable to get register resource\n");
516 hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
517 if (IS_ERR(hdmi_dev->regbase)) {
518 ret = PTR_ERR(hdmi_dev->regbase);
520 "cannot ioremap registers,err=%d\n", ret);
523 if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
524 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
527 "Unable to get phy register resource\n");
531 hdmi_dev->phybase = devm_ioremap_resource(&pdev->dev, res);
532 if (IS_ERR(hdmi_dev->phybase)) {
533 ret = PTR_ERR(hdmi_dev->phybase);
535 "cannot ioremap registers,err=%d\n", ret);
540 hdmi_dev->reset = devm_reset_control_get(&pdev->dev, "hdmi");
541 if (IS_ERR(hdmi_dev->reset) &&
542 hdmi_dev->soctype != HDMI_SOC_RK3288) {
543 ret = PTR_ERR(hdmi_dev->reset);
544 dev_err(&pdev->dev, "failed to get hdmi reset: %d\n", ret);
547 pm_runtime_enable(hdmi_dev->dev);
548 /*enable pd and pclk and hdcp_clk*/
549 if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) {
550 dev_err(&pdev->dev, "failed to enable hdmi clk\n");
554 /*lcdc source select*/
555 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
556 grf_writel(HDMI_SEL_LCDC(rk_hdmi_property.videosrc, 4),
557 RK3288_GRF_SOC_CON6);
558 /* select GPIO7_C0 as cec pin */
559 grf_writel(((1 << 12) | (1 << 28)), RK3288_GRF_SOC_CON8);
560 } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
561 regmap_write(hdmi_dev->grf_base,
563 HDMI_SEL_LCDC(rk_hdmi_property.videosrc, 6));
565 rockchip_hdmiv2_dev_init_ops(&rk_hdmi_ops);
566 /* Register HDMI device */
567 rk_hdmi_property.name = (char *)pdev->name;
568 rk_hdmi_property.priv = hdmi_dev;
569 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
570 rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;
571 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
572 rk_hdmi_property.feature |=
575 } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
576 rk_hdmi_property.feature |=
580 SUPPORT_YCBCR_INPUT |
582 } else if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
583 rk_hdmi_property.feature |=
586 SUPPORT_YCBCR_INPUT |
590 *if (rockchip_get_cpu_version())
591 * rk_hdmi_property.feature |=
593 * SUPPORT_DEEP_10BIT;
595 } else if (hdmi_dev->soctype == HDMI_SOC_RK3366) {
596 rk_hdmi_property.feature |=
597 SUPPORT_YCBCR_INPUT |
600 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
601 rk_hdmi_property.feature |=
605 SUPPORT_YCBCR_INPUT |
607 } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
608 rk_hdmi_property.feature |=
610 SUPPORT_YCBCR_INPUT |
613 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
614 rk_hdmi_property.feature |=
618 SUPPORT_YCBCR_INPUT |
625 rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops);
626 if (!hdmi_dev->hdmi) {
627 dev_err(&pdev->dev, "register hdmi device failed\n");
631 mutex_init(&hdmi_dev->ddc_lock);
632 hdmi_dev->hdmi->dev = &pdev->dev;
633 hdmi_dev->hdmi->soctype = hdmi_dev->soctype;
634 fb_register_client(&rockchip_hdmiv2_fb_notifier);
635 rockchip_hdmiv2_dev_initial(hdmi_dev);
636 pinctrl_select_state(hdmi_dev->dev->pins->p,
637 hdmi_dev->dev->pins->default_state);
638 #if defined(CONFIG_DEBUG_FS)
639 hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv2", NULL);
640 if (IS_ERR(hdmi_dev->debugfs_dir))
641 dev_err(hdmi_dev->hdmi->dev,
642 "failed to create debugfs dir for rockchip hdmiv2!\n");
644 debugfs_create_file("regs_ctrl", S_IRUSR,
645 hdmi_dev->debugfs_dir,
646 hdmi_dev, &hdmi_regs_ctrl_fops);
647 debugfs_create_file("regs_phy", S_IRUSR,
648 hdmi_dev->debugfs_dir,
649 hdmi_dev, &hdmi_regs_phy_fops);
653 #ifndef HDMI_INT_USE_POLL
654 /* get and request the IRQ */
655 hdmi_dev->irq = platform_get_irq(pdev, 0);
656 if (hdmi_dev->irq <= 0) {
657 dev_err(hdmi_dev->dev,
658 "failed to get hdmi irq resource (%d).\n",
664 ret = devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
665 rockchip_hdmiv2_dev_irq,
667 dev_name(hdmi_dev->dev), hdmi_dev);
669 dev_err(hdmi_dev->dev,
670 "hdmi request_irq failed (%d).\n",
675 hdmi_dev->workqueue =
676 create_singlethread_workqueue("rockchip hdmiv2 irq");
677 INIT_DELAYED_WORK(&hdmi_dev->delay_work,
678 rockchip_hdmiv2_irq_work_func);
679 rockchip_hdmiv2_irq_work_func(NULL);
682 rk_display_device_enable(hdmi_dev->hdmi->ddev);
683 dev_info(&pdev->dev, "rockchip hdmiv2 probe success.\n");
687 rockchip_hdmi_unregister(hdmi_dev->hdmi);
689 kfree(hdmi_dev->phy_table);
692 dev_err(&pdev->dev, "rockchip hdmiv2 probe error.\n");
696 static int rockchip_hdmiv2_suspend(struct platform_device *pdev,
700 hdmi_dev->grf_base &&
701 hdmi_dev->soctype == HDMI_SOC_RK322X) {
702 regmap_write(hdmi_dev->grf_base,
704 RK322X_PLL_POWER_DOWN);
709 static int rockchip_hdmiv2_resume(struct platform_device *pdev)
712 hdmi_dev->grf_base &&
713 hdmi_dev->soctype == HDMI_SOC_RK322X) {
714 regmap_write(hdmi_dev->grf_base,
716 RK322X_PLL_POWER_UP);
721 static int rockchip_hdmiv2_remove(struct platform_device *pdev)
723 dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n");
727 static void rockchip_hdmiv2_shutdown(struct platform_device *pdev)
732 #ifdef CONFIG_HAS_EARLYSUSPEND
733 unregister_early_suspend(&hdmi_dev->early_suspend);
735 hdmi = hdmi_dev->hdmi;
736 if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
738 hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE);
742 static struct platform_driver rockchip_hdmiv2_driver = {
743 .probe = rockchip_hdmiv2_probe,
744 .remove = rockchip_hdmiv2_remove,
746 .name = "rockchip-hdmiv2",
747 .owner = THIS_MODULE,
748 #if defined(CONFIG_OF)
749 .of_match_table = of_match_ptr(rk_hdmi_dt_ids),
752 .suspend = rockchip_hdmiv2_suspend,
753 .resume = rockchip_hdmiv2_resume,
754 .shutdown = rockchip_hdmiv2_shutdown,
757 static int __init rockchip_hdmiv2_init(void)
759 return platform_driver_register(&rockchip_hdmiv2_driver);
762 static void __exit rockchip_hdmiv2_exit(void)
764 platform_driver_unregister(&rockchip_hdmiv2_driver);
767 module_init(rockchip_hdmiv2_init);
768 module_exit(rockchip_hdmiv2_exit);