Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2017 Free Electrons
0004  */
0005 
0006 #include <linux/delay.h>
0007 #include <linux/gpio/consumer.h>
0008 #include <linux/module.h>
0009 #include <linux/regulator/consumer.h>
0010 #include <linux/spi/spi.h>
0011 
0012 #include <video/mipi_display.h>
0013 
0014 #include <drm/drm_device.h>
0015 #include <drm/drm_modes.h>
0016 #include <drm/drm_panel.h>
0017 
0018 #define ST7789V_COLMOD_RGB_FMT_18BITS       (6 << 4)
0019 #define ST7789V_COLMOD_CTRL_FMT_18BITS      (6 << 0)
0020 
0021 #define ST7789V_RAMCTRL_CMD     0xb0
0022 #define ST7789V_RAMCTRL_RM_RGB          BIT(4)
0023 #define ST7789V_RAMCTRL_DM_RGB          BIT(0)
0024 #define ST7789V_RAMCTRL_MAGIC           (3 << 6)
0025 #define ST7789V_RAMCTRL_EPF(n)          (((n) & 3) << 4)
0026 
0027 #define ST7789V_RGBCTRL_CMD     0xb1
0028 #define ST7789V_RGBCTRL_WO          BIT(7)
0029 #define ST7789V_RGBCTRL_RCM(n)          (((n) & 3) << 5)
0030 #define ST7789V_RGBCTRL_VSYNC_HIGH      BIT(3)
0031 #define ST7789V_RGBCTRL_HSYNC_HIGH      BIT(2)
0032 #define ST7789V_RGBCTRL_PCLK_HIGH       BIT(1)
0033 #define ST7789V_RGBCTRL_VBP(n)          ((n) & 0x7f)
0034 #define ST7789V_RGBCTRL_HBP(n)          ((n) & 0x1f)
0035 
0036 #define ST7789V_PORCTRL_CMD     0xb2
0037 #define ST7789V_PORCTRL_IDLE_BP(n)      (((n) & 0xf) << 4)
0038 #define ST7789V_PORCTRL_IDLE_FP(n)      ((n) & 0xf)
0039 #define ST7789V_PORCTRL_PARTIAL_BP(n)       (((n) & 0xf) << 4)
0040 #define ST7789V_PORCTRL_PARTIAL_FP(n)       ((n) & 0xf)
0041 
0042 #define ST7789V_GCTRL_CMD       0xb7
0043 #define ST7789V_GCTRL_VGHS(n)           (((n) & 7) << 4)
0044 #define ST7789V_GCTRL_VGLS(n)           ((n) & 7)
0045 
0046 #define ST7789V_VCOMS_CMD       0xbb
0047 
0048 #define ST7789V_LCMCTRL_CMD     0xc0
0049 #define ST7789V_LCMCTRL_XBGR            BIT(5)
0050 #define ST7789V_LCMCTRL_XMX         BIT(3)
0051 #define ST7789V_LCMCTRL_XMH         BIT(2)
0052 
0053 #define ST7789V_VDVVRHEN_CMD        0xc2
0054 #define ST7789V_VDVVRHEN_CMDEN          BIT(0)
0055 
0056 #define ST7789V_VRHS_CMD        0xc3
0057 
0058 #define ST7789V_VDVS_CMD        0xc4
0059 
0060 #define ST7789V_FRCTRL2_CMD     0xc6
0061 
0062 #define ST7789V_PWCTRL1_CMD     0xd0
0063 #define ST7789V_PWCTRL1_MAGIC           0xa4
0064 #define ST7789V_PWCTRL1_AVDD(n)         (((n) & 3) << 6)
0065 #define ST7789V_PWCTRL1_AVCL(n)         (((n) & 3) << 4)
0066 #define ST7789V_PWCTRL1_VDS(n)          ((n) & 3)
0067 
0068 #define ST7789V_PVGAMCTRL_CMD       0xe0
0069 #define ST7789V_PVGAMCTRL_JP0(n)        (((n) & 3) << 4)
0070 #define ST7789V_PVGAMCTRL_JP1(n)        (((n) & 3) << 4)
0071 #define ST7789V_PVGAMCTRL_VP0(n)        ((n) & 0xf)
0072 #define ST7789V_PVGAMCTRL_VP1(n)        ((n) & 0x3f)
0073 #define ST7789V_PVGAMCTRL_VP2(n)        ((n) & 0x3f)
0074 #define ST7789V_PVGAMCTRL_VP4(n)        ((n) & 0x1f)
0075 #define ST7789V_PVGAMCTRL_VP6(n)        ((n) & 0x1f)
0076 #define ST7789V_PVGAMCTRL_VP13(n)       ((n) & 0xf)
0077 #define ST7789V_PVGAMCTRL_VP20(n)       ((n) & 0x7f)
0078 #define ST7789V_PVGAMCTRL_VP27(n)       ((n) & 7)
0079 #define ST7789V_PVGAMCTRL_VP36(n)       (((n) & 7) << 4)
0080 #define ST7789V_PVGAMCTRL_VP43(n)       ((n) & 0x7f)
0081 #define ST7789V_PVGAMCTRL_VP50(n)       ((n) & 0xf)
0082 #define ST7789V_PVGAMCTRL_VP57(n)       ((n) & 0x1f)
0083 #define ST7789V_PVGAMCTRL_VP59(n)       ((n) & 0x1f)
0084 #define ST7789V_PVGAMCTRL_VP61(n)       ((n) & 0x3f)
0085 #define ST7789V_PVGAMCTRL_VP62(n)       ((n) & 0x3f)
0086 #define ST7789V_PVGAMCTRL_VP63(n)       (((n) & 0xf) << 4)
0087 
0088 #define ST7789V_NVGAMCTRL_CMD       0xe1
0089 #define ST7789V_NVGAMCTRL_JN0(n)        (((n) & 3) << 4)
0090 #define ST7789V_NVGAMCTRL_JN1(n)        (((n) & 3) << 4)
0091 #define ST7789V_NVGAMCTRL_VN0(n)        ((n) & 0xf)
0092 #define ST7789V_NVGAMCTRL_VN1(n)        ((n) & 0x3f)
0093 #define ST7789V_NVGAMCTRL_VN2(n)        ((n) & 0x3f)
0094 #define ST7789V_NVGAMCTRL_VN4(n)        ((n) & 0x1f)
0095 #define ST7789V_NVGAMCTRL_VN6(n)        ((n) & 0x1f)
0096 #define ST7789V_NVGAMCTRL_VN13(n)       ((n) & 0xf)
0097 #define ST7789V_NVGAMCTRL_VN20(n)       ((n) & 0x7f)
0098 #define ST7789V_NVGAMCTRL_VN27(n)       ((n) & 7)
0099 #define ST7789V_NVGAMCTRL_VN36(n)       (((n) & 7) << 4)
0100 #define ST7789V_NVGAMCTRL_VN43(n)       ((n) & 0x7f)
0101 #define ST7789V_NVGAMCTRL_VN50(n)       ((n) & 0xf)
0102 #define ST7789V_NVGAMCTRL_VN57(n)       ((n) & 0x1f)
0103 #define ST7789V_NVGAMCTRL_VN59(n)       ((n) & 0x1f)
0104 #define ST7789V_NVGAMCTRL_VN61(n)       ((n) & 0x3f)
0105 #define ST7789V_NVGAMCTRL_VN62(n)       ((n) & 0x3f)
0106 #define ST7789V_NVGAMCTRL_VN63(n)       (((n) & 0xf) << 4)
0107 
0108 #define ST7789V_TEST(val, func)         \
0109     do {                    \
0110         if ((val = (func)))     \
0111             return val;     \
0112     } while (0)
0113 
0114 struct st7789v {
0115     struct drm_panel panel;
0116     struct spi_device *spi;
0117     struct gpio_desc *reset;
0118     struct regulator *power;
0119 };
0120 
0121 enum st7789v_prefix {
0122     ST7789V_COMMAND = 0,
0123     ST7789V_DATA = 1,
0124 };
0125 
0126 static inline struct st7789v *panel_to_st7789v(struct drm_panel *panel)
0127 {
0128     return container_of(panel, struct st7789v, panel);
0129 }
0130 
0131 static int st7789v_spi_write(struct st7789v *ctx, enum st7789v_prefix prefix,
0132                  u8 data)
0133 {
0134     struct spi_transfer xfer = { };
0135     struct spi_message msg;
0136     u16 txbuf = ((prefix & 1) << 8) | data;
0137 
0138     spi_message_init(&msg);
0139 
0140     xfer.tx_buf = &txbuf;
0141     xfer.bits_per_word = 9;
0142     xfer.len = sizeof(txbuf);
0143 
0144     spi_message_add_tail(&xfer, &msg);
0145     return spi_sync(ctx->spi, &msg);
0146 }
0147 
0148 static int st7789v_write_command(struct st7789v *ctx, u8 cmd)
0149 {
0150     return st7789v_spi_write(ctx, ST7789V_COMMAND, cmd);
0151 }
0152 
0153 static int st7789v_write_data(struct st7789v *ctx, u8 cmd)
0154 {
0155     return st7789v_spi_write(ctx, ST7789V_DATA, cmd);
0156 }
0157 
0158 static const struct drm_display_mode default_mode = {
0159     .clock = 7000,
0160     .hdisplay = 240,
0161     .hsync_start = 240 + 38,
0162     .hsync_end = 240 + 38 + 10,
0163     .htotal = 240 + 38 + 10 + 10,
0164     .vdisplay = 320,
0165     .vsync_start = 320 + 8,
0166     .vsync_end = 320 + 8 + 4,
0167     .vtotal = 320 + 8 + 4 + 4,
0168 };
0169 
0170 static int st7789v_get_modes(struct drm_panel *panel,
0171                  struct drm_connector *connector)
0172 {
0173     struct drm_display_mode *mode;
0174 
0175     mode = drm_mode_duplicate(connector->dev, &default_mode);
0176     if (!mode) {
0177         dev_err(panel->dev, "failed to add mode %ux%ux@%u\n",
0178             default_mode.hdisplay, default_mode.vdisplay,
0179             drm_mode_vrefresh(&default_mode));
0180         return -ENOMEM;
0181     }
0182 
0183     drm_mode_set_name(mode);
0184 
0185     mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
0186     drm_mode_probed_add(connector, mode);
0187 
0188     connector->display_info.width_mm = 61;
0189     connector->display_info.height_mm = 103;
0190 
0191     return 1;
0192 }
0193 
0194 static int st7789v_prepare(struct drm_panel *panel)
0195 {
0196     struct st7789v *ctx = panel_to_st7789v(panel);
0197     int ret;
0198 
0199     ret = regulator_enable(ctx->power);
0200     if (ret)
0201         return ret;
0202 
0203     gpiod_set_value(ctx->reset, 1);
0204     msleep(30);
0205     gpiod_set_value(ctx->reset, 0);
0206     msleep(120);
0207 
0208     ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_EXIT_SLEEP_MODE));
0209 
0210     /* We need to wait 120ms after a sleep out command */
0211     msleep(120);
0212 
0213     ST7789V_TEST(ret, st7789v_write_command(ctx,
0214                         MIPI_DCS_SET_ADDRESS_MODE));
0215     ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
0216 
0217     ST7789V_TEST(ret, st7789v_write_command(ctx,
0218                         MIPI_DCS_SET_PIXEL_FORMAT));
0219     ST7789V_TEST(ret, st7789v_write_data(ctx,
0220                          (MIPI_DCS_PIXEL_FMT_18BIT << 4) |
0221                          (MIPI_DCS_PIXEL_FMT_18BIT)));
0222 
0223     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PORCTRL_CMD));
0224     ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
0225     ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc));
0226     ST7789V_TEST(ret, st7789v_write_data(ctx, 0));
0227     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PORCTRL_IDLE_BP(3) |
0228                          ST7789V_PORCTRL_IDLE_FP(3)));
0229     ST7789V_TEST(ret, st7789v_write_data(ctx,
0230                          ST7789V_PORCTRL_PARTIAL_BP(3) |
0231                          ST7789V_PORCTRL_PARTIAL_FP(3)));
0232 
0233     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_GCTRL_CMD));
0234     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_GCTRL_VGLS(5) |
0235                          ST7789V_GCTRL_VGHS(3)));
0236 
0237     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VCOMS_CMD));
0238     ST7789V_TEST(ret, st7789v_write_data(ctx, 0x2b));
0239 
0240     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_LCMCTRL_CMD));
0241     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_LCMCTRL_XMH |
0242                          ST7789V_LCMCTRL_XMX |
0243                          ST7789V_LCMCTRL_XBGR));
0244 
0245     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVVRHEN_CMD));
0246     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_VDVVRHEN_CMDEN));
0247 
0248     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VRHS_CMD));
0249     ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
0250 
0251     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_VDVS_CMD));
0252     ST7789V_TEST(ret, st7789v_write_data(ctx, 0x20));
0253 
0254     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_FRCTRL2_CMD));
0255     ST7789V_TEST(ret, st7789v_write_data(ctx, 0xf));
0256 
0257     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PWCTRL1_CMD));
0258     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_MAGIC));
0259     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PWCTRL1_AVDD(2) |
0260                          ST7789V_PWCTRL1_AVCL(2) |
0261                          ST7789V_PWCTRL1_VDS(1)));
0262 
0263     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PVGAMCTRL_CMD));
0264     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP63(0xd)));
0265     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP1(0xca)));
0266     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP2(0xe)));
0267     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP4(8)));
0268     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP6(9)));
0269     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP13(7)));
0270     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP20(0x2d)));
0271     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP27(0xb) |
0272                          ST7789V_PVGAMCTRL_VP36(3)));
0273     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP43(0x3d)));
0274     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_JP1(3) |
0275                          ST7789V_PVGAMCTRL_VP50(4)));
0276     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP57(0xa)));
0277     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP59(0xa)));
0278     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP61(0x1b)));
0279     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_PVGAMCTRL_VP62(0x28)));
0280 
0281     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_NVGAMCTRL_CMD));
0282     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN63(0xd)));
0283     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN1(0xca)));
0284     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN2(0xf)));
0285     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN4(8)));
0286     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN6(8)));
0287     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN13(7)));
0288     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN20(0x2e)));
0289     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN27(0xc) |
0290                          ST7789V_NVGAMCTRL_VN36(5)));
0291     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN43(0x40)));
0292     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_JN1(3) |
0293                          ST7789V_NVGAMCTRL_VN50(4)));
0294     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN57(9)));
0295     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN59(0xb)));
0296     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN61(0x1b)));
0297     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN62(0x28)));
0298 
0299     ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_INVERT_MODE));
0300 
0301     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RAMCTRL_CMD));
0302     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_DM_RGB |
0303                          ST7789V_RAMCTRL_RM_RGB));
0304     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_EPF(3) |
0305                          ST7789V_RAMCTRL_MAGIC));
0306 
0307     ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RGBCTRL_CMD));
0308     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_WO |
0309                          ST7789V_RGBCTRL_RCM(2) |
0310                          ST7789V_RGBCTRL_VSYNC_HIGH |
0311                          ST7789V_RGBCTRL_HSYNC_HIGH |
0312                          ST7789V_RGBCTRL_PCLK_HIGH));
0313     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_VBP(8)));
0314     ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_HBP(20)));
0315 
0316     return 0;
0317 }
0318 
0319 static int st7789v_enable(struct drm_panel *panel)
0320 {
0321     struct st7789v *ctx = panel_to_st7789v(panel);
0322 
0323     return st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_ON);
0324 }
0325 
0326 static int st7789v_disable(struct drm_panel *panel)
0327 {
0328     struct st7789v *ctx = panel_to_st7789v(panel);
0329     int ret;
0330 
0331     ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_SET_DISPLAY_OFF));
0332 
0333     return 0;
0334 }
0335 
0336 static int st7789v_unprepare(struct drm_panel *panel)
0337 {
0338     struct st7789v *ctx = panel_to_st7789v(panel);
0339     int ret;
0340 
0341     ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_SLEEP_MODE));
0342 
0343     regulator_disable(ctx->power);
0344 
0345     return 0;
0346 }
0347 
0348 static const struct drm_panel_funcs st7789v_drm_funcs = {
0349     .disable    = st7789v_disable,
0350     .enable     = st7789v_enable,
0351     .get_modes  = st7789v_get_modes,
0352     .prepare    = st7789v_prepare,
0353     .unprepare  = st7789v_unprepare,
0354 };
0355 
0356 static int st7789v_probe(struct spi_device *spi)
0357 {
0358     struct st7789v *ctx;
0359     int ret;
0360 
0361     ctx = devm_kzalloc(&spi->dev, sizeof(*ctx), GFP_KERNEL);
0362     if (!ctx)
0363         return -ENOMEM;
0364 
0365     spi_set_drvdata(spi, ctx);
0366     ctx->spi = spi;
0367 
0368     drm_panel_init(&ctx->panel, &spi->dev, &st7789v_drm_funcs,
0369                DRM_MODE_CONNECTOR_DPI);
0370 
0371     ctx->power = devm_regulator_get(&spi->dev, "power");
0372     if (IS_ERR(ctx->power))
0373         return PTR_ERR(ctx->power);
0374 
0375     ctx->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
0376     if (IS_ERR(ctx->reset)) {
0377         dev_err(&spi->dev, "Couldn't get our reset line\n");
0378         return PTR_ERR(ctx->reset);
0379     }
0380 
0381     ret = drm_panel_of_backlight(&ctx->panel);
0382     if (ret)
0383         return ret;
0384 
0385     drm_panel_add(&ctx->panel);
0386 
0387     return 0;
0388 }
0389 
0390 static void st7789v_remove(struct spi_device *spi)
0391 {
0392     struct st7789v *ctx = spi_get_drvdata(spi);
0393 
0394     drm_panel_remove(&ctx->panel);
0395 }
0396 
0397 static const struct of_device_id st7789v_of_match[] = {
0398     { .compatible = "sitronix,st7789v" },
0399     { }
0400 };
0401 MODULE_DEVICE_TABLE(of, st7789v_of_match);
0402 
0403 static struct spi_driver st7789v_driver = {
0404     .probe = st7789v_probe,
0405     .remove = st7789v_remove,
0406     .driver = {
0407         .name = "st7789v",
0408         .of_match_table = st7789v_of_match,
0409     },
0410 };
0411 module_spi_driver(st7789v_driver);
0412 
0413 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
0414 MODULE_DESCRIPTION("Sitronix st7789v LCD Driver");
0415 MODULE_LICENSE("GPL v2");