0001
0002
0003
0004
0005
0006 #include <linux/device.h>
0007 #include <linux/delay.h>
0008 #include <linux/gpio/consumer.h>
0009 #include <linux/i2c.h>
0010 #include <linux/media-bus-format.h>
0011 #include <linux/regmap.h>
0012
0013 #include <drm/drm_probe_helper.h>
0014 #include <drm/drm_atomic_helper.h>
0015 #include <drm/drm_edid.h>
0016 #include <drm/drm_mipi_dsi.h>
0017 #include <drm/drm_of.h>
0018
0019 #include <video/videomode.h>
0020
0021 #define I2C_MAIN 0
0022 #define I2C_ADDR_MAIN 0x48
0023
0024 #define I2C_CEC_DSI 1
0025 #define I2C_ADDR_CEC_DSI 0x49
0026
0027 #define I2C_MAX_IDX 2
0028
0029 struct lt8912 {
0030 struct device *dev;
0031 struct drm_bridge bridge;
0032 struct drm_connector connector;
0033
0034 struct i2c_client *i2c_client[I2C_MAX_IDX];
0035 struct regmap *regmap[I2C_MAX_IDX];
0036
0037 struct device_node *host_node;
0038 struct drm_bridge *hdmi_port;
0039
0040 struct mipi_dsi_device *dsi;
0041
0042 struct gpio_desc *gp_reset;
0043
0044 struct videomode mode;
0045
0046 u8 data_lanes;
0047 bool is_power_on;
0048 bool is_attached;
0049 };
0050
0051 static int lt8912_write_init_config(struct lt8912 *lt)
0052 {
0053 const struct reg_sequence seq[] = {
0054
0055 {0x08, 0xff},
0056 {0x09, 0xff},
0057 {0x0a, 0xff},
0058 {0x0b, 0x7c},
0059 {0x0c, 0xff},
0060 {0x42, 0x04},
0061
0062
0063 {0x31, 0xb1},
0064 {0x32, 0xb1},
0065 {0x33, 0x0e},
0066 {0x37, 0x00},
0067 {0x38, 0x22},
0068 {0x60, 0x82},
0069
0070
0071 {0x39, 0x45},
0072 {0x3a, 0x00},
0073 {0x3b, 0x00},
0074
0075
0076 {0x44, 0x31},
0077 {0x55, 0x44},
0078 {0x57, 0x01},
0079 {0x5a, 0x02},
0080
0081
0082 {0x3e, 0xd6},
0083 {0x3f, 0xd4},
0084 {0x41, 0x3c},
0085 {0xB2, 0x00},
0086 };
0087
0088 return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
0089 }
0090
0091 static int lt8912_write_mipi_basic_config(struct lt8912 *lt)
0092 {
0093 const struct reg_sequence seq[] = {
0094 {0x12, 0x04},
0095 {0x14, 0x00},
0096 {0x15, 0x00},
0097 {0x1a, 0x03},
0098 {0x1b, 0x03},
0099 };
0100
0101 return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
0102 };
0103
0104 static int lt8912_write_dds_config(struct lt8912 *lt)
0105 {
0106 const struct reg_sequence seq[] = {
0107 {0x4e, 0xff},
0108 {0x4f, 0x56},
0109 {0x50, 0x69},
0110 {0x51, 0x80},
0111 {0x1f, 0x5e},
0112 {0x20, 0x01},
0113 {0x21, 0x2c},
0114 {0x22, 0x01},
0115 {0x23, 0xfa},
0116 {0x24, 0x00},
0117 {0x25, 0xc8},
0118 {0x26, 0x00},
0119 {0x27, 0x5e},
0120 {0x28, 0x01},
0121 {0x29, 0x2c},
0122 {0x2a, 0x01},
0123 {0x2b, 0xfa},
0124 {0x2c, 0x00},
0125 {0x2d, 0xc8},
0126 {0x2e, 0x00},
0127 {0x42, 0x64},
0128 {0x43, 0x00},
0129 {0x44, 0x04},
0130 {0x45, 0x00},
0131 {0x46, 0x59},
0132 {0x47, 0x00},
0133 {0x48, 0xf2},
0134 {0x49, 0x06},
0135 {0x4a, 0x00},
0136 {0x4b, 0x72},
0137 {0x4c, 0x45},
0138 {0x4d, 0x00},
0139 {0x52, 0x08},
0140 {0x53, 0x00},
0141 {0x54, 0xb2},
0142 {0x55, 0x00},
0143 {0x56, 0xe4},
0144 {0x57, 0x0d},
0145 {0x58, 0x00},
0146 {0x59, 0xe4},
0147 {0x5a, 0x8a},
0148 {0x5b, 0x00},
0149 {0x5c, 0x34},
0150 {0x1e, 0x4f},
0151 {0x51, 0x00},
0152 };
0153
0154 return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq));
0155 }
0156
0157 static int lt8912_write_rxlogicres_config(struct lt8912 *lt)
0158 {
0159 int ret;
0160
0161 ret = regmap_write(lt->regmap[I2C_MAIN], 0x03, 0x7f);
0162 usleep_range(10000, 20000);
0163 ret |= regmap_write(lt->regmap[I2C_MAIN], 0x03, 0xff);
0164
0165 return ret;
0166 };
0167
0168 static int lt8912_write_lvds_config(struct lt8912 *lt)
0169 {
0170 const struct reg_sequence seq[] = {
0171 {0x44, 0x30},
0172 {0x51, 0x05},
0173 {0x50, 0x24},
0174 {0x51, 0x2d},
0175 {0x52, 0x04},
0176 {0x69, 0x0e},
0177 {0x69, 0x8e},
0178 {0x6a, 0x00},
0179 {0x6c, 0xb8},
0180 {0x6b, 0x51},
0181 {0x04, 0xfb},
0182 {0x04, 0xff},
0183 {0x7f, 0x00},
0184 {0xa8, 0x13},
0185 {0x02, 0xf7},
0186 {0x02, 0xff},
0187 {0x03, 0xcf},
0188 {0x03, 0xff},
0189 };
0190
0191 return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq));
0192 };
0193
0194 static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b)
0195 {
0196 return container_of(b, struct lt8912, bridge);
0197 }
0198
0199 static inline struct lt8912 *connector_to_lt8912(struct drm_connector *c)
0200 {
0201 return container_of(c, struct lt8912, connector);
0202 }
0203
0204 static const struct regmap_config lt8912_regmap_config = {
0205 .reg_bits = 8,
0206 .val_bits = 8,
0207 .max_register = 0xff,
0208 };
0209
0210 static int lt8912_init_i2c(struct lt8912 *lt, struct i2c_client *client)
0211 {
0212 unsigned int i;
0213
0214
0215
0216
0217 struct i2c_board_info info[] = {
0218 { I2C_BOARD_INFO("lt8912p0", I2C_ADDR_MAIN), },
0219 { I2C_BOARD_INFO("lt8912p1", I2C_ADDR_CEC_DSI), },
0220 };
0221
0222 if (!lt)
0223 return -ENODEV;
0224
0225 for (i = 0; i < ARRAY_SIZE(info); i++) {
0226 if (i > 0) {
0227 lt->i2c_client[i] = i2c_new_dummy_device(client->adapter,
0228 info[i].addr);
0229 if (IS_ERR(lt->i2c_client[i]))
0230 return PTR_ERR(lt->i2c_client[i]);
0231 }
0232
0233 lt->regmap[i] = devm_regmap_init_i2c(lt->i2c_client[i],
0234 <8912_regmap_config);
0235 if (IS_ERR(lt->regmap[i]))
0236 return PTR_ERR(lt->regmap[i]);
0237 }
0238 return 0;
0239 }
0240
0241 static int lt8912_free_i2c(struct lt8912 *lt)
0242 {
0243 unsigned int i;
0244
0245 for (i = 1; i < I2C_MAX_IDX; i++)
0246 i2c_unregister_device(lt->i2c_client[i]);
0247
0248 return 0;
0249 }
0250
0251 static int lt8912_hard_power_on(struct lt8912 *lt)
0252 {
0253 gpiod_set_value_cansleep(lt->gp_reset, 0);
0254 msleep(20);
0255
0256 return 0;
0257 }
0258
0259 static void lt8912_hard_power_off(struct lt8912 *lt)
0260 {
0261 gpiod_set_value_cansleep(lt->gp_reset, 1);
0262 msleep(20);
0263 lt->is_power_on = false;
0264 }
0265
0266 static int lt8912_video_setup(struct lt8912 *lt)
0267 {
0268 u32 hactive, h_total, hpw, hfp, hbp;
0269 u32 vactive, v_total, vpw, vfp, vbp;
0270 u8 settle = 0x08;
0271 int ret, hsync_activehigh, vsync_activehigh;
0272
0273 if (!lt)
0274 return -EINVAL;
0275
0276 hactive = lt->mode.hactive;
0277 hfp = lt->mode.hfront_porch;
0278 hpw = lt->mode.hsync_len;
0279 hbp = lt->mode.hback_porch;
0280 h_total = hactive + hfp + hpw + hbp;
0281 hsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH;
0282
0283 vactive = lt->mode.vactive;
0284 vfp = lt->mode.vfront_porch;
0285 vpw = lt->mode.vsync_len;
0286 vbp = lt->mode.vback_porch;
0287 v_total = vactive + vfp + vpw + vbp;
0288 vsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH;
0289
0290 if (vactive <= 600)
0291 settle = 0x04;
0292 else if (vactive == 1080)
0293 settle = 0x0a;
0294
0295 ret = regmap_write(lt->regmap[I2C_CEC_DSI], 0x10, 0x01);
0296 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x11, settle);
0297 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x18, hpw);
0298 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x19, vpw);
0299 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1c, hactive & 0xff);
0300 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x1d, hactive >> 8);
0301
0302 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x2f, 0x0c);
0303
0304 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x34, h_total & 0xff);
0305 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x35, h_total >> 8);
0306
0307 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x36, v_total & 0xff);
0308 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x37, v_total >> 8);
0309
0310 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x38, vbp & 0xff);
0311 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x39, vbp >> 8);
0312
0313 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3a, vfp & 0xff);
0314 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3b, vfp >> 8);
0315
0316 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3c, hbp & 0xff);
0317 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3d, hbp >> 8);
0318
0319 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff);
0320 ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8);
0321
0322 ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(0),
0323 vsync_activehigh ? BIT(0) : 0);
0324 ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1),
0325 hsync_activehigh ? BIT(1) : 0);
0326 ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xb2, BIT(0),
0327 lt->connector.display_info.is_hdmi ? BIT(0) : 0);
0328
0329 return ret;
0330 }
0331
0332 static int lt8912_soft_power_on(struct lt8912 *lt)
0333 {
0334 if (!lt->is_power_on) {
0335 u32 lanes = lt->data_lanes;
0336
0337 lt8912_write_init_config(lt);
0338 regmap_write(lt->regmap[I2C_CEC_DSI], 0x13, lanes & 3);
0339
0340 lt8912_write_mipi_basic_config(lt);
0341
0342 lt->is_power_on = true;
0343 }
0344
0345 return 0;
0346 }
0347
0348 static int lt8912_video_on(struct lt8912 *lt)
0349 {
0350 int ret;
0351
0352 ret = lt8912_video_setup(lt);
0353 if (ret < 0)
0354 goto end;
0355
0356 ret = lt8912_write_dds_config(lt);
0357 if (ret < 0)
0358 goto end;
0359
0360 ret = lt8912_write_rxlogicres_config(lt);
0361 if (ret < 0)
0362 goto end;
0363
0364 ret = lt8912_write_lvds_config(lt);
0365 if (ret < 0)
0366 goto end;
0367
0368 end:
0369 return ret;
0370 }
0371
0372 static enum drm_connector_status lt8912_check_cable_status(struct lt8912 *lt)
0373 {
0374 int ret;
0375 unsigned int reg_val;
0376
0377 ret = regmap_read(lt->regmap[I2C_MAIN], 0xC1, ®_val);
0378 if (ret)
0379 return connector_status_unknown;
0380
0381 if (reg_val & BIT(7))
0382 return connector_status_connected;
0383
0384 return connector_status_disconnected;
0385 }
0386
0387 static enum drm_connector_status
0388 lt8912_connector_detect(struct drm_connector *connector, bool force)
0389 {
0390 struct lt8912 *lt = connector_to_lt8912(connector);
0391
0392 if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
0393 return drm_bridge_detect(lt->hdmi_port);
0394
0395 return lt8912_check_cable_status(lt);
0396 }
0397
0398 static const struct drm_connector_funcs lt8912_connector_funcs = {
0399 .detect = lt8912_connector_detect,
0400 .fill_modes = drm_helper_probe_single_connector_modes,
0401 .destroy = drm_connector_cleanup,
0402 .reset = drm_atomic_helper_connector_reset,
0403 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0404 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0405 };
0406
0407 static enum drm_mode_status
0408 lt8912_connector_mode_valid(struct drm_connector *connector,
0409 struct drm_display_mode *mode)
0410 {
0411 if (mode->clock > 150000)
0412 return MODE_CLOCK_HIGH;
0413
0414 if (mode->hdisplay > 1920)
0415 return MODE_BAD_HVALUE;
0416
0417 if (mode->vdisplay > 1080)
0418 return MODE_BAD_VVALUE;
0419
0420 return MODE_OK;
0421 }
0422
0423 static int lt8912_connector_get_modes(struct drm_connector *connector)
0424 {
0425 struct edid *edid;
0426 int ret = -1;
0427 int num = 0;
0428 struct lt8912 *lt = connector_to_lt8912(connector);
0429 u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
0430
0431 edid = drm_bridge_get_edid(lt->hdmi_port, connector);
0432 if (edid) {
0433 drm_connector_update_edid_property(connector, edid);
0434 num = drm_add_edid_modes(connector, edid);
0435 } else {
0436 return ret;
0437 }
0438
0439 ret = drm_display_info_set_bus_formats(&connector->display_info,
0440 &bus_format, 1);
0441 if (ret)
0442 num = ret;
0443
0444 kfree(edid);
0445 return num;
0446 }
0447
0448 static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
0449 .get_modes = lt8912_connector_get_modes,
0450 .mode_valid = lt8912_connector_mode_valid,
0451 };
0452
0453 static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
0454 const struct drm_display_mode *mode,
0455 const struct drm_display_mode *adj)
0456 {
0457 struct lt8912 *lt = bridge_to_lt8912(bridge);
0458
0459 drm_display_mode_to_videomode(adj, <->mode);
0460 }
0461
0462 static void lt8912_bridge_enable(struct drm_bridge *bridge)
0463 {
0464 struct lt8912 *lt = bridge_to_lt8912(bridge);
0465
0466 lt8912_video_on(lt);
0467 }
0468
0469 static int lt8912_attach_dsi(struct lt8912 *lt)
0470 {
0471 struct device *dev = lt->dev;
0472 struct mipi_dsi_host *host;
0473 struct mipi_dsi_device *dsi;
0474 int ret = -1;
0475 const struct mipi_dsi_device_info info = { .type = "lt8912",
0476 .channel = 0,
0477 .node = NULL,
0478 };
0479
0480 host = of_find_mipi_dsi_host_by_node(lt->host_node);
0481 if (!host) {
0482 dev_err(dev, "failed to find dsi host\n");
0483 return -EPROBE_DEFER;
0484 }
0485
0486 dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
0487 if (IS_ERR(dsi)) {
0488 ret = PTR_ERR(dsi);
0489 dev_err(dev, "failed to create dsi device (%d)\n", ret);
0490 return ret;
0491 }
0492
0493 lt->dsi = dsi;
0494
0495 dsi->lanes = lt->data_lanes;
0496 dsi->format = MIPI_DSI_FMT_RGB888;
0497
0498 dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
0499 MIPI_DSI_MODE_VIDEO_BURST |
0500 MIPI_DSI_MODE_LPM |
0501 MIPI_DSI_MODE_NO_EOT_PACKET;
0502
0503 ret = devm_mipi_dsi_attach(dev, dsi);
0504 if (ret < 0) {
0505 dev_err(dev, "failed to attach dsi to host\n");
0506 return ret;
0507 }
0508
0509 return 0;
0510 }
0511
0512 static int lt8912_bridge_connector_init(struct drm_bridge *bridge)
0513 {
0514 int ret;
0515 struct lt8912 *lt = bridge_to_lt8912(bridge);
0516 struct drm_connector *connector = <->connector;
0517
0518 connector->polled = DRM_CONNECTOR_POLL_CONNECT |
0519 DRM_CONNECTOR_POLL_DISCONNECT;
0520
0521 ret = drm_connector_init(bridge->dev, connector,
0522 <8912_connector_funcs,
0523 lt->hdmi_port->type);
0524 if (ret)
0525 goto exit;
0526
0527 drm_connector_helper_add(connector, <8912_connector_helper_funcs);
0528
0529 connector->dpms = DRM_MODE_DPMS_OFF;
0530 drm_connector_attach_encoder(connector, bridge->encoder);
0531
0532 exit:
0533 return ret;
0534 }
0535
0536 static int lt8912_bridge_attach(struct drm_bridge *bridge,
0537 enum drm_bridge_attach_flags flags)
0538 {
0539 struct lt8912 *lt = bridge_to_lt8912(bridge);
0540 int ret;
0541
0542 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
0543 ret = lt8912_bridge_connector_init(bridge);
0544 if (ret) {
0545 dev_err(lt->dev, "Failed to init bridge ! (%d)\n", ret);
0546 return ret;
0547 }
0548 }
0549
0550 ret = lt8912_hard_power_on(lt);
0551 if (ret)
0552 return ret;
0553
0554 ret = lt8912_soft_power_on(lt);
0555 if (ret)
0556 goto error;
0557
0558 lt->is_attached = true;
0559
0560 return 0;
0561
0562 error:
0563 lt8912_hard_power_off(lt);
0564 return ret;
0565 }
0566
0567 static void lt8912_bridge_detach(struct drm_bridge *bridge)
0568 {
0569 struct lt8912 *lt = bridge_to_lt8912(bridge);
0570
0571 if (lt->is_attached) {
0572 lt8912_hard_power_off(lt);
0573 drm_connector_unregister(<->connector);
0574 drm_connector_cleanup(<->connector);
0575 }
0576 }
0577
0578 static enum drm_connector_status
0579 lt8912_bridge_detect(struct drm_bridge *bridge)
0580 {
0581 struct lt8912 *lt = bridge_to_lt8912(bridge);
0582
0583 if (lt->hdmi_port->ops & DRM_BRIDGE_OP_DETECT)
0584 return drm_bridge_detect(lt->hdmi_port);
0585
0586 return lt8912_check_cable_status(lt);
0587 }
0588
0589 static struct edid *lt8912_bridge_get_edid(struct drm_bridge *bridge,
0590 struct drm_connector *connector)
0591 {
0592 struct lt8912 *lt = bridge_to_lt8912(bridge);
0593
0594
0595
0596
0597
0598 if (lt->hdmi_port->ops & DRM_BRIDGE_OP_EDID)
0599 return drm_bridge_get_edid(lt->hdmi_port, connector);
0600
0601 dev_warn(lt->dev, "The connected bridge does not supports DRM_BRIDGE_OP_EDID\n");
0602 return NULL;
0603 }
0604
0605 static const struct drm_bridge_funcs lt8912_bridge_funcs = {
0606 .attach = lt8912_bridge_attach,
0607 .detach = lt8912_bridge_detach,
0608 .mode_set = lt8912_bridge_mode_set,
0609 .enable = lt8912_bridge_enable,
0610 .detect = lt8912_bridge_detect,
0611 .get_edid = lt8912_bridge_get_edid,
0612 };
0613
0614 static int lt8912_parse_dt(struct lt8912 *lt)
0615 {
0616 struct gpio_desc *gp_reset;
0617 struct device *dev = lt->dev;
0618 int ret;
0619 int data_lanes;
0620 struct device_node *port_node;
0621
0622 gp_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
0623 if (IS_ERR(gp_reset)) {
0624 ret = PTR_ERR(gp_reset);
0625 if (ret != -EPROBE_DEFER)
0626 dev_err(dev, "Failed to get reset gpio: %d\n", ret);
0627 return ret;
0628 }
0629 lt->gp_reset = gp_reset;
0630
0631 data_lanes = drm_of_get_data_lanes_count_ep(dev->of_node, 0, -1, 1, 4);
0632 if (data_lanes < 0) {
0633 dev_err(lt->dev, "%s: Bad data-lanes property\n", __func__);
0634 return data_lanes;
0635 }
0636
0637 lt->data_lanes = data_lanes;
0638
0639 lt->host_node = of_graph_get_remote_node(dev->of_node, 0, -1);
0640 if (!lt->host_node) {
0641 dev_err(lt->dev, "%s: Failed to get remote port\n", __func__);
0642 return -ENODEV;
0643 }
0644
0645 port_node = of_graph_get_remote_node(dev->of_node, 1, -1);
0646 if (!port_node) {
0647 dev_err(lt->dev, "%s: Failed to get connector port\n", __func__);
0648 ret = -ENODEV;
0649 goto err_free_host_node;
0650 }
0651
0652 lt->hdmi_port = of_drm_find_bridge(port_node);
0653 if (!lt->hdmi_port) {
0654 dev_err(lt->dev, "%s: Failed to get hdmi port\n", __func__);
0655 ret = -ENODEV;
0656 goto err_free_host_node;
0657 }
0658
0659 if (!of_device_is_compatible(port_node, "hdmi-connector")) {
0660 dev_err(lt->dev, "%s: Failed to get hdmi port\n", __func__);
0661 ret = -EINVAL;
0662 goto err_free_host_node;
0663 }
0664
0665 of_node_put(port_node);
0666 return 0;
0667
0668 err_free_host_node:
0669 of_node_put(port_node);
0670 of_node_put(lt->host_node);
0671 return ret;
0672 }
0673
0674 static int lt8912_put_dt(struct lt8912 *lt)
0675 {
0676 of_node_put(lt->host_node);
0677 return 0;
0678 }
0679
0680 static int lt8912_probe(struct i2c_client *client,
0681 const struct i2c_device_id *id)
0682 {
0683 static struct lt8912 *lt;
0684 int ret = 0;
0685 struct device *dev = &client->dev;
0686
0687 lt = devm_kzalloc(dev, sizeof(struct lt8912), GFP_KERNEL);
0688 if (!lt)
0689 return -ENOMEM;
0690
0691 lt->dev = dev;
0692 lt->i2c_client[0] = client;
0693
0694 ret = lt8912_parse_dt(lt);
0695 if (ret)
0696 goto err_dt_parse;
0697
0698 ret = lt8912_init_i2c(lt, client);
0699 if (ret)
0700 goto err_i2c;
0701
0702 i2c_set_clientdata(client, lt);
0703
0704 lt->bridge.funcs = <8912_bridge_funcs;
0705 lt->bridge.of_node = dev->of_node;
0706 lt->bridge.ops = (DRM_BRIDGE_OP_EDID |
0707 DRM_BRIDGE_OP_DETECT);
0708
0709 drm_bridge_add(<->bridge);
0710
0711 ret = lt8912_attach_dsi(lt);
0712 if (ret)
0713 goto err_attach;
0714
0715 return 0;
0716
0717 err_attach:
0718 drm_bridge_remove(<->bridge);
0719 lt8912_free_i2c(lt);
0720 err_i2c:
0721 lt8912_put_dt(lt);
0722 err_dt_parse:
0723 return ret;
0724 }
0725
0726 static int lt8912_remove(struct i2c_client *client)
0727 {
0728 struct lt8912 *lt = i2c_get_clientdata(client);
0729
0730 lt8912_bridge_detach(<->bridge);
0731 drm_bridge_remove(<->bridge);
0732 lt8912_free_i2c(lt);
0733 lt8912_put_dt(lt);
0734 return 0;
0735 }
0736
0737 static const struct of_device_id lt8912_dt_match[] = {
0738 {.compatible = "lontium,lt8912b"},
0739 {}
0740 };
0741 MODULE_DEVICE_TABLE(of, lt8912_dt_match);
0742
0743 static const struct i2c_device_id lt8912_id[] = {
0744 {"lt8912", 0},
0745 {},
0746 };
0747 MODULE_DEVICE_TABLE(i2c, lt8912_id);
0748
0749 static struct i2c_driver lt8912_i2c_driver = {
0750 .driver = {
0751 .name = "lt8912",
0752 .of_match_table = lt8912_dt_match,
0753 },
0754 .probe = lt8912_probe,
0755 .remove = lt8912_remove,
0756 .id_table = lt8912_id,
0757 };
0758 module_i2c_driver(lt8912_i2c_driver);
0759
0760 MODULE_AUTHOR("Adrien Grassein <adrien.grassein@gmail.com>");
0761 MODULE_DESCRIPTION("lt8912 drm driver");
0762 MODULE_LICENSE("GPL v2");