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