Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Novatek NT35510 panel driver
0004  * Copyright (C) 2020 Linus Walleij <linus.walleij@linaro.org>
0005  * Based on code by Robert Teather (C) 2012 Samsung
0006  *
0007  * This display driver (and I refer to the physical component NT35510,
0008  * not this Linux kernel software driver) can handle:
0009  * 480x864, 480x854, 480x800, 480x720 and 480x640 pixel displays.
0010  * It has 480x840x24bit SRAM embedded for storing a frame.
0011  * When powered on the display is by default in 480x800 mode.
0012  *
0013  * The actual panels using this component have different names, but
0014  * the code needed to set up and configure the panel will be similar,
0015  * so they should all use the NT35510 driver with appropriate configuration
0016  * per-panel, e.g. for physical size.
0017  *
0018  * This driver is for the DSI interface to panels using the NT35510.
0019  *
0020  * The NT35510 can also use an RGB (DPI) interface combined with an
0021  * I2C or SPI interface for setting up the NT35510. If this is needed
0022  * this panel driver should be refactored to also support that use
0023  * case.
0024  */
0025 #include <linux/backlight.h>
0026 #include <linux/bitops.h>
0027 #include <linux/gpio/consumer.h>
0028 #include <linux/module.h>
0029 #include <linux/of_device.h>
0030 #include <linux/regmap.h>
0031 #include <linux/regulator/consumer.h>
0032 
0033 #include <video/mipi_display.h>
0034 
0035 #include <drm/drm_mipi_dsi.h>
0036 #include <drm/drm_modes.h>
0037 #include <drm/drm_panel.h>
0038 
0039 #define MCS_CMD_MAUCCTR     0xF0 /* Manufacturer command enable */
0040 #define MCS_CMD_READ_ID1    0xDA
0041 #define MCS_CMD_READ_ID2    0xDB
0042 #define MCS_CMD_READ_ID3    0xDC
0043 #define MCS_CMD_MTP_READ_SETTING 0xF8 /* Uncertain about name */
0044 #define MCS_CMD_MTP_READ_PARAM 0xFF /* Uncertain about name */
0045 
0046 /*
0047  * These manufacturer commands are available after we enable manufacturer
0048  * command set (MCS) for page 0.
0049  */
0050 #define NT35510_P0_DOPCTR 0xB1
0051 #define NT35510_P0_SDHDTCTR 0xB6
0052 #define NT35510_P0_GSEQCTR 0xB7
0053 #define NT35510_P0_SDEQCTR 0xB8
0054 #define NT35510_P0_SDVPCTR 0xBA
0055 #define NT35510_P0_DPFRCTR1 0xBD
0056 #define NT35510_P0_DPFRCTR2 0xBE
0057 #define NT35510_P0_DPFRCTR3 0xBF
0058 #define NT35510_P0_DPMCTR12 0xCC
0059 
0060 #define NT35510_P0_DOPCTR_LEN 2
0061 #define NT35510_P0_GSEQCTR_LEN 2
0062 #define NT35510_P0_SDEQCTR_LEN 4
0063 #define NT35510_P0_SDVPCTR_LEN 1
0064 #define NT35510_P0_DPFRCTR1_LEN 5
0065 #define NT35510_P0_DPFRCTR2_LEN 5
0066 #define NT35510_P0_DPFRCTR3_LEN 5
0067 #define NT35510_P0_DPMCTR12_LEN 3
0068 
0069 #define NT35510_DOPCTR_0_RAMKP BIT(7) /* Contents kept in sleep */
0070 #define NT35510_DOPCTR_0_DSITE BIT(6) /* Enable TE signal */
0071 #define NT35510_DOPCTR_0_DSIG BIT(5) /* Enable generic read/write */
0072 #define NT35510_DOPCTR_0_DSIM BIT(4) /* Enable video mode on DSI */
0073 #define NT35510_DOPCTR_0_EOTP BIT(3) /* Support EoTP */
0074 #define NT35510_DOPCTR_0_N565 BIT(2) /* RGB or BGR pixel format */
0075 #define NT35510_DOPCTR_1_TW_PWR_SEL BIT(4) /* TE power selector */
0076 #define NT35510_DOPCTR_1_CRGB BIT(3) /* RGB or BGR byte order */
0077 #define NT35510_DOPCTR_1_CTB BIT(2) /* Vertical scanning direction */
0078 #define NT35510_DOPCTR_1_CRL BIT(1) /* Source driver data shift */
0079 #define NT35510_P0_SDVPCTR_PRG BIT(2) /* 0 = normal operation, 1 = VGLO */
0080 #define NT35510_P0_SDVPCTR_AVDD 0 /* source driver output = AVDD */
0081 #define NT35510_P0_SDVPCTR_OFFCOL 1 /* source driver output = off color */
0082 #define NT35510_P0_SDVPCTR_AVSS 2 /* source driver output = AVSS */
0083 #define NT35510_P0_SDVPCTR_HI_Z 3 /* source driver output = High impedance */
0084 
0085 /*
0086  * These manufacturer commands are available after we enable manufacturer
0087  * command set (MCS) for page 1.
0088  */
0089 #define NT35510_P1_SETAVDD 0xB0
0090 #define NT35510_P1_SETAVEE 0xB1
0091 #define NT35510_P1_SETVCL 0xB2
0092 #define NT35510_P1_SETVGH 0xB3
0093 #define NT35510_P1_SETVRGH 0xB4
0094 #define NT35510_P1_SETVGL 0xB5
0095 #define NT35510_P1_BT1CTR 0xB6
0096 #define NT35510_P1_BT2CTR 0xB7
0097 #define NT35510_P1_BT3CTR 0xB8
0098 #define NT35510_P1_BT4CTR 0xB9 /* VGH boosting times/freq */
0099 #define NT35510_P1_BT5CTR 0xBA
0100 #define NT35510_P1_PFMCTR 0xBB
0101 #define NT35510_P1_SETVGP 0xBC
0102 #define NT35510_P1_SETVGN 0xBD
0103 #define NT35510_P1_SETVCMOFF 0xBE
0104 #define NT35510_P1_VGHCTR 0xBF /* VGH output ctrl */
0105 #define NT35510_P1_SET_GAMMA_RED_POS 0xD1
0106 #define NT35510_P1_SET_GAMMA_GREEN_POS 0xD2
0107 #define NT35510_P1_SET_GAMMA_BLUE_POS 0xD3
0108 #define NT35510_P1_SET_GAMMA_RED_NEG 0xD4
0109 #define NT35510_P1_SET_GAMMA_GREEN_NEG 0xD5
0110 #define NT35510_P1_SET_GAMMA_BLUE_NEG 0xD6
0111 
0112 /* AVDD and AVEE setting 3 bytes */
0113 #define NT35510_P1_AVDD_LEN 3
0114 #define NT35510_P1_AVEE_LEN 3
0115 #define NT35510_P1_VGH_LEN 3
0116 #define NT35510_P1_VGL_LEN 3
0117 #define NT35510_P1_VGP_LEN 3
0118 #define NT35510_P1_VGN_LEN 3
0119 /* BT1CTR thru BT5CTR setting 3 bytes */
0120 #define NT35510_P1_BT1CTR_LEN 3
0121 #define NT35510_P1_BT2CTR_LEN 3
0122 #define NT35510_P1_BT4CTR_LEN 3
0123 #define NT35510_P1_BT5CTR_LEN 3
0124 /* 52 gamma parameters times two per color: positive and negative */
0125 #define NT35510_P1_GAMMA_LEN 52
0126 
0127 /**
0128  * struct nt35510_config - the display-specific NT35510 configuration
0129  *
0130  * Some of the settings provide an array of bytes, A, B C which mean:
0131  * A = normal / idle off mode
0132  * B = idle on mode
0133  * C = partial / idle off mode
0134  *
0135  * Gamma correction arrays are 10bit numbers, two consecutive bytes
0136  * makes out one point on the gamma correction curve. The points are
0137  * not linearly placed along the X axis, we get points 0, 1, 3, 5
0138  * 7, 11, 15, 23, 31, 47, 63, 95, 127, 128, 160, 192, 208, 224, 232,
0139  * 240, 244, 248, 250, 252, 254, 255. The voltages tuples form
0140  * V0, V1, V3 ... V255, with 0x0000 being the lowest voltage and
0141  * 0x03FF being the highest voltage.
0142  *
0143  * Each value must be strictly higher than the previous value forming
0144  * a rising curve like this:
0145  *
0146  * ^
0147  * |                                        V255
0148  * |                                 V254
0149  * |                         ....
0150  * |                    V5
0151  * |           V3
0152  * |     V1
0153  * | V0
0154  * +------------------------------------------->
0155  *
0156  * The details about all settings can be found in the NT35510 Application
0157  * Note.
0158  */
0159 struct nt35510_config {
0160     /**
0161      * @width_mm: physical panel width [mm]
0162      */
0163     u32 width_mm;
0164     /**
0165      * @height_mm: physical panel height [mm]
0166      */
0167     u32 height_mm;
0168     /**
0169      * @mode: the display mode. This is only relevant outside the panel
0170      * in video mode: in command mode this is configuring the internal
0171      * timing in the display controller.
0172      */
0173     const struct drm_display_mode mode;
0174     /**
0175      * @avdd: setting for AVDD ranging from 0x00 = 6.5V to 0x14 = 4.5V
0176      * in 0.1V steps the default is 0x05 which means 6.0V
0177      */
0178     u8 avdd[NT35510_P1_AVDD_LEN];
0179     /**
0180      * @bt1ctr: setting for boost power control for the AVDD step-up
0181      * circuit (1)
0182      * bits 0..2 in the lower nibble controls PCK, the booster clock
0183      * frequency for the step-up circuit:
0184      * 0 = Hsync/32
0185      * 1 = Hsync/16
0186      * 2 = Hsync/8
0187      * 3 = Hsync/4
0188      * 4 = Hsync/2
0189      * 5 = Hsync
0190      * 6 = Hsync x 2
0191      * 7 = Hsync x 4
0192      * bits 4..6 in the upper nibble controls BTP, the boosting
0193      * amplification for the step-up circuit:
0194      * 0 = Disable
0195      * 1 = 1.5 x VDDB
0196      * 2 = 1.66 x VDDB
0197      * 3 = 2 x VDDB
0198      * 4 = 2.5 x VDDB
0199      * 5 = 3 x VDDB
0200      * The defaults are 4 and 4 yielding 0x44
0201      */
0202     u8 bt1ctr[NT35510_P1_BT1CTR_LEN];
0203     /**
0204      * @avee: setting for AVEE ranging from 0x00 = -6.5V to 0x14 = -4.5V
0205      * in 0.1V steps the default is 0x05 which means -6.0V
0206      */
0207     u8 avee[NT35510_P1_AVEE_LEN];
0208     /**
0209      * @bt2ctr: setting for boost power control for the AVEE step-up
0210      * circuit (2)
0211      * bits 0..2 in the lower nibble controls NCK, the booster clock
0212      * frequency, the values are the same as for PCK in @bt1ctr.
0213      * bits 4..5 in the upper nibble controls BTN, the boosting
0214      * amplification for the step-up circuit.
0215      * 0 = Disable
0216      * 1 = -1.5 x VDDB
0217      * 2 = -2 x VDDB
0218      * 3 = -2.5 x VDDB
0219      * 4 = -3 x VDDB
0220      * The defaults are 4 and 3 yielding 0x34
0221      */
0222     u8 bt2ctr[NT35510_P1_BT2CTR_LEN];
0223     /**
0224      * @vgh: setting for VGH ranging from 0x00 = 7.0V to 0x0B = 18.0V
0225      * in 1V steps, the default is 0x08 which means 15V
0226      */
0227     u8 vgh[NT35510_P1_VGH_LEN];
0228     /**
0229      * @bt4ctr: setting for boost power control for the VGH step-up
0230      * circuit (4)
0231      * bits 0..2 in the lower nibble controls HCK, the booster clock
0232      * frequency, the values are the same as for PCK in @bt1ctr.
0233      * bits 4..5 in the upper nibble controls BTH, the boosting
0234      * amplification for the the step-up circuit.
0235      * 0 = AVDD + VDDB
0236      * 1 = AVDD - AVEE
0237      * 2 = AVDD - AVEE + VDDB
0238      * 3 = AVDD x 2 - AVEE
0239      * The defaults are 4 and 3 yielding 0x34
0240      */
0241     u8 bt4ctr[NT35510_P1_BT4CTR_LEN];
0242     /**
0243      * @vgl: setting for VGL ranging from 0x00 = -2V to 0x0f = -15V in
0244      * 1V steps, the default is 0x08 which means -10V
0245      */
0246     u8 vgl[NT35510_P1_VGL_LEN];
0247     /**
0248      * @bt5ctr: setting for boost power control for the VGL step-up
0249      * circuit (5)
0250      * bits 0..2 in the lower nibble controls LCK, the booster clock
0251      * frequency, the values are the same as for PCK in @bt1ctr.
0252      * bits 4..5 in the upper nibble controls BTL, the boosting
0253      * amplification for the step-up circuit.
0254      * 0 = AVEE + VCL
0255      * 1 = AVEE - AVDD
0256      * 2 = AVEE + VCL - AVDD
0257      * 3 = AVEE x 2 - AVDD
0258      * The defaults are 3 and 2 yielding 0x32
0259      */
0260     u8 bt5ctr[NT35510_P1_BT5CTR_LEN];
0261     /**
0262      * @vgp: setting for VGP, the positive gamma divider voltages
0263      * VGMP the high voltage and VGSP the low voltage.
0264      * The first byte contains bit 8 of VGMP and VGSP in bits 4 and 0
0265      * The second byte contains bit 0..7 of VGMP
0266      * The third byte contains bit 0..7 of VGSP
0267      * VGMP 0x00 = 3.0V .. 0x108 = 6.3V in steps of 12.5mV
0268      * VGSP 0x00 = 0V .. 0x111 = 3.7V in steps of 12.5mV
0269      */
0270     u8 vgp[NT35510_P1_VGP_LEN];
0271     /**
0272      * @vgn: setting for VGN, the negative gamma divider voltages,
0273      * same layout of bytes as @vgp.
0274      */
0275     u8 vgn[NT35510_P1_VGN_LEN];
0276     /**
0277      * @sdeqctr: Source driver control settings, first byte is
0278      * 0 for mode 1 and 1 for mode 2. Mode 1 uses two steps and
0279      * mode 2 uses three steps meaning EQS3 is not used in mode
0280      * 1. Mode 2 is default. The last three parameters are EQS1, EQS2
0281      * and EQS3, setting the rise time for each equalizer step:
0282      * 0x00 = 0.0 us to 0x0f = 7.5 us in steps of 0.5us. The default
0283      * is 0x07 = 3.5 us.
0284      */
0285     u8 sdeqctr[NT35510_P0_SDEQCTR_LEN];
0286     /**
0287      * @sdvpctr: power/voltage behaviour during vertical porch time
0288      */
0289     u8 sdvpctr;
0290     /**
0291      * @t1: the number of pixel clocks on one scanline, range
0292      * 0x100 (258 ticks) .. 0x3FF (1024 ticks) so the value + 1
0293      * clock ticks.
0294      */
0295     u16 t1;
0296     /**
0297      * @vbp: vertical back porch toward the PANEL note: not toward
0298      * the DSI host; these are separate interfaces, in from DSI host
0299      * and out to the panel.
0300      */
0301     u8 vbp;
0302     /**
0303      * @vfp: vertical front porch toward the PANEL.
0304      */
0305     u8 vfp;
0306     /**
0307      * @psel: pixel clock divisor: 0 = 1, 1 = 2, 2 = 4, 3 = 8.
0308      */
0309     u8 psel;
0310     /**
0311      * @dpmctr12: Display timing control 12
0312      * Byte 1 bit 4 selects LVGL voltage level: 0 = VGLX, 1 = VGL_REG
0313      * Byte 1 bit 1 selects gate signal mode: 0 = non-overlap, 1 = overlap
0314      * Byte 1 bit 0 selects output signal control R/L swap, 0 = normal
0315      * 1 = swap all O->E, L->R
0316      * Byte 2 is CLW delay clock for CK O/E and CKB O/E signals:
0317      * 0x00 = 0us .. 0xFF = 12.75us in 0.05us steps
0318      * Byte 3 is FTI_H0 delay time for STP O/E signals:
0319      * 0x00 = 0us .. 0xFF = 12.75us in 0.05us steps
0320      */
0321     u8 dpmctr12[NT35510_P0_DPMCTR12_LEN];
0322     /**
0323      * @gamma_corr_pos_r: Red gamma correction parameters, positive
0324      */
0325     u8 gamma_corr_pos_r[NT35510_P1_GAMMA_LEN];
0326     /**
0327      * @gamma_corr_pos_g: Green gamma correction parameters, positive
0328      */
0329     u8 gamma_corr_pos_g[NT35510_P1_GAMMA_LEN];
0330     /**
0331      * @gamma_corr_pos_b: Blue gamma correction parameters, positive
0332      */
0333     u8 gamma_corr_pos_b[NT35510_P1_GAMMA_LEN];
0334     /**
0335      * @gamma_corr_neg_r: Red gamma correction parameters, negative
0336      */
0337     u8 gamma_corr_neg_r[NT35510_P1_GAMMA_LEN];
0338     /**
0339      * @gamma_corr_neg_g: Green gamma correction parameters, negative
0340      */
0341     u8 gamma_corr_neg_g[NT35510_P1_GAMMA_LEN];
0342     /**
0343      * @gamma_corr_neg_b: Blue gamma correction parameters, negative
0344      */
0345     u8 gamma_corr_neg_b[NT35510_P1_GAMMA_LEN];
0346 };
0347 
0348 /**
0349  * struct nt35510 - state container for the NT35510 panel
0350  */
0351 struct nt35510 {
0352     /**
0353      * @dev: the container device
0354      */
0355     struct device *dev;
0356     /**
0357      * @conf: the specific panel configuration, as the NT35510
0358      * can be combined with many physical panels, they can have
0359      * different physical dimensions and gamma correction etc,
0360      * so this is stored in the config.
0361      */
0362     const struct nt35510_config *conf;
0363     /**
0364      * @panel: the DRM panel object for the instance
0365      */
0366     struct drm_panel panel;
0367     /**
0368      * @supplies: regulators supplying the panel
0369      */
0370     struct regulator_bulk_data supplies[2];
0371     /**
0372      * @reset_gpio: the reset line
0373      */
0374     struct gpio_desc *reset_gpio;
0375 };
0376 
0377 /* Manufacturer command has strictly this byte sequence */
0378 static const u8 nt35510_mauc_mtp_read_param[] = { 0xAA, 0x55, 0x25, 0x01 };
0379 static const u8 nt35510_mauc_mtp_read_setting[] = { 0x01, 0x02, 0x00, 0x20,
0380                             0x33, 0x13, 0x00, 0x40,
0381                             0x00, 0x00, 0x23, 0x02 };
0382 static const u8 nt35510_mauc_select_page_0[] = { 0x55, 0xAA, 0x52, 0x08, 0x00 };
0383 static const u8 nt35510_mauc_select_page_1[] = { 0x55, 0xAA, 0x52, 0x08, 0x01 };
0384 static const u8 nt35510_vgh_on[] = { 0x01 };
0385 
0386 static inline struct nt35510 *panel_to_nt35510(struct drm_panel *panel)
0387 {
0388     return container_of(panel, struct nt35510, panel);
0389 }
0390 
0391 #define NT35510_ROTATE_0_SETTING    0x02
0392 #define NT35510_ROTATE_180_SETTING  0x00
0393 
0394 static int nt35510_send_long(struct nt35510 *nt, struct mipi_dsi_device *dsi,
0395                  u8 cmd, u8 cmdlen, const u8 *seq)
0396 {
0397     const u8 *seqp = seq;
0398     int cmdwritten = 0;
0399     int chunk = cmdlen;
0400     int ret;
0401 
0402     if (chunk > 15)
0403         chunk = 15;
0404     ret = mipi_dsi_dcs_write(dsi, cmd, seqp, chunk);
0405     if (ret < 0) {
0406         dev_err(nt->dev, "error sending DCS command seq cmd %02x\n", cmd);
0407         return ret;
0408     }
0409     cmdwritten += chunk;
0410     seqp += chunk;
0411 
0412     while (cmdwritten < cmdlen) {
0413         chunk = cmdlen - cmdwritten;
0414         if (chunk > 15)
0415             chunk = 15;
0416         ret = mipi_dsi_generic_write(dsi, seqp, chunk);
0417         if (ret < 0) {
0418             dev_err(nt->dev, "error sending generic write seq %02x\n", cmd);
0419             return ret;
0420         }
0421         cmdwritten += chunk;
0422         seqp += chunk;
0423     }
0424     dev_dbg(nt->dev, "sent command %02x %02x bytes\n", cmd, cmdlen);
0425     return 0;
0426 }
0427 
0428 static int nt35510_read_id(struct nt35510 *nt)
0429 {
0430     struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0431     u8 id1, id2, id3;
0432     int ret;
0433 
0434     ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID1, &id1, 1);
0435     if (ret < 0) {
0436         dev_err(nt->dev, "could not read MTP ID1\n");
0437         return ret;
0438     }
0439     ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID2, &id2, 1);
0440     if (ret < 0) {
0441         dev_err(nt->dev, "could not read MTP ID2\n");
0442         return ret;
0443     }
0444     ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID3, &id3, 1);
0445     if (ret < 0) {
0446         dev_err(nt->dev, "could not read MTP ID3\n");
0447         return ret;
0448     }
0449 
0450     /*
0451      * Multi-Time Programmable (?) memory contains manufacturer
0452      * ID (e.g. Hydis 0x55), driver ID (e.g. NT35510 0xc0) and
0453      * version.
0454      */
0455     dev_info(nt->dev, "MTP ID manufacturer: %02x version: %02x driver: %02x\n", id1, id2, id3);
0456 
0457     return 0;
0458 }
0459 
0460 /**
0461  * nt35510_setup_power() - set up power config in page 1
0462  * @nt: the display instance to set up
0463  */
0464 static int nt35510_setup_power(struct nt35510 *nt)
0465 {
0466     struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0467     int ret;
0468 
0469     ret = nt35510_send_long(nt, dsi, NT35510_P1_SETAVDD,
0470                 NT35510_P1_AVDD_LEN,
0471                 nt->conf->avdd);
0472     if (ret)
0473         return ret;
0474     ret = nt35510_send_long(nt, dsi, NT35510_P1_BT1CTR,
0475                 NT35510_P1_BT1CTR_LEN,
0476                 nt->conf->bt1ctr);
0477     if (ret)
0478         return ret;
0479     ret = nt35510_send_long(nt, dsi, NT35510_P1_SETAVEE,
0480                 NT35510_P1_AVEE_LEN,
0481                 nt->conf->avee);
0482     if (ret)
0483         return ret;
0484     ret = nt35510_send_long(nt, dsi, NT35510_P1_BT2CTR,
0485                 NT35510_P1_BT2CTR_LEN,
0486                 nt->conf->bt2ctr);
0487     if (ret)
0488         return ret;
0489     ret = nt35510_send_long(nt, dsi, NT35510_P1_SETVGH,
0490                 NT35510_P1_VGH_LEN,
0491                 nt->conf->vgh);
0492     if (ret)
0493         return ret;
0494     ret = nt35510_send_long(nt, dsi, NT35510_P1_BT4CTR,
0495                 NT35510_P1_BT4CTR_LEN,
0496                 nt->conf->bt4ctr);
0497     if (ret)
0498         return ret;
0499     ret = nt35510_send_long(nt, dsi, NT35510_P1_VGHCTR,
0500                 ARRAY_SIZE(nt35510_vgh_on),
0501                 nt35510_vgh_on);
0502     if (ret)
0503         return ret;
0504     ret = nt35510_send_long(nt, dsi, NT35510_P1_SETVGL,
0505                 NT35510_P1_VGL_LEN,
0506                 nt->conf->vgl);
0507     if (ret)
0508         return ret;
0509     ret = nt35510_send_long(nt, dsi, NT35510_P1_BT5CTR,
0510                 NT35510_P1_BT5CTR_LEN,
0511                 nt->conf->bt5ctr);
0512     if (ret)
0513         return ret;
0514     ret = nt35510_send_long(nt, dsi, NT35510_P1_SETVGP,
0515                 NT35510_P1_VGP_LEN,
0516                 nt->conf->vgp);
0517     if (ret)
0518         return ret;
0519     ret = nt35510_send_long(nt, dsi, NT35510_P1_SETVGN,
0520                 NT35510_P1_VGN_LEN,
0521                 nt->conf->vgn);
0522     if (ret)
0523         return ret;
0524 
0525     /* Typically 10 ms */
0526     usleep_range(10000, 20000);
0527 
0528     return 0;
0529 }
0530 
0531 /**
0532  * nt35510_setup_display() - set up display config in page 0
0533  * @nt: the display instance to set up
0534  */
0535 static int nt35510_setup_display(struct nt35510 *nt)
0536 {
0537     struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0538     const struct nt35510_config *conf = nt->conf;
0539     u8 dopctr[NT35510_P0_DOPCTR_LEN];
0540     u8 gseqctr[NT35510_P0_GSEQCTR_LEN];
0541     u8 dpfrctr[NT35510_P0_DPFRCTR1_LEN];
0542     /* FIXME: set up any rotation (assume none for now) */
0543     u8 addr_mode = NT35510_ROTATE_0_SETTING;
0544     u8 val;
0545     int ret;
0546 
0547     /* Enable TE, EoTP and RGB pixel format */
0548     dopctr[0] = NT35510_DOPCTR_0_DSITE | NT35510_DOPCTR_0_EOTP |
0549         NT35510_DOPCTR_0_N565;
0550     dopctr[1] = NT35510_DOPCTR_1_CTB;
0551     ret = nt35510_send_long(nt, dsi, NT35510_P0_DOPCTR,
0552                 NT35510_P0_DOPCTR_LEN,
0553                 dopctr);
0554     if (ret)
0555         return ret;
0556 
0557     ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_ADDRESS_MODE, &addr_mode,
0558                  sizeof(addr_mode));
0559     if (ret < 0)
0560         return ret;
0561 
0562     /*
0563      * Source data hold time, default 0x05 = 2.5us
0564      * 0x00..0x3F = 0 .. 31.5us in steps of 0.5us
0565      * 0x0A = 5us
0566      */
0567     val = 0x0A;
0568     ret = mipi_dsi_dcs_write(dsi, NT35510_P0_SDHDTCTR, &val,
0569                  sizeof(val));
0570     if (ret < 0)
0571         return ret;
0572 
0573     /* EQ control for gate signals, 0x00 = 0 us */
0574     gseqctr[0] = 0x00;
0575     gseqctr[1] = 0x00;
0576     ret = nt35510_send_long(nt, dsi, NT35510_P0_GSEQCTR,
0577                 NT35510_P0_GSEQCTR_LEN,
0578                 gseqctr);
0579     if (ret)
0580         return ret;
0581 
0582     ret = nt35510_send_long(nt, dsi, NT35510_P0_SDEQCTR,
0583                 NT35510_P0_SDEQCTR_LEN,
0584                 conf->sdeqctr);
0585     if (ret)
0586         return ret;
0587 
0588     ret = mipi_dsi_dcs_write(dsi, NT35510_P0_SDVPCTR,
0589                  &conf->sdvpctr, 1);
0590     if (ret < 0)
0591         return ret;
0592 
0593     /*
0594      * Display timing control for active and idle off mode:
0595      * the first byte contains
0596      * the two high bits of T1A and second byte the low 8 bits, and
0597      * the valid range is 0x100 (257) to 0x3ff (1023) representing
0598      * 258..1024 (+1) pixel clock ticks for one scanline. At 20MHz pixel
0599      * clock this covers the range of 12.90us .. 51.20us in steps of
0600      * 0.05us, the default is 0x184 (388) representing 389 ticks.
0601      * The third byte is VBPDA, vertical back porch display active
0602      * and the fourth VFPDA, vertical front porch display active,
0603      * both given in number of scanlines in the range 0x02..0xff
0604      * for 2..255 scanlines. The fifth byte is 2 bits selecting
0605      * PSEL for active and idle off mode, how much the 20MHz clock
0606      * is divided by 0..3.  This needs to be adjusted to get the right
0607      * frame rate.
0608      */
0609     dpfrctr[0] = (conf->t1 >> 8) & 0xFF;
0610     dpfrctr[1] = conf->t1 & 0xFF;
0611     /* Vertical back porch */
0612     dpfrctr[2] = conf->vbp;
0613     /* Vertical front porch */
0614     dpfrctr[3] = conf->vfp;
0615     dpfrctr[4] = conf->psel;
0616     ret = nt35510_send_long(nt, dsi, NT35510_P0_DPFRCTR1,
0617                 NT35510_P0_DPFRCTR1_LEN,
0618                 dpfrctr);
0619     if (ret)
0620         return ret;
0621     /* For idle and partial idle off mode we decrease front porch by one */
0622     dpfrctr[3]--;
0623     ret = nt35510_send_long(nt, dsi, NT35510_P0_DPFRCTR2,
0624                 NT35510_P0_DPFRCTR2_LEN,
0625                 dpfrctr);
0626     if (ret)
0627         return ret;
0628     ret = nt35510_send_long(nt, dsi, NT35510_P0_DPFRCTR3,
0629                 NT35510_P0_DPFRCTR3_LEN,
0630                 dpfrctr);
0631     if (ret)
0632         return ret;
0633 
0634     /* Enable TE on vblank */
0635     ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
0636     if (ret)
0637         return ret;
0638 
0639     /* Turn on the pads? */
0640     ret = nt35510_send_long(nt, dsi, NT35510_P0_DPMCTR12,
0641                 NT35510_P0_DPMCTR12_LEN,
0642                 conf->dpmctr12);
0643     if (ret)
0644         return ret;
0645 
0646     return 0;
0647 }
0648 
0649 static int nt35510_set_brightness(struct backlight_device *bl)
0650 {
0651     struct nt35510 *nt = bl_get_data(bl);
0652     struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0653     u8 brightness = bl->props.brightness;
0654     int ret;
0655 
0656     dev_dbg(nt->dev, "set brightness %d\n", brightness);
0657     ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
0658                  &brightness,
0659                  sizeof(brightness));
0660     if (ret < 0)
0661         return ret;
0662 
0663     return 0;
0664 }
0665 
0666 static const struct backlight_ops nt35510_bl_ops = {
0667     .update_status = nt35510_set_brightness,
0668 };
0669 
0670 /*
0671  * This power-on sequence
0672  */
0673 static int nt35510_power_on(struct nt35510 *nt)
0674 {
0675     struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0676     int ret;
0677 
0678     ret = regulator_bulk_enable(ARRAY_SIZE(nt->supplies), nt->supplies);
0679     if (ret < 0) {
0680         dev_err(nt->dev, "unable to enable regulators\n");
0681         return ret;
0682     }
0683 
0684     /* Toggle RESET in accordance with datasheet page 370 */
0685     if (nt->reset_gpio) {
0686         gpiod_set_value(nt->reset_gpio, 1);
0687         /* Active min 10 us according to datasheet, let's say 20 */
0688         usleep_range(20, 1000);
0689         gpiod_set_value(nt->reset_gpio, 0);
0690         /*
0691          * 5 ms during sleep mode, 120 ms during sleep out mode
0692          * according to datasheet, let's use 120-140 ms.
0693          */
0694         usleep_range(120000, 140000);
0695     }
0696 
0697     ret = nt35510_send_long(nt, dsi, MCS_CMD_MTP_READ_PARAM,
0698                 ARRAY_SIZE(nt35510_mauc_mtp_read_param),
0699                 nt35510_mauc_mtp_read_param);
0700     if (ret)
0701         return ret;
0702 
0703     ret = nt35510_send_long(nt, dsi, MCS_CMD_MTP_READ_SETTING,
0704                 ARRAY_SIZE(nt35510_mauc_mtp_read_setting),
0705                 nt35510_mauc_mtp_read_setting);
0706     if (ret)
0707         return ret;
0708 
0709     nt35510_read_id(nt);
0710 
0711     /* Set up stuff in  manufacturer control, page 1 */
0712     ret = nt35510_send_long(nt, dsi, MCS_CMD_MAUCCTR,
0713                 ARRAY_SIZE(nt35510_mauc_select_page_1),
0714                 nt35510_mauc_select_page_1);
0715     if (ret)
0716         return ret;
0717 
0718     ret = nt35510_setup_power(nt);
0719     if (ret)
0720         return ret;
0721 
0722     ret = nt35510_send_long(nt, dsi, NT35510_P1_SET_GAMMA_RED_POS,
0723                 NT35510_P1_GAMMA_LEN,
0724                 nt->conf->gamma_corr_pos_r);
0725     if (ret)
0726         return ret;
0727     ret = nt35510_send_long(nt, dsi, NT35510_P1_SET_GAMMA_GREEN_POS,
0728                 NT35510_P1_GAMMA_LEN,
0729                 nt->conf->gamma_corr_pos_g);
0730     if (ret)
0731         return ret;
0732     ret = nt35510_send_long(nt, dsi, NT35510_P1_SET_GAMMA_BLUE_POS,
0733                 NT35510_P1_GAMMA_LEN,
0734                 nt->conf->gamma_corr_pos_b);
0735     if (ret)
0736         return ret;
0737     ret = nt35510_send_long(nt, dsi, NT35510_P1_SET_GAMMA_RED_NEG,
0738                 NT35510_P1_GAMMA_LEN,
0739                 nt->conf->gamma_corr_neg_r);
0740     if (ret)
0741         return ret;
0742     ret = nt35510_send_long(nt, dsi, NT35510_P1_SET_GAMMA_GREEN_NEG,
0743                 NT35510_P1_GAMMA_LEN,
0744                 nt->conf->gamma_corr_neg_g);
0745     if (ret)
0746         return ret;
0747     ret = nt35510_send_long(nt, dsi, NT35510_P1_SET_GAMMA_BLUE_NEG,
0748                 NT35510_P1_GAMMA_LEN,
0749                 nt->conf->gamma_corr_neg_b);
0750     if (ret)
0751         return ret;
0752 
0753     /* Set up stuff in  manufacturer control, page 0 */
0754     ret = nt35510_send_long(nt, dsi, MCS_CMD_MAUCCTR,
0755                 ARRAY_SIZE(nt35510_mauc_select_page_0),
0756                 nt35510_mauc_select_page_0);
0757     if (ret)
0758         return ret;
0759 
0760     ret = nt35510_setup_display(nt);
0761     if (ret)
0762         return ret;
0763 
0764     return 0;
0765 }
0766 
0767 static int nt35510_power_off(struct nt35510 *nt)
0768 {
0769     int ret;
0770 
0771     ret = regulator_bulk_disable(ARRAY_SIZE(nt->supplies), nt->supplies);
0772     if (ret)
0773         return ret;
0774 
0775     if (nt->reset_gpio)
0776         gpiod_set_value(nt->reset_gpio, 1);
0777 
0778     return 0;
0779 }
0780 
0781 static int nt35510_unprepare(struct drm_panel *panel)
0782 {
0783     struct nt35510 *nt = panel_to_nt35510(panel);
0784     struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0785     int ret;
0786 
0787     ret = mipi_dsi_dcs_set_display_off(dsi);
0788     if (ret) {
0789         dev_err(nt->dev, "failed to turn display off (%d)\n", ret);
0790         return ret;
0791     }
0792     usleep_range(10000, 20000);
0793 
0794     /* Enter sleep mode */
0795     ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
0796     if (ret) {
0797         dev_err(nt->dev, "failed to enter sleep mode (%d)\n", ret);
0798         return ret;
0799     }
0800 
0801     /* Wait 4 frames, how much is that 5ms in the vendor driver */
0802     usleep_range(5000, 10000);
0803 
0804     ret = nt35510_power_off(nt);
0805     if (ret)
0806         return ret;
0807 
0808     return 0;
0809 }
0810 
0811 static int nt35510_prepare(struct drm_panel *panel)
0812 {
0813     struct nt35510 *nt = panel_to_nt35510(panel);
0814     struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
0815     int ret;
0816 
0817     ret = nt35510_power_on(nt);
0818     if (ret)
0819         return ret;
0820 
0821     /* Exit sleep mode */
0822     ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
0823     if (ret) {
0824         dev_err(nt->dev, "failed to exit sleep mode (%d)\n", ret);
0825         return ret;
0826     }
0827     /* Up to 120 ms */
0828     usleep_range(120000, 150000);
0829 
0830     ret = mipi_dsi_dcs_set_display_on(dsi);
0831     if (ret) {
0832         dev_err(nt->dev, "failed to turn display on (%d)\n", ret);
0833         return ret;
0834     }
0835     /* Some 10 ms */
0836     usleep_range(10000, 20000);
0837 
0838     return 0;
0839 }
0840 
0841 static int nt35510_get_modes(struct drm_panel *panel,
0842                  struct drm_connector *connector)
0843 {
0844     struct nt35510 *nt = panel_to_nt35510(panel);
0845     struct drm_display_mode *mode;
0846     struct drm_display_info *info;
0847 
0848     info = &connector->display_info;
0849     info->width_mm = nt->conf->width_mm;
0850     info->height_mm = nt->conf->height_mm;
0851     mode = drm_mode_duplicate(connector->dev, &nt->conf->mode);
0852     if (!mode) {
0853         dev_err(panel->dev, "bad mode or failed to add mode\n");
0854         return -EINVAL;
0855     }
0856     drm_mode_set_name(mode);
0857     mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
0858 
0859     mode->width_mm = nt->conf->width_mm;
0860     mode->height_mm = nt->conf->height_mm;
0861     drm_mode_probed_add(connector, mode);
0862 
0863     return 1; /* Number of modes */
0864 }
0865 
0866 static const struct drm_panel_funcs nt35510_drm_funcs = {
0867     .unprepare = nt35510_unprepare,
0868     .prepare = nt35510_prepare,
0869     .get_modes = nt35510_get_modes,
0870 };
0871 
0872 static int nt35510_probe(struct mipi_dsi_device *dsi)
0873 {
0874     struct device *dev = &dsi->dev;
0875     struct nt35510 *nt;
0876     int ret;
0877 
0878     nt = devm_kzalloc(dev, sizeof(struct nt35510), GFP_KERNEL);
0879     if (!nt)
0880         return -ENOMEM;
0881     mipi_dsi_set_drvdata(dsi, nt);
0882     nt->dev = dev;
0883 
0884     dsi->lanes = 2;
0885     dsi->format = MIPI_DSI_FMT_RGB888;
0886     /*
0887      * Datasheet suggests max HS rate for NT35510 is 250 MHz
0888      * (period time 4ns, see figure 7.6.4 page 365) and max LP rate is
0889      * 20 MHz (period time 50ns, see figure 7.6.6. page 366).
0890      * However these frequencies appear in source code for the Hydis
0891      * HVA40WV1 panel and setting up the LP frequency makes the panel
0892      * not work.
0893      *
0894      * TODO: if other panels prove to be closer to the datasheet,
0895      * maybe make this a per-panel config in struct nt35510_config?
0896      */
0897     dsi->hs_rate = 349440000;
0898     dsi->lp_rate = 9600000;
0899     dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
0900 
0901     /*
0902      * Every new incarnation of this display must have a unique
0903      * data entry for the system in this driver.
0904      */
0905     nt->conf = of_device_get_match_data(dev);
0906     if (!nt->conf) {
0907         dev_err(dev, "missing device configuration\n");
0908         return -ENODEV;
0909     }
0910 
0911     nt->supplies[0].supply = "vdd"; /* 2.3-4.8 V */
0912     nt->supplies[1].supply = "vddi"; /* 1.65-3.3V */
0913     ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(nt->supplies),
0914                       nt->supplies);
0915     if (ret < 0)
0916         return ret;
0917     ret = regulator_set_voltage(nt->supplies[0].consumer,
0918                     2300000, 4800000);
0919     if (ret)
0920         return ret;
0921     ret = regulator_set_voltage(nt->supplies[1].consumer,
0922                     1650000, 3300000);
0923     if (ret)
0924         return ret;
0925 
0926     nt->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
0927     if (IS_ERR(nt->reset_gpio)) {
0928         dev_err(dev, "error getting RESET GPIO\n");
0929         return PTR_ERR(nt->reset_gpio);
0930     }
0931 
0932     drm_panel_init(&nt->panel, dev, &nt35510_drm_funcs,
0933                DRM_MODE_CONNECTOR_DSI);
0934 
0935     /*
0936      * First, try to locate an external backlight (such as on GPIO)
0937      * if this fails, assume we will want to use the internal backlight
0938      * control.
0939      */
0940     ret = drm_panel_of_backlight(&nt->panel);
0941     if (ret) {
0942         dev_err(dev, "error getting external backlight %d\n", ret);
0943         return ret;
0944     }
0945     if (!nt->panel.backlight) {
0946         struct backlight_device *bl;
0947 
0948         bl = devm_backlight_device_register(dev, "nt35510", dev, nt,
0949                             &nt35510_bl_ops, NULL);
0950         if (IS_ERR(bl)) {
0951             dev_err(dev, "failed to register backlight device\n");
0952             return PTR_ERR(bl);
0953         }
0954         bl->props.max_brightness = 255;
0955         bl->props.brightness = 255;
0956         bl->props.power = FB_BLANK_POWERDOWN;
0957         nt->panel.backlight = bl;
0958     }
0959 
0960     drm_panel_add(&nt->panel);
0961 
0962     ret = mipi_dsi_attach(dsi);
0963     if (ret < 0)
0964         drm_panel_remove(&nt->panel);
0965 
0966     return 0;
0967 }
0968 
0969 static int nt35510_remove(struct mipi_dsi_device *dsi)
0970 {
0971     struct nt35510 *nt = mipi_dsi_get_drvdata(dsi);
0972     int ret;
0973 
0974     mipi_dsi_detach(dsi);
0975     /* Power off */
0976     ret = nt35510_power_off(nt);
0977     drm_panel_remove(&nt->panel);
0978 
0979     return ret;
0980 }
0981 
0982 /*
0983  * These gamma correction values are 10bit tuples, so only bits 0 and 1 is
0984  * ever used in the first byte. They form a positive and negative gamma
0985  * correction curve for each color, values must be strictly higher for each
0986  * step on the curve. As can be seen these default curves goes from 0x0001
0987  * to 0x03FE.
0988  */
0989 #define NT35510_GAMMA_POS_DEFAULT 0x00, 0x01, 0x00, 0x43, 0x00, \
0990         0x6B, 0x00, 0x87, 0x00, 0xA3, 0x00, 0xCE, 0x00, 0xF1, 0x01, \
0991         0x27, 0x01, 0x53, 0x01, 0x98, 0x01, 0xCE, 0x02, 0x22, 0x02, \
0992         0x83, 0x02, 0x78, 0x02, 0x9E, 0x02, 0xDD, 0x03, 0x00, 0x03, \
0993         0x2E, 0x03, 0x54, 0x03, 0x7F, 0x03, 0x95, 0x03, 0xB3, 0x03, \
0994         0xC2, 0x03, 0xE1, 0x03, 0xF1, 0x03, 0xFE
0995 
0996 #define NT35510_GAMMA_NEG_DEFAULT 0x00, 0x01, 0x00, 0x43, 0x00, \
0997         0x6B, 0x00, 0x87, 0x00, 0xA3, 0x00, 0xCE, 0x00, 0xF1, 0x01, \
0998         0x27, 0x01, 0x53, 0x01, 0x98, 0x01, 0xCE, 0x02, 0x22, 0x02, \
0999         0x43, 0x02, 0x50, 0x02, 0x9E, 0x02, 0xDD, 0x03, 0x00, 0x03, \
1000         0x2E, 0x03, 0x54, 0x03, 0x7F, 0x03, 0x95, 0x03, 0xB3, 0x03, \
1001         0xC2, 0x03, 0xE1, 0x03, 0xF1, 0x03, 0xFE
1002 
1003 /*
1004  * The Hydis HVA40WV1 panel
1005  */
1006 static const struct nt35510_config nt35510_hydis_hva40wv1 = {
1007     .width_mm = 52,
1008     .height_mm = 86,
1009     /**
1010      * As the Hydis panel is used in command mode, the porches etc
1011      * are settings programmed internally into the NT35510 controller
1012      * and generated toward the physical display. As the panel is not
1013      * used in video mode, these are not really exposed to the DSI
1014      * host.
1015      *
1016      * Display frame rate control:
1017      * Frame rate = (20 MHz / 1) / (389 * (7 + 50 + 800)) ~= 60 Hz
1018      */
1019     .mode = {
1020         /* The internal pixel clock of the NT35510 is 20 MHz */
1021         .clock = 20000,
1022         .hdisplay = 480,
1023         .hsync_start = 480 + 2, /* HFP = 2 */
1024         .hsync_end = 480 + 2 + 0, /* HSync = 0 */
1025         .htotal = 480 + 2 + 0 + 5, /* HFP = 5 */
1026         .vdisplay = 800,
1027         .vsync_start = 800 + 2, /* VFP = 2 */
1028         .vsync_end = 800 + 2 + 0, /* VSync = 0 */
1029         .vtotal = 800 + 2 + 0 + 5, /* VBP = 5 */
1030         .flags = 0,
1031     },
1032     /* 0x09: AVDD = 5.6V */
1033     .avdd = { 0x09, 0x09, 0x09 },
1034     /* 0x34: PCK = Hsync/2, BTP = 2 x VDDB */
1035     .bt1ctr = { 0x34, 0x34, 0x34 },
1036     /* 0x09: AVEE = -5.6V */
1037     .avee = { 0x09, 0x09, 0x09 },
1038     /* 0x24: NCK = Hsync/2, BTN =  -2 x VDDB */
1039     .bt2ctr = { 0x24, 0x24, 0x24 },
1040     /* 0x05 = 12V */
1041     .vgh = { 0x05, 0x05, 0x05 },
1042     /* 0x24: NCKA = Hsync/2, VGH = 2 x AVDD - AVEE */
1043     .bt4ctr = { 0x24, 0x24, 0x24 },
1044     /* 0x0B = -13V */
1045     .vgl = { 0x0B, 0x0B, 0x0B },
1046     /* 0x24: LCKA = Hsync, VGL = AVDD + VCL - AVDD */
1047     .bt5ctr = { 0x24, 0x24, 0x24 },
1048     /* VGMP: 0x0A3 = 5.0375V, VGSP = 0V */
1049     .vgp = { 0x00, 0xA3, 0x00 },
1050     /* VGMP: 0x0A3 = 5.0375V, VGSP = 0V */
1051     .vgn = { 0x00, 0xA3, 0x00 },
1052     /* SDEQCTR: source driver EQ mode 2, 2.5 us rise time on each step */
1053     .sdeqctr = { 0x01, 0x05, 0x05, 0x05 },
1054     /* SDVPCTR: Normal operation off color during v porch */
1055     .sdvpctr = 0x01,
1056     /* T1: number of pixel clocks on one scanline: 0x184 = 389 clocks */
1057     .t1 = 0x0184,
1058     /* VBP: vertical back porch toward the panel */
1059     .vbp = 7,
1060     /* VFP: vertical front porch toward the panel */
1061     .vfp = 50,
1062     /* PSEL: divide pixel clock 20MHz with 1 (no clock downscaling) */
1063     .psel = 0,
1064     /* DPTMCTR12: 0x03: LVGL = VGLX, overlap mode, swap R->L O->E */
1065     .dpmctr12 = { 0x03, 0x00, 0x00, },
1066     /* Default gamma correction values */
1067     .gamma_corr_pos_r = { NT35510_GAMMA_POS_DEFAULT },
1068     .gamma_corr_pos_g = { NT35510_GAMMA_POS_DEFAULT },
1069     .gamma_corr_pos_b = { NT35510_GAMMA_POS_DEFAULT },
1070     .gamma_corr_neg_r = { NT35510_GAMMA_NEG_DEFAULT },
1071     .gamma_corr_neg_g = { NT35510_GAMMA_NEG_DEFAULT },
1072     .gamma_corr_neg_b = { NT35510_GAMMA_NEG_DEFAULT },
1073 };
1074 
1075 static const struct of_device_id nt35510_of_match[] = {
1076     {
1077         .compatible = "hydis,hva40wv1",
1078         .data = &nt35510_hydis_hva40wv1,
1079     },
1080     { }
1081 };
1082 MODULE_DEVICE_TABLE(of, nt35510_of_match);
1083 
1084 static struct mipi_dsi_driver nt35510_driver = {
1085     .probe = nt35510_probe,
1086     .remove = nt35510_remove,
1087     .driver = {
1088         .name = "panel-novatek-nt35510",
1089         .of_match_table = nt35510_of_match,
1090     },
1091 };
1092 module_mipi_dsi_driver(nt35510_driver);
1093 
1094 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
1095 MODULE_DESCRIPTION("NT35510-based panel driver");
1096 MODULE_LICENSE("GPL v2");