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