1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Panels based on the Ilitek ILI9882T display controller. 4 */ 5 #include <linux/delay.h> 6 #include <linux/gpio/consumer.h> 7 #include <linux/module.h> 8 #include <linux/of.h> 9 #include <linux/regulator/consumer.h> 10 11 #include <drm/display/drm_dsc.h> 12 #include <drm/display/drm_dsc_helper.h> 13 #include <drm/drm_connector.h> 14 #include <drm/drm_crtc.h> 15 #include <drm/drm_mipi_dsi.h> 16 #include <drm/drm_of.h> 17 #include <drm/drm_panel.h> 18 19 #include <video/mipi_display.h> 20 21 #define DSC_BPG_OFFSET(x) ((u8)((x) & DSC_RANGE_BPG_OFFSET_MASK)) 22 23 struct ili9882t; 24 25 /* 26 * Use this descriptor struct to describe different panels using the 27 * Ilitek ILI9882T display controller. 28 */ 29 struct panel_desc { 30 const struct drm_display_mode *modes; 31 const struct drm_dsc_config *dsc; 32 unsigned int bpc; 33 34 /** 35 * @width_mm: width of the panel's active display area 36 * @height_mm: height of the panel's active display area 37 */ 38 struct { 39 unsigned int width_mm; 40 unsigned int height_mm; 41 } size; 42 43 unsigned long mode_flags; 44 enum mipi_dsi_pixel_format format; 45 int (*init)(struct ili9882t *boe); 46 unsigned int lanes; 47 }; 48 49 struct ili9882t { 50 struct drm_panel base; 51 struct mipi_dsi_device *dsi; 52 53 const struct panel_desc *desc; 54 55 enum drm_panel_orientation orientation; 56 struct regulator *pp3300; 57 struct regulator *pp1800; 58 struct regulator *avee; 59 struct regulator *avdd; 60 struct gpio_desc *enable_gpio; 61 62 struct drm_dsc_config dsc; 63 }; 64 65 /* ILI9882-specific commands, add new commands as you decode them */ 66 #define ILI9882T_DCS_SWITCH_PAGE 0xFF 67 68 #define ili9882t_switch_page(ctx, page) \ 69 mipi_dsi_dcs_write_seq_multi(ctx, ILI9882T_DCS_SWITCH_PAGE, \ 70 0x98, 0x82, (page)) 71 72 /* IL79900A-specific commands, add new commands as you decode them */ 73 #define IL79900A_DCS_SWITCH_PAGE 0xFF 74 75 #define il79900a_switch_page(ctx, page) \ 76 mipi_dsi_dcs_write_seq_multi(ctx, IL79900A_DCS_SWITCH_PAGE, \ 77 0x5a, 0xa5, (page)) 78 79 static const struct drm_dsc_config tianma_il79900a_dsc = { 80 .dsc_version_major = 1, 81 .dsc_version_minor = 2, 82 .slice_height = 8, 83 .slice_width = 800, 84 .slice_count = 2, 85 .bits_per_component = 8, 86 .bits_per_pixel = 8 << 4, 87 .block_pred_enable = true, 88 .native_420 = false, 89 .native_422 = false, 90 .simple_422 = false, 91 .vbr_enable = false, 92 .pic_width = 1600, 93 .pic_height = 2560, 94 .convert_rgb = 0, 95 .rc_buf_thresh = {14, 28, 42, 56, 70, 84, 98, 105, 112, 119, 121, 123, 125, 126}, 96 .rc_model_size = DSC_RC_MODEL_SIZE_CONST, 97 .rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST, 98 .rc_tgt_offset_high = DSC_RC_TGT_OFFSET_HI_CONST, 99 .rc_tgt_offset_low = DSC_RC_TGT_OFFSET_LO_CONST, 100 .mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC, 101 .line_buf_depth = 9, 102 .first_line_bpg_offset = 12, 103 .initial_xmit_delay = 512, 104 .initial_offset = 6144, 105 .rc_quant_incr_limit0 = 11, 106 .rc_quant_incr_limit1 = 11, 107 .rc_range_params = { 108 { 0, 4, DSC_BPG_OFFSET(2)}, 109 { 0, 4, DSC_BPG_OFFSET(0)}, 110 { 1, 5, DSC_BPG_OFFSET(0)}, 111 { 1, 6, DSC_BPG_OFFSET(-2)}, 112 { 3, 7, DSC_BPG_OFFSET(-4)}, 113 { 3, 7, DSC_BPG_OFFSET(-6)}, 114 { 3, 7, DSC_BPG_OFFSET(-8)}, 115 { 3, 8, DSC_BPG_OFFSET(-8)}, 116 { 3, 9, DSC_BPG_OFFSET(-8)}, 117 { 3, 10, DSC_BPG_OFFSET(-10)}, 118 { 5, 10, DSC_BPG_OFFSET(-10)}, 119 { 5, 11, DSC_BPG_OFFSET(-12)}, 120 { 5, 11, DSC_BPG_OFFSET(-12)}, 121 { 9, 12, DSC_BPG_OFFSET(-12)}, 122 {12, 13, DSC_BPG_OFFSET(-12)}, 123 }, 124 .slice_chunk_size = 800, 125 .initial_dec_delay = 657, 126 .final_offset = 4320, 127 .scale_increment_interval = 222, 128 .scale_decrement_interval = 11, 129 .initial_scale_value = 32, 130 .nfl_bpg_offset = 3511, 131 .slice_bpg_offset = 2179, 132 .flatness_max_qp = 12, 133 .flatness_min_qp = 3, 134 }; 135 136 static int starry_ili9882t_init(struct ili9882t *ili) 137 { 138 struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi }; 139 140 usleep_range(5000, 5100); 141 142 ili9882t_switch_page(&ctx, 0x01); 143 mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x42); 144 mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x11); 145 mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x00); 146 mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x00); 147 148 mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x01); 149 mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x11); 150 mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x00); 151 mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x00); 152 153 mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x80); 154 mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x81); 155 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x71); 156 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x00); 157 158 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x00); 159 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x1a); 160 161 mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00); 162 mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x00); 163 mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x00); 164 mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00); 165 166 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0xd4); 167 mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x40); 168 169 mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x11); 170 171 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x32); 172 mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x30); 173 174 mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55); 175 176 mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x01); 177 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x93); 178 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x00); 179 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x80); 180 181 mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x07); 182 mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x07); 183 mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x07); 184 mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x07); 185 mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x07); 186 mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x01); 187 mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x00); 188 mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x28); 189 mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x29); 190 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x11); 191 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x13); 192 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x15); 193 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x17); 194 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x09); 195 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x0d); 196 mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x02); 197 mipi_dsi_dcs_write_seq_multi(&ctx, 0x41, 0x02); 198 mipi_dsi_dcs_write_seq_multi(&ctx, 0x42, 0x02); 199 mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x02); 200 mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x02); 201 mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x02); 202 mipi_dsi_dcs_write_seq_multi(&ctx, 0x46, 0x02); 203 204 mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x07); 205 mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x07); 206 mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x07); 207 mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x07); 208 mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x07); 209 mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x01); 210 mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x00); 211 mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x28); 212 mipi_dsi_dcs_write_seq_multi(&ctx, 0x4f, 0x29); 213 mipi_dsi_dcs_write_seq_multi(&ctx, 0x50, 0x10); 214 mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x12); 215 mipi_dsi_dcs_write_seq_multi(&ctx, 0x52, 0x14); 216 mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x16); 217 mipi_dsi_dcs_write_seq_multi(&ctx, 0x54, 0x08); 218 mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x0c); 219 mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x02); 220 mipi_dsi_dcs_write_seq_multi(&ctx, 0x57, 0x02); 221 mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x02); 222 mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x02); 223 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x02); 224 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x02); 225 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x02); 226 227 mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x07); 228 mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x07); 229 mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x07); 230 mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x07); 231 mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x07); 232 mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x01); 233 mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x00); 234 mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x28); 235 mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x29); 236 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x16); 237 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x14); 238 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x12); 239 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x10); 240 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x0c); 241 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6f, 0x08); 242 mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x02); 243 mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x02); 244 mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x02); 245 mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0x02); 246 mipi_dsi_dcs_write_seq_multi(&ctx, 0x74, 0x02); 247 mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0x02); 248 mipi_dsi_dcs_write_seq_multi(&ctx, 0x76, 0x02); 249 250 mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x07); 251 mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x07); 252 mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x07); 253 mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x07); 254 mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0x07); 255 mipi_dsi_dcs_write_seq_multi(&ctx, 0x7c, 0x01); 256 mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x00); 257 mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x28); 258 mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x29); 259 mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x17); 260 mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x15); 261 mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x13); 262 mipi_dsi_dcs_write_seq_multi(&ctx, 0x83, 0x11); 263 mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x0d); 264 mipi_dsi_dcs_write_seq_multi(&ctx, 0x85, 0x09); 265 mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x02); 266 mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x07); 267 mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x07); 268 mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x07); 269 mipi_dsi_dcs_write_seq_multi(&ctx, 0x8a, 0x07); 270 mipi_dsi_dcs_write_seq_multi(&ctx, 0x8b, 0x07); 271 mipi_dsi_dcs_write_seq_multi(&ctx, 0x8c, 0x07); 272 273 ili9882t_switch_page(&ctx, 0x02); 274 mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x3a); 275 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x3b); 276 277 mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x01); 278 mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x01); 279 mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x0c); 280 mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x44); 281 282 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a); 283 mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x11); 284 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x00); 285 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0c); 286 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x44); 287 288 mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x1f); 289 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40); 290 mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x00); 291 292 ili9882t_switch_page(&ctx, 0x03); 293 mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x01); 294 mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x3c); 295 mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0xfa); 296 297 ili9882t_switch_page(&ctx, 0x0a); 298 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x01); 299 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x01); 300 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x91); 301 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x3c); 302 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00); 303 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0xfa); 304 305 ili9882t_switch_page(&ctx, 0x12); 306 mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x2c); 307 308 ili9882t_switch_page(&ctx, 0x05); 309 mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0xe5); 310 mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x6b); 311 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0xa4); 312 mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x54); 313 mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x97); 314 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x97); 315 mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x3f); 316 mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0xda); 317 mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xf1); 318 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x01); 319 mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x3f); 320 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x90); 321 mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87); 322 323 ili9882t_switch_page(&ctx, 0x06); 324 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x80); 325 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x07); 326 mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x58); 327 mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x02); 328 mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x58); 329 mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x02); 330 mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x60); 331 mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x00); 332 mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22); 333 mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x08); 334 mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55); 335 mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x38); 336 337 ili9882t_switch_page(&ctx, 0x08); 338 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e, 339 0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce, 340 0xc6, 0xbd, 0xd5, 0xe2, 0xe8); 341 mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e, 342 0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce, 343 0xc6, 0xbd, 0xd5, 0xe2, 0xe8); 344 345 ili9882t_switch_page(&ctx, 0x04); 346 mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x81); 347 348 ili9882t_switch_page(&ctx, 0x0c); 349 mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x02); 350 mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x00); 351 mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x03); 352 mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x01); 353 mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x03); 354 mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x02); 355 mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x04); 356 mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x03); 357 mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x03); 358 mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x04); 359 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x04); 360 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x05); 361 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x04); 362 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x06); 363 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x05); 364 mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x07); 365 mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x04); 366 mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x08); 367 mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x05); 368 mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x09); 369 mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x05); 370 mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x0a); 371 mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x06); 372 mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x0b); 373 mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x05); 374 mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0c); 375 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x06); 376 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0d); 377 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x06); 378 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x0e); 379 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x07); 380 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x0f); 381 mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x06); 382 mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x10); 383 mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x07); 384 mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x11); 385 mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x07); 386 mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x12); 387 mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x08); 388 mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x13); 389 mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x07); 390 mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x14); 391 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x08); 392 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x15); 393 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0x08); 394 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x16); 395 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2e, 0x09); 396 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x17); 397 mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x08); 398 mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x18); 399 mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x09); 400 mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x19); 401 mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x09); 402 mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x1a); 403 mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x0a); 404 mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x1b); 405 mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x0a); 406 mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x1c); 407 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0a); 408 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x1d); 409 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a); 410 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x1e); 411 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x0a); 412 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x1f); 413 414 ili9882t_switch_page(&ctx, 0x04); 415 mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x01); 416 417 ili9882t_switch_page(&ctx, 0x0e); 418 mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x0c); 419 mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x10); 420 mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x16); 421 mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xe0); 422 mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00); 423 mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x71); 424 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x46); 425 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x1f); 426 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0xc7); 427 mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x02); 428 mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0xdf); 429 mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x5a); 430 mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0xc0); 431 mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x5a); 432 mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0xc0); 433 mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x65); 434 mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x3e); 435 mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0xa0); 436 mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01); 437 mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0xcc); 438 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x12); 439 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xcc); 440 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcc); 441 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xcc); 442 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xcc); 443 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xcc); 444 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xcc); 445 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xcc); 446 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0xcc); 447 mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x00); 448 mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x81); 449 mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x02); 450 mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x00); 451 mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x21); 452 mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x10); 453 454 ili9882t_switch_page(&ctx, 0x1e); 455 mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00); 456 mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x00); 457 mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x00); 458 459 ili9882t_switch_page(&ctx, 0x0b); 460 mipi_dsi_dcs_write_seq_multi(&ctx, 0xa6, 0x44); 461 mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xb6); 462 mipi_dsi_dcs_write_seq_multi(&ctx, 0xa8, 0x03); 463 mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x03); 464 mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x51); 465 mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x51); 466 mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x04); 467 mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x92); 468 mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa1); 469 470 ili9882t_switch_page(&ctx, 0x05); 471 mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87); 472 473 ili9882t_switch_page(&ctx, 0x06); 474 mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22); 475 476 ili9882t_switch_page(&ctx, 0x00); 477 mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); 478 479 mipi_dsi_msleep(&ctx, 120); 480 481 mipi_dsi_dcs_set_display_on_multi(&ctx); 482 483 mipi_dsi_msleep(&ctx, 20); 484 485 return ctx.accum_err; 486 }; 487 488 static int tianma_il79900a_init(struct ili9882t *ili) 489 { 490 struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi }; 491 struct drm_dsc_picture_parameter_set pps; 492 493 mipi_dsi_usleep_range(&ctx, 5000, 5100); 494 495 il79900a_switch_page(&ctx, 0x06); 496 mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x62); 497 498 il79900a_switch_page(&ctx, 0x01); 499 mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00); 500 501 il79900a_switch_page(&ctx, 0x02); 502 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x00); 503 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00); 504 mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40); 505 506 il79900a_switch_page(&ctx, 0x05); 507 mipi_dsi_dcs_write_seq_multi(&ctx, 0X9e, 0xe9); 508 509 il79900a_switch_page(&ctx, 0x07); 510 mipi_dsi_dcs_write_seq_multi(&ctx, 0X29, 0x01); 511 512 il79900a_switch_page(&ctx, 0x17); 513 mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 514 0x00, 0x89, 0x30, 0x80, 0x0a, 0x00, 0x06, 0x40, 0x00, 515 0x08, 0x03, 0x20, 0x03, 0x20, 0x02, 0x00, 0x02, 0x91, 516 0x00, 0x20, 0x00, 0xde, 0x00, 0x0b, 0x00, 0x0c, 0x0d, 517 0xb7, 0x08, 0x83, 0x18, 0x00, 0x10, 0xe0, 0x03, 0x0c, 518 0x20, 0x00, 0x06, 0x0b, 0x0b, 0x33, 0x0e, 0x1c, 0x2a, 519 0x38, 0x46, 0x54, 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b, 520 0x7d, 0x7e, 0x01, 0x02, 0x01, 0x00, 0x09, 0x40, 0x09, 521 0xbe, 0x19, 0xfc, 0x19, 0xfa, 0x19, 0xf8, 0x1a, 0x38, 522 0x1a, 0x78, 0x1a, 0xb6, 0x2a, 0xb6, 0x2a, 0xf4, 0x2a, 523 0xf4, 0x4b, 0x34, 0x63, 0x74); 524 525 il79900a_switch_page(&ctx, 0x06); 526 mipi_dsi_dcs_write_seq_multi(&ctx, 0x91, 0x45); 527 528 il79900a_switch_page(&ctx, 0x16); 529 mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x4b); 530 mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x73); 531 mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0xdf); 532 mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x01); 533 534 il79900a_switch_page(&ctx, 0x10); 535 mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x8c); 536 mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x3c); 537 mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x3d); 538 mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0xfc); 539 mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x9d); 540 541 il79900a_switch_page(&ctx, 0x0e); 542 mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x18); 543 mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x0e); 544 mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0xcd); 545 mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x53); 546 mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x0e); 547 548 il79900a_switch_page(&ctx, 0x1e); 549 mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x5c); 550 551 drm_dsc_pps_payload_pack(&pps, &tianma_il79900a_dsc); 552 553 mipi_dsi_picture_parameter_set_multi(&ctx, &pps); 554 555 mipi_dsi_compression_mode_ext_multi(&ctx, true, 556 MIPI_DSI_COMPRESSION_DSC, 1); 557 558 il79900a_switch_page(&ctx, 0x00); 559 mipi_dsi_dcs_exit_sleep_mode_multi(&ctx); 560 561 mipi_dsi_msleep(&ctx, 120); 562 563 mipi_dsi_dcs_set_display_on_multi(&ctx); 564 565 mipi_dsi_msleep(&ctx, 20); 566 567 return ctx.accum_err; 568 }; 569 570 static inline struct ili9882t *to_ili9882t(struct drm_panel *panel) 571 { 572 return container_of(panel, struct ili9882t, base); 573 } 574 575 static int ili9882t_disable(struct drm_panel *panel) 576 { 577 struct ili9882t *ili = to_ili9882t(panel); 578 struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi }; 579 580 ili9882t_switch_page(&ctx, 0x00); 581 582 ili->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; 583 584 mipi_dsi_dcs_set_display_off_multi(&ctx); 585 mipi_dsi_dcs_enter_sleep_mode_multi(&ctx); 586 587 mipi_dsi_msleep(&ctx, 150); 588 589 return ctx.accum_err; 590 } 591 592 static int ili9882t_unprepare(struct drm_panel *panel) 593 { 594 struct ili9882t *ili = to_ili9882t(panel); 595 596 gpiod_set_value_cansleep(ili->enable_gpio, 0); 597 usleep_range(1000, 2000); 598 regulator_disable(ili->avee); 599 regulator_disable(ili->avdd); 600 usleep_range(5000, 7000); 601 regulator_disable(ili->pp1800); 602 regulator_disable(ili->pp3300); 603 604 return 0; 605 } 606 607 static int ili9882t_prepare(struct drm_panel *panel) 608 { 609 struct ili9882t *ili = to_ili9882t(panel); 610 int ret; 611 612 gpiod_set_value_cansleep(ili->enable_gpio, 0); 613 usleep_range(1000, 1500); 614 615 ret = regulator_enable(ili->pp3300); 616 if (ret < 0) 617 return ret; 618 619 ret = regulator_enable(ili->pp1800); 620 if (ret < 0) 621 return ret; 622 623 usleep_range(3000, 5000); 624 625 ret = regulator_enable(ili->avdd); 626 if (ret < 0) 627 goto poweroff1v8; 628 ret = regulator_enable(ili->avee); 629 if (ret < 0) 630 goto poweroffavdd; 631 632 usleep_range(10000, 11000); 633 634 // MIPI needs to keep the LP11 state before the lcm_reset pin is pulled high 635 ret = mipi_dsi_dcs_nop(ili->dsi); 636 if (ret < 0) { 637 dev_err(&ili->dsi->dev, "Failed to send NOP: %d\n", ret); 638 goto poweroff; 639 } 640 usleep_range(1000, 2000); 641 642 gpiod_set_value_cansleep(ili->enable_gpio, 1); 643 usleep_range(1000, 2000); 644 gpiod_set_value_cansleep(ili->enable_gpio, 0); 645 msleep(50); 646 gpiod_set_value_cansleep(ili->enable_gpio, 1); 647 usleep_range(6000, 10000); 648 649 ret = ili->desc->init(ili); 650 if (ret < 0) 651 goto poweroff; 652 653 return 0; 654 655 poweroff: 656 gpiod_set_value_cansleep(ili->enable_gpio, 0); 657 regulator_disable(ili->avee); 658 poweroffavdd: 659 regulator_disable(ili->avdd); 660 poweroff1v8: 661 usleep_range(5000, 7000); 662 regulator_disable(ili->pp1800); 663 664 return ret; 665 } 666 667 static int ili9882t_enable(struct drm_panel *panel) 668 { 669 msleep(130); 670 return 0; 671 } 672 673 static const struct drm_display_mode starry_ili9882t_default_mode = { 674 .clock = 165280, 675 .hdisplay = 1200, 676 .hsync_start = 1200 + 72, 677 .hsync_end = 1200 + 72 + 30, 678 .htotal = 1200 + 72 + 30 + 72, 679 .vdisplay = 1920, 680 .vsync_start = 1920 + 68, 681 .vsync_end = 1920 + 68 + 2, 682 .vtotal = 1920 + 68 + 2 + 10, 683 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 684 }; 685 686 static const struct drm_display_mode tianma_il79900a_default_mode = { 687 .clock = 543850, 688 .hdisplay = 1600, 689 .hsync_start = 1600 + 20, 690 .hsync_end = 1600 + 20 + 2, 691 .htotal = 1600 + 20 + 2 + 20, 692 .vdisplay = 2560, 693 .vsync_start = 2560 + 62, 694 .vsync_end = 2560 + 62 + 2, 695 .vtotal = 2560 + 62 + 2 + 136, 696 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 697 }; 698 699 static const struct panel_desc starry_ili9882t_desc = { 700 .modes = &starry_ili9882t_default_mode, 701 .bpc = 8, 702 .size = { 703 .width_mm = 141, 704 .height_mm = 226, 705 }, 706 .lanes = 4, 707 .format = MIPI_DSI_FMT_RGB888, 708 .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | 709 MIPI_DSI_MODE_LPM, 710 .init = starry_ili9882t_init, 711 }; 712 713 static const struct panel_desc tianma_tl121bvms07_desc = { 714 .modes = &tianma_il79900a_default_mode, 715 .dsc = &tianma_il79900a_dsc, 716 .bpc = 8, 717 .size = { 718 .width_mm = 163, 719 .height_mm = 260, 720 }, 721 .lanes = 3, 722 .format = MIPI_DSI_FMT_RGB888, 723 .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | 724 MIPI_DSI_MODE_LPM, 725 .init = tianma_il79900a_init, 726 }; 727 728 static int ili9882t_get_modes(struct drm_panel *panel, 729 struct drm_connector *connector) 730 { 731 struct ili9882t *ili = to_ili9882t(panel); 732 const struct drm_display_mode *m = ili->desc->modes; 733 struct drm_display_mode *mode; 734 735 mode = drm_mode_duplicate(connector->dev, m); 736 if (!mode) { 737 dev_err(panel->dev, "failed to add mode %ux%u@%u\n", 738 m->hdisplay, m->vdisplay, drm_mode_vrefresh(m)); 739 return -ENOMEM; 740 } 741 742 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 743 drm_mode_set_name(mode); 744 drm_mode_probed_add(connector, mode); 745 746 connector->display_info.width_mm = ili->desc->size.width_mm; 747 connector->display_info.height_mm = ili->desc->size.height_mm; 748 connector->display_info.bpc = ili->desc->bpc; 749 750 return 1; 751 } 752 753 static enum drm_panel_orientation ili9882t_get_orientation(struct drm_panel *panel) 754 { 755 struct ili9882t *ili = to_ili9882t(panel); 756 757 return ili->orientation; 758 } 759 760 static const struct drm_panel_funcs ili9882t_funcs = { 761 .disable = ili9882t_disable, 762 .unprepare = ili9882t_unprepare, 763 .prepare = ili9882t_prepare, 764 .enable = ili9882t_enable, 765 .get_modes = ili9882t_get_modes, 766 .get_orientation = ili9882t_get_orientation, 767 }; 768 769 static int ili9882t_add(struct ili9882t *ili) 770 { 771 struct device *dev = &ili->dsi->dev; 772 int err; 773 774 ili->avdd = devm_regulator_get(dev, "avdd"); 775 if (IS_ERR(ili->avdd)) 776 return PTR_ERR(ili->avdd); 777 778 ili->avee = devm_regulator_get(dev, "avee"); 779 if (IS_ERR(ili->avee)) 780 return PTR_ERR(ili->avee); 781 782 ili->pp3300 = devm_regulator_get(dev, "pp3300"); 783 if (IS_ERR(ili->pp3300)) 784 return PTR_ERR(ili->pp3300); 785 786 ili->pp1800 = devm_regulator_get(dev, "pp1800"); 787 if (IS_ERR(ili->pp1800)) 788 return PTR_ERR(ili->pp1800); 789 790 ili->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); 791 if (IS_ERR(ili->enable_gpio)) { 792 dev_err(dev, "cannot get enable-gpios %ld\n", 793 PTR_ERR(ili->enable_gpio)); 794 return PTR_ERR(ili->enable_gpio); 795 } 796 797 gpiod_set_value_cansleep(ili->enable_gpio, 0); 798 799 err = drm_of_get_panel_orientation(dev->of_node, &ili->orientation); 800 if (err < 0) { 801 dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err); 802 return err; 803 } 804 805 err = drm_panel_of_backlight(&ili->base); 806 if (err) 807 return err; 808 809 ili->base.funcs = &ili9882t_funcs; 810 ili->base.dev = &ili->dsi->dev; 811 812 drm_panel_add(&ili->base); 813 814 return 0; 815 } 816 817 static int ili9882t_probe(struct mipi_dsi_device *dsi) 818 { 819 struct ili9882t *ili; 820 int ret; 821 const struct panel_desc *desc; 822 823 ili = devm_drm_panel_alloc(&dsi->dev, __typeof(*ili), base, 824 &ili9882t_funcs, DRM_MODE_CONNECTOR_DSI); 825 826 if (IS_ERR(ili)) 827 return PTR_ERR(ili); 828 829 desc = of_device_get_match_data(&dsi->dev); 830 dsi->lanes = desc->lanes; 831 dsi->format = desc->format; 832 dsi->mode_flags = desc->mode_flags; 833 ili->desc = desc; 834 ili->dsi = dsi; 835 836 if (desc->dsc) { 837 ili->dsc = *desc->dsc; 838 dsi->dsc = &ili->dsc; 839 } 840 841 ret = ili9882t_add(ili); 842 if (ret < 0) 843 return ret; 844 845 mipi_dsi_set_drvdata(dsi, ili); 846 847 ret = mipi_dsi_attach(dsi); 848 if (ret) 849 drm_panel_remove(&ili->base); 850 851 return ret; 852 } 853 854 static void ili9882t_remove(struct mipi_dsi_device *dsi) 855 { 856 struct ili9882t *ili = mipi_dsi_get_drvdata(dsi); 857 int ret; 858 859 ret = mipi_dsi_detach(dsi); 860 if (ret < 0) 861 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret); 862 863 if (ili->base.dev) 864 drm_panel_remove(&ili->base); 865 } 866 867 static const struct of_device_id ili9882t_of_match[] = { 868 { .compatible = "starry,ili9882t", 869 .data = &starry_ili9882t_desc 870 }, 871 { .compatible = "tianma,tl121bvms07-00", 872 .data = &tianma_tl121bvms07_desc 873 }, 874 { /* sentinel */ } 875 }; 876 MODULE_DEVICE_TABLE(of, ili9882t_of_match); 877 878 static struct mipi_dsi_driver ili9882t_driver = { 879 .driver = { 880 .name = "panel-ili9882t", 881 .of_match_table = ili9882t_of_match, 882 }, 883 .probe = ili9882t_probe, 884 .remove = ili9882t_remove, 885 }; 886 module_mipi_dsi_driver(ili9882t_driver); 887 888 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 889 MODULE_DESCRIPTION("Ilitek ILI9882T-based panels driver"); 890 MODULE_LICENSE("GPL"); 891