0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <drm/drm_atomic_helper.h>
0012 #include <drm/drm_of.h>
0013 #include <drm/drm_print.h>
0014 #include <drm/drm_mipi_dsi.h>
0015
0016 #include <linux/delay.h>
0017 #include <linux/gpio/consumer.h>
0018 #include <linux/i2c.h>
0019 #include <linux/media-bus-format.h>
0020 #include <linux/module.h>
0021 #include <linux/regmap.h>
0022 #include <linux/regulator/consumer.h>
0023
0024 enum cmd_registers {
0025 WR_INPUT_SOURCE = 0x05,
0026 WR_EXT_SOURCE_FMT = 0x07,
0027 WR_IMAGE_CROP = 0x10,
0028 WR_DISPLAY_SIZE = 0x12,
0029 WR_IMAGE_FREEZE = 0x1A,
0030 WR_INPUT_IMAGE_SIZE = 0x2E,
0031 WR_RGB_LED_EN = 0x52,
0032 WR_RGB_LED_CURRENT = 0x54,
0033 WR_RGB_LED_MAX_CURRENT = 0x5C,
0034 WR_DSI_HS_CLK = 0xBD,
0035 RD_DEVICE_ID = 0xD4,
0036 WR_DSI_PORT_EN = 0xD7,
0037 };
0038
0039 enum input_source {
0040 INPUT_EXTERNAL_VIDEO = 0,
0041 INPUT_TEST_PATTERN,
0042 INPUT_SPLASH_SCREEN,
0043 };
0044
0045 #define DEV_ID_MASK GENMASK(3, 0)
0046 #define IMAGE_FREESE_EN BIT(0)
0047 #define DSI_PORT_EN 0
0048 #define EXT_SOURCE_FMT_DSI 0
0049 #define RED_LED_EN BIT(0)
0050 #define GREEN_LED_EN BIT(1)
0051 #define BLUE_LED_EN BIT(2)
0052 #define LED_MASK GENMASK(2, 0)
0053 #define MAX_BYTE_SIZE 8
0054
0055 struct dlpc {
0056 struct device *dev;
0057 struct drm_bridge bridge;
0058 struct drm_bridge *next_bridge;
0059 struct device_node *host_node;
0060 struct mipi_dsi_device *dsi;
0061 struct drm_display_mode mode;
0062
0063 struct gpio_desc *enable_gpio;
0064 struct regulator *vcc_intf;
0065 struct regulator *vcc_flsh;
0066 struct regmap *regmap;
0067 unsigned int dsi_lanes;
0068 };
0069
0070 static inline struct dlpc *bridge_to_dlpc(struct drm_bridge *bridge)
0071 {
0072 return container_of(bridge, struct dlpc, bridge);
0073 }
0074
0075 static bool dlpc_writeable_noinc_reg(struct device *dev, unsigned int reg)
0076 {
0077 switch (reg) {
0078 case WR_IMAGE_CROP:
0079 case WR_DISPLAY_SIZE:
0080 case WR_INPUT_IMAGE_SIZE:
0081 case WR_DSI_HS_CLK:
0082 return true;
0083 default:
0084 return false;
0085 }
0086 }
0087
0088 static const struct regmap_range dlpc_volatile_ranges[] = {
0089 { .range_min = 0x10, .range_max = 0xBF },
0090 };
0091
0092 static const struct regmap_access_table dlpc_volatile_table = {
0093 .yes_ranges = dlpc_volatile_ranges,
0094 .n_yes_ranges = ARRAY_SIZE(dlpc_volatile_ranges),
0095 };
0096
0097 static struct regmap_config dlpc_regmap_config = {
0098 .reg_bits = 8,
0099 .val_bits = 8,
0100 .max_register = WR_DSI_PORT_EN,
0101 .writeable_noinc_reg = dlpc_writeable_noinc_reg,
0102 .volatile_table = &dlpc_volatile_table,
0103 .cache_type = REGCACHE_RBTREE,
0104 .name = "dlpc3433",
0105 };
0106
0107 static void dlpc_atomic_enable(struct drm_bridge *bridge,
0108 struct drm_bridge_state *old_bridge_state)
0109 {
0110 struct dlpc *dlpc = bridge_to_dlpc(bridge);
0111 struct device *dev = dlpc->dev;
0112 struct drm_display_mode *mode = &dlpc->mode;
0113 struct regmap *regmap = dlpc->regmap;
0114 char buf[MAX_BYTE_SIZE];
0115 unsigned int devid;
0116
0117 regmap_read(regmap, RD_DEVICE_ID, &devid);
0118 devid &= DEV_ID_MASK;
0119
0120 DRM_DEV_DEBUG(dev, "DLPC3433 device id: 0x%02x\n", devid);
0121
0122 if (devid != 0x01) {
0123 DRM_DEV_ERROR(dev, "Unsupported DLPC device id: 0x%02x\n", devid);
0124 return;
0125 }
0126
0127
0128 regmap_write(regmap, WR_IMAGE_FREEZE, IMAGE_FREESE_EN);
0129
0130
0131 regmap_write(regmap, WR_DSI_PORT_EN, DSI_PORT_EN);
0132
0133 memset(buf, 0, MAX_BYTE_SIZE);
0134
0135
0136 buf[4] = mode->hdisplay & 0xff;
0137 buf[5] = (mode->hdisplay & 0xff00) >> 8;
0138 buf[6] = mode->vdisplay & 0xff;
0139 buf[7] = (mode->vdisplay & 0xff00) >> 8;
0140 regmap_noinc_write(regmap, WR_IMAGE_CROP, buf, MAX_BYTE_SIZE);
0141
0142
0143 buf[4] = mode->hdisplay & 0xff;
0144 buf[5] = (mode->hdisplay & 0xff00) >> 8;
0145 buf[6] = mode->vdisplay & 0xff;
0146 buf[7] = (mode->vdisplay & 0xff00) >> 8;
0147 regmap_noinc_write(regmap, WR_DISPLAY_SIZE, buf, MAX_BYTE_SIZE);
0148
0149
0150 buf[0] = mode->hdisplay & 0xff;
0151 buf[1] = (mode->hdisplay & 0xff00) >> 8;
0152 buf[2] = mode->vdisplay & 0xff;
0153 buf[3] = (mode->vdisplay & 0xff00) >> 8;
0154 regmap_noinc_write(regmap, WR_INPUT_IMAGE_SIZE, buf, 4);
0155
0156
0157 regmap_write(regmap, WR_INPUT_SOURCE, INPUT_EXTERNAL_VIDEO);
0158
0159
0160 regmap_write(regmap, WR_EXT_SOURCE_FMT, EXT_SOURCE_FMT_DSI);
0161
0162
0163 regmap_write(regmap, WR_IMAGE_FREEZE, 0x00);
0164
0165
0166 regmap_update_bits(regmap, WR_RGB_LED_EN, LED_MASK,
0167 RED_LED_EN | GREEN_LED_EN | BLUE_LED_EN);
0168
0169 msleep(10);
0170 }
0171
0172 static void dlpc_atomic_pre_enable(struct drm_bridge *bridge,
0173 struct drm_bridge_state *old_bridge_state)
0174 {
0175 struct dlpc *dlpc = bridge_to_dlpc(bridge);
0176 int ret;
0177
0178 gpiod_set_value(dlpc->enable_gpio, 1);
0179
0180 msleep(500);
0181
0182 ret = regulator_enable(dlpc->vcc_intf);
0183 if (ret)
0184 DRM_DEV_ERROR(dlpc->dev,
0185 "failed to enable VCC_INTF regulator: %d\n", ret);
0186
0187 ret = regulator_enable(dlpc->vcc_flsh);
0188 if (ret)
0189 DRM_DEV_ERROR(dlpc->dev,
0190 "failed to enable VCC_FLSH regulator: %d\n", ret);
0191
0192 msleep(10);
0193 }
0194
0195 static void dlpc_atomic_post_disable(struct drm_bridge *bridge,
0196 struct drm_bridge_state *old_bridge_state)
0197 {
0198 struct dlpc *dlpc = bridge_to_dlpc(bridge);
0199
0200 regulator_disable(dlpc->vcc_flsh);
0201 regulator_disable(dlpc->vcc_intf);
0202
0203 msleep(10);
0204
0205 gpiod_set_value(dlpc->enable_gpio, 0);
0206
0207 msleep(500);
0208 }
0209
0210 #define MAX_INPUT_SEL_FORMATS 1
0211
0212 static u32 *
0213 dlpc_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
0214 struct drm_bridge_state *bridge_state,
0215 struct drm_crtc_state *crtc_state,
0216 struct drm_connector_state *conn_state,
0217 u32 output_fmt,
0218 unsigned int *num_input_fmts)
0219 {
0220 u32 *input_fmts;
0221
0222 *num_input_fmts = 0;
0223
0224 input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
0225 GFP_KERNEL);
0226 if (!input_fmts)
0227 return NULL;
0228
0229
0230 input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
0231 *num_input_fmts = 1;
0232
0233 return input_fmts;
0234 }
0235
0236 static void dlpc_mode_set(struct drm_bridge *bridge,
0237 const struct drm_display_mode *mode,
0238 const struct drm_display_mode *adjusted_mode)
0239 {
0240 struct dlpc *dlpc = bridge_to_dlpc(bridge);
0241
0242 drm_mode_copy(&dlpc->mode, adjusted_mode);
0243 }
0244
0245 static int dlpc_attach(struct drm_bridge *bridge,
0246 enum drm_bridge_attach_flags flags)
0247 {
0248 struct dlpc *dlpc = bridge_to_dlpc(bridge);
0249
0250 return drm_bridge_attach(bridge->encoder, dlpc->next_bridge, bridge, flags);
0251 }
0252
0253 static const struct drm_bridge_funcs dlpc_bridge_funcs = {
0254 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
0255 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
0256 .atomic_get_input_bus_fmts = dlpc_atomic_get_input_bus_fmts,
0257 .atomic_reset = drm_atomic_helper_bridge_reset,
0258 .atomic_pre_enable = dlpc_atomic_pre_enable,
0259 .atomic_enable = dlpc_atomic_enable,
0260 .atomic_post_disable = dlpc_atomic_post_disable,
0261 .mode_set = dlpc_mode_set,
0262 .attach = dlpc_attach,
0263 };
0264
0265 static int dlpc3433_parse_dt(struct dlpc *dlpc)
0266 {
0267 struct device *dev = dlpc->dev;
0268 struct device_node *endpoint;
0269 int ret;
0270
0271 dlpc->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
0272 if (IS_ERR(dlpc->enable_gpio))
0273 return PTR_ERR(dlpc->enable_gpio);
0274
0275 dlpc->vcc_intf = devm_regulator_get(dlpc->dev, "vcc_intf");
0276 if (IS_ERR(dlpc->vcc_intf))
0277 return dev_err_probe(dev, PTR_ERR(dlpc->vcc_intf),
0278 "failed to get VCC_INTF supply\n");
0279
0280 dlpc->vcc_flsh = devm_regulator_get(dlpc->dev, "vcc_flsh");
0281 if (IS_ERR(dlpc->vcc_flsh))
0282 return dev_err_probe(dev, PTR_ERR(dlpc->vcc_flsh),
0283 "failed to get VCC_FLSH supply\n");
0284
0285 dlpc->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
0286 if (IS_ERR(dlpc->next_bridge))
0287 return PTR_ERR(dlpc->next_bridge);
0288
0289 endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
0290 dlpc->dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes");
0291 if (dlpc->dsi_lanes < 0 || dlpc->dsi_lanes > 4) {
0292 ret = -EINVAL;
0293 goto err_put_endpoint;
0294 }
0295
0296 dlpc->host_node = of_graph_get_remote_port_parent(endpoint);
0297 if (!dlpc->host_node) {
0298 ret = -ENODEV;
0299 goto err_put_host;
0300 }
0301
0302 of_node_put(endpoint);
0303
0304 return 0;
0305
0306 err_put_host:
0307 of_node_put(dlpc->host_node);
0308 err_put_endpoint:
0309 of_node_put(endpoint);
0310 return ret;
0311 }
0312
0313 static int dlpc_host_attach(struct dlpc *dlpc)
0314 {
0315 struct device *dev = dlpc->dev;
0316 struct mipi_dsi_host *host;
0317 struct mipi_dsi_device_info info = {
0318 .type = "dlpc3433",
0319 .channel = 0,
0320 .node = NULL,
0321 };
0322
0323 host = of_find_mipi_dsi_host_by_node(dlpc->host_node);
0324 if (!host) {
0325 DRM_DEV_ERROR(dev, "failed to find dsi host\n");
0326 return -EPROBE_DEFER;
0327 }
0328
0329 dlpc->dsi = mipi_dsi_device_register_full(host, &info);
0330 if (IS_ERR(dlpc->dsi)) {
0331 DRM_DEV_ERROR(dev, "failed to create dsi device\n");
0332 return PTR_ERR(dlpc->dsi);
0333 }
0334
0335 dlpc->dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST;
0336 dlpc->dsi->format = MIPI_DSI_FMT_RGB565;
0337 dlpc->dsi->lanes = dlpc->dsi_lanes;
0338
0339 return devm_mipi_dsi_attach(dev, dlpc->dsi);
0340 }
0341
0342 static int dlpc3433_probe(struct i2c_client *client)
0343 {
0344 struct device *dev = &client->dev;
0345 struct dlpc *dlpc;
0346 int ret;
0347
0348 dlpc = devm_kzalloc(dev, sizeof(*dlpc), GFP_KERNEL);
0349 if (!dlpc)
0350 return -ENOMEM;
0351
0352 dlpc->dev = dev;
0353
0354 dlpc->regmap = devm_regmap_init_i2c(client, &dlpc_regmap_config);
0355 if (IS_ERR(dlpc->regmap))
0356 return PTR_ERR(dlpc->regmap);
0357
0358 ret = dlpc3433_parse_dt(dlpc);
0359 if (ret)
0360 return ret;
0361
0362 dev_set_drvdata(dev, dlpc);
0363 i2c_set_clientdata(client, dlpc);
0364
0365 dlpc->bridge.funcs = &dlpc_bridge_funcs;
0366 dlpc->bridge.of_node = dev->of_node;
0367 drm_bridge_add(&dlpc->bridge);
0368
0369 ret = dlpc_host_attach(dlpc);
0370 if (ret) {
0371 DRM_DEV_ERROR(dev, "failed to attach dsi host\n");
0372 goto err_remove_bridge;
0373 }
0374
0375 return 0;
0376
0377 err_remove_bridge:
0378 drm_bridge_remove(&dlpc->bridge);
0379 return ret;
0380 }
0381
0382 static int dlpc3433_remove(struct i2c_client *client)
0383 {
0384 struct dlpc *dlpc = i2c_get_clientdata(client);
0385
0386 drm_bridge_remove(&dlpc->bridge);
0387 of_node_put(dlpc->host_node);
0388
0389 return 0;
0390 }
0391
0392 static const struct i2c_device_id dlpc3433_id[] = {
0393 { "ti,dlpc3433", 0 },
0394 { }
0395 };
0396 MODULE_DEVICE_TABLE(i2c, dlpc3433_id);
0397
0398 static const struct of_device_id dlpc3433_match_table[] = {
0399 { .compatible = "ti,dlpc3433" },
0400 { }
0401 };
0402 MODULE_DEVICE_TABLE(of, dlpc3433_match_table);
0403
0404 static struct i2c_driver dlpc3433_driver = {
0405 .probe_new = dlpc3433_probe,
0406 .remove = dlpc3433_remove,
0407 .id_table = dlpc3433_id,
0408 .driver = {
0409 .name = "ti-dlpc3433",
0410 .of_match_table = dlpc3433_match_table,
0411 },
0412 };
0413 module_i2c_driver(dlpc3433_driver);
0414
0415 MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
0416 MODULE_AUTHOR("Christopher Vollo <chris@renewoutreach.org>");
0417 MODULE_DESCRIPTION("TI DLPC3433 MIPI DSI Display Controller Bridge");
0418 MODULE_LICENSE("GPL");