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