root/drivers/gpu/drm/omapdrm/dss/hdmi5.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hdmi_runtime_get
  2. hdmi_runtime_put
  3. hdmi_irq_handler
  4. hdmi_power_on_core
  5. hdmi_power_off_core
  6. hdmi_power_on_full
  7. hdmi_power_off_full
  8. hdmi_display_set_timings
  9. hdmi_dump_regs
  10. read_edid
  11. hdmi_start_audio_stream
  12. hdmi_stop_audio_stream
  13. hdmi_display_enable
  14. hdmi_display_disable
  15. hdmi_core_enable
  16. hdmi_core_disable
  17. hdmi_connect
  18. hdmi_disconnect
  19. hdmi_read_edid
  20. hdmi_set_infoframe
  21. hdmi_set_hdmi_mode
  22. hdmi_audio_startup
  23. hdmi_audio_shutdown
  24. hdmi_audio_start
  25. hdmi_audio_stop
  26. hdmi_audio_config
  27. hdmi_audio_register
  28. hdmi5_bind
  29. hdmi5_unbind
  30. hdmi5_init_output
  31. hdmi5_uninit_output
  32. hdmi5_probe_of
  33. hdmi5_probe
  34. hdmi5_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * HDMI driver for OMAP5
   4  *
   5  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
   6  *
   7  * Authors:
   8  *      Yong Zhi
   9  *      Mythri pk
  10  *      Archit Taneja <archit@ti.com>
  11  *      Tomi Valkeinen <tomi.valkeinen@ti.com>
  12  */
  13 
  14 #define DSS_SUBSYS_NAME "HDMI"
  15 
  16 #include <linux/kernel.h>
  17 #include <linux/module.h>
  18 #include <linux/err.h>
  19 #include <linux/io.h>
  20 #include <linux/interrupt.h>
  21 #include <linux/mutex.h>
  22 #include <linux/delay.h>
  23 #include <linux/string.h>
  24 #include <linux/platform_device.h>
  25 #include <linux/pm_runtime.h>
  26 #include <linux/clk.h>
  27 #include <linux/gpio.h>
  28 #include <linux/regulator/consumer.h>
  29 #include <linux/component.h>
  30 #include <linux/of.h>
  31 #include <linux/of_graph.h>
  32 #include <sound/omap-hdmi-audio.h>
  33 
  34 #include "omapdss.h"
  35 #include "hdmi5_core.h"
  36 #include "dss.h"
  37 
  38 static int hdmi_runtime_get(struct omap_hdmi *hdmi)
  39 {
  40         int r;
  41 
  42         DSSDBG("hdmi_runtime_get\n");
  43 
  44         r = pm_runtime_get_sync(&hdmi->pdev->dev);
  45         WARN_ON(r < 0);
  46         if (r < 0)
  47                 return r;
  48 
  49         return 0;
  50 }
  51 
  52 static void hdmi_runtime_put(struct omap_hdmi *hdmi)
  53 {
  54         int r;
  55 
  56         DSSDBG("hdmi_runtime_put\n");
  57 
  58         r = pm_runtime_put_sync(&hdmi->pdev->dev);
  59         WARN_ON(r < 0 && r != -ENOSYS);
  60 }
  61 
  62 static irqreturn_t hdmi_irq_handler(int irq, void *data)
  63 {
  64         struct omap_hdmi *hdmi = data;
  65         struct hdmi_wp_data *wp = &hdmi->wp;
  66         u32 irqstatus;
  67 
  68         irqstatus = hdmi_wp_get_irqstatus(wp);
  69         hdmi_wp_set_irqstatus(wp, irqstatus);
  70 
  71         if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
  72                         irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
  73                 u32 v;
  74                 /*
  75                  * If we get both connect and disconnect interrupts at the same
  76                  * time, turn off the PHY, clear interrupts, and restart, which
  77                  * raises connect interrupt if a cable is connected, or nothing
  78                  * if cable is not connected.
  79                  */
  80 
  81                 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
  82 
  83                 /*
  84                  * We always get bogus CONNECT & DISCONNECT interrupts when
  85                  * setting the PHY to LDOON. To ignore those, we force the RXDET
  86                  * line to 0 until the PHY power state has been changed.
  87                  */
  88                 v = hdmi_read_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
  89                 v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
  90                 v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
  91                 hdmi_write_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
  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 
  98                 REG_FLD_MOD(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
  99 
 100         } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
 101                 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
 102         } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
 103                 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
 104         }
 105 
 106         return IRQ_HANDLED;
 107 }
 108 
 109 static int hdmi_power_on_core(struct omap_hdmi *hdmi)
 110 {
 111         int r;
 112 
 113         r = regulator_enable(hdmi->vdda_reg);
 114         if (r)
 115                 return r;
 116 
 117         r = hdmi_runtime_get(hdmi);
 118         if (r)
 119                 goto err_runtime_get;
 120 
 121         /* Make selection of HDMI in DSS */
 122         dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK);
 123 
 124         hdmi->core_enabled = true;
 125 
 126         return 0;
 127 
 128 err_runtime_get:
 129         regulator_disable(hdmi->vdda_reg);
 130 
 131         return r;
 132 }
 133 
 134 static void hdmi_power_off_core(struct omap_hdmi *hdmi)
 135 {
 136         hdmi->core_enabled = false;
 137 
 138         hdmi_runtime_put(hdmi);
 139         regulator_disable(hdmi->vdda_reg);
 140 }
 141 
 142 static int hdmi_power_on_full(struct omap_hdmi *hdmi)
 143 {
 144         int r;
 145         const struct videomode *vm;
 146         struct dss_pll_clock_info hdmi_cinfo = { 0 };
 147         unsigned int pc;
 148 
 149         r = hdmi_power_on_core(hdmi);
 150         if (r)
 151                 return r;
 152 
 153         vm = &hdmi->cfg.vm;
 154 
 155         DSSDBG("hdmi_power_on hactive= %d vactive = %d\n", vm->hactive,
 156                vm->vactive);
 157 
 158         pc = vm->pixelclock;
 159         if (vm->flags & DISPLAY_FLAGS_DOUBLECLK)
 160                 pc *= 2;
 161 
 162         /* DSS_HDMI_TCLK is bitclk / 10 */
 163         pc *= 10;
 164 
 165         dss_pll_calc_b(&hdmi->pll.pll, clk_get_rate(hdmi->pll.pll.clkin),
 166                 pc, &hdmi_cinfo);
 167 
 168         /* disable and clear irqs */
 169         hdmi_wp_clear_irqenable(&hdmi->wp, 0xffffffff);
 170         hdmi_wp_set_irqstatus(&hdmi->wp,
 171                         hdmi_wp_get_irqstatus(&hdmi->wp));
 172 
 173         r = dss_pll_enable(&hdmi->pll.pll);
 174         if (r) {
 175                 DSSERR("Failed to enable PLL\n");
 176                 goto err_pll_enable;
 177         }
 178 
 179         r = dss_pll_set_config(&hdmi->pll.pll, &hdmi_cinfo);
 180         if (r) {
 181                 DSSERR("Failed to configure PLL\n");
 182                 goto err_pll_cfg;
 183         }
 184 
 185         r = hdmi_phy_configure(&hdmi->phy, hdmi_cinfo.clkdco,
 186                 hdmi_cinfo.clkout[0]);
 187         if (r) {
 188                 DSSDBG("Failed to start PHY\n");
 189                 goto err_phy_cfg;
 190         }
 191 
 192         r = hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_LDOON);
 193         if (r)
 194                 goto err_phy_pwr;
 195 
 196         hdmi5_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
 197 
 198         r = dss_mgr_enable(&hdmi->output);
 199         if (r)
 200                 goto err_mgr_enable;
 201 
 202         r = hdmi_wp_video_start(&hdmi->wp);
 203         if (r)
 204                 goto err_vid_enable;
 205 
 206         hdmi_wp_set_irqenable(&hdmi->wp,
 207                         HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
 208 
 209         return 0;
 210 
 211 err_vid_enable:
 212         dss_mgr_disable(&hdmi->output);
 213 err_mgr_enable:
 214         hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
 215 err_phy_pwr:
 216 err_phy_cfg:
 217 err_pll_cfg:
 218         dss_pll_disable(&hdmi->pll.pll);
 219 err_pll_enable:
 220         hdmi_power_off_core(hdmi);
 221         return -EIO;
 222 }
 223 
 224 static void hdmi_power_off_full(struct omap_hdmi *hdmi)
 225 {
 226         hdmi_wp_clear_irqenable(&hdmi->wp, 0xffffffff);
 227 
 228         hdmi_wp_video_stop(&hdmi->wp);
 229 
 230         dss_mgr_disable(&hdmi->output);
 231 
 232         hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
 233 
 234         dss_pll_disable(&hdmi->pll.pll);
 235 
 236         hdmi_power_off_core(hdmi);
 237 }
 238 
 239 static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
 240                                      const struct drm_display_mode *mode)
 241 {
 242         struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 243 
 244         mutex_lock(&hdmi->lock);
 245 
 246         drm_display_mode_to_videomode(mode, &hdmi->cfg.vm);
 247 
 248         dispc_set_tv_pclk(hdmi->dss->dispc, mode->clock * 1000);
 249 
 250         mutex_unlock(&hdmi->lock);
 251 }
 252 
 253 static int hdmi_dump_regs(struct seq_file *s, void *p)
 254 {
 255         struct omap_hdmi *hdmi = s->private;
 256 
 257         mutex_lock(&hdmi->lock);
 258 
 259         if (hdmi_runtime_get(hdmi)) {
 260                 mutex_unlock(&hdmi->lock);
 261                 return 0;
 262         }
 263 
 264         hdmi_wp_dump(&hdmi->wp, s);
 265         hdmi_pll_dump(&hdmi->pll, s);
 266         hdmi_phy_dump(&hdmi->phy, s);
 267         hdmi5_core_dump(&hdmi->core, s);
 268 
 269         hdmi_runtime_put(hdmi);
 270         mutex_unlock(&hdmi->lock);
 271         return 0;
 272 }
 273 
 274 static int read_edid(struct omap_hdmi *hdmi, u8 *buf, int len)
 275 {
 276         int r;
 277         int idlemode;
 278 
 279         mutex_lock(&hdmi->lock);
 280 
 281         r = hdmi_runtime_get(hdmi);
 282         BUG_ON(r);
 283 
 284         idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
 285         /* No-idle mode */
 286         REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
 287 
 288         r = hdmi5_read_edid(&hdmi->core,  buf, len);
 289 
 290         REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
 291 
 292         hdmi_runtime_put(hdmi);
 293         mutex_unlock(&hdmi->lock);
 294 
 295         return r;
 296 }
 297 
 298 static void hdmi_start_audio_stream(struct omap_hdmi *hd)
 299 {
 300         REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
 301         hdmi_wp_audio_enable(&hd->wp, true);
 302         hdmi_wp_audio_core_req_enable(&hd->wp, true);
 303 }
 304 
 305 static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
 306 {
 307         hdmi_wp_audio_core_req_enable(&hd->wp, false);
 308         hdmi_wp_audio_enable(&hd->wp, false);
 309         REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
 310 }
 311 
 312 static void hdmi_display_enable(struct omap_dss_device *dssdev)
 313 {
 314         struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 315         unsigned long flags;
 316         int r;
 317 
 318         DSSDBG("ENTER hdmi_display_enable\n");
 319 
 320         mutex_lock(&hdmi->lock);
 321 
 322         r = hdmi_power_on_full(hdmi);
 323         if (r) {
 324                 DSSERR("failed to power on device\n");
 325                 goto done;
 326         }
 327 
 328         if (hdmi->audio_configured) {
 329                 r = hdmi5_audio_config(&hdmi->core, &hdmi->wp,
 330                                        &hdmi->audio_config,
 331                                        hdmi->cfg.vm.pixelclock);
 332                 if (r) {
 333                         DSSERR("Error restoring audio configuration: %d", r);
 334                         hdmi->audio_abort_cb(&hdmi->pdev->dev);
 335                         hdmi->audio_configured = false;
 336                 }
 337         }
 338 
 339         spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
 340         if (hdmi->audio_configured && hdmi->audio_playing)
 341                 hdmi_start_audio_stream(hdmi);
 342         hdmi->display_enabled = true;
 343         spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
 344 
 345 done:
 346         mutex_unlock(&hdmi->lock);
 347 }
 348 
 349 static void hdmi_display_disable(struct omap_dss_device *dssdev)
 350 {
 351         struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 352         unsigned long flags;
 353 
 354         DSSDBG("Enter hdmi_display_disable\n");
 355 
 356         mutex_lock(&hdmi->lock);
 357 
 358         spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
 359         hdmi_stop_audio_stream(hdmi);
 360         hdmi->display_enabled = false;
 361         spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
 362 
 363         hdmi_power_off_full(hdmi);
 364 
 365         mutex_unlock(&hdmi->lock);
 366 }
 367 
 368 static int hdmi_core_enable(struct omap_hdmi *hdmi)
 369 {
 370         int r = 0;
 371 
 372         DSSDBG("ENTER omapdss_hdmi_core_enable\n");
 373 
 374         mutex_lock(&hdmi->lock);
 375 
 376         r = hdmi_power_on_core(hdmi);
 377         if (r) {
 378                 DSSERR("failed to power on device\n");
 379                 goto err0;
 380         }
 381 
 382         mutex_unlock(&hdmi->lock);
 383         return 0;
 384 
 385 err0:
 386         mutex_unlock(&hdmi->lock);
 387         return r;
 388 }
 389 
 390 static void hdmi_core_disable(struct omap_hdmi *hdmi)
 391 {
 392         DSSDBG("Enter omapdss_hdmi_core_disable\n");
 393 
 394         mutex_lock(&hdmi->lock);
 395 
 396         hdmi_power_off_core(hdmi);
 397 
 398         mutex_unlock(&hdmi->lock);
 399 }
 400 
 401 static int hdmi_connect(struct omap_dss_device *src,
 402                         struct omap_dss_device *dst)
 403 {
 404         return omapdss_device_connect(dst->dss, dst, dst->next);
 405 }
 406 
 407 static void hdmi_disconnect(struct omap_dss_device *src,
 408                             struct omap_dss_device *dst)
 409 {
 410         omapdss_device_disconnect(dst, dst->next);
 411 }
 412 
 413 static int hdmi_read_edid(struct omap_dss_device *dssdev,
 414                 u8 *edid, int len)
 415 {
 416         struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 417         bool need_enable;
 418         int r;
 419 
 420         need_enable = hdmi->core_enabled == false;
 421 
 422         if (need_enable) {
 423                 r = hdmi_core_enable(hdmi);
 424                 if (r)
 425                         return r;
 426         }
 427 
 428         r = read_edid(hdmi, edid, len);
 429 
 430         if (need_enable)
 431                 hdmi_core_disable(hdmi);
 432 
 433         return r;
 434 }
 435 
 436 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
 437                 const struct hdmi_avi_infoframe *avi)
 438 {
 439         struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 440 
 441         hdmi->cfg.infoframe = *avi;
 442         return 0;
 443 }
 444 
 445 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
 446                 bool hdmi_mode)
 447 {
 448         struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 449 
 450         hdmi->cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
 451         return 0;
 452 }
 453 
 454 static const struct omap_dss_device_ops hdmi_ops = {
 455         .connect                = hdmi_connect,
 456         .disconnect             = hdmi_disconnect,
 457 
 458         .enable                 = hdmi_display_enable,
 459         .disable                = hdmi_display_disable,
 460 
 461         .set_timings            = hdmi_display_set_timings,
 462 
 463         .read_edid              = hdmi_read_edid,
 464 
 465         .hdmi = {
 466                 .set_infoframe          = hdmi_set_infoframe,
 467                 .set_hdmi_mode          = hdmi_set_hdmi_mode,
 468         },
 469 };
 470 
 471 /* -----------------------------------------------------------------------------
 472  * Audio Callbacks
 473  */
 474 
 475 static int hdmi_audio_startup(struct device *dev,
 476                               void (*abort_cb)(struct device *dev))
 477 {
 478         struct omap_hdmi *hd = dev_get_drvdata(dev);
 479 
 480         mutex_lock(&hd->lock);
 481 
 482         WARN_ON(hd->audio_abort_cb != NULL);
 483 
 484         hd->audio_abort_cb = abort_cb;
 485 
 486         mutex_unlock(&hd->lock);
 487 
 488         return 0;
 489 }
 490 
 491 static int hdmi_audio_shutdown(struct device *dev)
 492 {
 493         struct omap_hdmi *hd = dev_get_drvdata(dev);
 494 
 495         mutex_lock(&hd->lock);
 496         hd->audio_abort_cb = NULL;
 497         hd->audio_configured = false;
 498         hd->audio_playing = false;
 499         mutex_unlock(&hd->lock);
 500 
 501         return 0;
 502 }
 503 
 504 static int hdmi_audio_start(struct device *dev)
 505 {
 506         struct omap_hdmi *hd = dev_get_drvdata(dev);
 507         unsigned long flags;
 508 
 509         spin_lock_irqsave(&hd->audio_playing_lock, flags);
 510 
 511         if (hd->display_enabled) {
 512                 if (!hdmi_mode_has_audio(&hd->cfg))
 513                         DSSERR("%s: Video mode does not support audio\n",
 514                                __func__);
 515                 hdmi_start_audio_stream(hd);
 516         }
 517         hd->audio_playing = true;
 518 
 519         spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
 520         return 0;
 521 }
 522 
 523 static void hdmi_audio_stop(struct device *dev)
 524 {
 525         struct omap_hdmi *hd = dev_get_drvdata(dev);
 526         unsigned long flags;
 527 
 528         if (!hdmi_mode_has_audio(&hd->cfg))
 529                 DSSERR("%s: Video mode does not support audio\n", __func__);
 530 
 531         spin_lock_irqsave(&hd->audio_playing_lock, flags);
 532 
 533         if (hd->display_enabled)
 534                 hdmi_stop_audio_stream(hd);
 535         hd->audio_playing = false;
 536 
 537         spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
 538 }
 539 
 540 static int hdmi_audio_config(struct device *dev,
 541                              struct omap_dss_audio *dss_audio)
 542 {
 543         struct omap_hdmi *hd = dev_get_drvdata(dev);
 544         int ret = 0;
 545 
 546         mutex_lock(&hd->lock);
 547 
 548         if (hd->display_enabled) {
 549                 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
 550                                          hd->cfg.vm.pixelclock);
 551                 if (ret)
 552                         goto out;
 553         }
 554 
 555         hd->audio_configured = true;
 556         hd->audio_config = *dss_audio;
 557 out:
 558         mutex_unlock(&hd->lock);
 559 
 560         return ret;
 561 }
 562 
 563 static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
 564         .audio_startup = hdmi_audio_startup,
 565         .audio_shutdown = hdmi_audio_shutdown,
 566         .audio_start = hdmi_audio_start,
 567         .audio_stop = hdmi_audio_stop,
 568         .audio_config = hdmi_audio_config,
 569 };
 570 
 571 static int hdmi_audio_register(struct omap_hdmi *hdmi)
 572 {
 573         struct omap_hdmi_audio_pdata pdata = {
 574                 .dev = &hdmi->pdev->dev,
 575                 .version = 5,
 576                 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi->wp),
 577                 .ops = &hdmi_audio_ops,
 578         };
 579 
 580         hdmi->audio_pdev = platform_device_register_data(
 581                 &hdmi->pdev->dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
 582                 &pdata, sizeof(pdata));
 583 
 584         if (IS_ERR(hdmi->audio_pdev))
 585                 return PTR_ERR(hdmi->audio_pdev);
 586 
 587         hdmi_runtime_get(hdmi);
 588         hdmi->wp_idlemode =
 589                 REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
 590         hdmi_runtime_put(hdmi);
 591 
 592         return 0;
 593 }
 594 
 595 /* -----------------------------------------------------------------------------
 596  * Component Bind & Unbind
 597  */
 598 
 599 static int hdmi5_bind(struct device *dev, struct device *master, void *data)
 600 {
 601         struct dss_device *dss = dss_get_device(master);
 602         struct omap_hdmi *hdmi = dev_get_drvdata(dev);
 603         int r;
 604 
 605         hdmi->dss = dss;
 606 
 607         r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
 608         if (r)
 609                 return r;
 610 
 611         r = hdmi_audio_register(hdmi);
 612         if (r) {
 613                 DSSERR("Registering HDMI audio failed %d\n", r);
 614                 goto err_pll_uninit;
 615         }
 616 
 617         hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
 618                                                 hdmi);
 619 
 620         return 0;
 621 
 622 err_pll_uninit:
 623         hdmi_pll_uninit(&hdmi->pll);
 624         return r;
 625 }
 626 
 627 static void hdmi5_unbind(struct device *dev, struct device *master, void *data)
 628 {
 629         struct omap_hdmi *hdmi = dev_get_drvdata(dev);
 630 
 631         dss_debugfs_remove_file(hdmi->debugfs);
 632 
 633         if (hdmi->audio_pdev)
 634                 platform_device_unregister(hdmi->audio_pdev);
 635 
 636         hdmi_pll_uninit(&hdmi->pll);
 637 }
 638 
 639 static const struct component_ops hdmi5_component_ops = {
 640         .bind   = hdmi5_bind,
 641         .unbind = hdmi5_unbind,
 642 };
 643 
 644 /* -----------------------------------------------------------------------------
 645  * Probe & Remove, Suspend & Resume
 646  */
 647 
 648 static int hdmi5_init_output(struct omap_hdmi *hdmi)
 649 {
 650         struct omap_dss_device *out = &hdmi->output;
 651         int r;
 652 
 653         out->dev = &hdmi->pdev->dev;
 654         out->id = OMAP_DSS_OUTPUT_HDMI;
 655         out->type = OMAP_DISPLAY_TYPE_HDMI;
 656         out->name = "hdmi.0";
 657         out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
 658         out->ops = &hdmi_ops;
 659         out->owner = THIS_MODULE;
 660         out->of_ports = BIT(0);
 661         out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
 662 
 663         r = omapdss_device_init_output(out);
 664         if (r < 0)
 665                 return r;
 666 
 667         omapdss_device_register(out);
 668 
 669         return 0;
 670 }
 671 
 672 static void hdmi5_uninit_output(struct omap_hdmi *hdmi)
 673 {
 674         struct omap_dss_device *out = &hdmi->output;
 675 
 676         omapdss_device_unregister(out);
 677         omapdss_device_cleanup_output(out);
 678 }
 679 
 680 static int hdmi5_probe_of(struct omap_hdmi *hdmi)
 681 {
 682         struct platform_device *pdev = hdmi->pdev;
 683         struct device_node *node = pdev->dev.of_node;
 684         struct device_node *ep;
 685         int r;
 686 
 687         ep = of_graph_get_endpoint_by_regs(node, 0, 0);
 688         if (!ep)
 689                 return 0;
 690 
 691         r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
 692         of_node_put(ep);
 693         return r;
 694 }
 695 
 696 static int hdmi5_probe(struct platform_device *pdev)
 697 {
 698         struct omap_hdmi *hdmi;
 699         int irq;
 700         int r;
 701 
 702         hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
 703         if (!hdmi)
 704                 return -ENOMEM;
 705 
 706         hdmi->pdev = pdev;
 707 
 708         dev_set_drvdata(&pdev->dev, hdmi);
 709 
 710         mutex_init(&hdmi->lock);
 711         spin_lock_init(&hdmi->audio_playing_lock);
 712 
 713         r = hdmi5_probe_of(hdmi);
 714         if (r)
 715                 goto err_free;
 716 
 717         r = hdmi_wp_init(pdev, &hdmi->wp, 5);
 718         if (r)
 719                 goto err_free;
 720 
 721         r = hdmi_phy_init(pdev, &hdmi->phy, 5);
 722         if (r)
 723                 goto err_free;
 724 
 725         r = hdmi5_core_init(pdev, &hdmi->core);
 726         if (r)
 727                 goto err_free;
 728 
 729         irq = platform_get_irq(pdev, 0);
 730         if (irq < 0) {
 731                 DSSERR("platform_get_irq failed\n");
 732                 r = -ENODEV;
 733                 goto err_free;
 734         }
 735 
 736         r = devm_request_threaded_irq(&pdev->dev, irq,
 737                         NULL, hdmi_irq_handler,
 738                         IRQF_ONESHOT, "OMAP HDMI", hdmi);
 739         if (r) {
 740                 DSSERR("HDMI IRQ request failed\n");
 741                 goto err_free;
 742         }
 743 
 744         hdmi->vdda_reg = devm_regulator_get(&pdev->dev, "vdda");
 745         if (IS_ERR(hdmi->vdda_reg)) {
 746                 r = PTR_ERR(hdmi->vdda_reg);
 747                 if (r != -EPROBE_DEFER)
 748                         DSSERR("can't get VDDA regulator\n");
 749                 goto err_free;
 750         }
 751 
 752         pm_runtime_enable(&pdev->dev);
 753 
 754         r = hdmi5_init_output(hdmi);
 755         if (r)
 756                 goto err_pm_disable;
 757 
 758         r = component_add(&pdev->dev, &hdmi5_component_ops);
 759         if (r)
 760                 goto err_uninit_output;
 761 
 762         return 0;
 763 
 764 err_uninit_output:
 765         hdmi5_uninit_output(hdmi);
 766 err_pm_disable:
 767         pm_runtime_disable(&pdev->dev);
 768 err_free:
 769         kfree(hdmi);
 770         return r;
 771 }
 772 
 773 static int hdmi5_remove(struct platform_device *pdev)
 774 {
 775         struct omap_hdmi *hdmi = platform_get_drvdata(pdev);
 776 
 777         component_del(&pdev->dev, &hdmi5_component_ops);
 778 
 779         hdmi5_uninit_output(hdmi);
 780 
 781         pm_runtime_disable(&pdev->dev);
 782 
 783         kfree(hdmi);
 784         return 0;
 785 }
 786 
 787 static const struct of_device_id hdmi_of_match[] = {
 788         { .compatible = "ti,omap5-hdmi", },
 789         { .compatible = "ti,dra7-hdmi", },
 790         {},
 791 };
 792 
 793 struct platform_driver omapdss_hdmi5hw_driver = {
 794         .probe          = hdmi5_probe,
 795         .remove         = hdmi5_remove,
 796         .driver         = {
 797                 .name   = "omapdss_hdmi5",
 798                 .of_match_table = hdmi_of_match,
 799                 .suppress_bind_attrs = true,
 800         },
 801 };

/* [<][>][^][v][top][bottom][index][help] */