0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/backlight.h>
0017 #include <linux/delay.h>
0018 #include <linux/gpio/consumer.h>
0019 #include <linux/module.h>
0020 #include <linux/of.h>
0021 #include <linux/of_device.h>
0022 #include <linux/regulator/consumer.h>
0023
0024 #include <video/mipi_display.h>
0025
0026 #include <drm/drm_mipi_dsi.h>
0027 #include <drm/drm_modes.h>
0028 #include <drm/drm_panel.h>
0029
0030 #define NT35560_DCS_READ_ID1 0xDA
0031 #define NT35560_DCS_READ_ID2 0xDB
0032 #define NT35560_DCS_READ_ID3 0xDC
0033 #define NT35560_DCS_SET_MDDI 0xAE
0034
0035
0036
0037
0038 #define DISPLAY_SONY_ACX424AKP_ID1 0x8103
0039 #define DISPLAY_SONY_ACX424AKP_ID2 0x811a
0040 #define DISPLAY_SONY_ACX424AKP_ID3 0x811b
0041
0042
0043
0044
0045 #define DISPLAY_SONY_ACX424AKP_ID4 0x8000
0046
0047 struct nt35560_config {
0048 const struct drm_display_mode *vid_mode;
0049 const struct drm_display_mode *cmd_mode;
0050 };
0051
0052 struct nt35560 {
0053 const struct nt35560_config *conf;
0054 struct drm_panel panel;
0055 struct device *dev;
0056 struct regulator *supply;
0057 struct gpio_desc *reset_gpio;
0058 bool video_mode;
0059 };
0060
0061 static const struct drm_display_mode sony_acx424akp_vid_mode = {
0062 .clock = 27234,
0063 .hdisplay = 480,
0064 .hsync_start = 480 + 15,
0065 .hsync_end = 480 + 15 + 0,
0066 .htotal = 480 + 15 + 0 + 15,
0067 .vdisplay = 864,
0068 .vsync_start = 864 + 14,
0069 .vsync_end = 864 + 14 + 1,
0070 .vtotal = 864 + 14 + 1 + 11,
0071 .width_mm = 48,
0072 .height_mm = 84,
0073 .flags = DRM_MODE_FLAG_PVSYNC,
0074 };
0075
0076
0077
0078
0079
0080 static const struct drm_display_mode sony_acx424akp_cmd_mode = {
0081 .clock = 35478,
0082 .hdisplay = 480,
0083 .hsync_start = 480 + 154,
0084 .hsync_end = 480 + 154 + 16,
0085 .htotal = 480 + 154 + 16 + 32,
0086 .vdisplay = 864,
0087 .vsync_start = 864 + 1,
0088 .vsync_end = 864 + 1 + 1,
0089 .vtotal = 864 + 1 + 1 + 1,
0090
0091
0092
0093
0094 .width_mm = 48,
0095 .height_mm = 84,
0096 };
0097
0098 static const struct nt35560_config sony_acx424akp_data = {
0099 .vid_mode = &sony_acx424akp_vid_mode,
0100 .cmd_mode = &sony_acx424akp_cmd_mode,
0101 };
0102
0103 static const struct drm_display_mode sony_acx424akm_vid_mode = {
0104 .clock = 27234,
0105 .hdisplay = 480,
0106 .hsync_start = 480 + 15,
0107 .hsync_end = 480 + 15 + 0,
0108 .htotal = 480 + 15 + 0 + 15,
0109 .vdisplay = 854,
0110 .vsync_start = 854 + 14,
0111 .vsync_end = 854 + 14 + 1,
0112 .vtotal = 854 + 14 + 1 + 11,
0113 .width_mm = 46,
0114 .height_mm = 82,
0115 .flags = DRM_MODE_FLAG_PVSYNC,
0116 };
0117
0118
0119
0120
0121
0122 static const struct drm_display_mode sony_acx424akm_cmd_mode = {
0123 .clock = 35478,
0124 .hdisplay = 480,
0125 .hsync_start = 480 + 154,
0126 .hsync_end = 480 + 154 + 16,
0127 .htotal = 480 + 154 + 16 + 32,
0128 .vdisplay = 854,
0129 .vsync_start = 854 + 1,
0130 .vsync_end = 854 + 1 + 1,
0131 .vtotal = 854 + 1 + 1 + 1,
0132 .width_mm = 46,
0133 .height_mm = 82,
0134 };
0135
0136 static const struct nt35560_config sony_acx424akm_data = {
0137 .vid_mode = &sony_acx424akm_vid_mode,
0138 .cmd_mode = &sony_acx424akm_cmd_mode,
0139 };
0140
0141 static inline struct nt35560 *panel_to_nt35560(struct drm_panel *panel)
0142 {
0143 return container_of(panel, struct nt35560, panel);
0144 }
0145
0146 #define FOSC 20
0147 #define SCALE_FACTOR_NS_DIV_MHZ 1000
0148
0149 static int nt35560_set_brightness(struct backlight_device *bl)
0150 {
0151 struct nt35560 *nt = bl_get_data(bl);
0152 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0153 int period_ns = 1023;
0154 int duty_ns = bl->props.brightness;
0155 u8 pwm_ratio;
0156 u8 pwm_div;
0157 u8 par;
0158 int ret;
0159
0160 if (backlight_is_blank(bl)) {
0161
0162 par = 0x00;
0163 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
0164 &par, 1);
0165 if (ret) {
0166 dev_err(nt->dev, "failed to disable display backlight (%d)\n", ret);
0167 return ret;
0168 }
0169 return 0;
0170 }
0171
0172
0173 pwm_ratio = max(((duty_ns * 256) / period_ns) - 1, 1);
0174 pwm_div = max(1,
0175 ((FOSC * period_ns) / 256) /
0176 SCALE_FACTOR_NS_DIV_MHZ);
0177
0178
0179 dev_dbg(nt->dev, "calculated duty cycle %02x\n", pwm_ratio);
0180 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
0181 &pwm_ratio, 1);
0182 if (ret < 0) {
0183 dev_err(nt->dev, "failed to set display PWM ratio (%d)\n", ret);
0184 return ret;
0185 }
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 par = 0xaa;
0197 ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1);
0198 if (ret < 0) {
0199 dev_err(nt->dev, "failed to unlock CMD 2 (%d)\n", ret);
0200 return ret;
0201 }
0202 par = 0x01;
0203 ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1);
0204 if (ret < 0) {
0205 dev_err(nt->dev, "failed to enter page 1 (%d)\n", ret);
0206 return ret;
0207 }
0208 par = 0x01;
0209 ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1);
0210 if (ret < 0) {
0211 dev_err(nt->dev, "failed to disable MTP reload (%d)\n", ret);
0212 return ret;
0213 }
0214 ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1);
0215 if (ret < 0) {
0216 dev_err(nt->dev, "failed to set PWM divisor (%d)\n", ret);
0217 return ret;
0218 }
0219 par = 0xaa;
0220 ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1);
0221 if (ret < 0) {
0222 dev_err(nt->dev, "failed to lock CMD 2 (%d)\n", ret);
0223 return ret;
0224 }
0225
0226
0227 par = 0x24;
0228 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
0229 &par, 1);
0230 if (ret < 0) {
0231 dev_err(nt->dev, "failed to enable display backlight (%d)\n", ret);
0232 return ret;
0233 }
0234
0235 return 0;
0236 }
0237
0238 static const struct backlight_ops nt35560_bl_ops = {
0239 .update_status = nt35560_set_brightness,
0240 };
0241
0242 static const struct backlight_properties nt35560_bl_props = {
0243 .type = BACKLIGHT_RAW,
0244 .brightness = 512,
0245 .max_brightness = 1023,
0246 };
0247
0248 static int nt35560_read_id(struct nt35560 *nt)
0249 {
0250 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0251 u8 vendor, version, panel;
0252 u16 val;
0253 int ret;
0254
0255 ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID1, &vendor, 1);
0256 if (ret < 0) {
0257 dev_err(nt->dev, "could not vendor ID byte\n");
0258 return ret;
0259 }
0260 ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID2, &version, 1);
0261 if (ret < 0) {
0262 dev_err(nt->dev, "could not read device version byte\n");
0263 return ret;
0264 }
0265 ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID3, &panel, 1);
0266 if (ret < 0) {
0267 dev_err(nt->dev, "could not read panel ID byte\n");
0268 return ret;
0269 }
0270
0271 if (vendor == 0x00) {
0272 dev_err(nt->dev, "device vendor ID is zero\n");
0273 return -ENODEV;
0274 }
0275
0276 val = (vendor << 8) | panel;
0277 switch (val) {
0278 case DISPLAY_SONY_ACX424AKP_ID1:
0279 case DISPLAY_SONY_ACX424AKP_ID2:
0280 case DISPLAY_SONY_ACX424AKP_ID3:
0281 case DISPLAY_SONY_ACX424AKP_ID4:
0282 dev_info(nt->dev, "MTP vendor: %02x, version: %02x, panel: %02x\n",
0283 vendor, version, panel);
0284 break;
0285 default:
0286 dev_info(nt->dev, "unknown vendor: %02x, version: %02x, panel: %02x\n",
0287 vendor, version, panel);
0288 break;
0289 }
0290
0291 return 0;
0292 }
0293
0294 static int nt35560_power_on(struct nt35560 *nt)
0295 {
0296 int ret;
0297
0298 ret = regulator_enable(nt->supply);
0299 if (ret) {
0300 dev_err(nt->dev, "failed to enable supply (%d)\n", ret);
0301 return ret;
0302 }
0303
0304
0305 gpiod_set_value_cansleep(nt->reset_gpio, 1);
0306 udelay(20);
0307
0308 gpiod_set_value_cansleep(nt->reset_gpio, 0);
0309 usleep_range(11000, 20000);
0310
0311 return 0;
0312 }
0313
0314 static void nt35560_power_off(struct nt35560 *nt)
0315 {
0316
0317 gpiod_set_value_cansleep(nt->reset_gpio, 1);
0318 usleep_range(11000, 20000);
0319
0320 regulator_disable(nt->supply);
0321 }
0322
0323 static int nt35560_prepare(struct drm_panel *panel)
0324 {
0325 struct nt35560 *nt = panel_to_nt35560(panel);
0326 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0327 const u8 mddi = 3;
0328 int ret;
0329
0330 ret = nt35560_power_on(nt);
0331 if (ret)
0332 return ret;
0333
0334 ret = nt35560_read_id(nt);
0335 if (ret) {
0336 dev_err(nt->dev, "failed to read panel ID (%d)\n", ret);
0337 goto err_power_off;
0338 }
0339
0340
0341 ret = mipi_dsi_dcs_set_tear_on(dsi,
0342 MIPI_DSI_DCS_TEAR_MODE_VBLANK);
0343 if (ret) {
0344 dev_err(nt->dev, "failed to enable vblank TE (%d)\n", ret);
0345 goto err_power_off;
0346 }
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 ret = mipi_dsi_dcs_write(dsi, NT35560_DCS_SET_MDDI,
0359 &mddi, sizeof(mddi));
0360 if (ret < 0) {
0361 dev_err(nt->dev, "failed to set MDDI (%d)\n", ret);
0362 goto err_power_off;
0363 }
0364
0365
0366 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
0367 if (ret) {
0368 dev_err(nt->dev, "failed to exit sleep mode (%d)\n", ret);
0369 goto err_power_off;
0370 }
0371 msleep(140);
0372
0373 ret = mipi_dsi_dcs_set_display_on(dsi);
0374 if (ret) {
0375 dev_err(nt->dev, "failed to turn display on (%d)\n", ret);
0376 goto err_power_off;
0377 }
0378 if (nt->video_mode) {
0379
0380 ret = mipi_dsi_turn_on_peripheral(dsi);
0381 if (ret) {
0382 dev_err(nt->dev, "failed to turn on peripheral\n");
0383 goto err_power_off;
0384 }
0385 }
0386
0387 return 0;
0388
0389 err_power_off:
0390 nt35560_power_off(nt);
0391 return ret;
0392 }
0393
0394 static int nt35560_unprepare(struct drm_panel *panel)
0395 {
0396 struct nt35560 *nt = panel_to_nt35560(panel);
0397 struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0398 int ret;
0399
0400 ret = mipi_dsi_dcs_set_display_off(dsi);
0401 if (ret) {
0402 dev_err(nt->dev, "failed to turn display off (%d)\n", ret);
0403 return ret;
0404 }
0405
0406
0407 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
0408 if (ret) {
0409 dev_err(nt->dev, "failed to enter sleep mode (%d)\n", ret);
0410 return ret;
0411 }
0412 msleep(85);
0413
0414 nt35560_power_off(nt);
0415
0416 return 0;
0417 }
0418
0419
0420 static int nt35560_get_modes(struct drm_panel *panel,
0421 struct drm_connector *connector)
0422 {
0423 struct nt35560 *nt = panel_to_nt35560(panel);
0424 const struct nt35560_config *conf = nt->conf;
0425 struct drm_display_mode *mode;
0426
0427 if (nt->video_mode)
0428 mode = drm_mode_duplicate(connector->dev,
0429 conf->vid_mode);
0430 else
0431 mode = drm_mode_duplicate(connector->dev,
0432 conf->cmd_mode);
0433 if (!mode) {
0434 dev_err(panel->dev, "bad mode or failed to add mode\n");
0435 return -EINVAL;
0436 }
0437 drm_mode_set_name(mode);
0438 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
0439
0440 connector->display_info.width_mm = mode->width_mm;
0441 connector->display_info.height_mm = mode->height_mm;
0442
0443 drm_mode_probed_add(connector, mode);
0444
0445 return 1;
0446 }
0447
0448 static const struct drm_panel_funcs nt35560_drm_funcs = {
0449 .unprepare = nt35560_unprepare,
0450 .prepare = nt35560_prepare,
0451 .get_modes = nt35560_get_modes,
0452 };
0453
0454 static int nt35560_probe(struct mipi_dsi_device *dsi)
0455 {
0456 struct device *dev = &dsi->dev;
0457 struct nt35560 *nt;
0458 int ret;
0459
0460 nt = devm_kzalloc(dev, sizeof(struct nt35560), GFP_KERNEL);
0461 if (!nt)
0462 return -ENOMEM;
0463 nt->video_mode = of_property_read_bool(dev->of_node,
0464 "enforce-video-mode");
0465
0466 mipi_dsi_set_drvdata(dsi, nt);
0467 nt->dev = dev;
0468
0469 nt->conf = of_device_get_match_data(dev);
0470 if (!nt->conf) {
0471 dev_err(dev, "missing device configuration\n");
0472 return -ENODEV;
0473 }
0474
0475 dsi->lanes = 2;
0476 dsi->format = MIPI_DSI_FMT_RGB888;
0477
0478
0479
0480
0481
0482
0483 dsi->lp_rate = 19200000;
0484 dsi->hs_rate = 420160000;
0485
0486 if (nt->video_mode)
0487
0488 dsi->mode_flags =
0489 MIPI_DSI_MODE_VIDEO |
0490 MIPI_DSI_MODE_VIDEO_BURST;
0491 else
0492 dsi->mode_flags =
0493 MIPI_DSI_CLOCK_NON_CONTINUOUS;
0494
0495 nt->supply = devm_regulator_get(dev, "vddi");
0496 if (IS_ERR(nt->supply))
0497 return PTR_ERR(nt->supply);
0498
0499
0500 nt->reset_gpio = devm_gpiod_get_optional(dev, "reset",
0501 GPIOD_OUT_HIGH);
0502 if (IS_ERR(nt->reset_gpio))
0503 return dev_err_probe(dev, PTR_ERR(nt->reset_gpio),
0504 "failed to request GPIO\n");
0505
0506 drm_panel_init(&nt->panel, dev, &nt35560_drm_funcs,
0507 DRM_MODE_CONNECTOR_DSI);
0508
0509 nt->panel.backlight = devm_backlight_device_register(dev, "nt35560", dev, nt,
0510 &nt35560_bl_ops, &nt35560_bl_props);
0511 if (IS_ERR(nt->panel.backlight))
0512 return dev_err_probe(dev, PTR_ERR(nt->panel.backlight),
0513 "failed to register backlight device\n");
0514
0515 drm_panel_add(&nt->panel);
0516
0517 ret = mipi_dsi_attach(dsi);
0518 if (ret < 0) {
0519 drm_panel_remove(&nt->panel);
0520 return ret;
0521 }
0522
0523 return 0;
0524 }
0525
0526 static int nt35560_remove(struct mipi_dsi_device *dsi)
0527 {
0528 struct nt35560 *nt = mipi_dsi_get_drvdata(dsi);
0529
0530 mipi_dsi_detach(dsi);
0531 drm_panel_remove(&nt->panel);
0532
0533 return 0;
0534 }
0535
0536 static const struct of_device_id nt35560_of_match[] = {
0537 {
0538 .compatible = "sony,acx424akp",
0539 .data = &sony_acx424akp_data,
0540 },
0541 {
0542 .compatible = "sony,acx424akm",
0543 .data = &sony_acx424akm_data,
0544 },
0545 { }
0546 };
0547 MODULE_DEVICE_TABLE(of, nt35560_of_match);
0548
0549 static struct mipi_dsi_driver nt35560_driver = {
0550 .probe = nt35560_probe,
0551 .remove = nt35560_remove,
0552 .driver = {
0553 .name = "panel-novatek-nt35560",
0554 .of_match_table = nt35560_of_match,
0555 },
0556 };
0557 module_mipi_dsi_driver(nt35560_driver);
0558
0559 MODULE_AUTHOR("Linus Wallei <linus.walleij@linaro.org>");
0560 MODULE_DESCRIPTION("MIPI-DSI Novatek NT35560 Panel Driver");
0561 MODULE_LICENSE("GPL v2");