1c8afe684SRob Clark /* 2c8afe684SRob Clark * Copyright (C) 2013 Red Hat 3c8afe684SRob Clark * Author: Rob Clark <robdclark@gmail.com> 4c8afe684SRob Clark * 5c8afe684SRob Clark * This program is free software; you can redistribute it and/or modify it 6c8afe684SRob Clark * under the terms of the GNU General Public License version 2 as published by 7c8afe684SRob Clark * the Free Software Foundation. 8c8afe684SRob Clark * 9c8afe684SRob Clark * This program is distributed in the hope that it will be useful, but WITHOUT 10c8afe684SRob Clark * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11c8afe684SRob Clark * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12c8afe684SRob Clark * more details. 13c8afe684SRob Clark * 14c8afe684SRob Clark * You should have received a copy of the GNU General Public License along with 15c8afe684SRob Clark * this program. If not, see <http://www.gnu.org/licenses/>. 16c8afe684SRob Clark */ 17c8afe684SRob Clark 18c8afe684SRob Clark #include "hdmi.h" 19c8afe684SRob Clark 20c8afe684SRob Clark void hdmi_set_mode(struct hdmi *hdmi, bool power_on) 21c8afe684SRob Clark { 22c8afe684SRob Clark uint32_t ctrl = 0; 23c8afe684SRob Clark 24c8afe684SRob Clark if (power_on) { 25c8afe684SRob Clark ctrl |= HDMI_CTRL_ENABLE; 26c8afe684SRob Clark if (!hdmi->hdmi_mode) { 27c8afe684SRob Clark ctrl |= HDMI_CTRL_HDMI; 28c8afe684SRob Clark hdmi_write(hdmi, REG_HDMI_CTRL, ctrl); 29c8afe684SRob Clark ctrl &= ~HDMI_CTRL_HDMI; 30c8afe684SRob Clark } else { 31c8afe684SRob Clark ctrl |= HDMI_CTRL_HDMI; 32c8afe684SRob Clark } 33c8afe684SRob Clark } else { 34c8afe684SRob Clark ctrl = HDMI_CTRL_HDMI; 35c8afe684SRob Clark } 36c8afe684SRob Clark 37c8afe684SRob Clark hdmi_write(hdmi, REG_HDMI_CTRL, ctrl); 38c8afe684SRob Clark DBG("HDMI Core: %s, HDMI_CTRL=0x%08x", 39c8afe684SRob Clark power_on ? "Enable" : "Disable", ctrl); 40c8afe684SRob Clark } 41c8afe684SRob Clark 42dada25bdSRob Clark irqreturn_t hdmi_irq(int irq, void *dev_id) 43c8afe684SRob Clark { 44c8afe684SRob Clark struct hdmi *hdmi = dev_id; 45c8afe684SRob Clark 46c8afe684SRob Clark /* Process HPD: */ 47c8afe684SRob Clark hdmi_connector_irq(hdmi->connector); 48c8afe684SRob Clark 49c8afe684SRob Clark /* Process DDC: */ 50c8afe684SRob Clark hdmi_i2c_irq(hdmi->i2c); 51c8afe684SRob Clark 52c8afe684SRob Clark /* TODO audio.. */ 53c8afe684SRob Clark 54c8afe684SRob Clark return IRQ_HANDLED; 55c8afe684SRob Clark } 56c8afe684SRob Clark 57a3376e3eSRob Clark void hdmi_destroy(struct kref *kref) 58c8afe684SRob Clark { 59a3376e3eSRob Clark struct hdmi *hdmi = container_of(kref, struct hdmi, refcount); 60c8afe684SRob Clark struct hdmi_phy *phy = hdmi->phy; 61c8afe684SRob Clark 62c8afe684SRob Clark if (phy) 63c8afe684SRob Clark phy->funcs->destroy(phy); 64c8afe684SRob Clark 65c8afe684SRob Clark if (hdmi->i2c) 66c8afe684SRob Clark hdmi_i2c_destroy(hdmi->i2c); 67c8afe684SRob Clark 68c0c0d9eeSRob Clark platform_set_drvdata(hdmi->pdev, NULL); 69c8afe684SRob Clark } 70c8afe684SRob Clark 71c8afe684SRob Clark /* initialize connector */ 72dada25bdSRob Clark struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) 73c8afe684SRob Clark { 74a3376e3eSRob Clark struct hdmi *hdmi = NULL; 75a3376e3eSRob Clark struct msm_drm_private *priv = dev->dev_private; 76060530f1SRob Clark struct platform_device *pdev = priv->hdmi_pdev; 77c8afe684SRob Clark struct hdmi_platform_config *config; 78dada25bdSRob Clark int i, ret; 79c8afe684SRob Clark 80c8afe684SRob Clark if (!pdev) { 81c8afe684SRob Clark dev_err(dev->dev, "no hdmi device\n"); 82c8afe684SRob Clark ret = -ENXIO; 83c8afe684SRob Clark goto fail; 84c8afe684SRob Clark } 85c8afe684SRob Clark 86c8afe684SRob Clark config = pdev->dev.platform_data; 87c8afe684SRob Clark 88a3376e3eSRob Clark hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL); 89a3376e3eSRob Clark if (!hdmi) { 90a3376e3eSRob Clark ret = -ENOMEM; 91a3376e3eSRob Clark goto fail; 92a3376e3eSRob Clark } 93a3376e3eSRob Clark 94a3376e3eSRob Clark kref_init(&hdmi->refcount); 95a3376e3eSRob Clark 96c8afe684SRob Clark hdmi->dev = dev; 97c8afe684SRob Clark hdmi->pdev = pdev; 98dada25bdSRob Clark hdmi->config = config; 99a3376e3eSRob Clark hdmi->encoder = encoder; 100c8afe684SRob Clark 101c0c0d9eeSRob Clark hdmi_audio_infoframe_init(&hdmi->audio.infoframe); 102c0c0d9eeSRob Clark 103c8afe684SRob Clark /* not sure about which phy maps to which msm.. probably I miss some */ 104c8afe684SRob Clark if (config->phy_init) 105c8afe684SRob Clark hdmi->phy = config->phy_init(hdmi); 106c8afe684SRob Clark else 107c8afe684SRob Clark hdmi->phy = ERR_PTR(-ENXIO); 108c8afe684SRob Clark 109c8afe684SRob Clark if (IS_ERR(hdmi->phy)) { 110c8afe684SRob Clark ret = PTR_ERR(hdmi->phy); 111c8afe684SRob Clark dev_err(dev->dev, "failed to load phy: %d\n", ret); 112c8afe684SRob Clark hdmi->phy = NULL; 113c8afe684SRob Clark goto fail; 114c8afe684SRob Clark } 115c8afe684SRob Clark 116dada25bdSRob Clark hdmi->mmio = msm_ioremap(pdev, config->mmio_name, "HDMI"); 117c8afe684SRob Clark if (IS_ERR(hdmi->mmio)) { 118c8afe684SRob Clark ret = PTR_ERR(hdmi->mmio); 119c8afe684SRob Clark goto fail; 120c8afe684SRob Clark } 121c8afe684SRob Clark 122dada25bdSRob Clark BUG_ON(config->hpd_reg_cnt > ARRAY_SIZE(hdmi->hpd_regs)); 123dada25bdSRob Clark for (i = 0; i < config->hpd_reg_cnt; i++) { 124dada25bdSRob Clark struct regulator *reg; 125dada25bdSRob Clark 126dada25bdSRob Clark reg = devm_regulator_get(&pdev->dev, config->hpd_reg_names[i]); 127dada25bdSRob Clark if (IS_ERR(reg)) { 128dada25bdSRob Clark ret = PTR_ERR(reg); 129dada25bdSRob Clark dev_err(dev->dev, "failed to get hpd regulator: %s (%d)\n", 130dada25bdSRob Clark config->hpd_reg_names[i], ret); 131c8afe684SRob Clark goto fail; 132c8afe684SRob Clark } 133c8afe684SRob Clark 134dada25bdSRob Clark hdmi->hpd_regs[i] = reg; 135dada25bdSRob Clark } 136c8afe684SRob Clark 137dada25bdSRob Clark BUG_ON(config->pwr_reg_cnt > ARRAY_SIZE(hdmi->pwr_regs)); 138dada25bdSRob Clark for (i = 0; i < config->pwr_reg_cnt; i++) { 139dada25bdSRob Clark struct regulator *reg; 140dada25bdSRob Clark 141dada25bdSRob Clark reg = devm_regulator_get(&pdev->dev, config->pwr_reg_names[i]); 142dada25bdSRob Clark if (IS_ERR(reg)) { 143dada25bdSRob Clark ret = PTR_ERR(reg); 144dada25bdSRob Clark dev_err(dev->dev, "failed to get pwr regulator: %s (%d)\n", 145dada25bdSRob Clark config->pwr_reg_names[i], ret); 146c8afe684SRob Clark goto fail; 147c8afe684SRob Clark } 148c8afe684SRob Clark 149dada25bdSRob Clark hdmi->pwr_regs[i] = reg; 150dada25bdSRob Clark } 151dada25bdSRob Clark 152dada25bdSRob Clark BUG_ON(config->hpd_clk_cnt > ARRAY_SIZE(hdmi->hpd_clks)); 153dada25bdSRob Clark for (i = 0; i < config->hpd_clk_cnt; i++) { 154dada25bdSRob Clark struct clk *clk; 155dada25bdSRob Clark 156dada25bdSRob Clark clk = devm_clk_get(&pdev->dev, config->hpd_clk_names[i]); 157dada25bdSRob Clark if (IS_ERR(clk)) { 158dada25bdSRob Clark ret = PTR_ERR(clk); 159dada25bdSRob Clark dev_err(dev->dev, "failed to get hpd clk: %s (%d)\n", 160dada25bdSRob Clark config->hpd_clk_names[i], ret); 161c8afe684SRob Clark goto fail; 162c8afe684SRob Clark } 163c8afe684SRob Clark 164dada25bdSRob Clark hdmi->hpd_clks[i] = clk; 165dada25bdSRob Clark } 166dada25bdSRob Clark 167dada25bdSRob Clark BUG_ON(config->pwr_clk_cnt > ARRAY_SIZE(hdmi->pwr_clks)); 168dada25bdSRob Clark for (i = 0; i < config->pwr_clk_cnt; i++) { 169dada25bdSRob Clark struct clk *clk; 170dada25bdSRob Clark 171dada25bdSRob Clark clk = devm_clk_get(&pdev->dev, config->pwr_clk_names[i]); 172dada25bdSRob Clark if (IS_ERR(clk)) { 173dada25bdSRob Clark ret = PTR_ERR(clk); 174dada25bdSRob Clark dev_err(dev->dev, "failed to get pwr clk: %s (%d)\n", 175dada25bdSRob Clark config->pwr_clk_names[i], ret); 176c8afe684SRob Clark goto fail; 177c8afe684SRob Clark } 178c8afe684SRob Clark 179dada25bdSRob Clark hdmi->pwr_clks[i] = clk; 180dada25bdSRob Clark } 181dada25bdSRob Clark 182c8afe684SRob Clark hdmi->i2c = hdmi_i2c_init(hdmi); 183c8afe684SRob Clark if (IS_ERR(hdmi->i2c)) { 184c8afe684SRob Clark ret = PTR_ERR(hdmi->i2c); 185c8afe684SRob Clark dev_err(dev->dev, "failed to get i2c: %d\n", ret); 186c8afe684SRob Clark hdmi->i2c = NULL; 187c8afe684SRob Clark goto fail; 188c8afe684SRob Clark } 189c8afe684SRob Clark 190a3376e3eSRob Clark hdmi->bridge = hdmi_bridge_init(hdmi); 191a3376e3eSRob Clark if (IS_ERR(hdmi->bridge)) { 192a3376e3eSRob Clark ret = PTR_ERR(hdmi->bridge); 193a3376e3eSRob Clark dev_err(dev->dev, "failed to create HDMI bridge: %d\n", ret); 194a3376e3eSRob Clark hdmi->bridge = NULL; 195a3376e3eSRob Clark goto fail; 196a3376e3eSRob Clark } 197a3376e3eSRob Clark 198a3376e3eSRob Clark hdmi->connector = hdmi_connector_init(hdmi); 199a3376e3eSRob Clark if (IS_ERR(hdmi->connector)) { 200a3376e3eSRob Clark ret = PTR_ERR(hdmi->connector); 201a3376e3eSRob Clark dev_err(dev->dev, "failed to create HDMI connector: %d\n", ret); 202a3376e3eSRob Clark hdmi->connector = NULL; 203a3376e3eSRob Clark goto fail; 204a3376e3eSRob Clark } 205a3376e3eSRob Clark 206dada25bdSRob Clark if (!config->shared_irq) { 207c8afe684SRob Clark hdmi->irq = platform_get_irq(pdev, 0); 208c8afe684SRob Clark if (hdmi->irq < 0) { 209c8afe684SRob Clark ret = hdmi->irq; 210c8afe684SRob Clark dev_err(dev->dev, "failed to get irq: %d\n", ret); 211c8afe684SRob Clark goto fail; 212c8afe684SRob Clark } 213c8afe684SRob Clark 214c8afe684SRob Clark ret = devm_request_threaded_irq(&pdev->dev, hdmi->irq, 215c8afe684SRob Clark NULL, hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 216c8afe684SRob Clark "hdmi_isr", hdmi); 217c8afe684SRob Clark if (ret < 0) { 218c8afe684SRob Clark dev_err(dev->dev, "failed to request IRQ%u: %d\n", 219c8afe684SRob Clark hdmi->irq, ret); 220c8afe684SRob Clark goto fail; 221c8afe684SRob Clark } 222dada25bdSRob Clark } 223c8afe684SRob Clark 224a3376e3eSRob Clark encoder->bridge = hdmi->bridge; 225a3376e3eSRob Clark 226a3376e3eSRob Clark priv->bridges[priv->num_bridges++] = hdmi->bridge; 227a3376e3eSRob Clark priv->connectors[priv->num_connectors++] = hdmi->connector; 228a3376e3eSRob Clark 229c0c0d9eeSRob Clark platform_set_drvdata(pdev, hdmi); 230c0c0d9eeSRob Clark 231dada25bdSRob Clark return hdmi; 232c8afe684SRob Clark 233c8afe684SRob Clark fail: 234a3376e3eSRob Clark if (hdmi) { 235a3376e3eSRob Clark /* bridge/connector are normally destroyed by drm: */ 236a3376e3eSRob Clark if (hdmi->bridge) 237a3376e3eSRob Clark hdmi->bridge->funcs->destroy(hdmi->bridge); 238a3376e3eSRob Clark if (hdmi->connector) 239a3376e3eSRob Clark hdmi->connector->funcs->destroy(hdmi->connector); 240a3376e3eSRob Clark hdmi_destroy(&hdmi->refcount); 241a3376e3eSRob Clark } 242c8afe684SRob Clark 243dada25bdSRob Clark return ERR_PTR(ret); 244c8afe684SRob Clark } 245c8afe684SRob Clark 246c8afe684SRob Clark /* 247c8afe684SRob Clark * The hdmi device: 248c8afe684SRob Clark */ 249c8afe684SRob Clark 250dada25bdSRob Clark #include <linux/of_gpio.h> 251dada25bdSRob Clark 252060530f1SRob Clark static void set_hdmi_pdev(struct drm_device *dev, 253060530f1SRob Clark struct platform_device *pdev) 254060530f1SRob Clark { 255060530f1SRob Clark struct msm_drm_private *priv = dev->dev_private; 256060530f1SRob Clark priv->hdmi_pdev = pdev; 257060530f1SRob Clark } 258060530f1SRob Clark 259060530f1SRob Clark static int hdmi_bind(struct device *dev, struct device *master, void *data) 260c8afe684SRob Clark { 261c8afe684SRob Clark static struct hdmi_platform_config config = {}; 262c8afe684SRob Clark #ifdef CONFIG_OF 263060530f1SRob Clark struct device_node *of_node = dev->of_node; 264dada25bdSRob Clark 265dada25bdSRob Clark int get_gpio(const char *name) 266dada25bdSRob Clark { 267dada25bdSRob Clark int gpio = of_get_named_gpio(of_node, name, 0); 268dada25bdSRob Clark if (gpio < 0) { 269060530f1SRob Clark dev_err(dev, "failed to get gpio: %s (%d)\n", 270dada25bdSRob Clark name, gpio); 271dada25bdSRob Clark gpio = -1; 272dada25bdSRob Clark } 273dada25bdSRob Clark return gpio; 274dada25bdSRob Clark } 275dada25bdSRob Clark 276dada25bdSRob Clark /* TODO actually use DT.. */ 277dada25bdSRob Clark static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; 278dada25bdSRob Clark static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; 279dada25bdSRob Clark static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; 280b77f47e7SStephane Viau static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; 281dada25bdSRob Clark static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; 282dada25bdSRob Clark 283dada25bdSRob Clark config.phy_init = hdmi_phy_8x74_init; 284dada25bdSRob Clark config.mmio_name = "core_physical"; 285dada25bdSRob Clark config.hpd_reg_names = hpd_reg_names; 286dada25bdSRob Clark config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); 287dada25bdSRob Clark config.pwr_reg_names = pwr_reg_names; 288dada25bdSRob Clark config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); 289dada25bdSRob Clark config.hpd_clk_names = hpd_clk_names; 290b77f47e7SStephane Viau config.hpd_freq = hpd_clk_freq; 291dada25bdSRob Clark config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); 292dada25bdSRob Clark config.pwr_clk_names = pwr_clk_names; 293dada25bdSRob Clark config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); 294dada25bdSRob Clark config.ddc_clk_gpio = get_gpio("qcom,hdmi-tx-ddc-clk"); 295dada25bdSRob Clark config.ddc_data_gpio = get_gpio("qcom,hdmi-tx-ddc-data"); 296dada25bdSRob Clark config.hpd_gpio = get_gpio("qcom,hdmi-tx-hpd"); 297dada25bdSRob Clark config.mux_en_gpio = get_gpio("qcom,hdmi-tx-mux-en"); 298dada25bdSRob Clark config.mux_sel_gpio = get_gpio("qcom,hdmi-tx-mux-sel"); 299dada25bdSRob Clark config.shared_irq = true; 300dada25bdSRob Clark 301c8afe684SRob Clark #else 302dada25bdSRob Clark static const char *hpd_clk_names[] = { 303dada25bdSRob Clark "core_clk", "master_iface_clk", "slave_iface_clk", 304dada25bdSRob Clark }; 305c8afe684SRob Clark if (cpu_is_apq8064()) { 306dada25bdSRob Clark static const char *hpd_reg_names[] = {"8921_hdmi_mvs"}; 307c8afe684SRob Clark config.phy_init = hdmi_phy_8960_init; 308dada25bdSRob Clark config.mmio_name = "hdmi_msm_hdmi_addr"; 309dada25bdSRob Clark config.hpd_reg_names = hpd_reg_names; 310dada25bdSRob Clark config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); 311dada25bdSRob Clark config.hpd_clk_names = hpd_clk_names; 312dada25bdSRob Clark config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); 313c8afe684SRob Clark config.ddc_clk_gpio = 70; 314c8afe684SRob Clark config.ddc_data_gpio = 71; 315c8afe684SRob Clark config.hpd_gpio = 72; 316dada25bdSRob Clark config.mux_en_gpio = -1; 317c0c0d9eeSRob Clark config.mux_sel_gpio = -1; 318e529c7e6SRob Clark } else if (cpu_is_msm8960() || cpu_is_msm8960ab()) { 319dada25bdSRob Clark static const char *hpd_reg_names[] = {"8921_hdmi_mvs"}; 320c8afe684SRob Clark config.phy_init = hdmi_phy_8960_init; 321dada25bdSRob Clark config.mmio_name = "hdmi_msm_hdmi_addr"; 322dada25bdSRob Clark config.hpd_reg_names = hpd_reg_names; 323dada25bdSRob Clark config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); 324dada25bdSRob Clark config.hpd_clk_names = hpd_clk_names; 325dada25bdSRob Clark config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); 326c8afe684SRob Clark config.ddc_clk_gpio = 100; 327c8afe684SRob Clark config.ddc_data_gpio = 101; 328c8afe684SRob Clark config.hpd_gpio = 102; 329dada25bdSRob Clark config.mux_en_gpio = -1; 330dada25bdSRob Clark config.mux_sel_gpio = -1; 331c8afe684SRob Clark } else if (cpu_is_msm8x60()) { 332dada25bdSRob Clark static const char *hpd_reg_names[] = { 333dada25bdSRob Clark "8901_hdmi_mvs", "8901_mpp0" 334dada25bdSRob Clark }; 335c8afe684SRob Clark config.phy_init = hdmi_phy_8x60_init; 336dada25bdSRob Clark config.mmio_name = "hdmi_msm_hdmi_addr"; 337dada25bdSRob Clark config.hpd_reg_names = hpd_reg_names; 338dada25bdSRob Clark config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); 339dada25bdSRob Clark config.hpd_clk_names = hpd_clk_names; 340dada25bdSRob Clark config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); 341c8afe684SRob Clark config.ddc_clk_gpio = 170; 342c8afe684SRob Clark config.ddc_data_gpio = 171; 343c8afe684SRob Clark config.hpd_gpio = 172; 344dada25bdSRob Clark config.mux_en_gpio = -1; 345dada25bdSRob Clark config.mux_sel_gpio = -1; 346c8afe684SRob Clark } 347c8afe684SRob Clark #endif 348060530f1SRob Clark dev->platform_data = &config; 349060530f1SRob Clark set_hdmi_pdev(dev_get_drvdata(master), to_platform_device(dev)); 350c8afe684SRob Clark return 0; 351c8afe684SRob Clark } 352c8afe684SRob Clark 353060530f1SRob Clark static void hdmi_unbind(struct device *dev, struct device *master, 354060530f1SRob Clark void *data) 355060530f1SRob Clark { 356060530f1SRob Clark set_hdmi_pdev(dev_get_drvdata(master), NULL); 357060530f1SRob Clark } 358060530f1SRob Clark 359060530f1SRob Clark static const struct component_ops hdmi_ops = { 360060530f1SRob Clark .bind = hdmi_bind, 361060530f1SRob Clark .unbind = hdmi_unbind, 362060530f1SRob Clark }; 363060530f1SRob Clark 364060530f1SRob Clark static int hdmi_dev_probe(struct platform_device *pdev) 365060530f1SRob Clark { 366060530f1SRob Clark return component_add(&pdev->dev, &hdmi_ops); 367060530f1SRob Clark } 368060530f1SRob Clark 369c8afe684SRob Clark static int hdmi_dev_remove(struct platform_device *pdev) 370c8afe684SRob Clark { 371060530f1SRob Clark component_del(&pdev->dev, &hdmi_ops); 372c8afe684SRob Clark return 0; 373c8afe684SRob Clark } 374c8afe684SRob Clark 375dada25bdSRob Clark static const struct of_device_id dt_match[] = { 376dada25bdSRob Clark { .compatible = "qcom,hdmi-tx" }, 377dada25bdSRob Clark {} 378dada25bdSRob Clark }; 379dada25bdSRob Clark 380c8afe684SRob Clark static struct platform_driver hdmi_driver = { 381c8afe684SRob Clark .probe = hdmi_dev_probe, 382c8afe684SRob Clark .remove = hdmi_dev_remove, 383dada25bdSRob Clark .driver = { 384dada25bdSRob Clark .name = "hdmi_msm", 385dada25bdSRob Clark .of_match_table = dt_match, 386dada25bdSRob Clark }, 387c8afe684SRob Clark }; 388c8afe684SRob Clark 389c8afe684SRob Clark void __init hdmi_register(void) 390c8afe684SRob Clark { 391c8afe684SRob Clark platform_driver_register(&hdmi_driver); 392c8afe684SRob Clark } 393c8afe684SRob Clark 394c8afe684SRob Clark void __exit hdmi_unregister(void) 395c8afe684SRob Clark { 396c8afe684SRob Clark platform_driver_unregister(&hdmi_driver); 397c8afe684SRob Clark } 398