1 /* 2 * HDMI interface DSS driver for TI's OMAP4 family of SoCs. 3 * 4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ 5 * Authors: Yong Zhi 6 * Mythri pk <mythripk@ti.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 as published by 10 * the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along with 18 * this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #define DSS_SUBSYS_NAME "HDMI" 22 23 #include <linux/kernel.h> 24 #include <linux/module.h> 25 #include <linux/err.h> 26 #include <linux/io.h> 27 #include <linux/interrupt.h> 28 #include <linux/mutex.h> 29 #include <linux/delay.h> 30 #include <linux/string.h> 31 #include <linux/platform_device.h> 32 #include <linux/pm_runtime.h> 33 #include <linux/clk.h> 34 #include <linux/gpio.h> 35 #include <linux/regulator/consumer.h> 36 #include <linux/component.h> 37 #include <linux/of.h> 38 #include <linux/of_graph.h> 39 #include <sound/omap-hdmi-audio.h> 40 #include <media/cec.h> 41 42 #include "omapdss.h" 43 #include "hdmi4_core.h" 44 #include "hdmi4_cec.h" 45 #include "dss.h" 46 #include "hdmi.h" 47 48 static struct omap_hdmi hdmi; 49 50 static int hdmi_runtime_get(void) 51 { 52 int r; 53 54 DSSDBG("hdmi_runtime_get\n"); 55 56 r = pm_runtime_get_sync(&hdmi.pdev->dev); 57 WARN_ON(r < 0); 58 if (r < 0) 59 return r; 60 61 return 0; 62 } 63 64 static void hdmi_runtime_put(void) 65 { 66 int r; 67 68 DSSDBG("hdmi_runtime_put\n"); 69 70 r = pm_runtime_put_sync(&hdmi.pdev->dev); 71 WARN_ON(r < 0 && r != -ENOSYS); 72 } 73 74 static irqreturn_t hdmi_irq_handler(int irq, void *data) 75 { 76 struct omap_hdmi *hdmi = data; 77 struct hdmi_wp_data *wp = &hdmi->wp; 78 u32 irqstatus; 79 80 irqstatus = hdmi_wp_get_irqstatus(wp); 81 hdmi_wp_set_irqstatus(wp, irqstatus); 82 83 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && 84 irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 85 /* 86 * If we get both connect and disconnect interrupts at the same 87 * time, turn off the PHY, clear interrupts, and restart, which 88 * raises connect interrupt if a cable is connected, or nothing 89 * if cable is not connected. 90 */ 91 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); 92 93 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | 94 HDMI_IRQ_LINK_DISCONNECT); 95 96 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 97 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { 98 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); 99 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 100 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 101 } 102 if (irqstatus & HDMI_IRQ_CORE) { 103 u32 intr4 = hdmi_read_reg(hdmi->core.base, HDMI_CORE_SYS_INTR4); 104 105 hdmi_write_reg(hdmi->core.base, HDMI_CORE_SYS_INTR4, intr4); 106 if (intr4 & 8) 107 hdmi4_cec_irq(&hdmi->core); 108 } 109 110 return IRQ_HANDLED; 111 } 112 113 static int hdmi_init_regulator(void) 114 { 115 struct regulator *reg; 116 117 if (hdmi.vdda_reg != NULL) 118 return 0; 119 120 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); 121 122 if (IS_ERR(reg)) { 123 if (PTR_ERR(reg) != -EPROBE_DEFER) 124 DSSERR("can't get VDDA regulator\n"); 125 return PTR_ERR(reg); 126 } 127 128 hdmi.vdda_reg = reg; 129 130 return 0; 131 } 132 133 static int hdmi_power_on_core(struct omap_dss_device *dssdev) 134 { 135 int r; 136 137 if (hdmi.core.core_pwr_cnt++) 138 return 0; 139 140 r = regulator_enable(hdmi.vdda_reg); 141 if (r) 142 goto err_reg_enable; 143 144 r = hdmi_runtime_get(); 145 if (r) 146 goto err_runtime_get; 147 148 hdmi4_core_powerdown_disable(&hdmi.core); 149 150 /* Make selection of HDMI in DSS */ 151 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 152 153 hdmi.core_enabled = true; 154 155 return 0; 156 157 err_runtime_get: 158 regulator_disable(hdmi.vdda_reg); 159 err_reg_enable: 160 hdmi.core.core_pwr_cnt--; 161 162 return r; 163 } 164 165 static void hdmi_power_off_core(struct omap_dss_device *dssdev) 166 { 167 if (--hdmi.core.core_pwr_cnt) 168 return; 169 170 hdmi.core_enabled = false; 171 172 hdmi_runtime_put(); 173 regulator_disable(hdmi.vdda_reg); 174 } 175 176 static int hdmi_power_on_full(struct omap_dss_device *dssdev) 177 { 178 int r; 179 struct videomode *vm; 180 enum omap_channel channel = dssdev->dispc_channel; 181 struct hdmi_wp_data *wp = &hdmi.wp; 182 struct dss_pll_clock_info hdmi_cinfo = { 0 }; 183 unsigned pc; 184 185 r = hdmi_power_on_core(dssdev); 186 if (r) 187 return r; 188 189 /* disable and clear irqs */ 190 hdmi_wp_clear_irqenable(wp, ~HDMI_IRQ_CORE); 191 hdmi_wp_set_irqstatus(wp, ~HDMI_IRQ_CORE); 192 193 vm = &hdmi.cfg.vm; 194 195 DSSDBG("hdmi_power_on hactive= %d vactive = %d\n", vm->hactive, 196 vm->vactive); 197 198 pc = vm->pixelclock; 199 if (vm->flags & DISPLAY_FLAGS_DOUBLECLK) 200 pc *= 2; 201 202 /* DSS_HDMI_TCLK is bitclk / 10 */ 203 pc *= 10; 204 205 dss_pll_calc_b(&hdmi.pll.pll, clk_get_rate(hdmi.pll.pll.clkin), 206 pc, &hdmi_cinfo); 207 208 r = dss_pll_enable(&hdmi.pll.pll); 209 if (r) { 210 DSSERR("Failed to enable PLL\n"); 211 goto err_pll_enable; 212 } 213 214 r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); 215 if (r) { 216 DSSERR("Failed to configure PLL\n"); 217 goto err_pll_cfg; 218 } 219 220 r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, 221 hdmi_cinfo.clkout[0]); 222 if (r) { 223 DSSDBG("Failed to configure PHY\n"); 224 goto err_phy_cfg; 225 } 226 227 r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 228 if (r) 229 goto err_phy_pwr; 230 231 hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 232 233 /* tv size */ 234 dss_mgr_set_timings(channel, vm); 235 236 r = dss_mgr_enable(channel); 237 if (r) 238 goto err_mgr_enable; 239 240 r = hdmi_wp_video_start(&hdmi.wp); 241 if (r) 242 goto err_vid_enable; 243 244 hdmi_wp_set_irqenable(wp, 245 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); 246 247 return 0; 248 249 err_vid_enable: 250 dss_mgr_disable(channel); 251 err_mgr_enable: 252 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 253 err_phy_pwr: 254 err_phy_cfg: 255 err_pll_cfg: 256 dss_pll_disable(&hdmi.pll.pll); 257 err_pll_enable: 258 hdmi_power_off_core(dssdev); 259 return -EIO; 260 } 261 262 static void hdmi_power_off_full(struct omap_dss_device *dssdev) 263 { 264 enum omap_channel channel = dssdev->dispc_channel; 265 266 hdmi_wp_clear_irqenable(&hdmi.wp, ~HDMI_IRQ_CORE); 267 268 hdmi_wp_video_stop(&hdmi.wp); 269 270 dss_mgr_disable(channel); 271 272 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 273 274 dss_pll_disable(&hdmi.pll.pll); 275 276 hdmi_power_off_core(dssdev); 277 } 278 279 static int hdmi_display_check_timing(struct omap_dss_device *dssdev, 280 struct videomode *vm) 281 { 282 if (!dispc_mgr_timings_ok(dssdev->dispc_channel, vm)) 283 return -EINVAL; 284 285 return 0; 286 } 287 288 static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 289 struct videomode *vm) 290 { 291 mutex_lock(&hdmi.lock); 292 293 hdmi.cfg.vm = *vm; 294 295 dispc_set_tv_pclk(vm->pixelclock); 296 297 mutex_unlock(&hdmi.lock); 298 } 299 300 static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 301 struct videomode *vm) 302 { 303 *vm = hdmi.cfg.vm; 304 } 305 306 static void hdmi_dump_regs(struct seq_file *s) 307 { 308 mutex_lock(&hdmi.lock); 309 310 if (hdmi_runtime_get()) { 311 mutex_unlock(&hdmi.lock); 312 return; 313 } 314 315 hdmi_wp_dump(&hdmi.wp, s); 316 hdmi_pll_dump(&hdmi.pll, s); 317 hdmi_phy_dump(&hdmi.phy, s); 318 hdmi4_core_dump(&hdmi.core, s); 319 320 hdmi_runtime_put(); 321 mutex_unlock(&hdmi.lock); 322 } 323 324 static int read_edid(u8 *buf, int len) 325 { 326 int r; 327 328 mutex_lock(&hdmi.lock); 329 330 r = hdmi_runtime_get(); 331 BUG_ON(r); 332 333 r = hdmi4_read_edid(&hdmi.core, buf, len); 334 335 hdmi_runtime_put(); 336 mutex_unlock(&hdmi.lock); 337 338 return r; 339 } 340 341 static void hdmi_start_audio_stream(struct omap_hdmi *hd) 342 { 343 hdmi_wp_audio_enable(&hd->wp, true); 344 hdmi4_audio_start(&hd->core, &hd->wp); 345 } 346 347 static void hdmi_stop_audio_stream(struct omap_hdmi *hd) 348 { 349 hdmi4_audio_stop(&hd->core, &hd->wp); 350 hdmi_wp_audio_enable(&hd->wp, false); 351 } 352 353 static int hdmi_display_enable(struct omap_dss_device *dssdev) 354 { 355 struct omap_dss_device *out = &hdmi.output; 356 unsigned long flags; 357 int r = 0; 358 359 DSSDBG("ENTER hdmi_display_enable\n"); 360 361 mutex_lock(&hdmi.lock); 362 363 if (!out->dispc_channel_connected) { 364 DSSERR("failed to enable display: no output/manager\n"); 365 r = -ENODEV; 366 goto err0; 367 } 368 369 r = hdmi_power_on_full(dssdev); 370 if (r) { 371 DSSERR("failed to power on device\n"); 372 goto err0; 373 } 374 375 if (hdmi.audio_configured) { 376 r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config, 377 hdmi.cfg.vm.pixelclock); 378 if (r) { 379 DSSERR("Error restoring audio configuration: %d", r); 380 hdmi.audio_abort_cb(&hdmi.pdev->dev); 381 hdmi.audio_configured = false; 382 } 383 } 384 385 spin_lock_irqsave(&hdmi.audio_playing_lock, flags); 386 if (hdmi.audio_configured && hdmi.audio_playing) 387 hdmi_start_audio_stream(&hdmi); 388 hdmi.display_enabled = true; 389 spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); 390 391 mutex_unlock(&hdmi.lock); 392 return 0; 393 394 err0: 395 mutex_unlock(&hdmi.lock); 396 return r; 397 } 398 399 static void hdmi_display_disable(struct omap_dss_device *dssdev) 400 { 401 unsigned long flags; 402 403 DSSDBG("Enter hdmi_display_disable\n"); 404 405 mutex_lock(&hdmi.lock); 406 407 spin_lock_irqsave(&hdmi.audio_playing_lock, flags); 408 hdmi_stop_audio_stream(&hdmi); 409 hdmi.display_enabled = false; 410 spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); 411 412 hdmi_power_off_full(dssdev); 413 414 mutex_unlock(&hdmi.lock); 415 } 416 417 int hdmi4_core_enable(struct omap_dss_device *dssdev) 418 { 419 int r = 0; 420 421 DSSDBG("ENTER omapdss_hdmi4_core_enable\n"); 422 423 mutex_lock(&hdmi.lock); 424 425 r = hdmi_power_on_core(dssdev); 426 if (r) { 427 DSSERR("failed to power on device\n"); 428 goto err0; 429 } 430 431 mutex_unlock(&hdmi.lock); 432 return 0; 433 434 err0: 435 mutex_unlock(&hdmi.lock); 436 return r; 437 } 438 439 void hdmi4_core_disable(struct omap_dss_device *dssdev) 440 { 441 DSSDBG("Enter omapdss_hdmi4_core_disable\n"); 442 443 mutex_lock(&hdmi.lock); 444 445 hdmi_power_off_core(dssdev); 446 447 mutex_unlock(&hdmi.lock); 448 } 449 450 static int hdmi_connect(struct omap_dss_device *dssdev, 451 struct omap_dss_device *dst) 452 { 453 enum omap_channel channel = dssdev->dispc_channel; 454 int r; 455 456 r = hdmi_init_regulator(); 457 if (r) 458 return r; 459 460 r = dss_mgr_connect(channel, dssdev); 461 if (r) 462 return r; 463 464 r = omapdss_output_set_device(dssdev, dst); 465 if (r) { 466 DSSERR("failed to connect output to new device: %s\n", 467 dst->name); 468 dss_mgr_disconnect(channel, dssdev); 469 return r; 470 } 471 472 return 0; 473 } 474 475 static void hdmi_disconnect(struct omap_dss_device *dssdev, 476 struct omap_dss_device *dst) 477 { 478 enum omap_channel channel = dssdev->dispc_channel; 479 480 WARN_ON(dst != dssdev->dst); 481 482 if (dst != dssdev->dst) 483 return; 484 485 omapdss_output_unset_device(dssdev); 486 487 dss_mgr_disconnect(channel, dssdev); 488 } 489 490 static int hdmi_read_edid(struct omap_dss_device *dssdev, 491 u8 *edid, int len) 492 { 493 bool need_enable; 494 int r; 495 496 need_enable = hdmi.core_enabled == false; 497 498 if (need_enable) { 499 r = hdmi4_core_enable(dssdev); 500 if (r) 501 return r; 502 } 503 504 r = read_edid(edid, len); 505 if (r >= 256) 506 hdmi4_cec_set_phys_addr(&hdmi.core, 507 cec_get_edid_phys_addr(edid, r, NULL)); 508 else 509 hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID); 510 if (need_enable) 511 hdmi4_core_disable(dssdev); 512 513 return r; 514 } 515 516 static void hdmi_lost_hotplug(struct omap_dss_device *dssdev) 517 { 518 hdmi4_cec_set_phys_addr(&hdmi.core, CEC_PHYS_ADDR_INVALID); 519 } 520 521 static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 522 const struct hdmi_avi_infoframe *avi) 523 { 524 hdmi.cfg.infoframe = *avi; 525 return 0; 526 } 527 528 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, 529 bool hdmi_mode) 530 { 531 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; 532 return 0; 533 } 534 535 static const struct omapdss_hdmi_ops hdmi_ops = { 536 .connect = hdmi_connect, 537 .disconnect = hdmi_disconnect, 538 539 .enable = hdmi_display_enable, 540 .disable = hdmi_display_disable, 541 542 .check_timings = hdmi_display_check_timing, 543 .set_timings = hdmi_display_set_timing, 544 .get_timings = hdmi_display_get_timings, 545 546 .read_edid = hdmi_read_edid, 547 .lost_hotplug = hdmi_lost_hotplug, 548 .set_infoframe = hdmi_set_infoframe, 549 .set_hdmi_mode = hdmi_set_hdmi_mode, 550 }; 551 552 static void hdmi_init_output(struct platform_device *pdev) 553 { 554 struct omap_dss_device *out = &hdmi.output; 555 556 out->dev = &pdev->dev; 557 out->id = OMAP_DSS_OUTPUT_HDMI; 558 out->output_type = OMAP_DISPLAY_TYPE_HDMI; 559 out->name = "hdmi.0"; 560 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 561 out->ops.hdmi = &hdmi_ops; 562 out->owner = THIS_MODULE; 563 564 omapdss_register_output(out); 565 } 566 567 static void hdmi_uninit_output(struct platform_device *pdev) 568 { 569 struct omap_dss_device *out = &hdmi.output; 570 571 omapdss_unregister_output(out); 572 } 573 574 static int hdmi_probe_of(struct platform_device *pdev) 575 { 576 struct device_node *node = pdev->dev.of_node; 577 struct device_node *ep; 578 int r; 579 580 ep = of_graph_get_endpoint_by_regs(node, 0, 0); 581 if (!ep) 582 return 0; 583 584 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); 585 if (r) 586 goto err; 587 588 of_node_put(ep); 589 return 0; 590 591 err: 592 of_node_put(ep); 593 return r; 594 } 595 596 /* Audio callbacks */ 597 static int hdmi_audio_startup(struct device *dev, 598 void (*abort_cb)(struct device *dev)) 599 { 600 struct omap_hdmi *hd = dev_get_drvdata(dev); 601 int ret = 0; 602 603 mutex_lock(&hd->lock); 604 605 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 606 ret = -EPERM; 607 goto out; 608 } 609 610 hd->audio_abort_cb = abort_cb; 611 612 out: 613 mutex_unlock(&hd->lock); 614 615 return ret; 616 } 617 618 static int hdmi_audio_shutdown(struct device *dev) 619 { 620 struct omap_hdmi *hd = dev_get_drvdata(dev); 621 622 mutex_lock(&hd->lock); 623 hd->audio_abort_cb = NULL; 624 hd->audio_configured = false; 625 hd->audio_playing = false; 626 mutex_unlock(&hd->lock); 627 628 return 0; 629 } 630 631 static int hdmi_audio_start(struct device *dev) 632 { 633 struct omap_hdmi *hd = dev_get_drvdata(dev); 634 unsigned long flags; 635 636 WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); 637 638 spin_lock_irqsave(&hd->audio_playing_lock, flags); 639 640 if (hd->display_enabled) 641 hdmi_start_audio_stream(hd); 642 hd->audio_playing = true; 643 644 spin_unlock_irqrestore(&hd->audio_playing_lock, flags); 645 return 0; 646 } 647 648 static void hdmi_audio_stop(struct device *dev) 649 { 650 struct omap_hdmi *hd = dev_get_drvdata(dev); 651 unsigned long flags; 652 653 WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); 654 655 spin_lock_irqsave(&hd->audio_playing_lock, flags); 656 657 if (hd->display_enabled) 658 hdmi_stop_audio_stream(hd); 659 hd->audio_playing = false; 660 661 spin_unlock_irqrestore(&hd->audio_playing_lock, flags); 662 } 663 664 static int hdmi_audio_config(struct device *dev, 665 struct omap_dss_audio *dss_audio) 666 { 667 struct omap_hdmi *hd = dev_get_drvdata(dev); 668 int ret; 669 670 mutex_lock(&hd->lock); 671 672 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 673 ret = -EPERM; 674 goto out; 675 } 676 677 ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio, 678 hd->cfg.vm.pixelclock); 679 if (!ret) { 680 hd->audio_configured = true; 681 hd->audio_config = *dss_audio; 682 } 683 out: 684 mutex_unlock(&hd->lock); 685 686 return ret; 687 } 688 689 static const struct omap_hdmi_audio_ops hdmi_audio_ops = { 690 .audio_startup = hdmi_audio_startup, 691 .audio_shutdown = hdmi_audio_shutdown, 692 .audio_start = hdmi_audio_start, 693 .audio_stop = hdmi_audio_stop, 694 .audio_config = hdmi_audio_config, 695 }; 696 697 static int hdmi_audio_register(struct device *dev) 698 { 699 struct omap_hdmi_audio_pdata pdata = { 700 .dev = dev, 701 .version = 4, 702 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), 703 .ops = &hdmi_audio_ops, 704 }; 705 706 hdmi.audio_pdev = platform_device_register_data( 707 dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO, 708 &pdata, sizeof(pdata)); 709 710 if (IS_ERR(hdmi.audio_pdev)) 711 return PTR_ERR(hdmi.audio_pdev); 712 713 return 0; 714 } 715 716 /* HDMI HW IP initialisation */ 717 static int hdmi4_bind(struct device *dev, struct device *master, void *data) 718 { 719 struct platform_device *pdev = to_platform_device(dev); 720 int r; 721 int irq; 722 723 hdmi.pdev = pdev; 724 dev_set_drvdata(&pdev->dev, &hdmi); 725 726 mutex_init(&hdmi.lock); 727 spin_lock_init(&hdmi.audio_playing_lock); 728 729 r = hdmi_probe_of(pdev); 730 if (r) 731 return r; 732 733 r = hdmi_wp_init(pdev, &hdmi.wp, 4); 734 if (r) 735 return r; 736 737 r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp); 738 if (r) 739 return r; 740 741 r = hdmi_phy_init(pdev, &hdmi.phy, 4); 742 if (r) 743 goto err; 744 745 r = hdmi4_core_init(pdev, &hdmi.core); 746 if (r) 747 goto err; 748 749 r = hdmi4_cec_init(pdev, &hdmi.core, &hdmi.wp); 750 if (r) 751 goto err; 752 753 irq = platform_get_irq(pdev, 0); 754 if (irq < 0) { 755 DSSERR("platform_get_irq failed\n"); 756 r = -ENODEV; 757 goto err; 758 } 759 760 r = devm_request_threaded_irq(&pdev->dev, irq, 761 NULL, hdmi_irq_handler, 762 IRQF_ONESHOT, "OMAP HDMI", &hdmi); 763 if (r) { 764 DSSERR("HDMI IRQ request failed\n"); 765 goto err; 766 } 767 768 pm_runtime_enable(&pdev->dev); 769 770 hdmi_init_output(pdev); 771 772 r = hdmi_audio_register(&pdev->dev); 773 if (r) { 774 DSSERR("Registering HDMI audio failed\n"); 775 hdmi_uninit_output(pdev); 776 pm_runtime_disable(&pdev->dev); 777 return r; 778 } 779 780 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 781 782 return 0; 783 err: 784 hdmi_pll_uninit(&hdmi.pll); 785 return r; 786 } 787 788 static void hdmi4_unbind(struct device *dev, struct device *master, void *data) 789 { 790 struct platform_device *pdev = to_platform_device(dev); 791 792 if (hdmi.audio_pdev) 793 platform_device_unregister(hdmi.audio_pdev); 794 795 hdmi_uninit_output(pdev); 796 797 hdmi4_cec_uninit(&hdmi.core); 798 799 hdmi_pll_uninit(&hdmi.pll); 800 801 pm_runtime_disable(&pdev->dev); 802 } 803 804 static const struct component_ops hdmi4_component_ops = { 805 .bind = hdmi4_bind, 806 .unbind = hdmi4_unbind, 807 }; 808 809 static int hdmi4_probe(struct platform_device *pdev) 810 { 811 return component_add(&pdev->dev, &hdmi4_component_ops); 812 } 813 814 static int hdmi4_remove(struct platform_device *pdev) 815 { 816 component_del(&pdev->dev, &hdmi4_component_ops); 817 return 0; 818 } 819 820 static int hdmi_runtime_suspend(struct device *dev) 821 { 822 dispc_runtime_put(); 823 824 return 0; 825 } 826 827 static int hdmi_runtime_resume(struct device *dev) 828 { 829 int r; 830 831 r = dispc_runtime_get(); 832 if (r < 0) 833 return r; 834 835 return 0; 836 } 837 838 static const struct dev_pm_ops hdmi_pm_ops = { 839 .runtime_suspend = hdmi_runtime_suspend, 840 .runtime_resume = hdmi_runtime_resume, 841 }; 842 843 static const struct of_device_id hdmi_of_match[] = { 844 { .compatible = "ti,omap4-hdmi", }, 845 {}, 846 }; 847 848 struct platform_driver omapdss_hdmi4hw_driver = { 849 .probe = hdmi4_probe, 850 .remove = hdmi4_remove, 851 .driver = { 852 .name = "omapdss_hdmi", 853 .pm = &hdmi_pm_ops, 854 .of_match_table = hdmi_of_match, 855 .suppress_bind_attrs = true, 856 }, 857 }; 858