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 static struct hdmi_dev *hdmi_dev;
25 static struct hdmi_property rk_hdmi_property = {
26 .videosrc = DISPLAY_SOURCE_LCDC0,
27 .display = DISPLAY_MAIN,
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},
51 static int hdmi_regs_ctrl_show(struct seq_file *s, void *v)
53 u32 i = 0, j = 0, val = 0;
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-----------------------------------------------------------------");
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);
69 seq_puts(s, "\n-----------------------------------------------------------------\n");
74 static ssize_t hdmi_regs_ctrl_write(struct file *file,
75 const char __user *buf,
76 size_t count, loff_t *ppos)
81 if (copy_from_user(kbuf, buf, count))
83 if (sscanf(kbuf, "%x%x", ®, &val) == -1)
85 if ((reg < 0) || (reg > I2CM_SCDC_UPDATE1)) {
86 dev_info(hdmi_dev->hdmi->dev, "it is no hdmi reg\n");
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);
97 static int hdmi_regs_phy_show(struct seq_file *s, void *v)
101 if (hdmi_dev->soctype == HDMI_SOC_RK322X)
105 seq_puts(s, "\n>>>hdmi_phy reg ");
106 for (i = 0; i < count; i++)
107 seq_printf(s, "regs %02x val %04x\n",
108 i, rockchip_hdmiv2_read_phy(hdmi_dev, i));
112 static ssize_t hdmi_regs_phy_write(struct file *file,
113 const char __user *buf,
114 size_t count, loff_t *ppos)
119 if (copy_from_user(kbuf, buf, count))
121 if (sscanf(kbuf, "%x%x", ®, &val) == -1)
123 dev_info(hdmi_dev->hdmi->dev,
124 "/**********hdmi reg phy config******/");
125 dev_info(hdmi_dev->hdmi->dev, "\n reg=%x val=%x\n", reg, val);
126 rockchip_hdmiv2_write_phy(hdmi_dev, reg, val);
130 #define HDMI_DEBUG_ENTRY(name) \
131 static int hdmi_##name##_open(struct inode *inode, struct file *file) \
133 return single_open(file, hdmi_##name##_show, inode->i_private); \
136 static const struct file_operations hdmi_##name##_fops = { \
137 .owner = THIS_MODULE, \
138 .open = hdmi_##name##_open, \
140 .write = hdmi_##name##_write, \
141 .llseek = seq_lseek, \
142 .release = single_release, \
145 HDMI_DEBUG_ENTRY(regs_phy);
146 HDMI_DEBUG_ENTRY(regs_ctrl);
149 #ifdef CONFIG_HAS_EARLYSUSPEND
150 static void rockchip_hdmiv2_early_suspend(struct early_suspend *h)
152 struct hdmi *hdmi = hdmi_dev->hdmi;
153 struct pinctrl_state *gpio_state;
155 HDMIDBG("hdmi enter early suspend\n");
156 hdmi_submit_work(hdmi, HDMI_SUSPEND_CTL, 0, 1);
157 /* iomux to gpio and pull down when suspend */
158 gpio_state = pinctrl_lookup_state(hdmi_dev->dev->pins->p, "gpio");
159 pinctrl_select_state(hdmi_dev->dev->pins->p, gpio_state);
160 rockchip_hdmiv2_clk_disable(hdmi_dev);
163 static void rockchip_hdmiv2_early_resume(struct early_suspend *h)
165 struct hdmi *hdmi = hdmi_dev->hdmi;
167 HDMIDBG("hdmi exit early resume\n");
168 /* iomux to default state for hdmi use when resume */
169 pinctrl_select_state(hdmi_dev->dev->pins->p,
170 hdmi_dev->dev->pins->default_state);
171 rockchip_hdmiv2_clk_enable(hdmi_dev);
172 hdmi_dev_initial(hdmi_dev);
173 if (hdmi->ops->hdcp_power_on_cb)
174 hdmi->ops->hdcp_power_on_cb();
175 hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, 0);
179 void ext_pll_set_27m_out(void)
181 if (!hdmi_dev || hdmi_dev->soctype != HDMI_SOC_RK322X)
183 /* PHY PLL VCO is 1080MHz, output pclk is 27MHz */
184 rockchip_hdmiv2_write_phy(hdmi_dev,
185 EXT_PHY_PLL_PRE_DIVIDER,
187 rockchip_hdmiv2_write_phy(hdmi_dev,
188 EXT_PHY_PLL_FB_DIVIDER,
190 rockchip_hdmiv2_write_phy(hdmi_dev,
191 EXT_PHY_PCLK_DIVIDER1,
193 rockchip_hdmiv2_write_phy(hdmi_dev,
194 EXT_PHY_PCLK_DIVIDER2,
196 rockchip_hdmiv2_write_phy(hdmi_dev,
197 EXT_PHY_TMDSCLK_DIVIDER,
201 static int rockchip_hdmiv2_clk_enable(struct hdmi_dev *hdmi_dev)
203 if ((hdmi_dev->clk_on & HDMI_PD_ON) == 0) {
204 pm_runtime_get_sync(hdmi_dev->dev);
205 hdmi_dev->clk_on |= HDMI_PD_ON;
208 if (hdmi_dev->soctype == HDMI_SOC_RK322X ||
209 hdmi_dev->soctype == HDMI_SOC_RK3366 ||
210 hdmi_dev->soctype == HDMI_SOC_RK3399) {
211 if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) == 0) {
212 if (!hdmi_dev->pclk_phy) {
213 if (hdmi_dev->soctype == HDMI_SOC_RK322X)
215 devm_clk_get(hdmi_dev->dev,
219 devm_clk_get(hdmi_dev->dev,
221 if (IS_ERR(hdmi_dev->pclk_phy)) {
222 dev_err(hdmi_dev->dev,
223 "get hdmi phy pclk error\n");
227 clk_prepare_enable(hdmi_dev->pclk_phy);
228 hdmi_dev->clk_on |= HDMI_EXT_PHY_CLK_ON;
231 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) == 0) {
232 if (!hdmi_dev->pclk) {
234 devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
235 if (IS_ERR(hdmi_dev->pclk)) {
236 dev_err(hdmi_dev->dev,
237 "Unable to get hdmi pclk\n");
241 clk_prepare_enable(hdmi_dev->pclk);
242 hdmi_dev->clk_on |= HDMI_PCLK_ON;
245 if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) == 0) {
246 if (!hdmi_dev->hdcp_clk) {
248 devm_clk_get(hdmi_dev->dev, "hdcp_clk_hdmi");
249 if (IS_ERR(hdmi_dev->hdcp_clk)) {
250 dev_err(hdmi_dev->dev,
251 "Unable to get hdmi hdcp_clk\n");
255 clk_prepare_enable(hdmi_dev->hdcp_clk);
256 hdmi_dev->clk_on |= HDMI_HDCPCLK_ON;
259 if ((rk_hdmi_property.feature & SUPPORT_CEC) &&
260 (hdmi_dev->clk_on & HDMI_CECCLK_ON) == 0) {
261 if (!hdmi_dev->cec_clk) {
263 devm_clk_get(hdmi_dev->dev, "cec_clk_hdmi");
264 if (IS_ERR(hdmi_dev->cec_clk)) {
265 dev_err(hdmi_dev->dev,
266 "Unable to get hdmi cec_clk\n");
270 clk_prepare_enable(hdmi_dev->cec_clk);
271 hdmi_dev->clk_on |= HDMI_CECCLK_ON;
274 if ((hdmi_dev->clk_on & HDMI_SFRCLK_ON) == 0) {
275 if (!hdmi_dev->sfr_clk) {
277 devm_clk_get(hdmi_dev->dev, "sclk_hdmi_sfr");
278 if (IS_ERR(hdmi_dev->sfr_clk)) {
279 dev_err(hdmi_dev->dev,
280 "Unable to get hdmi sfr_clk\n");
284 clk_prepare_enable(hdmi_dev->sfr_clk);
285 hdmi_dev->clk_on |= HDMI_SFRCLK_ON;
291 static int rockchip_hdmiv2_clk_disable(struct hdmi_dev *hdmi_dev)
293 if (hdmi_dev->clk_on == 0)
296 if ((hdmi_dev->clk_on & HDMI_PD_ON)) {
297 pm_runtime_put(hdmi_dev->dev);
298 hdmi_dev->clk_on &= ~HDMI_PD_ON;
301 if ((hdmi_dev->clk_on & HDMI_PCLK_ON) &&
303 clk_disable_unprepare(hdmi_dev->pclk);
304 hdmi_dev->clk_on &= ~HDMI_PCLK_ON;
307 if ((hdmi_dev->clk_on & HDMI_HDCPCLK_ON) &&
308 (hdmi_dev->hdcp_clk)) {
309 clk_disable_unprepare(hdmi_dev->hdcp_clk);
310 hdmi_dev->clk_on &= ~HDMI_HDCPCLK_ON;
313 if ((hdmi_dev->clk_on & HDMI_EXT_PHY_CLK_ON) &&
314 hdmi_dev->pclk_phy) {
315 clk_disable_unprepare(hdmi_dev->pclk_phy);
316 hdmi_dev->clk_on &= ~HDMI_EXT_PHY_CLK_ON;
319 if ((hdmi_dev->clk_on & HDMI_SFRCLK_ON) &&
320 (hdmi_dev->sfr_clk)) {
321 clk_disable_unprepare(hdmi_dev->sfr_clk);
322 hdmi_dev->clk_on &= ~HDMI_SFRCLK_ON;
329 static int rockchip_hdmiv2_fb_event_notify(struct notifier_block *self,
330 unsigned long action, void *data)
332 struct fb_event *event = data;
333 int blank_mode = *((int *)event->data);
334 struct hdmi *hdmi = hdmi_dev->hdmi;
335 struct pinctrl_state *gpio_state;
336 #ifdef CONFIG_PINCTRL
337 struct dev_pin_info *pins = hdmi_dev->dev->pins;
340 if (action == FB_EARLY_EVENT_BLANK) {
341 switch (blank_mode) {
342 case FB_BLANK_UNBLANK:
345 HDMIDBG("suspend hdmi\n");
347 hdmi_submit_work(hdmi,
350 if (hdmi_dev->hdcp2_en)
351 hdmi_dev->hdcp2_en(0);
352 mutex_lock(&hdmi->pclk_lock);
353 rockchip_hdmiv2_clk_disable(hdmi_dev);
354 mutex_unlock(&hdmi->pclk_lock);
355 #ifdef CONFIG_PINCTRL
356 if (hdmi_dev->soctype == HDMI_SOC_RK3288)
358 pinctrl_lookup_state(pins->p,
362 pinctrl_lookup_state(pins->p,
364 pinctrl_select_state(pins->p,
370 } else if (action == FB_EVENT_BLANK) {
371 switch (blank_mode) {
372 case FB_BLANK_UNBLANK:
373 HDMIDBG("resume hdmi\n");
375 #ifdef CONFIG_PINCTRL
376 pinctrl_select_state(pins->p,
377 pins->default_state);
379 mutex_lock(&hdmi->pclk_lock);
380 rockchip_hdmiv2_clk_enable(hdmi_dev);
381 mutex_unlock(&hdmi->pclk_lock);
382 rockchip_hdmiv2_dev_initial(hdmi_dev);
383 if (hdmi->ops->hdcp_power_on_cb)
384 hdmi->ops->hdcp_power_on_cb();
385 if (hdmi_dev->hdcp2_reset)
386 hdmi_dev->hdcp2_reset();
387 if (hdmi_dev->hdcp2_en)
388 hdmi_dev->hdcp2_en(1);
389 hdmi_submit_work(hdmi, HDMI_RESUME_CTL,
400 static struct notifier_block rockchip_hdmiv2_fb_notifier = {
401 .notifier_call = rockchip_hdmiv2_fb_event_notify,
404 #ifdef HDMI_INT_USE_POLL
405 static void rockchip_hdmiv2_irq_work_func(struct work_struct *work)
407 if (hdmi_dev->enable) {
408 rockchip_hdmiv2_dev_irq(0, hdmi_dev);
409 queue_delayed_work(hdmi_dev->workqueue,
410 &hdmi_dev->delay_work,
411 msecs_to_jiffies(50));
416 static struct hdmi_ops rk_hdmi_ops;
418 #if defined(CONFIG_OF)
419 static const struct of_device_id rk_hdmi_dt_ids[] = {
420 {.compatible = "rockchip,rk322x-hdmi",},
421 {.compatible = "rockchip,rk3288-hdmi",},
422 {.compatible = "rockchip,rk3366-hdmi",},
423 {.compatible = "rockchip,rk3368-hdmi",},
424 {.compatible = "rockchip,rk3399-hdmi",},
428 static int rockchip_hdmiv2_parse_dt(struct hdmi_dev *hdmi_dev)
431 struct device_node *np = hdmi_dev->dev->of_node;
432 const struct of_device_id *match;
434 match = of_match_node(rk_hdmi_dt_ids, np);
436 return PTR_ERR(match);
438 if (!strcmp(match->compatible, "rockchip,rk3288-hdmi")) {
439 hdmi_dev->soctype = HDMI_SOC_RK3288;
440 } else if (!strcmp(match->compatible, "rockchip,rk3368-hdmi")) {
441 hdmi_dev->soctype = HDMI_SOC_RK3368;
442 } else if (!strcmp(match->compatible, "rockchip,rk322x-hdmi")) {
443 hdmi_dev->soctype = HDMI_SOC_RK322X;
444 } else if (!strcmp(match->compatible, "rockchip,rk3366-hdmi")) {
445 hdmi_dev->soctype = HDMI_SOC_RK3366;
446 } else if (!strcmp(match->compatible, "rockchip,rk3399-hdmi")) {
447 hdmi_dev->soctype = HDMI_SOC_RK3399;
449 pr_err("It is not a valid rockchip soc!");
453 if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val))
454 rk_hdmi_property.videosrc = val;
456 if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val))
457 hdmi_dev->audiosrc = val;
459 if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
461 pr_debug("hdmi support cec\n");
462 rk_hdmi_property.feature |= SUPPORT_CEC;
464 if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
466 pr_debug("hdmi support hdcp\n");
467 rk_hdmi_property.feature |= SUPPORT_HDCP;
469 if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
471 pr_debug("default mode is %d\n", val);
472 rk_hdmi_property.defaultmode = val;
474 rk_hdmi_property.defaultmode = HDMI_VIDEO_DEFAULT_MODE;
476 if (of_get_property(np, "rockchip,phy_table", &val)) {
477 hdmi_dev->phy_table = kmalloc(val, GFP_KERNEL);
478 if (!hdmi_dev->phy_table) {
479 pr_err("kmalloc phy table %d error\n", val);
482 hdmi_dev->phy_table_size =
483 val / sizeof(struct hdmi_dev_phy_para);
484 of_property_read_u32_array(np, "rockchip,phy_table",
485 (u32 *)hdmi_dev->phy_table,
488 pr_info("hdmi phy_table not exist\n");
491 of_property_read_string(np, "rockchip,vendor",
492 &hdmi_dev->vendor_name);
493 of_property_read_string(np, "rockchip,product",
494 &hdmi_dev->product_name);
495 if (!of_property_read_u32(np, "rockchip,deviceinfo", &val))
496 hdmi_dev->deviceinfo = val & 0xff;
498 #ifdef CONFIG_MFD_SYSCON
500 syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
501 if (IS_ERR(hdmi_dev->grf_base)) {
502 hdmi_dev->grf_base = NULL;
509 static int rockchip_hdmiv2_probe(struct platform_device *pdev)
512 struct resource *res;
514 HDMIDBG("%s\n", __func__);
515 hdmi_dev = kmalloc(sizeof(*hdmi_dev), GFP_KERNEL);
517 dev_err(&pdev->dev, ">>rockchip hdmiv2 kmalloc fail!");
520 memset(hdmi_dev, 0, sizeof(struct hdmi_dev));
521 platform_set_drvdata(pdev, hdmi_dev);
522 hdmi_dev->dev = &pdev->dev;
524 if (rockchip_hdmiv2_parse_dt(hdmi_dev))
527 /*request and remap iomem*/
528 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
530 dev_err(&pdev->dev, "Unable to get register resource\n");
534 hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
535 if (IS_ERR(hdmi_dev->regbase)) {
536 ret = PTR_ERR(hdmi_dev->regbase);
538 "cannot ioremap registers,err=%d\n", ret);
541 if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
542 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
545 "Unable to get phy register resource\n");
549 hdmi_dev->phybase = devm_ioremap_resource(&pdev->dev, res);
550 if (IS_ERR(hdmi_dev->phybase)) {
551 ret = PTR_ERR(hdmi_dev->phybase);
553 "cannot ioremap registers,err=%d\n", ret);
558 hdmi_dev->reset = devm_reset_control_get(&pdev->dev, "hdmi");
559 if (IS_ERR(hdmi_dev->reset) &&
560 hdmi_dev->soctype != HDMI_SOC_RK3288) {
561 ret = PTR_ERR(hdmi_dev->reset);
562 dev_err(&pdev->dev, "failed to get hdmi reset: %d\n", ret);
565 pm_runtime_enable(hdmi_dev->dev);
566 /*enable pd and clk*/
567 if (rockchip_hdmiv2_clk_enable(hdmi_dev) < 0) {
568 dev_err(&pdev->dev, "failed to enable hdmi clk\n");
572 rockchip_hdmiv2_dev_init_ops(&rk_hdmi_ops);
573 /* Register HDMI device */
574 rk_hdmi_property.name = (char *)pdev->name;
575 rk_hdmi_property.priv = hdmi_dev;
576 if (hdmi_dev->soctype == HDMI_SOC_RK3288) {
577 rk_hdmi_property.feature |= SUPPORT_DEEP_10BIT;
578 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
579 rk_hdmi_property.feature |=
582 } else if (hdmi_dev->soctype == HDMI_SOC_RK3368) {
583 rk_hdmi_property.feature |=
587 SUPPORT_YCBCR_INPUT |
589 } else if (hdmi_dev->soctype == HDMI_SOC_RK322X) {
590 rk_hdmi_property.feature |=
593 SUPPORT_YCBCR_INPUT |
597 *if (rockchip_get_cpu_version())
598 * rk_hdmi_property.feature |=
600 * SUPPORT_DEEP_10BIT;
602 } else if (hdmi_dev->soctype == HDMI_SOC_RK3366) {
603 rk_hdmi_property.feature |=
604 SUPPORT_YCBCR_INPUT |
607 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
608 rk_hdmi_property.feature |=
612 SUPPORT_YCBCR_INPUT |
614 } else if (hdmi_dev->soctype == HDMI_SOC_RK3399) {
615 rk_hdmi_property.feature |=
617 SUPPORT_YCBCR_INPUT |
620 if (rk_hdmi_property.videosrc == DISPLAY_SOURCE_LCDC0)
621 rk_hdmi_property.feature |=
625 SUPPORT_YCBCR_INPUT |
632 rockchip_hdmi_register(&rk_hdmi_property, &rk_hdmi_ops);
633 if (!hdmi_dev->hdmi) {
634 dev_err(&pdev->dev, "register hdmi device failed\n");
638 mutex_init(&hdmi_dev->ddc_lock);
639 hdmi_dev->hdmi->dev = &pdev->dev;
640 hdmi_dev->hdmi->soctype = hdmi_dev->soctype;
641 fb_register_client(&rockchip_hdmiv2_fb_notifier);
642 rockchip_hdmiv2_dev_initial(hdmi_dev);
643 pinctrl_select_state(hdmi_dev->dev->pins->p,
644 hdmi_dev->dev->pins->default_state);
645 #if defined(CONFIG_DEBUG_FS)
646 hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv2", NULL);
647 if (IS_ERR(hdmi_dev->debugfs_dir))
648 dev_err(hdmi_dev->hdmi->dev,
649 "failed to create debugfs dir for rockchip hdmiv2!\n");
651 debugfs_create_file("regs_ctrl", S_IRUSR,
652 hdmi_dev->debugfs_dir,
653 hdmi_dev, &hdmi_regs_ctrl_fops);
654 debugfs_create_file("regs_phy", S_IRUSR,
655 hdmi_dev->debugfs_dir,
656 hdmi_dev, &hdmi_regs_phy_fops);
660 #ifndef HDMI_INT_USE_POLL
661 /* get and request the IRQ */
662 hdmi_dev->irq = platform_get_irq(pdev, 0);
663 if (hdmi_dev->irq <= 0) {
664 dev_err(hdmi_dev->dev,
665 "failed to get hdmi irq resource (%d).\n",
671 ret = devm_request_irq(hdmi_dev->dev, hdmi_dev->irq,
672 rockchip_hdmiv2_dev_irq,
674 dev_name(hdmi_dev->dev), hdmi_dev);
676 dev_err(hdmi_dev->dev,
677 "hdmi request_irq failed (%d).\n",
682 hdmi_dev->workqueue =
683 create_singlethread_workqueue("rockchip hdmiv2 irq");
684 INIT_DELAYED_WORK(&hdmi_dev->delay_work,
685 rockchip_hdmiv2_irq_work_func);
686 rockchip_hdmiv2_irq_work_func(NULL);
689 rk_display_device_enable(hdmi_dev->hdmi->ddev);
690 dev_info(&pdev->dev, "rockchip hdmiv2 probe success.\n");
694 rockchip_hdmi_unregister(hdmi_dev->hdmi);
696 kfree(hdmi_dev->phy_table);
699 dev_err(&pdev->dev, "rockchip hdmiv2 probe error.\n");
703 static int rockchip_hdmiv2_suspend(struct platform_device *pdev,
707 hdmi_dev->grf_base &&
708 hdmi_dev->soctype == HDMI_SOC_RK322X) {
709 regmap_write(hdmi_dev->grf_base,
711 RK322X_PLL_POWER_DOWN);
716 static int rockchip_hdmiv2_resume(struct platform_device *pdev)
719 hdmi_dev->grf_base &&
720 hdmi_dev->soctype == HDMI_SOC_RK322X) {
721 regmap_write(hdmi_dev->grf_base,
723 RK322X_PLL_POWER_UP);
728 static int rockchip_hdmiv2_remove(struct platform_device *pdev)
730 dev_info(&pdev->dev, "rk3288 hdmi driver removed.\n");
734 static void rockchip_hdmiv2_shutdown(struct platform_device *pdev)
739 #ifdef CONFIG_HAS_EARLYSUSPEND
740 unregister_early_suspend(&hdmi_dev->early_suspend);
742 hdmi = hdmi_dev->hdmi;
743 if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
745 hdmi->ops->setmute(hdmi, HDMI_VIDEO_MUTE);
747 pm_runtime_disable(hdmi_dev->dev);
750 static struct platform_driver rockchip_hdmiv2_driver = {
751 .probe = rockchip_hdmiv2_probe,
752 .remove = rockchip_hdmiv2_remove,
754 .name = "rockchip-hdmiv2",
755 .owner = THIS_MODULE,
756 #if defined(CONFIG_OF)
757 .of_match_table = of_match_ptr(rk_hdmi_dt_ids),
760 .suspend = rockchip_hdmiv2_suspend,
761 .resume = rockchip_hdmiv2_resume,
762 .shutdown = rockchip_hdmiv2_shutdown,
765 static int __init rockchip_hdmiv2_init(void)
767 return platform_driver_register(&rockchip_hdmiv2_driver);
770 static void __exit rockchip_hdmiv2_exit(void)
772 platform_driver_unregister(&rockchip_hdmiv2_driver);
775 module_init(rockchip_hdmiv2_init);
776 module_exit(rockchip_hdmiv2_exit);