linux/drivers/gpu/drm/bridge/lontium-lt8912b.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
   4 */
   5
   6#include <linux/device.h>
   7#include <linux/delay.h>
   8#include <linux/gpio/consumer.h>
   9#include <linux/i2c.h>
  10#include <linux/regmap.h>
  11
  12#include <drm/drm_probe_helper.h>
  13#include <drm/drm_atomic_helper.h>
  14#include <drm/drm_mipi_dsi.h>
  15#include <drm/drm_of.h>
  16
  17#include <video/videomode.h>
  18
  19#define I2C_MAIN 0
  20#define I2C_ADDR_MAIN 0x48
  21
  22#define I2C_CEC_DSI 1
  23#define I2C_ADDR_CEC_DSI 0x49
  24
  25#define I2C_MAX_IDX 2
  26
  27struct lt8912 {
  28        struct device *dev;
  29        struct drm_bridge bridge;
  30        struct drm_connector connector;
  31
  32        struct i2c_client *i2c_client[I2C_MAX_IDX];
  33        struct regmap *regmap[I2C_MAX_IDX];
  34
  35        struct device_node *host_node;
  36        struct drm_bridge *hdmi_port;
  37
  38        struct mipi_dsi_device *dsi;
  39
  40        struct gpio_desc *gp_reset;
  41
  42        struct videomode mode;
  43
  44        u8 data_lanes;
  45        bool is_power_on;
  46        bool is_attached;
  47};
  48
  49static int lt8912_write_init_config(struct lt8912 *lt)
  50{
  51        const struct reg_sequence seq[] = {
  52                /* Digital clock en*/
  53                {0x08, 0xff},
  54                {0x09, 0xff},
  55                {0x0a, 0xff},
  56                {0x0b, 0x7c},
  57                {0x0c, 0xff},
  58                {0x42, 0x04},
  59
  60                /*Tx Analog*/
  61                {0x31, 0xb1},
  62                {0x32, 0xb1},
  63                {0x33, 0x0e},
  64                {0x37, 0x00},
  65                {0x38, 0x22},
  66                {0x60, 0x82},
  67
  68                /*Cbus Analog*/
  69                {0x39, 0x45},
  70                {0x3a, 0x00},
  71                {0x3b, 0x00},
  72
  73                /*HDMI Pll Analog*/
  74                {0x44, 0x31},
  75                {0x55, 0x44},
  76                {0x57, 0x01},
  77                {0x5a, 0x02},
  78
  79                /*MIPI Analog*/
  80                {0x3e, 0xd6},
  81                {0x3f, 0xd4},
  82                {0x41, 0x3c},
  83                {0xB2, 0x00},
  84        };
  85
  86        return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
  87}
  88
  89static int lt8912_write_mipi_basic_config(struct lt8912 *lt)
  90{
  91        const struct reg_sequence seq[] = {
  92                {0x12, 0x04},
  93                {0x14, 0x00},
  94                {0x15, 0x00},
  95                {0x1a, 0x03},
  96                {0x1b, 0x03},
  97        };
  98
  99        return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
 100};
 101
 102static int lt8912_write_dds_config(struct lt8912 *lt)
 103{
 104        const struct reg_sequence seq[] = {
 105                {0x4e, 0xff},
 106                {0x4f, 0x56},
 107                {0x50, 0x69},
 108                {0x51, 0x80},
 109                {0x1f, 0x5e},
 110                {0x20, 0x01},
 111                {0x21, 0x2c},
 112                {0x22, 0x01},
 113                {0x23, 0xfa},
 114                {0x24, 0x00},
 115                {0x25, 0xc8},
 116                {0x26, 0x00},
 117                {0x27, 0x5e},
 118                {0x28, 0x01},
 119                {0x29, 0x2c},
 120                {0x2a, 0x01},
 121                {0x2b, 0xfa},
 122                {0x2c, 0x00},
 123                {0x2d, 0xc8},
 124                {0x2e, 0x00},
 125                {0x42, 0x64},
 126                {0x43, 0x00},
 127                {0x44, 0x04},
 128                {0x45, 0x00},
 129                {0x46, 0x59},
 130                {0x47, 0x00},
 131                {0x48, 0xf2},
 132                {0x49, 0x06},
 133                {0x4a, 0x00},
 134                {0x4b, 0x72},
 135                {0x4c, 0x45},
 136                {0x4d, 0x00},
 137                {0x52, 0x08},
 138                {0x53, 0x00},
 139                {0x54, 0xb2},
 140                {0x55, 0x00},
 141                {0x56, 0xe4},
 142                {0x57, 0x0d},
 143                {0x58, 0x00},
 144                {0x59, 0xe4},
 145                {0x5a, 0x8a},
 146                {0x5b, 0x00},
 147                {0x5c, 0x34},
 148                {0x1e, 0x4f},
 149                {0x51, 0x00},
 150        };
 151
 152        return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
 153}
 154
 155static int lt8912_write_rxlogicres_config(struct lt8912 *lt)
 156{
 157        int ret;
 158
 159        ret = regmap_write(lt->regmap[I2C_MAIN], 0x03, 0x7f);
 160        usleep_range(10000, 20000);
 161        ret |= regmap_write(lt->regmap[I2C_MAIN], 0x03, 0xff);
 162
 163        return ret;
 164};
 165
 166static int lt8912_write_lvds_config(struct lt8912 *lt)
 167{
 168        const struct reg_sequence seq[] = {
 169                {0x44, 0x30},
 170                {0x51, 0x05},
 171                {0x50, 0x24},
 172                {0x51, 0x2d},
 173                {0x52, 0x04},
 174                {0x69, 0x0e},
 175                {0x69, 0x8e},
 176                {0x6a, 0x00},
 177                {0x6c, 0xb8},
 178                {0x6b, 0x51},
 179                {0x04, 0xfb},
 180                {0x04, 0xff},
 181                {0x7f, 0x00},
 182                {0xa8, 0x13},
 183                {0x02, 0xf7},
 184                {0x02, 0xff},
 185                {0x03, 0xcf},
 186                {0x03, 0xff},
 187        };
 188
 189        return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
 190};
 191
 192static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b)
 193{
 194        return container_of(b, struct lt8912, bridge);
 195}
 196
 197static inline struct lt8912 *connector_to_lt8912(struct drm_connector *c)
 198{
 199        return container_of(c, struct lt8912, connector);
 200}
 201
 202static const struct regmap_config lt8912_regmap_config = {
 203        .reg_bits = 8,
 204        .val_bits = 8,
 205        .max_register = 0xff,
 206};
 207
 208static int lt8912_init_i2c(struct lt8912 *lt, struct i2c_client *client)
 209{
 210        unsigned int i;
 211        /*
 212         * At this time we only initialize 2 chips, but the lt8912 provides
 213         * a third interface for the audio over HDMI configuration.
 214         */
 215        struct i2c_board_info info[] = {
 216                { I2C_BOARD_INFO("lt8912p0", I2C_ADDR_MAIN), },
 217                { I2C_BOARD_INFO("lt8912p1", I2C_ADDR_CEC_DSI), },
 218        };
 219
 220        if (!lt)
 221                return -ENODEV;
 222
 223        for (i = 0; i < ARRAY_SIZE(info); i++) {
 224                if (i > 0) {
 225                        lt->i2c_client[i] = i2c_new_dummy_device(client->adapter,
 226                                                                 info[i].addr);
 227                        if (IS_ERR(lt->i2c_client[i]))
 228                                return PTR_ERR(lt->i2c_client[i]);
 229                }
 230
 231                lt->regmap[i] = devm_regmap_init_i2c(lt->i2c_client[i],
 232                                                     &lt8912_regmap_config);
 233                if (IS_ERR(lt->regmap[i]))
 234                        return PTR_ERR(lt->regmap[i]);
 235        }
 236        return 0;
 237}
 238
 239static int lt8912_free_i2c(struct lt8912 *lt)
 240{
 241        unsigned int i;
 242
 243        for (i = 1; i < I2C_MAX_IDX; i++)
 244                i2c_unregister_device(lt->i2c_client[i]);
 245
 246        return 0;
 247}
 248
 249static int lt8912_hard_power_on(struct lt8912 *lt)
 250{
 251        gpiod_set_value_cansleep(lt->gp_reset, 0);
 252        msleep(20);
 253
 254        return 0;
 255}
 256
 257static void lt8912_hard_power_off(struct lt8912 *lt)
 258{
 259        gpiod_set_value_cansleep(lt->gp_reset, 1);
 260        msleep(20);
 261        lt->is_power_on = false;
 262}
 263
 264static int lt8912_video_setup(struct lt8912 *lt)
 265{
 266        u32 hactive, h_total, hpw, hfp, hbp;
 267        u32 vactive, v_total, vpw, vfp, vbp;
 268        u8 settle = 0x08;
 269        int ret;
 270
 271        if (!lt)
 272                return -EINVAL;
 273
 274        hactive = lt->mode.hactive;
 275        hfp = lt->mode.hfront_porch;
 276        hpw = lt->mode.hsync_len;
 277        hbp = lt->mode.hback_porch;
 278        h_total = hactive + hfp + hpw + hbp;
 279
 280        vactive = lt->mode.vactive;
 281        vfp = lt->mode.vfront_porch;
 282        vpw = lt->mode.vsync_len;
 283        vbp = lt->mode.vback_porch;
 284        v_total = vactive + vfp + vpw + vbp;
 285
 286        if (vactive <= 600)
 287                settle = 0x04;
 288        else if (vactive == 1080)
 289                settle = 0x0a;
 290
 291        ret = regmap_write(lt->regmap[I2C_CEC_DSI], 0x10, 0x01);
 292        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x11, settle);
 293        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x18, hpw);
 294        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x19, vpw);
 295        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1c, hactive & 0xff);
 296        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1d, hactive >> 8);
 297
 298        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x2f, 0x0c);
 299
 300        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x34, h_total & 0xff);
 301        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x35, h_total >> 8);
 302
 303        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x36, v_total & 0xff);
 304        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x37, v_total >> 8);
 305
 306        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x38, vbp & 0xff);
 307        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x39, vbp >> 8);
 308
 309        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3a, vfp & 0xff);
 310        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3b, vfp >> 8);
 311
 312        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3c, hbp & 0xff);
 313        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3d, hbp >> 8);
 314
 315        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff);
 316        ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8);
 317
 318        return ret;
 319}
 320
 321static int lt8912_soft_power_on(struct lt8912 *lt)
 322{
 323        if (!lt->is_power_on) {
 324                u32 lanes = lt->data_lanes;
 325
 326                lt8912_write_init_config(lt);
 327                regmap_write(lt->regmap[I2C_CEC_DSI], 0x13, lanes & 3);
 328
 329                lt8912_write_mipi_basic_config(lt);
 330
 331                lt->is_power_on = true;
 332        }
 333
 334        return 0;
 335}
 336
 337static int lt8912_video_on(struct lt8912 *lt)
 338{
 339        int ret;
 340
 341        ret = lt8912_video_setup(lt);
 342        if (ret < 0)
 343                goto end;
 344
 345        ret = lt8912_write_dds_config(lt);
 346        if (ret < 0)
 347                goto end;
 348
 349        ret = lt8912_write_rxlogicres_config(lt);
 350        if (ret < 0)
 351                goto end;
 352
 353        ret = lt8912_write_lvds_config(lt);
 354        if (ret < 0)
 355                goto end;
 356
 357end:
 358        return ret;
 359}
 360
 361static enum drm_connector_status lt8912_check_cable_status(struct lt8912 *lt)
 362{
 363        int ret;
 364        unsigned int reg_val;
 365
 366        ret = regmap_read(lt->regmap[I2C_MAIN], 0xC1, &reg_val);
 367        if (ret)
 368                return connector_status_unknown;
 369
 370        if (reg_val & BIT(7))
 371                return connector_status_connected;
 372
 373        return connector_status_disconnected;
 374}
 375
 376static enum drm_connector_status
 377lt8912_connector_detect(struct drm_connector *connector, bool force)
 378{
 379        struct lt8912 *lt = connector_to_lt8912(connector);
 380
 381        if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
 382                return drm_bridge_detect(lt->hdmi_port);
 383
 384        return lt8912_check_cable_status(lt);
 385}
 386
 387static const struct drm_connector_funcs lt8912_connector_funcs = {
 388        .detect = lt8912_connector_detect,
 389        .fill_modes = drm_helper_probe_single_connector_modes,
 390        .destroy = drm_connector_cleanup,
 391        .reset = drm_atomic_helper_connector_reset,
 392        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 393        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 394};
 395
 396static enum drm_mode_status
 397lt8912_connector_mode_valid(struct drm_connector *connector,
 398                            struct drm_display_mode *mode)
 399{
 400        if (mode->clock > 150000)
 401                return MODE_CLOCK_HIGH;
 402
 403        if (mode->hdisplay > 1920)
 404                return MODE_BAD_HVALUE;
 405
 406        if (mode->vdisplay > 1080)
 407                return MODE_BAD_VVALUE;
 408
 409        return MODE_OK;
 410}
 411
 412static int lt8912_connector_get_modes(struct drm_connector *connector)
 413{
 414        struct edid *edid;
 415        int ret = -1;
 416        int num = 0;
 417        struct lt8912 *lt = connector_to_lt8912(connector);
 418        u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 419
 420        edid = drm_bridge_get_edid(lt->hdmi_port, connector);
 421        if (edid) {
 422                drm_connector_update_edid_property(connector, edid);
 423                num = drm_add_edid_modes(connector, edid);
 424        } else {
 425                return ret;
 426        }
 427
 428        ret = drm_display_info_set_bus_formats(&connector->display_info,
 429                                               &bus_format, 1);
 430        if (ret)
 431                num = ret;
 432
 433        kfree(edid);
 434        return num;
 435}
 436
 437static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
 438        .get_modes = lt8912_connector_get_modes,
 439        .mode_valid = lt8912_connector_mode_valid,
 440};
 441
 442static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
 443                                   const struct drm_display_mode *mode,
 444                                   const struct drm_display_mode *adj)
 445{
 446        struct lt8912 *lt = bridge_to_lt8912(bridge);
 447
 448        drm_display_mode_to_videomode(adj, &lt->mode);
 449}
 450
 451static void lt8912_bridge_enable(struct drm_bridge *bridge)
 452{
 453        struct lt8912 *lt = bridge_to_lt8912(bridge);
 454
 455        lt8912_video_on(lt);
 456}
 457
 458static int lt8912_attach_dsi(struct lt8912 *lt)
 459{
 460        struct device *dev = lt->dev;
 461        struct mipi_dsi_host *host;
 462        struct mipi_dsi_device *dsi;
 463        int ret = -1;
 464        const struct mipi_dsi_device_info info = { .type = "lt8912",
 465                                                   .channel = 0,
 466                                                   .node = NULL,
 467                                                 };
 468
 469        host = of_find_mipi_dsi_host_by_node(lt->host_node);
 470        if (!host) {
 471                dev_err(dev, "failed to find dsi host\n");
 472                return -EPROBE_DEFER;
 473        }
 474
 475        dsi = mipi_dsi_device_register_full(host, &info);
 476        if (IS_ERR(dsi)) {
 477                ret = PTR_ERR(dsi);
 478                dev_err(dev, "failed to create dsi device (%d)\n", ret);
 479                goto err_dsi_device;
 480        }
 481
 482        lt->dsi = dsi;
 483
 484        dsi->lanes = lt->data_lanes;
 485        dsi->format = MIPI_DSI_FMT_RGB888;
 486
 487        dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
 488                          MIPI_DSI_MODE_VIDEO_BURST |
 489                          MIPI_DSI_MODE_LPM |
 490                          MIPI_DSI_MODE_NO_EOT_PACKET;
 491
 492        ret = mipi_dsi_attach(dsi);
 493        if (ret < 0) {
 494                dev_err(dev, "failed to attach dsi to host\n");
 495                goto err_dsi_attach;
 496        }
 497
 498        return 0;
 499
 500err_dsi_attach:
 501        mipi_dsi_device_unregister(dsi);
 502err_dsi_device:
 503        return ret;
 504}
 505
 506static void lt8912_detach_dsi(struct lt8912 *lt)
 507{
 508        mipi_dsi_detach(lt->dsi);
 509        mipi_dsi_device_unregister(lt->dsi);
 510}
 511
 512static int lt8912_bridge_connector_init(struct drm_bridge *bridge)
 513{
 514        int ret;
 515        struct lt8912 *lt = bridge_to_lt8912(bridge);
 516        struct drm_connector *connector = &lt->connector;
 517
 518        connector->polled = DRM_CONNECTOR_POLL_CONNECT |
 519                            DRM_CONNECTOR_POLL_DISCONNECT;
 520
 521        ret = drm_connector_init(bridge->dev, connector,
 522                                 &lt8912_connector_funcs,
 523                                 lt->hdmi_port->type);
 524        if (ret)
 525                goto exit;
 526
 527        drm_connector_helper_add(connector, &lt8912_connector_helper_funcs);
 528
 529        connector->dpms = DRM_MODE_DPMS_OFF;
 530        drm_connector_attach_encoder(connector, bridge->encoder);
 531
 532exit:
 533        return ret;
 534}
 535
 536static int lt8912_bridge_attach(struct drm_bridge *bridge,
 537                                enum drm_bridge_attach_flags flags)
 538{
 539        struct lt8912 *lt = bridge_to_lt8912(bridge);
 540        int ret;
 541
 542        if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
 543                ret = lt8912_bridge_connector_init(bridge);
 544                if (ret) {
 545                        dev_err(lt->dev, "Failed to init bridge ! (%d)\n", ret);
 546                        return ret;
 547                }
 548        }
 549
 550        ret = lt8912_hard_power_on(lt);
 551        if (ret)
 552                return ret;
 553
 554        ret = lt8912_soft_power_on(lt);
 555        if (ret)
 556                goto error;
 557
 558        ret = lt8912_attach_dsi(lt);
 559        if (ret)
 560                goto error;
 561
 562        lt->is_attached = true;
 563
 564        return 0;
 565
 566error:
 567        lt8912_hard_power_off(lt);
 568        return ret;
 569}
 570
 571static void lt8912_bridge_detach(struct drm_bridge *bridge)
 572{
 573        struct lt8912 *lt = bridge_to_lt8912(bridge);
 574
 575        if (lt->is_attached) {
 576                lt8912_detach_dsi(lt);
 577                lt8912_hard_power_off(lt);
 578                drm_connector_unregister(&lt->connector);
 579                drm_connector_cleanup(&lt->connector);
 580        }
 581}
 582
 583static enum drm_connector_status
 584lt8912_bridge_detect(struct drm_bridge *bridge)
 585{
 586        struct lt8912 *lt = bridge_to_lt8912(bridge);
 587
 588        if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
 589                return drm_bridge_detect(lt->hdmi_port);
 590
 591        return lt8912_check_cable_status(lt);
 592}
 593
 594static struct edid *lt8912_bridge_get_edid(struct drm_bridge *bridge,
 595                                           struct drm_connector *connector)
 596{
 597        struct lt8912 *lt = bridge_to_lt8912(bridge);
 598
 599        /*
 600         * edid must be read through the ddc bus but it must be
 601         * given to the hdmi connector node.
 602         */
 603        if (lt->hdmi_port->ops & DRM_BRIDGE_OP_EDID)
 604                return drm_bridge_get_edid(lt->hdmi_port, connector);
 605
 606        dev_warn(lt->dev, "The connected bridge does not supports DRM_BRIDGE_OP_EDID\n");
 607        return NULL;
 608}
 609
 610static const struct drm_bridge_funcs lt8912_bridge_funcs = {
 611        .attach = lt8912_bridge_attach,
 612        .detach = lt8912_bridge_detach,
 613        .mode_set = lt8912_bridge_mode_set,
 614        .enable = lt8912_bridge_enable,
 615        .detect = lt8912_bridge_detect,
 616        .get_edid = lt8912_bridge_get_edid,
 617};
 618
 619static int lt8912_parse_dt(struct lt8912 *lt)
 620{
 621        struct gpio_desc *gp_reset;
 622        struct device *dev = lt->dev;
 623        int ret;
 624        int data_lanes;
 625        struct device_node *port_node;
 626        struct device_node *endpoint;
 627
 628        gp_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 629        if (IS_ERR(gp_reset)) {
 630                ret = PTR_ERR(gp_reset);
 631                if (ret != -EPROBE_DEFER)
 632                        dev_err(dev, "Failed to get reset gpio: %d\n", ret);
 633                return ret;
 634        }
 635        lt->gp_reset = gp_reset;
 636
 637        endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
 638        if (!endpoint)
 639                return -ENODEV;
 640
 641        data_lanes = of_property_count_u32_elems(endpoint, "data-lanes");
 642        of_node_put(endpoint);
 643        if (data_lanes < 0) {
 644                dev_err(lt->dev, "%s: Bad data-lanes property\n", __func__);
 645                return data_lanes;
 646        }
 647        lt->data_lanes = data_lanes;
 648
 649        lt->host_node = of_graph_get_remote_node(dev->of_node, 0, -1);
 650        if (!lt->host_node) {
 651                dev_err(lt->dev, "%s: Failed to get remote port\n", __func__);
 652                return -ENODEV;
 653        }
 654
 655        port_node = of_graph_get_remote_node(dev->of_node, 1, -1);
 656        if (!port_node) {
 657                dev_err(lt->dev, "%s: Failed to get connector port\n", __func__);
 658                ret = -ENODEV;
 659                goto err_free_host_node;
 660        }
 661
 662        lt->hdmi_port = of_drm_find_bridge(port_node);
 663        if (!lt->hdmi_port) {
 664                dev_err(lt->dev, "%s: Failed to get hdmi port\n", __func__);
 665                ret = -ENODEV;
 666                goto err_free_host_node;
 667        }
 668
 669        if (!of_device_is_compatible(port_node, "hdmi-connector")) {
 670                dev_err(lt->dev, "%s: Failed to get hdmi port\n", __func__);
 671                ret = -EINVAL;
 672                goto err_free_host_node;
 673        }
 674
 675        of_node_put(port_node);
 676        return 0;
 677
 678err_free_host_node:
 679        of_node_put(port_node);
 680        of_node_put(lt->host_node);
 681        return ret;
 682}
 683
 684static int lt8912_put_dt(struct lt8912 *lt)
 685{
 686        of_node_put(lt->host_node);
 687        return 0;
 688}
 689
 690static int lt8912_probe(struct i2c_client *client,
 691                        const struct i2c_device_id *id)
 692{
 693        static struct lt8912 *lt;
 694        int ret = 0;
 695        struct device *dev = &client->dev;
 696
 697        lt = devm_kzalloc(dev, sizeof(struct lt8912), GFP_KERNEL);
 698        if (!lt)
 699                return -ENOMEM;
 700
 701        lt->dev = dev;
 702        lt->i2c_client[0] = client;
 703
 704        ret = lt8912_parse_dt(lt);
 705        if (ret)
 706                goto err_dt_parse;
 707
 708        ret = lt8912_init_i2c(lt, client);
 709        if (ret)
 710                goto err_i2c;
 711
 712        i2c_set_clientdata(client, lt);
 713
 714        lt->bridge.funcs = &lt8912_bridge_funcs;
 715        lt->bridge.of_node = dev->of_node;
 716        lt->bridge.ops = (DRM_BRIDGE_OP_EDID |
 717                          DRM_BRIDGE_OP_DETECT);
 718
 719        drm_bridge_add(&lt->bridge);
 720
 721        return 0;
 722
 723err_i2c:
 724        lt8912_put_dt(lt);
 725err_dt_parse:
 726        return ret;
 727}
 728
 729static int lt8912_remove(struct i2c_client *client)
 730{
 731        struct lt8912 *lt = i2c_get_clientdata(client);
 732
 733        lt8912_bridge_detach(&lt->bridge);
 734        drm_bridge_remove(&lt->bridge);
 735        lt8912_free_i2c(lt);
 736        lt8912_put_dt(lt);
 737        return 0;
 738}
 739
 740static const struct of_device_id lt8912_dt_match[] = {
 741        {.compatible = "lontium,lt8912b"},
 742        {}
 743};
 744MODULE_DEVICE_TABLE(of, lt8912_dt_match);
 745
 746static const struct i2c_device_id lt8912_id[] = {
 747        {"lt8912", 0},
 748        {},
 749};
 750MODULE_DEVICE_TABLE(i2c, lt8912_id);
 751
 752static struct i2c_driver lt8912_i2c_driver = {
 753        .driver = {
 754                .name = "lt8912",
 755                .of_match_table = lt8912_dt_match,
 756        },
 757        .probe = lt8912_probe,
 758        .remove = lt8912_remove,
 759        .id_table = lt8912_id,
 760};
 761module_i2c_driver(lt8912_i2c_driver);
 762
 763MODULE_AUTHOR("Adrien Grassein <adrien.grassein@gmail.com>");
 764MODULE_DESCRIPTION("lt8912 drm driver");
 765MODULE_LICENSE("GPL v2");
 766