1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Samsung AMS561RA01 panel with S6E8AA5X01 controller. 4 * 5 * Copyright (C) 2025 Kaustabh Chakraborty <kauschluss@disroot.org> 6 */ 7 8 #include <linux/backlight.h> 9 #include <linux/gpio/consumer.h> 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/regulator/consumer.h> 13 14 #include <drm/drm_mipi_dsi.h> 15 #include <drm/drm_modes.h> 16 #include <drm/drm_panel.h> 17 #include <drm/drm_probe_helper.h> 18 19 /* Manufacturer Command Set */ 20 #define MCS_AIDCTL 0xb2 21 #define MCS_ADAPTIVECTL 0xb5 22 #define MCS_ELVSS 0xb6 23 #define MCS_TEMPERCTL 0xb8 24 #define MCS_PENTILE 0xc0 25 #define MCS_GAMMACTL 0xca 26 #define MCS_LTPSCTL 0xcb 27 #define MCS_PCD 0xcc 28 #define MCS_ERRFLAG 0xe7 29 #define MCS_ACCESSPROT 0xf0 30 #define MCS_DISPCTL 0xf2 31 #define MCS_GAMMAUPD 0xf7 32 33 #define GAMMA_CMD_LEN 34 34 #define AID_CMD_LEN 3 35 36 static const struct { 37 u8 gamma[GAMMA_CMD_LEN]; 38 u8 aid[AID_CMD_LEN]; 39 } s6e8aa5x01_ams561ra01_cmds[] = { 40 { 41 /* 5 nits */ 42 { MCS_GAMMACTL, 43 0x00, 0x98, 0x00, 0xa4, 0x00, 0x94, 44 0x88, 0x89, 0x8a, 0x87, 0x87, 0x89, 45 0x8d, 0x8c, 0x8d, 0x89, 0x8c, 0x8e, 46 0x8e, 0x8f, 0x90, 0xa3, 0xa2, 0x9a, 47 0xcf, 0xca, 0x9f, 0xe6, 0xff, 0xb4, 48 0x00, 0x00, 0x00, }, 49 { MCS_AIDCTL, 0x05, 0xa5 }, 50 }, { 51 /* 6 nits */ 52 { MCS_GAMMACTL, 53 0x00, 0x98, 0x00, 0xa4, 0x00, 0x95, 54 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 55 0x8c, 0x8a, 0x8c, 0x85, 0x88, 0x8c, 56 0x8b, 0x8c, 0x8e, 0xa2, 0xa2, 0x9a, 57 0xd0, 0xcc, 0xa2, 0xed, 0xff, 0xb7, 58 0x00, 0x00, 0x00, }, 59 { MCS_AIDCTL, 0x05, 0x95 }, 60 }, { 61 /* 7 nits */ 62 { MCS_GAMMACTL, 63 0x00, 0x98, 0x00, 0xa4, 0x00, 0x95, 64 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 65 0x8c, 0x8a, 0x8c, 0x85, 0x88, 0x8c, 66 0x8b, 0x8c, 0x8e, 0xa2, 0xa2, 0x99, 67 0xc8, 0xc4, 0x9d, 0xed, 0xff, 0xb7, 68 0x00, 0x00, 0x00, }, 69 { MCS_AIDCTL, 0x05, 0x89 }, 70 }, { 71 /* 8 nits */ 72 { MCS_GAMMACTL, 73 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 74 0x88, 0x89, 0x8a, 0x87, 0x87, 0x89, 75 0x8a, 0x88, 0x8b, 0x83, 0x86, 0x8b, 76 0x8c, 0x8b, 0x8d, 0x9d, 0x9f, 0x97, 77 0xc7, 0xc3, 0x9c, 0xf5, 0xff, 0xbb, 78 0x00, 0x00, 0x00, }, 79 { MCS_AIDCTL, 0x05, 0x7e }, 80 }, { 81 /* 9 nits */ 82 { MCS_GAMMACTL, 83 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 84 0x88, 0x89, 0x8a, 0x87, 0x87, 0x89, 85 0x89, 0x86, 0x8a, 0x82, 0x84, 0x88, 86 0x90, 0x8f, 0x91, 0x95, 0x97, 0x94, 87 0xc6, 0xc2, 0x9d, 0xf5, 0xff, 0xbb, 88 0x00, 0x00, 0x00, }, 89 { MCS_AIDCTL, 0x05, 0x73 }, 90 }, { 91 /* 10 nits */ 92 { MCS_GAMMACTL, 93 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 94 0x88, 0x89, 0x8a, 0x87, 0x87, 0x89, 95 0x89, 0x86, 0x8a, 0x82, 0x84, 0x88, 96 0x90, 0x8f, 0x91, 0x94, 0x97, 0x93, 97 0xc6, 0xc2, 0x9e, 0xec, 0xff, 0xb7, 98 0x00, 0x00, 0x00, }, 99 { MCS_AIDCTL, 0x05, 0x67 }, 100 }, { 101 /* 11 nits */ 102 { MCS_GAMMACTL, 103 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 104 0x88, 0x89, 0x8a, 0x87, 0x87, 0x89, 105 0x89, 0x86, 0x8a, 0x82, 0x84, 0x88, 106 0x8b, 0x8b, 0x8d, 0x90, 0x93, 0x92, 107 0xc5, 0xc1, 0x9c, 0xf5, 0xff, 0xbb, 108 0x00, 0x00, 0x00, }, 109 { MCS_AIDCTL, 0x05, 0x56 }, 110 }, { 111 /* 12 nits */ 112 { MCS_GAMMACTL, 113 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 114 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 115 0x89, 0x86, 0x89, 0x82, 0x84, 0x88, 116 0x87, 0x86, 0x8a, 0x8c, 0x90, 0x8f, 117 0xcd, 0xc9, 0xa1, 0xec, 0xff, 0xb7, 118 0x00, 0x00, 0x00, }, 119 { MCS_AIDCTL, 0x05, 0x4a }, 120 }, { 121 /* 13 nits */ 122 { MCS_GAMMACTL, 123 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 124 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 125 0x89, 0x86, 0x89, 0x82, 0x84, 0x88, 126 0x87, 0x86, 0x8a, 0x8c, 0x90, 0x8e, 127 0xc4, 0xbf, 0x9c, 0xf5, 0xff, 0xbb, 128 0x00, 0x00, 0x00, }, 129 { MCS_AIDCTL, 0x05, 0x3b }, 130 }, { 131 /* 14 nits */ 132 { MCS_GAMMACTL, 133 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 134 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 135 0x89, 0x86, 0x89, 0x82, 0x84, 0x88, 136 0x87, 0x86, 0x89, 0x8c, 0x90, 0x8f, 137 0xc2, 0xbf, 0x9c, 0xec, 0xff, 0xb7, 138 0x00, 0x00, 0x00, }, 139 { MCS_AIDCTL, 0x05, 0x35 }, 140 }, { 141 /* 15 nits */ 142 { MCS_GAMMACTL, 143 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 144 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 145 0x89, 0x86, 0x89, 0x82, 0x84, 0x88, 146 0x87, 0x86, 0x89, 0x8c, 0x90, 0x8f, 147 0xb7, 0xb6, 0x96, 0xec, 0xff, 0xb7, 148 0x00, 0x00, 0x00, }, 149 { MCS_AIDCTL, 0x05, 0x25 }, 150 }, { 151 /* 16 nits */ 152 { MCS_GAMMACTL, 153 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 154 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 155 0x89, 0x86, 0x89, 0x82, 0x84, 0x88, 156 0x88, 0x86, 0x89, 0x8c, 0x90, 0x8f, 157 0xb7, 0xb6, 0x96, 0xec, 0xff, 0xb7, 158 0x00, 0x00, 0x00, }, 159 { MCS_AIDCTL, 0x05, 0x20 }, 160 }, { 161 /* 17 nits */ 162 { MCS_GAMMACTL, 163 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 164 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 165 0x89, 0x86, 0x89, 0x7f, 0x80, 0x86, 166 0x86, 0x85, 0x89, 0x88, 0x8c, 0x8e, 167 0xbf, 0xbe, 0x9c, 0xec, 0xff, 0xb7, 168 0x00, 0x00, 0x00, }, 169 { MCS_AIDCTL, 0x05, 0x11 }, 170 }, { 171 /* 19 nits */ 172 { MCS_GAMMACTL, 173 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 174 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 175 0x89, 0x86, 0x89, 0x7f, 0x80, 0x86, 176 0x87, 0x85, 0x89, 0x88, 0x8c, 0x8e, 177 0xb3, 0xb4, 0x97, 0xeb, 0xff, 0xb7, 178 0x00, 0x00, 0x00, }, 179 { MCS_AIDCTL, 0x04, 0xf2 }, 180 }, { 181 /* 20 nits */ 182 { MCS_GAMMACTL, 183 0x00, 0x98, 0x00, 0xa4, 0x00, 0x95, 184 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 185 0x89, 0x86, 0x89, 0x7f, 0x80, 0x86, 186 0x87, 0x85, 0x89, 0x89, 0x8c, 0x8e, 187 0xb3, 0xb4, 0x97, 0xeb, 0xff, 0xb7, 188 0x00, 0x00, 0x00, }, 189 { MCS_AIDCTL, 0x04, 0xe4 }, 190 }, { 191 /* 21 nits */ 192 { MCS_GAMMACTL, 193 0x00, 0x98, 0x00, 0xa4, 0x00, 0x96, 194 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 195 0x8a, 0x88, 0x8b, 0x7d, 0x7e, 0x84, 196 0x8c, 0x8a, 0x8c, 0x8e, 0x90, 0x8f, 197 0xb6, 0xb6, 0x97, 0xe3, 0xff, 0xb3, 198 0x00, 0x00, 0x00, }, 199 { MCS_AIDCTL, 0x04, 0xd5 }, 200 }, { 201 /* 22 nits */ 202 { MCS_GAMMACTL, 203 0x00, 0x98, 0x00, 0xa4, 0x00, 0x97, 204 0x88, 0x89, 0x8b, 0x87, 0x87, 0x89, 205 0x8a, 0x88, 0x8b, 0x81, 0x82, 0x86, 206 0x87, 0x86, 0x88, 0x8e, 0x90, 0x8f, 207 0xb6, 0xb6, 0x95, 0xe3, 0xff, 0xb3, 208 0x00, 0x00, 0x00, }, 209 { MCS_AIDCTL, 0x04, 0xc5 }, 210 }, { 211 /* 24 nits */ 212 { MCS_GAMMACTL, 213 0x00, 0x98, 0x00, 0xa4, 0x00, 0x97, 214 0x88, 0x89, 0x8b, 0x88, 0x88, 0x8a, 215 0x8a, 0x87, 0x8a, 0x81, 0x82, 0x86, 216 0x87, 0x86, 0x88, 0x8e, 0x90, 0x8f, 217 0xb6, 0xb6, 0x94, 0xe3, 0xff, 0xb3, 218 0x00, 0x00, 0x00, }, 219 { MCS_AIDCTL, 0x04, 0xa7 }, 220 }, { 221 /* 25 nits */ 222 { MCS_GAMMACTL, 223 0x00, 0x98, 0x00, 0xa4, 0x00, 0x98, 224 0x88, 0x89, 0x8b, 0x88, 0x88, 0x8a, 225 0x8a, 0x87, 0x8a, 0x81, 0x82, 0x86, 226 0x87, 0x86, 0x87, 0x8e, 0x90, 0x8f, 227 0xbf, 0xbf, 0x9a, 0xda, 0xfa, 0xaf, 228 0x00, 0x00, 0x00, }, 229 { MCS_AIDCTL, 0x04, 0x95 }, 230 }, { 231 /* 27 nits */ 232 { MCS_GAMMACTL, 233 0x00, 0x98, 0x00, 0xa4, 0x00, 0x99, 234 0x88, 0x89, 0x8b, 0x88, 0x88, 0x8a, 235 0x8a, 0x87, 0x8a, 0x83, 0x86, 0x8a, 236 0x88, 0x87, 0x87, 0x88, 0x8b, 0x8c, 237 0xbf, 0xbf, 0x9a, 0xda, 0xfa, 0xaf, 238 0x00, 0x00, 0x00, }, 239 { MCS_AIDCTL, 0x04, 0x76 }, 240 }, { 241 /* 29 nits */ 242 { MCS_GAMMACTL, 243 0x00, 0x98, 0x00, 0xa4, 0x00, 0x99, 244 0x88, 0x89, 0x8b, 0x88, 0x88, 0x8a, 245 0x8a, 0x87, 0x8b, 0x83, 0x86, 0x89, 246 0x88, 0x87, 0x88, 0x88, 0x8b, 0x8b, 247 0xbf, 0xbf, 0x9a, 0xda, 0xfa, 0xaf, 248 0x00, 0x00, 0x00, }, 249 { MCS_AIDCTL, 0x04, 0x54 }, 250 }, { 251 /* 30 nits */ 252 { MCS_GAMMACTL, 253 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9a, 254 0x88, 0x89, 0x8b, 0x88, 0x88, 0x8a, 255 0x8a, 0x87, 0x8a, 0x84, 0x86, 0x8a, 256 0x87, 0x87, 0x87, 0x88, 0x8b, 0x8b, 257 0xbf, 0xbf, 0x99, 0xda, 0xfa, 0xaf, 258 0x00, 0x00, 0x00, }, 259 { MCS_AIDCTL, 0x04, 0x44 }, 260 }, { 261 /* 32 nits */ 262 { MCS_GAMMACTL, 263 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9a, 264 0x89, 0x89, 0x8c, 0x88, 0x88, 0x8a, 265 0x89, 0x87, 0x8a, 0x84, 0x86, 0x8a, 266 0x87, 0x87, 0x87, 0x89, 0x8b, 0x8b, 267 0xbf, 0xbf, 0x98, 0xd2, 0xf2, 0xac, 268 0x00, 0x00, 0x00, }, 269 { MCS_AIDCTL, 0x04, 0x1f }, 270 }, { 271 /* 34 nits */ 272 { MCS_GAMMACTL, 273 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9b, 274 0x88, 0x89, 0x8b, 0x88, 0x88, 0x8a, 275 0x8b, 0x87, 0x8b, 0x83, 0x86, 0x89, 276 0x87, 0x87, 0x88, 0x88, 0x8b, 0x8a, 277 0xbf, 0xbf, 0x98, 0xd2, 0xf2, 0xac, 278 0x00, 0x00, 0x00, }, 279 { MCS_AIDCTL, 0x03, 0xff }, 280 }, { 281 /* 37 nits */ 282 { MCS_GAMMACTL, 283 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9b, 284 0x89, 0x89, 0x8c, 0x88, 0x88, 0x8a, 285 0x8a, 0x87, 0x8a, 0x81, 0x82, 0x86, 286 0x86, 0x86, 0x86, 0x8d, 0x90, 0x8d, 287 0xc0, 0xbf, 0x9a, 0xd2, 0xf2, 0xac, 288 0x00, 0x00, 0x00, }, 289 { MCS_AIDCTL, 0x03, 0xd3 }, 290 }, { 291 /* 39 nits */ 292 { MCS_GAMMACTL, 293 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9b, 294 0x89, 0x89, 0x8c, 0x88, 0x88, 0x8a, 295 0x8a, 0x87, 0x8a, 0x81, 0x82, 0x86, 296 0x87, 0x86, 0x87, 0x8d, 0x90, 0x8d, 297 0xb6, 0xb6, 0x93, 0xda, 0xf9, 0xaf, 298 0x00, 0x00, 0x00, }, 299 { MCS_AIDCTL, 0x03, 0xb3 }, 300 }, { 301 /* 41 nits */ 302 { MCS_GAMMACTL, 303 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9b, 304 0x89, 0x89, 0x8c, 0x88, 0x88, 0x8a, 305 0x8a, 0x87, 0x8b, 0x81, 0x82, 0x85, 306 0x87, 0x86, 0x87, 0x8d, 0x90, 0x8d, 307 0xb6, 0xb6, 0x94, 0xda, 0xf9, 0xaf, 308 0x00, 0x00, 0x00, }, 309 { MCS_AIDCTL, 0x03, 0x93 }, 310 }, { 311 /* 44 nits */ 312 { MCS_GAMMACTL, 313 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9b, 314 0x89, 0x89, 0x8c, 0x88, 0x88, 0x8a, 315 0x8a, 0x87, 0x8b, 0x81, 0x82, 0x86, 316 0x87, 0x86, 0x86, 0x85, 0x87, 0x8a, 317 0xbe, 0xbe, 0x99, 0xda, 0xf9, 0xaf, 318 0x00, 0x00, 0x00, }, 319 { MCS_AIDCTL, 0x03, 0x66 }, 320 }, { 321 /* 47 nits */ 322 { MCS_GAMMACTL, 323 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9b, 324 0x89, 0x89, 0x8c, 0x88, 0x88, 0x8a, 325 0x8a, 0x87, 0x8b, 0x81, 0x82, 0x86, 326 0x88, 0x86, 0x87, 0x84, 0x87, 0x89, 327 0xb4, 0xb4, 0x94, 0xe2, 0xff, 0xb3, 328 0x00, 0x00, 0x00, }, 329 { MCS_AIDCTL, 0x03, 0x40 }, 330 }, { 331 /* 50 nits */ 332 { MCS_GAMMACTL, 333 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9c, 334 0x89, 0x89, 0x8b, 0x88, 0x88, 0x8a, 335 0x8a, 0x87, 0x8b, 0x81, 0x82, 0x86, 336 0x88, 0x86, 0x87, 0x84, 0x87, 0x89, 337 0xb4, 0xb4, 0x95, 0xe2, 0xff, 0xb3, 338 0x00, 0x00, 0x00, }, 339 { MCS_AIDCTL, 0x03, 0x0e }, 340 }, { 341 /* 53 nits */ 342 { MCS_GAMMACTL, 343 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9c, 344 0x89, 0x89, 0x8b, 0x88, 0x88, 0x8a, 345 0x8a, 0x87, 0x8b, 0x81, 0x82, 0x86, 346 0x88, 0x86, 0x87, 0x85, 0x87, 0x8a, 347 0xb4, 0xb4, 0x96, 0xe2, 0xff, 0xb3, 348 0x00, 0x00, 0x00, }, 349 { MCS_AIDCTL, 0x02, 0xe2 }, 350 }, { 351 /* 56 nits */ 352 { MCS_GAMMACTL, 353 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9c, 354 0x89, 0x89, 0x8b, 0x88, 0x88, 0x8a, 355 0x8a, 0x87, 0x8b, 0x81, 0x82, 0x86, 356 0x88, 0x86, 0x87, 0x85, 0x87, 0x8a, 357 0xab, 0xab, 0x90, 0xdd, 0xf7, 0xaf, 358 0x00, 0x00, 0x00, }, 359 { MCS_AIDCTL, 0x02, 0xb5 }, 360 }, { 361 /* 60 nits */ 362 { MCS_GAMMACTL, 363 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9c, 364 0x89, 0x89, 0x8b, 0x88, 0x88, 0x8a, 365 0x8a, 0x87, 0x8b, 0x82, 0x82, 0x87, 366 0x83, 0x81, 0x84, 0x81, 0x84, 0x88, 367 0xb3, 0xb3, 0x96, 0xcf, 0xe5, 0xa8, 368 0x00, 0x00, 0x00, }, 369 { MCS_AIDCTL, 0x02, 0x77 }, 370 }, { 371 /* 64 nits */ 372 { MCS_GAMMACTL, 373 0x00, 0x98, 0x00, 0xa4, 0x00, 0x9c, 374 0x89, 0x89, 0x8b, 0x88, 0x88, 0x8a, 375 0x8a, 0x87, 0x8b, 0x82, 0x82, 0x87, 376 0x83, 0x81, 0x84, 0x82, 0x84, 0x88, 377 0xb2, 0xb3, 0x97, 0xcf, 0xe5, 0xa8, 378 0x00, 0x00, 0x00, }, 379 { MCS_AIDCTL, 0x02, 0x36 }, 380 }, { 381 /* 68 nits */ 382 { MCS_GAMMACTL, 383 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x9d, 384 0x88, 0x88, 0x89, 0x89, 0x89, 0x8b, 385 0x8a, 0x88, 0x8b, 0x7f, 0x80, 0x86, 386 0x88, 0x86, 0x87, 0x7d, 0x7f, 0x85, 387 0xb2, 0xb3, 0x97, 0xcf, 0xe5, 0xa8, 388 0x00, 0x00, 0x00, }, 389 { MCS_AIDCTL, 0x02, 0x15 }, 390 }, { 391 /* 72 nits */ 392 { MCS_GAMMACTL, 393 0x00, 0x9c, 0x00, 0xa9, 0x00, 0xa0, 394 0x88, 0x88, 0x89, 0x88, 0x88, 0x8a, 395 0x8c, 0x8a, 0x8d, 0x7f, 0x81, 0x85, 396 0x84, 0x82, 0x84, 0x85, 0x87, 0x8a, 397 0xaa, 0xab, 0x93, 0xcf, 0xe5, 0xa8, 398 0x00, 0x00, 0x00, }, 399 { MCS_AIDCTL, 0x02, 0x15 }, 400 }, { 401 /* 77 nits */ 402 { MCS_GAMMACTL, 403 0x00, 0xa1, 0x00, 0xad, 0x00, 0xa5, 404 0x89, 0x89, 0x8a, 0x88, 0x87, 0x89, 405 0x8c, 0x89, 0x8d, 0x7f, 0x81, 0x85, 406 0x84, 0x83, 0x84, 0x81, 0x83, 0x86, 407 0xaa, 0xab, 0x93, 0xc0, 0xd3, 0xa1, 408 0x00, 0x00, 0x00, }, 409 { MCS_AIDCTL, 0x02, 0x15 }, 410 }, { 411 /* 82 nits */ 412 { MCS_GAMMACTL, 413 0x00, 0xa5, 0x00, 0xb0, 0x00, 0xa9, 414 0x88, 0x89, 0x89, 0x85, 0x86, 0x89, 415 0x8a, 0x88, 0x8b, 0x82, 0x82, 0x87, 416 0x81, 0x80, 0x82, 0x89, 0x8b, 0x8b, 417 0xa2, 0xa3, 0x8e, 0xc0, 0xd3, 0xa1, 418 0x00, 0x00, 0x00, }, 419 { MCS_AIDCTL, 0x02, 0x15 }, 420 }, { 421 /* 87 nits */ 422 { MCS_GAMMACTL, 423 0x00, 0xab, 0x00, 0xb4, 0x00, 0xad, 424 0x88, 0x89, 0x8a, 0x84, 0x86, 0x88, 425 0x8a, 0x88, 0x8b, 0x7f, 0x7f, 0x84, 426 0x86, 0x84, 0x85, 0x85, 0x86, 0x88, 427 0xa2, 0xa3, 0x8f, 0xc0, 0xd3, 0xa1, 428 0x00, 0x00, 0x00, }, 429 { MCS_AIDCTL, 0x02, 0x15 }, 430 }, { 431 /* 93 nits */ 432 { MCS_GAMMACTL, 433 0x00, 0xaf, 0x00, 0xb9, 0x00, 0xb1, 434 0x88, 0x89, 0x8a, 0x84, 0x85, 0x87, 435 0x8a, 0x89, 0x8b, 0x7e, 0x7e, 0x83, 436 0x87, 0x86, 0x86, 0x88, 0x8a, 0x89, 437 0x9c, 0x9c, 0x8b, 0xc0, 0xd3, 0xa1, 438 0x00, 0x00, 0x00, }, 439 { MCS_AIDCTL, 0x02, 0x15 }, 440 }, { 441 /* 98 nits */ 442 { MCS_GAMMACTL, 443 0x00, 0xb3, 0x00, 0xbc, 0x00, 0xb5, 444 0x88, 0x88, 0x88, 0x84, 0x84, 0x86, 445 0x8a, 0x88, 0x8a, 0x7f, 0x7f, 0x84, 446 0x84, 0x83, 0x84, 0x88, 0x8a, 0x89, 447 0x9c, 0x9c, 0x8b, 0xc0, 0xd3, 0xa1, 448 0x00, 0x00, 0x00, }, 449 { MCS_AIDCTL, 0x02, 0x15 }, 450 }, { 451 /* 105 nits */ 452 { MCS_GAMMACTL, 453 0x00, 0xb7, 0x00, 0xc0, 0x00, 0xba, 454 0x87, 0x87, 0x88, 0x85, 0x85, 0x87, 455 0x89, 0x88, 0x89, 0x7f, 0x7f, 0x83, 456 0x81, 0x80, 0x82, 0x88, 0x8a, 0x89, 457 0x9c, 0x9c, 0x8c, 0xb2, 0xc2, 0x9a, 458 0x00, 0x00, 0x00, }, 459 { MCS_AIDCTL, 0x02, 0x15 }, 460 }, { 461 /* 111 nits */ 462 { MCS_GAMMACTL, 463 0x00, 0xbb, 0x00, 0xc3, 0x00, 0xbe, 464 0x87, 0x87, 0x88, 0x85, 0x85, 0x88, 465 0x88, 0x87, 0x89, 0x80, 0x80, 0x84, 466 0x81, 0x81, 0x82, 0x85, 0x86, 0x87, 467 0x9c, 0x9c, 0x8b, 0xb2, 0xc2, 0x9a, 468 0x00, 0x00, 0x00, }, 469 { MCS_AIDCTL, 0x02, 0x15 }, 470 }, { 471 /* 119 nits */ 472 { MCS_GAMMACTL, 473 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc4, 474 0x87, 0x87, 0x88, 0x82, 0x84, 0x86, 475 0x87, 0x85, 0x87, 0x82, 0x81, 0x84, 476 0x83, 0x82, 0x83, 0x80, 0x81, 0x84, 477 0x9c, 0x9c, 0x8c, 0xb2, 0xc2, 0x9a, 478 0x00, 0x00, 0x00, }, 479 { MCS_AIDCTL, 0x02, 0x14 }, 480 }, { 481 /* 126 nits */ 482 { MCS_GAMMACTL, 483 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc4, 484 0x87, 0x87, 0x88, 0x82, 0x84, 0x86, 485 0x87, 0x85, 0x87, 0x82, 0x81, 0x84, 486 0x83, 0x82, 0x83, 0x80, 0x81, 0x84, 487 0x9c, 0x9c, 0x8d, 0xb2, 0xc2, 0x9a, 488 0x00, 0x00, 0x00, }, 489 { MCS_AIDCTL, 0x01, 0xde }, 490 }, { 491 /* 134 nits */ 492 { MCS_GAMMACTL, 493 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc4, 494 0x87, 0x87, 0x88, 0x82, 0x84, 0x86, 495 0x87, 0x85, 0x87, 0x82, 0x81, 0x84, 496 0x83, 0x82, 0x83, 0x80, 0x81, 0x84, 497 0x9c, 0x9c, 0x8d, 0xa4, 0xb0, 0x92, 498 0x00, 0x00, 0x00, }, 499 { MCS_AIDCTL, 0x01, 0x94 }, 500 }, { 501 /* 143 nits */ 502 { MCS_GAMMACTL, 503 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc3, 504 0x87, 0x87, 0x88, 0x82, 0x84, 0x86, 505 0x87, 0x85, 0x87, 0x82, 0x81, 0x85, 506 0x83, 0x82, 0x83, 0x80, 0x81, 0x84, 507 0x92, 0x92, 0x89, 0xab, 0xb6, 0x96, 508 0x00, 0x00, 0x00, }, 509 { MCS_AIDCTL, 0x01, 0x46 }, 510 }, { 511 /* 152 nits */ 512 { MCS_GAMMACTL, 513 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc3, 514 0x87, 0x87, 0x88, 0x83, 0x84, 0x86, 515 0x87, 0x85, 0x87, 0x81, 0x81, 0x85, 516 0x84, 0x82, 0x83, 0x80, 0x81, 0x83, 517 0x92, 0x92, 0x8b, 0xab, 0xb6, 0x96, 518 0x00, 0x00, 0x00, }, 519 { MCS_AIDCTL, 0x00, 0xfa }, 520 }, { 521 /* 162 nits */ 522 { MCS_GAMMACTL, 523 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc3, 524 0x87, 0x87, 0x88, 0x83, 0x84, 0x86, 525 0x87, 0x85, 0x87, 0x81, 0x81, 0x84, 526 0x84, 0x82, 0x84, 0x80, 0x81, 0x83, 527 0x92, 0x92, 0x8b, 0x9d, 0xa4, 0x8e, 528 0x00, 0x00, 0x00, }, 529 { MCS_AIDCTL, 0x00, 0xac }, 530 }, { 531 /* 172 nits */ 532 { MCS_GAMMACTL, 533 0x00, 0xc0, 0x00, 0xc8, 0x00, 0xc3, 534 0x87, 0x87, 0x88, 0x83, 0x84, 0x86, 535 0x87, 0x85, 0x87, 0x81, 0x81, 0x84, 536 0x84, 0x82, 0x83, 0x80, 0x81, 0x84, 537 0x93, 0x92, 0x8c, 0x9d, 0xa4, 0x8e, 538 0x00, 0x00, 0x00, }, 539 { MCS_AIDCTL, 0x00, 0x57 }, 540 }, { 541 /* 183 nits */ 542 { MCS_GAMMACTL, 543 0x00, 0xc2, 0x00, 0xca, 0x00, 0xc5, 544 0x86, 0x86, 0x87, 0x85, 0x84, 0x87, 545 0x87, 0x86, 0x88, 0x7e, 0x80, 0x83, 546 0x84, 0x82, 0x83, 0x80, 0x81, 0x83, 547 0x93, 0x92, 0x8c, 0x9d, 0xa4, 0x8e, 548 0x00, 0x00, 0x00, }, 549 { MCS_AIDCTL, 0x00, 0x10 }, 550 }, { 551 /* 195 nits */ 552 { MCS_GAMMACTL, 553 0x00, 0xc7, 0x00, 0xce, 0x00, 0xc9, 554 0x86, 0x87, 0x86, 0x83, 0x83, 0x85, 555 0x85, 0x84, 0x86, 0x82, 0x82, 0x85, 556 0x80, 0x80, 0x81, 0x81, 0x81, 0x84, 557 0x93, 0x92, 0x8c, 0x9d, 0xa4, 0x8e, 558 0x00, 0x00, 0x00, }, 559 { MCS_AIDCTL, 0x00, 0x10 }, 560 }, { 561 /* 207 nits */ 562 { MCS_GAMMACTL, 563 0x00, 0xcc, 0x00, 0xd2, 0x00, 0xce, 564 0x86, 0x86, 0x87, 0x81, 0x83, 0x84, 565 0x84, 0x82, 0x84, 0x83, 0x83, 0x85, 566 0x81, 0x81, 0x82, 0x7c, 0x7d, 0x81, 567 0x93, 0x92, 0x8c, 0x9d, 0xa4, 0x8e, 568 0x00, 0x00, 0x00, }, 569 { MCS_AIDCTL, 0x00, 0x10 }, 570 }, { 571 /* 220 nits */ 572 { MCS_GAMMACTL, 573 0x00, 0xd1, 0x00, 0xd6, 0x00, 0xd3, 574 0x86, 0x86, 0x86, 0x81, 0x83, 0x84, 575 0x84, 0x82, 0x84, 0x80, 0x80, 0x83, 576 0x81, 0x81, 0x82, 0x7c, 0x7d, 0x81, 577 0x93, 0x92, 0x8c, 0x9d, 0xa4, 0x8e, 578 0x00, 0x00, 0x00, }, 579 { MCS_AIDCTL, 0x00, 0x10 }, 580 }, { 581 /* 234 nits */ 582 { MCS_GAMMACTL, 583 0x00, 0xd6, 0x00, 0xdb, 0x00, 0xd8, 584 0x85, 0x85, 0x85, 0x81, 0x83, 0x84, 585 0x83, 0x82, 0x83, 0x80, 0x80, 0x82, 586 0x84, 0x82, 0x83, 0x79, 0x79, 0x7e, 587 0x93, 0x92, 0x8d, 0x9d, 0xa4, 0x8e, 588 0x00, 0x00, 0x00, }, 589 { MCS_AIDCTL, 0x00, 0x10 }, 590 }, { 591 /* 249 nits */ 592 { MCS_GAMMACTL, 593 0x00, 0xdc, 0x00, 0xe0, 0x00, 0xdd, 594 0x84, 0x84, 0x84, 0x81, 0x82, 0x83, 595 0x84, 0x82, 0x84, 0x7f, 0x7f, 0x82, 596 0x81, 0x80, 0x81, 0x80, 0x81, 0x82, 597 0x8c, 0x8c, 0x86, 0x9d, 0xa4, 0x8e, 598 0x00, 0x00, 0x00, }, 599 { MCS_AIDCTL, 0x00, 0x10 }, 600 }, { 601 /* 265 nits */ 602 { MCS_GAMMACTL, 603 0x00, 0xe2, 0x00, 0xe5, 0x00, 0xe3, 604 0x83, 0x83, 0x83, 0x81, 0x82, 0x83, 605 0x82, 0x82, 0x83, 0x82, 0x81, 0x83, 606 0x7f, 0x7e, 0x80, 0x7c, 0x7d, 0x80, 607 0x8c, 0x8c, 0x86, 0x8e, 0x92, 0x87, 608 0x00, 0x00, 0x00, }, 609 { MCS_AIDCTL, 0x00, 0x10 }, 610 }, { 611 /* 282 nits */ 612 { MCS_GAMMACTL, 613 0x00, 0xe8, 0x00, 0xea, 0x00, 0xe9, 614 0x83, 0x83, 0x83, 0x80, 0x82, 0x82, 615 0x81, 0x82, 0x82, 0x82, 0x81, 0x82, 616 0x81, 0x80, 0x81, 0x80, 0x80, 0x81, 617 0x85, 0x85, 0x83, 0x8e, 0x92, 0x87, 618 0x00, 0x00, 0x00, }, 619 { MCS_AIDCTL, 0x00, 0x10 }, 620 }, { 621 /* 300 nits */ 622 { MCS_GAMMACTL, 623 0x00, 0xed, 0x00, 0xef, 0x00, 0xed, 624 0x81, 0x82, 0x81, 0x81, 0x81, 0x82, 625 0x82, 0x82, 0x83, 0x80, 0x80, 0x81, 626 0x81, 0x81, 0x82, 0x83, 0x83, 0x83, 627 0x80, 0x80, 0x7f, 0x8e, 0x92, 0x87, 628 0x00, 0x00, 0x00, }, 629 { MCS_AIDCTL, 0x00, 0x10 }, 630 }, { 631 /* 316 nits */ 632 { MCS_GAMMACTL, 633 0x00, 0xf3, 0x00, 0xf4, 0x00, 0xf3, 634 0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 635 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 636 0x82, 0x82, 0x83, 0x80, 0x80, 0x80, 637 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 638 0x00, 0x00, 0x00, }, 639 { MCS_AIDCTL, 0x00, 0x10 }, 640 }, { 641 /* 333 nits */ 642 { MCS_GAMMACTL, 643 0x00, 0xf8, 0x00, 0xf8, 0x00, 0xf8, 644 0x80, 0x81, 0x80, 0x81, 0x80, 0x81, 645 0x81, 0x82, 0x82, 0x81, 0x80, 0x81, 646 0x83, 0x83, 0x83, 0x7e, 0x7d, 0x7e, 647 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 648 0x00, 0x00, 0x00, }, 649 { MCS_AIDCTL, 0x00, 0x10 }, 650 }, { 651 /* 360 nits */ 652 { MCS_GAMMACTL, 653 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 654 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 655 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 656 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 657 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 658 0x00, 0x00, 0x00, }, 659 { MCS_AIDCTL, 0x00, 0x10 }, 660 }, { 661 /* 378 nits */ 662 { MCS_GAMMACTL, 663 0x01, 0x04, 0x01, 0x03, 0x01, 0x04, 664 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 665 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 666 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 667 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 668 0x00, 0x00, 0x00, }, 669 { MCS_AIDCTL, 0x00, 0x10 }, 670 }, { 671 /* 395 nits */ 672 { MCS_GAMMACTL, 673 0x01, 0x09, 0x01, 0x07, 0x01, 0x08, 674 0x7e, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 675 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 676 0x80, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 677 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7f, 678 0x00, 0x00, 0x00, }, 679 { MCS_AIDCTL, 0x00, 0x10 }, 680 }, { 681 /* 413 nits */ 682 { MCS_GAMMACTL, 683 0x01, 0x0e, 0x01, 0x0b, 0x01, 0x0c, 684 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7e, 685 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 686 0x80, 0x7f, 0x7f, 0x7d, 0x7d, 0x7d, 687 0x80, 0x80, 0x7f, 0x7d, 0x7e, 0x7e, 688 0x00, 0x00, 0x00, }, 689 { MCS_AIDCTL, 0x00, 0x10 }, 690 }, { 691 /* 430 nits */ 692 { MCS_GAMMACTL, 693 0x01, 0x13, 0x01, 0x0f, 0x01, 0x10, 694 0x7d, 0x7f, 0x80, 0x7e, 0x7e, 0x7e, 695 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 696 0x80, 0x7f, 0x7f, 0x7d, 0x7d, 0x7d, 697 0x80, 0x80, 0x7f, 0x7c, 0x7d, 0x7e, 698 0x00, 0x00, 0x00, }, 699 { MCS_AIDCTL, 0x00, 0x10 }, 700 }, { 701 /* 448 nits */ 702 { MCS_GAMMACTL, 703 0x01, 0x18, 0x01, 0x13, 0x01, 0x14, 704 0x7c, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 705 0x7e, 0x7e, 0x7d, 0x7e, 0x7f, 0x7e, 706 0x80, 0x7f, 0x7f, 0x7c, 0x7c, 0x7c, 707 0x80, 0x80, 0x7e, 0x7b, 0x7c, 0x7d, 708 0x00, 0x00, 0x00, }, 709 { MCS_AIDCTL, 0x00, 0x10 }, 710 }, { 711 /* 465 nits */ 712 { MCS_GAMMACTL, 713 0x01, 0x1d, 0x01, 0x17, 0x01, 0x18, 714 0x7c, 0x7e, 0x80, 0x7d, 0x7d, 0x7d, 715 0x7d, 0x7d, 0x7d, 0x7e, 0x7f, 0x7e, 716 0x80, 0x7f, 0x7f, 0x7b, 0x7b, 0x7b, 717 0x80, 0x80, 0x7e, 0x7a, 0x7c, 0x7d, 718 0x00, 0x00, 0x00, }, 719 { MCS_AIDCTL, 0x00, 0x10 }, 720 }, { 721 /* 483 nits */ 722 { MCS_GAMMACTL, 723 0x01, 0x22, 0x01, 0x1b, 0x01, 0x1c, 724 0x7b, 0x7e, 0x80, 0x7d, 0x7d, 0x7d, 725 0x7d, 0x7d, 0x7c, 0x7e, 0x7f, 0x7e, 726 0x80, 0x7f, 0x7f, 0x7a, 0x7a, 0x7a, 727 0x80, 0x80, 0x7e, 0x79, 0x7b, 0x7c, 728 0x00, 0x00, 0x00, }, 729 { MCS_AIDCTL, 0x00, 0x10 }, 730 }, { 731 /* 500 nits */ 732 { MCS_GAMMACTL, 733 0x01, 0x27, 0x01, 0x1f, 0x01, 0x20, 734 0x7b, 0x7e, 0x80, 0x7d, 0x7d, 0x7d, 735 0x7d, 0x7d, 0x7c, 0x7e, 0x7f, 0x7e, 736 0x80, 0x7f, 0x7f, 0x7a, 0x7a, 0x7a, 737 0x81, 0x80, 0x7e, 0x79, 0x7b, 0x7c, 738 0x00, 0x00, 0x00, }, 739 { MCS_AIDCTL, 0x00, 0x10 }, 740 }, 741 }; 742 743 struct s6e8aa5x01_ams561ra01_ctx { 744 struct drm_panel panel; 745 struct mipi_dsi_device *dsi; 746 struct backlight_device *bl; 747 struct gpio_desc *reset_gpio; 748 struct regulator_bulk_data *supplies; 749 u32 nr_supplies; 750 }; 751 752 static const struct regulator_bulk_data s6e8aa5x01_ams561ra01_supplies[] = { 753 { .supply = "vdd" }, 754 { .supply = "vci" }, 755 }; 756 757 static inline struct s6e8aa5x01_ams561ra01_ctx *to_ctx(struct drm_panel *panel) 758 { 759 return container_of(panel, struct s6e8aa5x01_ams561ra01_ctx, panel); 760 } 761 762 static int s6e8aa5x01_ams561ra01_update_status(struct backlight_device *bl) 763 { 764 struct s6e8aa5x01_ams561ra01_ctx *ctx = bl_get_data(bl); 765 struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; 766 u16 lvl = backlight_get_brightness(bl); 767 768 if (!ctx->panel.enabled) 769 return 0; 770 771 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_ACCESSPROT, 0x5a, 0x5a); 772 773 mipi_dsi_dcs_write_buffer_multi(&dsi, 774 s6e8aa5x01_ams561ra01_cmds[lvl].gamma, 775 GAMMA_CMD_LEN); 776 mipi_dsi_dcs_write_buffer_multi(&dsi, 777 s6e8aa5x01_ams561ra01_cmds[lvl].aid, 778 AID_CMD_LEN); 779 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_GAMMAUPD, 0x03); 780 781 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_ACCESSPROT, 0xa5, 0xa5); 782 783 return dsi.accum_err; 784 } 785 786 static int s6e8aa5x01_ams561ra01_prepare(struct drm_panel *panel) 787 { 788 struct s6e8aa5x01_ams561ra01_ctx *ctx = to_ctx(panel); 789 struct device *dev = &ctx->dsi->dev; 790 int ret; 791 792 ret = regulator_bulk_enable(ctx->nr_supplies, ctx->supplies); 793 if (ret < 0) { 794 dev_err(dev, "failed to enable regulators: %d\n", ret); 795 return ret; 796 } 797 798 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 799 usleep_range(5000, 6000); 800 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 801 usleep_range(5000, 6000); 802 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 803 usleep_range(10000, 11000); 804 805 return 0; 806 } 807 808 static int s6e8aa5x01_ams561ra01_unprepare(struct drm_panel *panel) 809 { 810 struct s6e8aa5x01_ams561ra01_ctx *ctx = to_ctx(panel); 811 812 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 813 usleep_range(5000, 6000); 814 815 regulator_bulk_disable(ctx->nr_supplies, ctx->supplies); 816 817 return 0; 818 } 819 820 static int s6e8aa5x01_ams561ra01_enable(struct drm_panel *panel) 821 { 822 struct s6e8aa5x01_ams561ra01_ctx *ctx = to_ctx(panel); 823 struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; 824 825 mipi_dsi_dcs_exit_sleep_mode_multi(&dsi); 826 mipi_dsi_msleep(&dsi, 100); 827 828 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_ACCESSPROT, 0x5a, 0x5a); 829 830 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_PENTILE, 0xd8, 0xd8, 0x00); 831 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_PCD, 0x5c); 832 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_ERRFLAG, 0xed, 0xc7, 0x23, 0x67); 833 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_DISPCTL, 0x0c, 0x0c, 0xb9, 0x01); 834 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_LTPSCTL, 835 0x00, 0x45, 0x10, 0x10, 0x08, 0x32, 0x54, 0x00, 836 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 837 0x00, 0x00, 0x48, 0x5e, 0x00, 0x00, 0x00, 0x00, 838 0x00, 0x03, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 839 0x08, 0x05, 0x2a, 0x54, 0x03, 0xcc, 0x00, 0xff, 840 0xfb, 0x03, 0x0d, 0x00, 0x11, 0x0f, 0x02, 0x03, 841 0x0b, 0x0c, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 842 0x13, 0x13, 0x13, 0x13, 0x00, 0x02, 0x03, 0x0b, 843 0x0c, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 844 0x13, 0x13); 845 846 mipi_dsi_dcs_write_seq_multi(&dsi, MCS_ACCESSPROT, 0xa5, 0xa5); 847 848 mipi_dsi_dcs_set_display_on_multi(&dsi); 849 850 return dsi.accum_err; 851 } 852 853 static int s6e8aa5x01_ams561ra01_disable(struct drm_panel *panel) 854 { 855 struct s6e8aa5x01_ams561ra01_ctx *ctx = to_ctx(panel); 856 struct mipi_dsi_multi_context dsi = { .dsi = ctx->dsi }; 857 858 mipi_dsi_dcs_set_display_off_multi(&dsi); 859 mipi_dsi_msleep(&dsi, 100); 860 861 mipi_dsi_dcs_enter_sleep_mode_multi(&dsi); 862 mipi_dsi_msleep(&dsi, 150); 863 864 return dsi.accum_err; 865 } 866 867 static const struct drm_display_mode s6e8aa5x01_ams561ra01_mode = { 868 .clock = (720 + 62 + 2 + 26) * (1480 + 12 + 2 + 10) * 60 / 1000, 869 .hdisplay = 720, 870 .hsync_start = 720 + 62, 871 .hsync_end = 720 + 62 + 2, 872 .htotal = 720 + 62 + 2 + 26, 873 .vdisplay = 1480, 874 .vsync_start = 1480 + 12, 875 .vsync_end = 1480 + 12 + 2, 876 .vtotal = 1480 + 12 + 2 + 10, 877 .width_mm = 62, 878 .height_mm = 128, 879 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 880 }; 881 882 static int s6e8aa5x01_ams561ra01_get_modes(struct drm_panel *panel, 883 struct drm_connector *connector) 884 { 885 return drm_connector_helper_get_modes_fixed(connector, 886 &s6e8aa5x01_ams561ra01_mode); 887 } 888 889 static const struct backlight_ops s6e8aa5x01_ams561ra01_bl_ops = { 890 .update_status = s6e8aa5x01_ams561ra01_update_status, 891 }; 892 893 static const struct drm_panel_funcs s6e8aa5x01_ams561ra01_panel_funcs = { 894 .prepare = s6e8aa5x01_ams561ra01_prepare, 895 .unprepare = s6e8aa5x01_ams561ra01_unprepare, 896 .enable = s6e8aa5x01_ams561ra01_enable, 897 .disable = s6e8aa5x01_ams561ra01_disable, 898 .get_modes = s6e8aa5x01_ams561ra01_get_modes, 899 }; 900 901 static int s6e8aa5x01_ams561ra01_probe(struct mipi_dsi_device *dsi) 902 { 903 struct device *dev = &dsi->dev; 904 struct s6e8aa5x01_ams561ra01_ctx *ctx; 905 int ret; 906 907 ctx = devm_drm_panel_alloc(dev, struct s6e8aa5x01_ams561ra01_ctx, panel, 908 &s6e8aa5x01_ams561ra01_panel_funcs, 909 DRM_MODE_CONNECTOR_DSI); 910 if (IS_ERR(ctx)) 911 return PTR_ERR(ctx); 912 913 ctx->dsi = dsi; 914 mipi_dsi_set_drvdata(dsi, ctx); 915 916 ctx->nr_supplies = ARRAY_SIZE(s6e8aa5x01_ams561ra01_supplies); 917 ret = devm_regulator_bulk_get_const(dev, ctx->nr_supplies, 918 s6e8aa5x01_ams561ra01_supplies, 919 &ctx->supplies); 920 if (ret < 0) 921 return dev_err_probe(dev, ret, "failed to get regulators\n"); 922 923 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); 924 if (IS_ERR(ctx->reset_gpio)) 925 return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), 926 "failed to get reset-gpios\n"); 927 928 ctx->bl = devm_backlight_device_register(dev, dev_name(dev), dev, ctx, 929 &s6e8aa5x01_ams561ra01_bl_ops, 930 NULL); 931 if (IS_ERR(ctx->bl)) 932 return dev_err_probe(dev, PTR_ERR(ctx->bl), 933 "failed to register backlight device\n"); 934 935 ctx->bl->props.type = BACKLIGHT_PLATFORM; 936 ctx->bl->props.brightness = ARRAY_SIZE(s6e8aa5x01_ams561ra01_cmds) - 1; 937 ctx->bl->props.max_brightness = ctx->bl->props.brightness; 938 939 dsi->lanes = 4; 940 dsi->format = MIPI_DSI_FMT_RGB888; 941 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | 942 MIPI_DSI_MODE_VIDEO_NO_HFP; 943 944 ctx->panel.prepare_prev_first = true; 945 drm_panel_add(&ctx->panel); 946 947 ret = devm_mipi_dsi_attach(dev, dsi); 948 if (ret < 0) { 949 drm_panel_remove(&ctx->panel); 950 return dev_err_probe(dev, ret, "failed to attach to DSI host\n"); 951 } 952 953 return 0; 954 } 955 956 static void s6e8aa5x01_ams561ra01_remove(struct mipi_dsi_device *dsi) 957 { 958 struct s6e8aa5x01_ams561ra01_ctx *ctx = mipi_dsi_get_drvdata(dsi); 959 960 drm_panel_remove(&ctx->panel); 961 } 962 963 static const struct of_device_id s6e8aa5x01_ams561ra01_of_device_id[] = { 964 { .compatible = "samsung,s6e8aa5x01-ams561ra01" }, 965 { } 966 }; 967 MODULE_DEVICE_TABLE(of, s6e8aa5x01_ams561ra01_of_device_id); 968 969 static struct mipi_dsi_driver s6e8aa5x01_ams561ra01_dsi_driver = { 970 .probe = s6e8aa5x01_ams561ra01_probe, 971 .remove = s6e8aa5x01_ams561ra01_remove, 972 .driver = { 973 .name = "panel-samsung-s6e8aa5x01-ams561ra01", 974 .of_match_table = s6e8aa5x01_ams561ra01_of_device_id, 975 }, 976 }; 977 module_mipi_dsi_driver(s6e8aa5x01_ams561ra01_dsi_driver); 978 979 MODULE_AUTHOR("Kaustabh Chakraborty <kauschluss@disroot.org>"); 980 MODULE_DESCRIPTION("Samsung AMS561RA01 Panel with S6E8AA5X01 Controller"); 981 MODULE_LICENSE("GPL"); 982