1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * DRM driver for PIXPAPER e-ink panel 4 * 5 * Author: LiangCheng Wang <zaq14760@gmail.com>, 6 */ 7 #include <linux/delay.h> 8 #include <linux/module.h> 9 #include <linux/spi/spi.h> 10 11 #include <drm/clients/drm_client_setup.h> 12 #include <drm/drm_atomic.h> 13 #include <drm/drm_atomic_helper.h> 14 #include <drm/drm_drv.h> 15 #include <drm/drm_fbdev_shmem.h> 16 #include <drm/drm_framebuffer.h> 17 #include <drm/drm_gem_atomic_helper.h> 18 #include <drm/drm_gem_shmem_helper.h> 19 #include <drm/drm_gem_framebuffer_helper.h> 20 #include <drm/drm_print.h> 21 #include <drm/drm_probe_helper.h> 22 23 /* 24 * Note on Undocumented Commands/Registers: 25 * 26 * Several commands and register parameters defined in this header are not 27 * documented in the datasheet. Their values and usage have been derived 28 * through analysis of existing userspace example programs. 29 * 30 * These 'unknown' definitions are crucial for the proper initialization 31 * and stable operation of the panel. Modifying these values without 32 * thorough understanding may lead to display anomalies, panel damage, 33 * or unexpected behavior. 34 */ 35 36 /* Command definitions */ 37 #define PIXPAPER_CMD_PANEL_SETTING 0x00 /* R00H: Panel settings */ 38 #define PIXPAPER_CMD_POWER_SETTING 0x01 /* R01H: Power settings */ 39 #define PIXPAPER_CMD_POWER_OFF 0x02 /* R02H: Power off */ 40 #define PIXPAPER_CMD_POWER_OFF_SEQUENCE 0x03 /* R03H: Power off sequence */ 41 #define PIXPAPER_CMD_POWER_ON 0x04 /* R04H: Power on */ 42 #define PIXPAPER_CMD_BOOSTER_SOFT_START 0x06 /* R06H: Booster soft start */ 43 #define PIXPAPER_CMD_DEEP_SLEEP 0x07 /* R07H: Deep sleep */ 44 #define PIXPAPER_CMD_DATA_START_TRANSMISSION 0x10 45 /* R10H: Data transmission start */ 46 #define PIXPAPER_CMD_DISPLAY_REFRESH 0x12 /* R12H: Display refresh */ 47 #define PIXPAPER_CMD_PLL_CONTROL 0x30 /* R30H: PLL control */ 48 #define PIXPAPER_CMD_TEMP_SENSOR_CALIB 0x41 49 /* R41H: Temperature sensor calibration */ 50 #define PIXPAPER_CMD_UNKNOWN_4D 0x4D /* R4DH: Unknown command */ 51 #define PIXPAPER_CMD_VCOM_INTERVAL 0x50 /* R50H: VCOM interval */ 52 #define PIXPAPER_CMD_UNKNOWN_60 0x60 /* R60H: Unknown command */ 53 #define PIXPAPER_CMD_RESOLUTION_SETTING 0x61 /* R61H: Resolution settings */ 54 #define PIXPAPER_CMD_GATE_SOURCE_START 0x65 /* R65H: Gate/source start */ 55 #define PIXPAPER_CMD_UNKNOWN_B4 0xB4 /* RB4H: Unknown command */ 56 #define PIXPAPER_CMD_UNKNOWN_B5 0xB5 /* RB5H: Unknown command */ 57 #define PIXPAPER_CMD_UNKNOWN_E0 0xE0 /* RE0H: Unknown command */ 58 #define PIXPAPER_CMD_POWER_SAVING 0xE3 /* RE3H: Power saving */ 59 #define PIXPAPER_CMD_UNKNOWN_E7 0xE7 /* RE7H: Unknown command */ 60 #define PIXPAPER_CMD_UNKNOWN_E9 0xE9 /* RE9H: Unknown command */ 61 62 /* R00H PSR - First Parameter */ 63 #define PIXPAPER_PSR_RST_N BIT(0) 64 /* Bit 0: RST_N, 1=no effect (default), 0=reset with booster OFF */ 65 #define PIXPAPER_PSR_SHD_N BIT(1) 66 /* Bit 1: SHD_N, 1=booster ON (default), 0=booster OFF */ 67 #define PIXPAPER_PSR_SHL BIT(2) 68 /* Bit 2: SHL, 1=shift right (default), 0=shift left */ 69 #define PIXPAPER_PSR_UD BIT(3) 70 /* Bit 3: UD, 1=scan up (default), 0=scan down */ 71 #define PIXPAPER_PSR_PST_MODE BIT(5) 72 /* Bit 5: PST_MODE, 0=frame scanning (default), 1=external */ 73 #define PIXPAPER_PSR_RES_MASK (3 << 6) 74 /* Bits 7-6: RES[1:0], resolution setting */ 75 #define PIXPAPER_PSR_RES_176x296 (0x0 << 6) /* 00: 176x296 */ 76 #define PIXPAPER_PSR_RES_128x296 (0x1 << 6) /* 01: 128x296 */ 77 #define PIXPAPER_PSR_RES_128x250 (0x2 << 6) /* 10: 128x250 */ 78 #define PIXPAPER_PSR_RES_112x204 (0x3 << 6) /* 11: 112x204 */ 79 #define PIXPAPER_PSR_CONFIG \ 80 (PIXPAPER_PSR_RST_N | PIXPAPER_PSR_SHD_N | PIXPAPER_PSR_SHL | \ 81 PIXPAPER_PSR_UD) 82 /* 0x0F: Default settings, resolution set by R61H */ 83 84 /* R00H PSR - Second Parameter */ 85 #define PIXPAPER_PSR2_VC_LUTZ \ 86 (1 << 0) /* Bit 0: VC_LUTZ, 1=VCOM float after refresh (default), 0=no effect */ 87 #define PIXPAPER_PSR2_NORG \ 88 (1 << 1) /* Bit 1: NORG, 1=VCOM to GND before power off, 0=no effect (default) */ 89 #define PIXPAPER_PSR2_TIEG \ 90 (1 << 2) /* Bit 2: TIEG, 1=VGN to GND on power off, 0=no effect (default) */ 91 #define PIXPAPER_PSR2_TS_AUTO \ 92 (1 << 3) /* Bit 3: TS_AUTO, 1=sensor on RST_N low to high (default), 0=on booster */ 93 #define PIXPAPER_PSR2_VCMZ \ 94 (1 << 4) /* Bit 4: VCMZ, 1=VCOM always floating, 0=no effect (default) */ 95 #define PIXPAPER_PSR2_FOPT \ 96 (1 << 5) /* Bit 5: FOPT, 0=scan 1 frame (default), 1=no scan, HiZ */ 97 #define PIXPAPER_PSR_CONFIG2 \ 98 (PIXPAPER_PSR2_VC_LUTZ | \ 99 PIXPAPER_PSR2_TS_AUTO) /* 0x09: Default VCOM and temp sensor settings */ 100 101 /* R01H PWR - Power Setting Register */ 102 /* First Parameter */ 103 #define PIXPAPER_PWR_VDG_EN \ 104 (1 << 0) /* Bit 0: VDG_EN, 1=internal DCDC for VGP/VGN (default), 0=external */ 105 #define PIXPAPER_PWR_VDS_EN \ 106 (1 << 1) /* Bit 1: VDS_EN, 1=internal regulator for VSP/VSN (default), 0=external */ 107 #define PIXPAPER_PWR_VSC_EN \ 108 (1 << 2) /* Bit 2: VSC_EN, 1=internal regulator for VSPL (default), 0=external */ 109 #define PIXPAPER_PWR_V_MODE \ 110 (1 << 3) /* Bit 3: V_MODE, 0=Mode0 (default), 1=Mode1 */ 111 #define PIXPAPER_PWR_CONFIG1 \ 112 (PIXPAPER_PWR_VDG_EN | PIXPAPER_PWR_VDS_EN | \ 113 PIXPAPER_PWR_VSC_EN) /* 0x07: Internal power for VGP/VGN, VSP/VSN, VSPL */ 114 115 /* Second Parameter */ 116 #define PIXPAPER_PWR_VGPN_MASK \ 117 (3 << 0) /* Bits 1-0: VGPN, VGP/VGN voltage levels */ 118 #define PIXPAPER_PWR_VGPN_20V (0x0 << 0) /* 00: VGP=20V, VGN=-20V (default) */ 119 #define PIXPAPER_PWR_VGPN_17V (0x1 << 0) /* 01: VGP=17V, VGN=-17V */ 120 #define PIXPAPER_PWR_VGPN_15V (0x2 << 0) /* 10: VGP=15V, VGN=-15V */ 121 #define PIXPAPER_PWR_VGPN_10V (0x3 << 0) /* 11: VGP=10V, VGN=-10V */ 122 #define PIXPAPER_PWR_CONFIG2 PIXPAPER_PWR_VGPN_20V /* 0x00: VGP=20V, VGN=-20V */ 123 124 /* Third, Fourth, Sixth Parameters (VSP_1, VSPL_0, VSPL_1) */ 125 #define PIXPAPER_PWR_VSP_8_2V 0x22 /* VSP_1/VSPL_1: 8.2V (34 decimal) */ 126 #define PIXPAPER_PWR_VSPL_15V 0x78 /* VSPL_0: 15V (120 decimal) */ 127 128 /* Fifth Parameter (VSN_1) */ 129 #define PIXPAPER_PWR_VSN_4V 0x0A /* VSN_1: -4V (10 decimal) */ 130 131 /* R03H PFS - Power Off Sequence Setting Register */ 132 /* First Parameter */ 133 #define PIXPAPER_PFS_T_VDS_OFF_MASK \ 134 (3 << 0) /* Bits 1-0: T_VDS_OFF, VSP/VSN power-off sequence */ 135 #define PIXPAPER_PFS_T_VDS_OFF_20MS (0x0 << 0) /* 00: 20 ms (default) */ 136 #define PIXPAPER_PFS_T_VDS_OFF_40MS (0x1 << 0) /* 01: 40 ms */ 137 #define PIXPAPER_PFS_T_VDS_OFF_60MS (0x2 << 0) /* 10: 60 ms */ 138 #define PIXPAPER_PFS_T_VDS_OFF_80MS (0x3 << 0) /* 11: 80 ms */ 139 #define PIXPAPER_PFS_T_VDPG_OFF_MASK \ 140 (3 << 4) /* Bits 5-4: T_VDPG_OFF, VGP/VGN power-off sequence */ 141 #define PIXPAPER_PFS_T_VDPG_OFF_20MS (0x0 << 4) /* 00: 20 ms (default) */ 142 #define PIXPAPER_PFS_T_VDPG_OFF_40MS (0x1 << 4) /* 01: 40 ms */ 143 #define PIXPAPER_PFS_T_VDPG_OFF_60MS (0x2 << 4) /* 10: 60 ms */ 144 #define PIXPAPER_PFS_T_VDPG_OFF_80MS (0x3 << 4) /* 11: 80 ms */ 145 #define PIXPAPER_PFS_CONFIG1 \ 146 (PIXPAPER_PFS_T_VDS_OFF_20MS | \ 147 PIXPAPER_PFS_T_VDPG_OFF_20MS) /* 0x10: Default 20 ms for VSP/VSN and VGP/VGN */ 148 149 /* Second Parameter */ 150 #define PIXPAPER_PFS_VGP_EXT_MASK \ 151 (0xF << 0) /* Bits 3-0: VGP_EXT, VGP extension time */ 152 #define PIXPAPER_PFS_VGP_EXT_0MS (0x0 << 0) /* 0000: 0 ms */ 153 #define PIXPAPER_PFS_VGP_EXT_500MS (0x1 << 0) /* 0001: 500 ms */ 154 #define PIXPAPER_PFS_VGP_EXT_1000MS (0x2 << 0) /* 0010: 1000 ms */ 155 #define PIXPAPER_PFS_VGP_EXT_1500MS (0x3 << 0) /* 0011: 1500 ms */ 156 #define PIXPAPER_PFS_VGP_EXT_2000MS (0x4 << 0) /* 0100: 2000 ms (default) */ 157 #define PIXPAPER_PFS_VGP_EXT_2500MS (0x5 << 0) /* 0101: 2500 ms */ 158 #define PIXPAPER_PFS_VGP_EXT_3000MS (0x6 << 0) /* 0110: 3000 ms */ 159 #define PIXPAPER_PFS_VGP_EXT_3500MS (0x7 << 0) /* 0111: 3500 ms */ 160 #define PIXPAPER_PFS_VGP_EXT_4000MS (0x8 << 0) /* 1000: 4000 ms */ 161 #define PIXPAPER_PFS_VGP_EXT_4500MS (0x9 << 0) /* 1001: 4500 ms */ 162 #define PIXPAPER_PFS_VGP_EXT_5000MS (0xA << 0) /* 1010: 5000 ms */ 163 #define PIXPAPER_PFS_VGP_EXT_5500MS (0xB << 0) /* 1011: 5500 ms */ 164 #define PIXPAPER_PFS_VGP_EXT_6000MS (0xC << 0) /* 1100: 6000 ms */ 165 #define PIXPAPER_PFS_VGP_EXT_6500MS (0xD << 0) /* 1101: 6500 ms */ 166 #define PIXPAPER_PFS_VGP_LEN_MASK \ 167 (0xF << 4) /* Bits 7-4: VGP_LEN, VGP at 10V during power-off */ 168 #define PIXPAPER_PFS_VGP_LEN_0MS (0x0 << 4) /* 0000: 0 ms */ 169 #define PIXPAPER_PFS_VGP_LEN_500MS (0x1 << 4) /* 0001: 500 ms */ 170 #define PIXPAPER_PFS_VGP_LEN_1000MS (0x2 << 4) /* 0010: 1000 ms */ 171 #define PIXPAPER_PFS_VGP_LEN_1500MS (0x3 << 4) /* 0011: 1500 ms */ 172 #define PIXPAPER_PFS_VGP_LEN_2000MS (0x4 << 4) /* 0100: 2000 ms */ 173 #define PIXPAPER_PFS_VGP_LEN_2500MS (0x5 << 4) /* 0101: 2500 ms (default) */ 174 #define PIXPAPER_PFS_VGP_LEN_3000MS (0x6 << 4) /* 0110: 3000 ms */ 175 #define PIXPAPER_PFS_VGP_LEN_3500MS (0x7 << 4) /* 0111: 3500 ms */ 176 #define PIXPAPER_PFS_VGP_LEN_4000MS (0x8 << 4) /* 1000: 4000 ms */ 177 #define PIXPAPER_PFS_VGP_LEN_4500MS (0x9 << 4) /* 1001: 4500 ms */ 178 #define PIXPAPER_PFS_VGP_LEN_5000MS (0xA << 4) /* 1010: 5000 ms */ 179 #define PIXPAPER_PFS_VGP_LEN_5500MS (0xB << 4) /* 1011: 5500 ms */ 180 #define PIXPAPER_PFS_VGP_LEN_6000MS (0xC << 4) /* 1100: 6000 ms */ 181 #define PIXPAPER_PFS_VGP_LEN_6500MS (0xD << 4) /* 1101: 6500 ms */ 182 #define PIXPAPER_PFS_CONFIG2 \ 183 (PIXPAPER_PFS_VGP_EXT_1000MS | \ 184 PIXPAPER_PFS_VGP_LEN_2500MS) /* 0x54: VGP extension 1000 ms, VGP at 10V for 2500 ms */ 185 186 /* Third Parameter */ 187 #define PIXPAPER_PFS_XON_LEN_MASK \ 188 (0xF << 0) /* Bits 3-0: XON_LEN, XON enable time */ 189 #define PIXPAPER_PFS_XON_LEN_0MS (0x0 << 0) /* 0000: 0 ms */ 190 #define PIXPAPER_PFS_XON_LEN_500MS (0x1 << 0) /* 0001: 500 ms */ 191 #define PIXPAPER_PFS_XON_LEN_1000MS (0x2 << 0) /* 0010: 1000 ms */ 192 #define PIXPAPER_PFS_XON_LEN_1500MS (0x3 << 0) /* 0011: 1500 ms */ 193 #define PIXPAPER_PFS_XON_LEN_2000MS (0x4 << 0) /* 0100: 2000 ms (default) */ 194 #define PIXPAPER_PFS_XON_LEN_2500MS (0x5 << 0) /* 0101: 2500 ms */ 195 #define PIXPAPER_PFS_XON_LEN_3000MS (0x6 << 0) /* 0110: 3000 ms */ 196 #define PIXPAPER_PFS_XON_LEN_3500MS (0x7 << 0) /* 0111: 3500 ms */ 197 #define PIXPAPER_PFS_XON_LEN_4000MS (0x8 << 0) /* 1000: 4000 ms */ 198 #define PIXPAPER_PFS_XON_LEN_4500MS (0x9 << 0) /* 1001: 4500 ms */ 199 #define PIXPAPER_PFS_XON_LEN_5000MS (0xA << 0) /* 1010: 5000 ms */ 200 #define PIXPAPER_PFS_XON_LEN_5500MS (0xB << 0) /* 1011: 5500 ms */ 201 #define PIXPAPER_PFS_XON_LEN_6000MS (0xC << 0) /* 1100: 6000 ms */ 202 #define PIXPAPER_PFS_XON_DLY_MASK \ 203 (0xF << 4) /* Bits 7-4: XON_DLY, XON delay time */ 204 #define PIXPAPER_PFS_XON_DLY_0MS (0x0 << 4) /* 0000: 0 ms */ 205 #define PIXPAPER_PFS_XON_DLY_500MS (0x1 << 4) /* 0001: 500 ms */ 206 #define PIXPAPER_PFS_XON_DLY_1000MS (0x2 << 4) /* 0010: 1000 ms */ 207 #define PIXPAPER_PFS_XON_DLY_1500MS (0x3 << 4) /* 0011: 1500 ms */ 208 #define PIXPAPER_PFS_XON_DLY_2000MS (0x4 << 4) /* 0100: 2000 ms (default) */ 209 #define PIXPAPER_PFS_XON_DLY_2500MS (0x5 << 4) /* 0101: 2500 ms */ 210 #define PIXPAPER_PFS_XON_DLY_3000MS (0x6 << 4) /* 0110: 3000 ms */ 211 #define PIXPAPER_PFS_XON_DLY_3500MS (0x7 << 4) /* 0111: 3500 ms */ 212 #define PIXPAPER_PFS_XON_DLY_4000MS (0x8 << 4) /* 1000: 4000 ms */ 213 #define PIXPAPER_PFS_XON_DLY_4500MS (0x9 << 4) /* 1001: 4500 ms */ 214 #define PIXPAPER_PFS_XON_DLY_5000MS (0xA << 4) /* 1010: 5000 ms */ 215 #define PIXPAPER_PFS_XON_DLY_5500MS (0xB << 4) /* 1011: 5500 ms */ 216 #define PIXPAPER_PFS_XON_DLY_6000MS (0xC << 4) /* 1100: 6000 ms */ 217 #define PIXPAPER_PFS_CONFIG3 \ 218 (PIXPAPER_PFS_XON_LEN_2000MS | \ 219 PIXPAPER_PFS_XON_DLY_2000MS) /* 0x44: XON enable and delay at 2000 ms */ 220 221 /* R06H BTST - Booster Soft Start Command */ 222 /* First Parameter */ 223 #define PIXPAPER_BTST_PHA_SFT_MASK \ 224 (3 << 0) /* Bits 1-0: PHA_SFT, soft start period for phase A */ 225 #define PIXPAPER_BTST_PHA_SFT_10MS (0x0 << 0) /* 00: 10 ms (default) */ 226 #define PIXPAPER_BTST_PHA_SFT_20MS (0x1 << 0) /* 01: 20 ms */ 227 #define PIXPAPER_BTST_PHA_SFT_30MS (0x2 << 0) /* 10: 30 ms */ 228 #define PIXPAPER_BTST_PHA_SFT_40MS (0x3 << 0) /* 11: 40 ms */ 229 #define PIXPAPER_BTST_PHB_SFT_MASK \ 230 (3 << 2) /* Bits 3-2: PHB_SFT, soft start period for phase B */ 231 #define PIXPAPER_BTST_PHB_SFT_10MS (0x0 << 2) /* 00: 10 ms (default) */ 232 #define PIXPAPER_BTST_PHB_SFT_20MS (0x1 << 2) /* 01: 20 ms */ 233 #define PIXPAPER_BTST_PHB_SFT_30MS (0x2 << 2) /* 10: 30 ms */ 234 #define PIXPAPER_BTST_PHB_SFT_40MS (0x3 << 2) /* 11: 40 ms */ 235 #define PIXPAPER_BTST_CONFIG1 \ 236 (PIXPAPER_BTST_PHA_SFT_40MS | \ 237 PIXPAPER_BTST_PHB_SFT_40MS) /* 0x0F: 40 ms for phase A and B */ 238 239 /* Second to Seventh Parameters (Driving Strength or Minimum OFF Time) */ 240 #define PIXPAPER_BTST_CONFIG2 0x0A /* Strength11 */ 241 #define PIXPAPER_BTST_CONFIG3 0x2F /* Period48 */ 242 #define PIXPAPER_BTST_CONFIG4 0x25 /* Strength38 */ 243 #define PIXPAPER_BTST_CONFIG5 0x22 /* Period35 */ 244 #define PIXPAPER_BTST_CONFIG6 0x2E /* Strength47 */ 245 #define PIXPAPER_BTST_CONFIG7 0x21 /* Period34 */ 246 247 /* R12H: DRF (Display Refresh) */ 248 #define PIXPAPER_DRF_VCOM_AC 0x00 /* AC VCOM: VCOM follows LUTC (default) */ 249 #define PIXPAPER_DRF_VCOM_DC 0x01 /* DC VCOM: VCOM fixed to VCOMDC */ 250 251 /* R30H PLL - PLL Control Register */ 252 /* First Parameter */ 253 #define PIXPAPER_PLL_FR_MASK (0x7 << 0) /* Bits 2-0: FR, frame rate */ 254 #define PIXPAPER_PLL_FR_12_5HZ (0x0 << 0) /* 000: 12.5 Hz */ 255 #define PIXPAPER_PLL_FR_25HZ (0x1 << 0) /* 001: 25 Hz */ 256 #define PIXPAPER_PLL_FR_50HZ (0x2 << 0) /* 010: 50 Hz (default) */ 257 #define PIXPAPER_PLL_FR_65HZ (0x3 << 0) /* 011: 65 Hz */ 258 #define PIXPAPER_PLL_FR_75HZ (0x4 << 0) /* 100: 75 Hz */ 259 #define PIXPAPER_PLL_FR_85HZ (0x5 << 0) /* 101: 85 Hz */ 260 #define PIXPAPER_PLL_FR_100HZ (0x6 << 0) /* 110: 100 Hz */ 261 #define PIXPAPER_PLL_FR_120HZ (0x7 << 0) /* 111: 120 Hz */ 262 #define PIXPAPER_PLL_DFR \ 263 (1 << 3) /* Bit 3: Dynamic frame rate, 0=disabled (default), 1=enabled */ 264 #define PIXPAPER_PLL_CONFIG \ 265 (PIXPAPER_PLL_FR_50HZ) /* 0x02: 50 Hz, dynamic frame rate disabled */ 266 267 /* R41H TSE - Temperature Sensor Calibration Register */ 268 /* First Parameter */ 269 #define PIXPAPER_TSE_TO_MASK \ 270 (0xF << 0) /* Bits 3-0: TO[3:0], temperature offset */ 271 #define PIXPAPER_TSE_TO_POS_0C (0x0 << 0) /* 0000: +0°C (default) */ 272 #define PIXPAPER_TSE_TO_POS_0_5C (0x1 << 0) /* 0001: +0.5°C */ 273 #define PIXPAPER_TSE_TO_POS_1C (0x2 << 0) /* 0010: +1°C */ 274 #define PIXPAPER_TSE_TO_POS_1_5C (0x3 << 0) /* 0011: +1.5°C */ 275 #define PIXPAPER_TSE_TO_POS_2C (0x4 << 0) /* 0100: +2°C */ 276 #define PIXPAPER_TSE_TO_POS_2_5C (0x5 << 0) /* 0101: +2.5°C */ 277 #define PIXPAPER_TSE_TO_POS_3C (0x6 << 0) /* 0110: +3°C */ 278 #define PIXPAPER_TSE_TO_POS_3_5C (0x7 << 0) /* 0111: +3.5°C */ 279 #define PIXPAPER_TSE_TO_NEG_4C (0x8 << 0) /* 1000: -4°C */ 280 #define PIXPAPER_TSE_TO_NEG_3_5C (0x9 << 0) /* 1001: -3.5°C */ 281 #define PIXPAPER_TSE_TO_NEG_3C (0xA << 0) /* 1010: -3°C */ 282 #define PIXPAPER_TSE_TO_NEG_2_5C (0xB << 0) /* 1011: -2.5°C */ 283 #define PIXPAPER_TSE_TO_NEG_2C (0xC << 0) /* 1100: -2°C */ 284 #define PIXPAPER_TSE_TO_NEG_1_5C (0xD << 0) /* 1101: -1.5°C */ 285 #define PIXPAPER_TSE_TO_NEG_1C (0xE << 0) /* 1110: -1°C */ 286 #define PIXPAPER_TSE_TO_NEG_0_5C (0xF << 0) /* 1111: -0.5°C */ 287 #define PIXPAPER_TSE_TO_FINE_MASK \ 288 (0x3 << 4) /* Bits 5-4: TO[5:4], fine adjustment for positive offsets */ 289 #define PIXPAPER_TSE_TO_FINE_0C (0x0 << 4) /* 00: +0.0°C (default) */ 290 #define PIXPAPER_TSE_TO_FINE_0_25C (0x1 << 4) /* 01: +0.25°C */ 291 #define PIXPAPER_TSE_ENABLE \ 292 (0 << 7) /* Bit 7: TSE, 0=internal sensor enabled (default), 1=disabled (external) */ 293 #define PIXPAPER_TSE_DISABLE \ 294 (1 << 7) /* Bit 7: TSE, 1=internal sensor disabled, use external */ 295 #define PIXPAPER_TSE_CONFIG \ 296 (PIXPAPER_TSE_TO_POS_0C | PIXPAPER_TSE_TO_FINE_0C | \ 297 PIXPAPER_TSE_ENABLE) /* 0x00: Internal sensor enabled, +0°C offset */ 298 299 /* R4DH */ 300 #define PIXPAPER_UNKNOWN_4D_CONFIG \ 301 0x78 /* This value is essential for initialization, derived from userspace examples. */ 302 303 /* R50H CDI - VCOM and DATA Interval Setting Register */ 304 /* First Parameter */ 305 #define PIXPAPER_CDI_INTERVAL_MASK \ 306 (0xF << 0) /* Bits 3-0: CDI[3:0], VCOM and data interval (hsync) */ 307 #define PIXPAPER_CDI_17_HSYNC (0x0 << 0) /* 0000: 17 hsync */ 308 #define PIXPAPER_CDI_16_HSYNC (0x1 << 0) /* 0001: 16 hsync */ 309 #define PIXPAPER_CDI_15_HSYNC (0x2 << 0) /* 0010: 15 hsync */ 310 #define PIXPAPER_CDI_14_HSYNC (0x3 << 0) /* 0011: 14 hsync */ 311 #define PIXPAPER_CDI_13_HSYNC (0x4 << 0) /* 0100: 13 hsync */ 312 #define PIXPAPER_CDI_12_HSYNC (0x5 << 0) /* 0101: 12 hsync */ 313 #define PIXPAPER_CDI_11_HSYNC (0x6 << 0) /* 0110: 11 hsync */ 314 #define PIXPAPER_CDI_10_HSYNC (0x7 << 0) /* 0111: 10 hsync (default) */ 315 #define PIXPAPER_CDI_9_HSYNC (0x8 << 0) /* 1000: 9 hsync */ 316 #define PIXPAPER_CDI_8_HSYNC (0x9 << 0) /* 1001: 8 hsync */ 317 #define PIXPAPER_CDI_7_HSYNC (0xA << 0) /* 1010: 7 hsync */ 318 #define PIXPAPER_CDI_6_HSYNC (0xB << 0) /* 1011: 6 hsync */ 319 #define PIXPAPER_CDI_5_HSYNC (0xC << 0) /* 1100: 5 hsync */ 320 #define PIXPAPER_CDI_4_HSYNC (0xD << 0) /* 1101: 4 hsync */ 321 #define PIXPAPER_CDI_3_HSYNC (0xE << 0) /* 1110: 3 hsync */ 322 #define PIXPAPER_CDI_2_HSYNC (0xF << 0) /* 1111: 2 hsync */ 323 #define PIXPAPER_CDI_DDX \ 324 (1 << 4) /* Bit 4: DDX, 0=grayscale mapping 0, 1=grayscale mapping 1 (default) */ 325 #define PIXPAPER_CDI_VBD_MASK \ 326 (0x7 << 5) /* Bits 7-5: VBD[2:0], border data selection */ 327 #define PIXPAPER_CDI_VBD_FLOAT (0x0 << 5) /* 000: Floating (DDX=0 or 1) */ 328 #define PIXPAPER_CDI_VBD_GRAY3_DDX0 \ 329 (0x1 << 5) /* 001: Gray3 (border_buf=011) when DDX=0 */ 330 #define PIXPAPER_CDI_VBD_GRAY2_DDX0 \ 331 (0x2 << 5) /* 010: Gray2 (border_buf=010) when DDX=0 */ 332 #define PIXPAPER_CDI_VBD_GRAY1_DDX0 \ 333 (0x3 << 5) /* 011: Gray1 (border_buf=001) when DDX=0 */ 334 #define PIXPAPER_CDI_VBD_GRAY0_DDX0 \ 335 (0x4 << 5) /* 100: Gray0 (border_buf=000) when DDX=0 */ 336 #define PIXPAPER_CDI_VBD_GRAY0_DDX1 \ 337 (0x0 << 5) /* 000: Gray0 (border_buf=000) when DDX=1 */ 338 #define PIXPAPER_CDI_VBD_GRAY1_DDX1 \ 339 (0x1 << 5) /* 001: Gray1 (border_buf=001) when DDX=1 */ 340 #define PIXPAPER_CDI_VBD_GRAY2_DDX1 \ 341 (0x2 << 5) /* 010: Gray2 (border_buf=010) when DDX=1 */ 342 #define PIXPAPER_CDI_VBD_GRAY3_DDX1 \ 343 (0x3 << 5) /* 011: Gray3 (border_buf=011) when DDX=1 */ 344 #define PIXPAPER_CDI_VBD_FLOAT_DDX1 (0x4 << 5) /* 100: Floating when DDX=1 */ 345 #define PIXPAPER_CDI_CONFIG \ 346 (PIXPAPER_CDI_10_HSYNC | PIXPAPER_CDI_DDX | \ 347 PIXPAPER_CDI_VBD_GRAY1_DDX1) /* 0x37: 10 hsync, DDX=1, border Gray1 */ 348 349 /* R60H */ 350 #define PIXPAPER_UNKNOWN_60_CONFIG1 \ 351 0x02 /* This value is essential for initialization, derived from userspace examples. */ 352 #define PIXPAPER_UNKNOWN_60_CONFIG2 \ 353 0x02 /* This value is essential for initialization, derived from userspace examples. */ 354 355 /* R61H TRES - Resolution Setting Register */ 356 #define PIXPAPER_TRES_HRES_H \ 357 ((PIXPAPER_PANEL_BUFFER_WIDTH >> 8) & \ 358 0xFF) /* HRES[9:8]: High byte of horizontal resolution (128) */ 359 #define PIXPAPER_TRES_HRES_L \ 360 (PIXPAPER_PANEL_BUFFER_WIDTH & \ 361 0xFF) /* HRES[7:0]: Low byte of horizontal resolution (128 = 0x80) */ 362 #define PIXPAPER_TRES_VRES_H \ 363 ((PIXPAPER_HEIGHT >> 8) & \ 364 0xFF) /* VRES[9:8]: High byte of vertical resolution (250) */ 365 #define PIXPAPER_TRES_VRES_L \ 366 (PIXPAPER_HEIGHT & \ 367 0xFF) /* VRES[7:0]: Low byte of vertical resolution (250 = 0xFA) */ 368 369 /* R65H GSST - Gate/Source Start Setting Register */ 370 #define PIXPAPER_GSST_S_START 0x00 /* S_Start[7:0]: First source line (S0) */ 371 #define PIXPAPER_GSST_RESERVED 0x00 /* Reserved byte */ 372 #define PIXPAPER_GSST_G_START_H \ 373 0x00 /* G_Start[8]: High bit of first gate line (G0) */ 374 #define PIXPAPER_GSST_G_START_L \ 375 0x00 /* G_Start[7:0]: Low byte of first gate line (G0) */ 376 377 /* RB4H */ 378 #define PIXPAPER_UNKNOWN_B4_CONFIG \ 379 0xD0 /* This value is essential for initialization, derived from userspace examples. */ 380 381 /* RB5H */ 382 #define PIXPAPER_UNKNOWN_B5_CONFIG \ 383 0x03 /* This value is essential for initialization, derived from userspace examples. */ 384 385 /* RE0H */ 386 #define PIXPAPER_UNKNOWN_E0_CONFIG \ 387 0x00 /* This value is essential for initialization, derived from userspace examples. */ 388 389 /* RE3H PWS - Power Saving Register */ 390 /* First Parameter */ 391 #define PIXPAPER_PWS_VCOM_W_MASK \ 392 (0xF \ 393 << 4) /* Bits 7-4: VCOM_W[3:0], VCOM power-saving width (line periods) */ 394 #define PIXPAPER_PWS_VCOM_W_0 (0x0 << 4) /* 0000: 0 line periods */ 395 #define PIXPAPER_PWS_VCOM_W_1 (0x1 << 4) /* 0001: 1 line period */ 396 #define PIXPAPER_PWS_VCOM_W_2 (0x2 << 4) /* 0010: 2 line periods */ 397 #define PIXPAPER_PWS_VCOM_W_3 (0x3 << 4) /* 0011: 3 line periods */ 398 #define PIXPAPER_PWS_VCOM_W_4 (0x4 << 4) /* 0100: 4 line periods */ 399 #define PIXPAPER_PWS_VCOM_W_5 (0x5 << 4) /* 0101: 5 line periods */ 400 #define PIXPAPER_PWS_VCOM_W_6 (0x6 << 4) /* 0110: 6 line periods */ 401 #define PIXPAPER_PWS_VCOM_W_7 (0x7 << 4) /* 0111: 7 line periods */ 402 #define PIXPAPER_PWS_VCOM_W_8 (0x8 << 4) /* 1000: 8 line periods */ 403 #define PIXPAPER_PWS_VCOM_W_9 (0x9 << 4) /* 1001: 9 line periods */ 404 #define PIXPAPER_PWS_VCOM_W_10 (0xA << 4) /* 1010: 10 line periods */ 405 #define PIXPAPER_PWS_VCOM_W_11 (0xB << 4) /* 1011: 11 line periods */ 406 #define PIXPAPER_PWS_VCOM_W_12 (0xC << 4) /* 1100: 12 line periods */ 407 #define PIXPAPER_PWS_VCOM_W_13 (0xD << 4) /* 1101: 13 line periods */ 408 #define PIXPAPER_PWS_VCOM_W_14 (0xE << 4) /* 1110: 14 line periods */ 409 #define PIXPAPER_PWS_VCOM_W_15 (0xF << 4) /* 1111: 15 line periods */ 410 #define PIXPAPER_PWS_SD_W_MASK \ 411 (0xF << 0) /* Bits 3-0: SD_W[3:0], source power-saving width (660 ns units) */ 412 #define PIXPAPER_PWS_SD_W_0 (0x0 << 0) /* 0000: 0 ns */ 413 #define PIXPAPER_PWS_SD_W_1 (0x1 << 0) /* 0001: 660 ns */ 414 #define PIXPAPER_PWS_SD_W_2 (0x2 << 0) /* 0010: 1320 ns */ 415 #define PIXPAPER_PWS_SD_W_3 (0x3 << 0) /* 0011: 1980 ns */ 416 #define PIXPAPER_PWS_SD_W_4 (0x4 << 0) /* 0100: 2640 ns */ 417 #define PIXPAPER_PWS_SD_W_5 (0x5 << 0) /* 0101: 3300 ns */ 418 #define PIXPAPER_PWS_SD_W_6 (0x6 << 0) /* 0110: 3960 ns */ 419 #define PIXPAPER_PWS_SD_W_7 (0x7 << 0) /* 0111: 4620 ns */ 420 #define PIXPAPER_PWS_SD_W_8 (0x8 << 0) /* 1000: 5280 ns */ 421 #define PIXPAPER_PWS_SD_W_9 (0x9 << 0) /* 1001: 5940 ns */ 422 #define PIXPAPER_PWS_SD_W_10 (0xA << 0) /* 1010: 6600 ns */ 423 #define PIXPAPER_PWS_SD_W_11 (0xB << 0) /* 1011: 7260 ns */ 424 #define PIXPAPER_PWS_SD_W_12 (0xC << 0) /* 1100: 7920 ns */ 425 #define PIXPAPER_PWS_SD_W_13 (0xD << 0) /* 1101: 8580 ns */ 426 #define PIXPAPER_PWS_SD_W_14 (0xE << 0) /* 1110: 9240 ns */ 427 #define PIXPAPER_PWS_SD_W_15 (0xF << 0) /* 1111: 9900 ns */ 428 #define PIXPAPER_PWS_CONFIG \ 429 (PIXPAPER_PWS_VCOM_W_2 | \ 430 PIXPAPER_PWS_SD_W_2) /* 0x22: VCOM 2 line periods (160 µs), source 1320 ns */ 431 432 /* RE7H */ 433 #define PIXPAPER_UNKNOWN_E7_CONFIG \ 434 0x1C /* This value is essential for initialization, derived from userspace examples. */ 435 436 /* RE9H */ 437 #define PIXPAPER_UNKNOWN_E9_CONFIG \ 438 0x01 /* This value is essential for initialization, derived from userspace examples. */ 439 440 MODULE_IMPORT_NS("DMA_BUF"); 441 442 /* 443 * The panel has a visible resolution of 122x250. 444 * However, the controller requires the horizontal resolution to be aligned to 128 pixels. 445 * No porch or sync timing values are provided in the datasheet, so we define minimal 446 * placeholder values to satisfy the DRM framework. 447 */ 448 449 /* Panel visible resolution */ 450 #define PIXPAPER_WIDTH 122 451 #define PIXPAPER_HEIGHT 250 452 453 /* Controller requires 128 horizontal pixels total (for memory alignment) */ 454 #define PIXPAPER_HTOTAL 128 455 #define PIXPAPER_HFP 2 456 #define PIXPAPER_HSYNC 2 457 #define PIXPAPER_HBP (PIXPAPER_HTOTAL - PIXPAPER_WIDTH - PIXPAPER_HFP - PIXPAPER_HSYNC) 458 459 /* 460 * According to the datasheet, the total vertical blanking must be 55 lines, 461 * regardless of how the vertical back porch is set. 462 * Here we allocate VFP=2, VSYNC=2, and VBP=51 to sum up to 55 lines. 463 * Total vertical lines = 250 (visible) + 55 (blanking) = 305. 464 */ 465 #define PIXPAPER_VTOTAL (250 + 55) 466 #define PIXPAPER_VFP 2 467 #define PIXPAPER_VSYNC 2 468 #define PIXPAPER_VBP (55 - PIXPAPER_VFP - PIXPAPER_VSYNC) 469 470 /* 471 * Pixel clock calculation: 472 * pixel_clock = htotal * vtotal * refresh_rate 473 * = 128 * 305 * 50 474 * = 1,952,000 Hz = 1952 kHz 475 */ 476 #define PIXPAPER_PIXEL_CLOCK 1952 477 478 #define PIXPAPER_WIDTH_MM 24 /* approximate from 23.7046mm */ 479 #define PIXPAPER_HEIGHT_MM 49 /* approximate from 48.55mm */ 480 481 #define PIXPAPER_SPI_BITS_PER_WORD 8 482 #define PIXPAPER_SPI_SPEED_DEFAULT 1000000 483 484 #define PIXPAPER_PANEL_BUFFER_WIDTH 128 485 #define PIXPAPER_PANEL_BUFFER_TWO_BYTES_PER_ROW (PIXPAPER_PANEL_BUFFER_WIDTH / 4) 486 487 #define PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL 60 488 #define PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL 200 489 #define PIXPAPER_COLOR_THRESHOLD_YELLOW_MIN_GREEN 180 490 491 struct pixpaper_error_ctx { 492 int errno_code; 493 }; 494 495 struct pixpaper_panel { 496 struct drm_device drm; 497 struct drm_plane plane; 498 struct drm_crtc crtc; 499 struct drm_encoder encoder; 500 struct drm_connector connector; 501 502 struct spi_device *spi; 503 struct gpio_desc *reset; 504 struct gpio_desc *busy; 505 struct gpio_desc *dc; 506 }; 507 508 static inline struct pixpaper_panel *to_pixpaper_panel(struct drm_device *drm) 509 { 510 return container_of(drm, struct pixpaper_panel, drm); 511 } 512 513 static void pixpaper_wait_for_panel(struct pixpaper_panel *panel) 514 { 515 unsigned int timeout_ms = 10000; 516 unsigned long timeout_jiffies = jiffies + msecs_to_jiffies(timeout_ms); 517 518 usleep_range(1000, 1500); 519 while (gpiod_get_value_cansleep(panel->busy) != 1) { 520 if (time_after(jiffies, timeout_jiffies)) { 521 drm_warn(&panel->drm, "Busy wait timed out\n"); 522 return; 523 } 524 usleep_range(100, 200); 525 } 526 } 527 528 static void pixpaper_spi_sync(struct spi_device *spi, struct spi_message *msg, 529 struct pixpaper_error_ctx *err) 530 { 531 if (err->errno_code) 532 return; 533 534 int ret = spi_sync(spi, msg); 535 536 if (ret < 0) 537 err->errno_code = ret; 538 } 539 540 static void pixpaper_send_cmd(struct pixpaper_panel *panel, u8 cmd, 541 struct pixpaper_error_ctx *err) 542 { 543 if (err->errno_code) 544 return; 545 546 struct spi_transfer xfer = { 547 .tx_buf = &cmd, 548 .len = 1, 549 }; 550 struct spi_message msg; 551 552 spi_message_init(&msg); 553 spi_message_add_tail(&xfer, &msg); 554 555 gpiod_set_value_cansleep(panel->dc, 0); 556 usleep_range(1, 5); 557 pixpaper_spi_sync(panel->spi, &msg, err); 558 } 559 560 static void pixpaper_send_data(struct pixpaper_panel *panel, u8 data, 561 struct pixpaper_error_ctx *err) 562 { 563 if (err->errno_code) 564 return; 565 566 struct spi_transfer xfer = { 567 .tx_buf = &data, 568 .len = 1, 569 }; 570 struct spi_message msg; 571 572 spi_message_init(&msg); 573 spi_message_add_tail(&xfer, &msg); 574 575 gpiod_set_value_cansleep(panel->dc, 1); 576 usleep_range(1, 5); 577 pixpaper_spi_sync(panel->spi, &msg, err); 578 } 579 580 static int pixpaper_panel_hw_init(struct pixpaper_panel *panel) 581 { 582 struct pixpaper_error_ctx err = { .errno_code = 0 }; 583 584 gpiod_set_value_cansleep(panel->reset, 0); 585 msleep(50); 586 gpiod_set_value_cansleep(panel->reset, 1); 587 msleep(50); 588 589 pixpaper_wait_for_panel(panel); 590 591 pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_4D, &err); 592 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_4D_CONFIG, &err); 593 if (err.errno_code) 594 goto init_fail; 595 pixpaper_wait_for_panel(panel); 596 597 pixpaper_send_cmd(panel, PIXPAPER_CMD_PANEL_SETTING, &err); 598 pixpaper_send_data(panel, PIXPAPER_PSR_CONFIG, &err); 599 pixpaper_send_data(panel, PIXPAPER_PSR_CONFIG2, &err); 600 if (err.errno_code) 601 goto init_fail; 602 pixpaper_wait_for_panel(panel); 603 604 pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_SETTING, &err); 605 pixpaper_send_data(panel, PIXPAPER_PWR_CONFIG1, &err); 606 pixpaper_send_data(panel, PIXPAPER_PWR_CONFIG2, &err); 607 pixpaper_send_data(panel, PIXPAPER_PWR_VSP_8_2V, &err); 608 pixpaper_send_data(panel, PIXPAPER_PWR_VSPL_15V, &err); 609 pixpaper_send_data(panel, PIXPAPER_PWR_VSN_4V, &err); 610 pixpaper_send_data(panel, PIXPAPER_PWR_VSP_8_2V, &err); 611 if (err.errno_code) 612 goto init_fail; 613 pixpaper_wait_for_panel(panel); 614 615 pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_OFF_SEQUENCE, &err); 616 pixpaper_send_data(panel, PIXPAPER_PFS_CONFIG1, &err); 617 pixpaper_send_data(panel, PIXPAPER_PFS_CONFIG2, &err); 618 pixpaper_send_data(panel, PIXPAPER_PFS_CONFIG3, &err); 619 if (err.errno_code) 620 goto init_fail; 621 pixpaper_wait_for_panel(panel); 622 623 pixpaper_send_cmd(panel, PIXPAPER_CMD_BOOSTER_SOFT_START, &err); 624 pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG1, &err); 625 pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG2, &err); 626 pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG3, &err); 627 pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG4, &err); 628 pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG5, &err); 629 pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG6, &err); 630 pixpaper_send_data(panel, PIXPAPER_BTST_CONFIG7, &err); 631 if (err.errno_code) 632 goto init_fail; 633 pixpaper_wait_for_panel(panel); 634 635 pixpaper_send_cmd(panel, PIXPAPER_CMD_PLL_CONTROL, &err); 636 pixpaper_send_data(panel, PIXPAPER_PLL_CONFIG, &err); 637 if (err.errno_code) 638 goto init_fail; 639 pixpaper_wait_for_panel(panel); 640 641 pixpaper_send_cmd(panel, PIXPAPER_CMD_TEMP_SENSOR_CALIB, &err); 642 pixpaper_send_data(panel, PIXPAPER_TSE_CONFIG, &err); 643 if (err.errno_code) 644 goto init_fail; 645 pixpaper_wait_for_panel(panel); 646 647 pixpaper_send_cmd(panel, PIXPAPER_CMD_VCOM_INTERVAL, &err); 648 pixpaper_send_data(panel, PIXPAPER_CDI_CONFIG, &err); 649 if (err.errno_code) 650 goto init_fail; 651 pixpaper_wait_for_panel(panel); 652 653 pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_60, &err); 654 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_60_CONFIG1, &err); 655 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_60_CONFIG2, &err); 656 if (err.errno_code) 657 goto init_fail; 658 pixpaper_wait_for_panel(panel); 659 660 pixpaper_send_cmd(panel, PIXPAPER_CMD_RESOLUTION_SETTING, &err); 661 pixpaper_send_data(panel, PIXPAPER_TRES_HRES_H, &err); 662 pixpaper_send_data(panel, PIXPAPER_TRES_HRES_L, &err); 663 pixpaper_send_data(panel, PIXPAPER_TRES_VRES_H, &err); 664 pixpaper_send_data(panel, PIXPAPER_TRES_VRES_L, &err); 665 if (err.errno_code) 666 goto init_fail; 667 pixpaper_wait_for_panel(panel); 668 669 pixpaper_send_cmd(panel, PIXPAPER_CMD_GATE_SOURCE_START, &err); 670 pixpaper_send_data(panel, PIXPAPER_GSST_S_START, &err); 671 pixpaper_send_data(panel, PIXPAPER_GSST_RESERVED, &err); 672 pixpaper_send_data(panel, PIXPAPER_GSST_G_START_H, &err); 673 pixpaper_send_data(panel, PIXPAPER_GSST_G_START_L, &err); 674 if (err.errno_code) 675 goto init_fail; 676 pixpaper_wait_for_panel(panel); 677 678 pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_E7, &err); 679 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_E7_CONFIG, &err); 680 if (err.errno_code) 681 goto init_fail; 682 pixpaper_wait_for_panel(panel); 683 684 pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_SAVING, &err); 685 pixpaper_send_data(panel, PIXPAPER_PWS_CONFIG, &err); 686 if (err.errno_code) 687 goto init_fail; 688 pixpaper_wait_for_panel(panel); 689 690 pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_E0, &err); 691 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_E0_CONFIG, &err); 692 if (err.errno_code) 693 goto init_fail; 694 pixpaper_wait_for_panel(panel); 695 696 pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_B4, &err); 697 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_B4_CONFIG, &err); 698 if (err.errno_code) 699 goto init_fail; 700 pixpaper_wait_for_panel(panel); 701 702 pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_B5, &err); 703 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_B5_CONFIG, &err); 704 if (err.errno_code) 705 goto init_fail; 706 pixpaper_wait_for_panel(panel); 707 708 pixpaper_send_cmd(panel, PIXPAPER_CMD_UNKNOWN_E9, &err); 709 pixpaper_send_data(panel, PIXPAPER_UNKNOWN_E9_CONFIG, &err); 710 if (err.errno_code) 711 goto init_fail; 712 pixpaper_wait_for_panel(panel); 713 714 return 0; 715 716 init_fail: 717 drm_err(&panel->drm, "Hardware initialization failed (err=%d)\n", 718 err.errno_code); 719 return err.errno_code; 720 } 721 722 /* 723 * Convert framebuffer pixels to 2-bit e-paper format: 724 * 00 - White 725 * 01 - Black 726 * 10 - Yellow 727 * 11 - Red 728 */ 729 static u8 pack_pixels_to_byte(__le32 *src_pixels, int i, int j, 730 struct drm_framebuffer *fb) 731 { 732 u8 packed_byte = 0; 733 int k; 734 735 for (k = 0; k < 4; k++) { 736 int current_pixel_x = j * 4 + k; 737 u8 two_bit_val; 738 739 if (current_pixel_x < PIXPAPER_WIDTH) { 740 u32 pixel_offset = 741 (i * (fb->pitches[0] / 4)) + current_pixel_x; 742 u32 pixel = le32_to_cpu(src_pixels[pixel_offset]); 743 u32 r = (pixel >> 16) & 0xFF; 744 u32 g = (pixel >> 8) & 0xFF; 745 u32 b = pixel & 0xFF; 746 747 if (r < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL && 748 g < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL && 749 b < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL) { 750 two_bit_val = 0b00; 751 } else if (r > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 752 g > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 753 b > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL) { 754 two_bit_val = 0b01; 755 } else if (r > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 756 g < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL && 757 b < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL) { 758 two_bit_val = 0b11; 759 } else if (r > PIXPAPER_COLOR_THRESHOLD_HIGH_CHANNEL && 760 g > PIXPAPER_COLOR_THRESHOLD_YELLOW_MIN_GREEN && 761 b < PIXPAPER_COLOR_THRESHOLD_LOW_CHANNEL) { 762 two_bit_val = 0b10; 763 } else { 764 two_bit_val = 0b01; 765 } 766 } else { 767 two_bit_val = 0b01; 768 } 769 770 packed_byte |= two_bit_val << ((3 - k) * 2); 771 } 772 773 return packed_byte; 774 } 775 776 static int pixpaper_plane_helper_atomic_check(struct drm_plane *plane, 777 struct drm_atomic_state *state) 778 { 779 struct drm_plane_state *new_plane_state = 780 drm_atomic_get_new_plane_state(state, plane); 781 struct drm_crtc *new_crtc = new_plane_state->crtc; 782 struct drm_crtc_state *new_crtc_state = NULL; 783 int ret; 784 785 if (new_crtc) 786 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_crtc); 787 788 ret = drm_atomic_helper_check_plane_state(new_plane_state, 789 new_crtc_state, DRM_PLANE_NO_SCALING, 790 DRM_PLANE_NO_SCALING, false, false); 791 if (ret) 792 return ret; 793 else if (!new_plane_state->visible) 794 return 0; 795 796 return 0; 797 } 798 799 static int pixpaper_crtc_helper_atomic_check(struct drm_crtc *crtc, 800 struct drm_atomic_state *state) 801 { 802 struct drm_crtc_state *crtc_state = 803 drm_atomic_get_new_crtc_state(state, crtc); 804 805 if (!crtc_state->enable) 806 return 0; 807 808 return drm_atomic_helper_check_crtc_primary_plane(crtc_state); 809 } 810 811 static void pixpaper_crtc_atomic_enable(struct drm_crtc *crtc, 812 struct drm_atomic_state *state) 813 { 814 struct pixpaper_panel *panel = to_pixpaper_panel(crtc->dev); 815 struct drm_device *drm = &panel->drm; 816 int idx; 817 struct pixpaper_error_ctx err = { .errno_code = 0 }; 818 819 if (!drm_dev_enter(drm, &idx)) 820 return; 821 822 pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_ON, &err); 823 if (err.errno_code) { 824 drm_err_once(drm, "Failed to send PON command: %d\n", err.errno_code); 825 goto exit_drm_dev; 826 } 827 828 pixpaper_wait_for_panel(panel); 829 830 drm_dbg(drm, "Panel enabled and powered on\n"); 831 832 exit_drm_dev: 833 drm_dev_exit(idx); 834 } 835 836 static void pixpaper_crtc_atomic_disable(struct drm_crtc *crtc, 837 struct drm_atomic_state *state) 838 { 839 struct pixpaper_panel *panel = to_pixpaper_panel(crtc->dev); 840 struct drm_device *drm = &panel->drm; 841 struct pixpaper_error_ctx err = { .errno_code = 0 }; 842 int idx; 843 844 if (!drm_dev_enter(drm, &idx)) 845 return; 846 847 pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_OFF, &err); 848 if (err.errno_code) { 849 drm_err_once(drm, "Failed to send POF command: %d\n", err.errno_code); 850 goto exit_drm_dev; 851 } 852 pixpaper_wait_for_panel(panel); 853 854 drm_dbg(drm, "Panel disabled\n"); 855 856 exit_drm_dev: 857 drm_dev_exit(idx); 858 } 859 860 static void pixpaper_plane_atomic_update(struct drm_plane *plane, 861 struct drm_atomic_state *state) 862 { 863 struct drm_plane_state *plane_state = 864 drm_atomic_get_new_plane_state(state, plane); 865 struct drm_shadow_plane_state *shadow_plane_state = 866 to_drm_shadow_plane_state(plane_state); 867 struct drm_crtc *crtc = plane_state->crtc; 868 struct pixpaper_panel *panel = to_pixpaper_panel(crtc->dev); 869 870 struct drm_device *drm = &panel->drm; 871 struct drm_framebuffer *fb = plane_state->fb; 872 struct iosys_map map = shadow_plane_state->data[0]; 873 void *vaddr = map.vaddr; 874 int i, j, idx; 875 __le32 *src_pixels = NULL; 876 struct pixpaper_error_ctx err = { .errno_code = 0 }; 877 878 if (!drm_dev_enter(drm, &idx)) 879 return; 880 881 drm_dbg(drm, "Starting frame update (phys=%dx%d, buf_w=%d)\n", 882 PIXPAPER_WIDTH, PIXPAPER_HEIGHT, PIXPAPER_PANEL_BUFFER_WIDTH); 883 884 if (!fb || !plane_state->visible) { 885 drm_err_once(drm, "No framebuffer or plane not visible, skipping update\n"); 886 goto update_cleanup; 887 } 888 889 src_pixels = (__le32 *)vaddr; 890 891 pixpaper_send_cmd(panel, PIXPAPER_CMD_DATA_START_TRANSMISSION, &err); 892 if (err.errno_code) 893 goto update_cleanup; 894 895 pixpaper_wait_for_panel(panel); 896 897 for (i = 0; i < PIXPAPER_HEIGHT; i++) { 898 for (j = 0; j < PIXPAPER_PANEL_BUFFER_TWO_BYTES_PER_ROW; j++) { 899 u8 packed_byte = 900 pack_pixels_to_byte(src_pixels, i, j, fb); 901 902 pixpaper_wait_for_panel(panel); 903 pixpaper_send_data(panel, packed_byte, &err); 904 } 905 } 906 pixpaper_wait_for_panel(panel); 907 908 pixpaper_send_cmd(panel, PIXPAPER_CMD_POWER_ON, &err); 909 if (err.errno_code) { 910 drm_err_once(drm, "Failed to send PON command: %d\n", err.errno_code); 911 goto update_cleanup; 912 } 913 pixpaper_wait_for_panel(panel); 914 915 pixpaper_send_cmd(panel, PIXPAPER_CMD_DISPLAY_REFRESH, &err); 916 pixpaper_send_data(panel, PIXPAPER_DRF_VCOM_AC, &err); 917 if (err.errno_code) { 918 drm_err_once(drm, "Failed sending data after DRF: %d\n", err.errno_code); 919 goto update_cleanup; 920 } 921 pixpaper_wait_for_panel(panel); 922 923 update_cleanup: 924 if (err.errno_code && err.errno_code != -ETIMEDOUT) 925 drm_err_once(drm, "Frame update function failed with error %d\n", err.errno_code); 926 927 drm_dev_exit(idx); 928 } 929 930 static const struct drm_display_mode pixpaper_mode = { 931 .clock = PIXPAPER_PIXEL_CLOCK, 932 .hdisplay = PIXPAPER_WIDTH, 933 .hsync_start = PIXPAPER_WIDTH + PIXPAPER_HFP, 934 .hsync_end = PIXPAPER_WIDTH + PIXPAPER_HFP + PIXPAPER_HSYNC, 935 .htotal = PIXPAPER_HTOTAL, 936 .vdisplay = PIXPAPER_HEIGHT, 937 .vsync_start = PIXPAPER_HEIGHT + PIXPAPER_VFP, 938 .vsync_end = PIXPAPER_HEIGHT + PIXPAPER_VFP + PIXPAPER_VSYNC, 939 .vtotal = PIXPAPER_VTOTAL, 940 .width_mm = PIXPAPER_WIDTH_MM, 941 .height_mm = PIXPAPER_HEIGHT_MM, 942 .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, 943 }; 944 945 static int pixpaper_connector_get_modes(struct drm_connector *connector) 946 { 947 return drm_connector_helper_get_modes_fixed(connector, &pixpaper_mode); 948 } 949 950 static const struct drm_plane_funcs pixpaper_plane_funcs = { 951 .update_plane = drm_atomic_helper_update_plane, 952 .disable_plane = drm_atomic_helper_disable_plane, 953 .destroy = drm_plane_cleanup, 954 DRM_GEM_SHADOW_PLANE_FUNCS, 955 }; 956 957 static const struct drm_plane_helper_funcs pixpaper_plane_helper_funcs = { 958 DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, 959 .atomic_check = pixpaper_plane_helper_atomic_check, 960 .atomic_update = pixpaper_plane_atomic_update, 961 }; 962 963 static const struct drm_crtc_funcs pixpaper_crtc_funcs = { 964 .set_config = drm_atomic_helper_set_config, 965 .page_flip = drm_atomic_helper_page_flip, 966 .reset = drm_atomic_helper_crtc_reset, 967 .destroy = drm_crtc_cleanup, 968 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 969 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 970 }; 971 972 static enum drm_mode_status 973 pixpaper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) 974 { 975 if (mode->hdisplay == PIXPAPER_WIDTH && 976 mode->vdisplay == PIXPAPER_HEIGHT) { 977 return MODE_OK; 978 } 979 return MODE_BAD; 980 } 981 982 static const struct drm_crtc_helper_funcs pixpaper_crtc_helper_funcs = { 983 .mode_valid = pixpaper_mode_valid, 984 .atomic_check = pixpaper_crtc_helper_atomic_check, 985 .atomic_enable = pixpaper_crtc_atomic_enable, 986 .atomic_disable = pixpaper_crtc_atomic_disable, 987 }; 988 989 static const struct drm_encoder_funcs pixpaper_encoder_funcs = { 990 .destroy = drm_encoder_cleanup, 991 }; 992 993 static const struct drm_connector_funcs pixpaper_connector_funcs = { 994 .reset = drm_atomic_helper_connector_reset, 995 .fill_modes = drm_helper_probe_single_connector_modes, 996 .destroy = drm_connector_cleanup, 997 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 998 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 999 }; 1000 1001 static const struct drm_connector_helper_funcs pixpaper_connector_helper_funcs = { 1002 .get_modes = pixpaper_connector_get_modes, 1003 }; 1004 1005 DEFINE_DRM_GEM_FOPS(pixpaper_fops); 1006 1007 static struct drm_driver pixpaper_drm_driver = { 1008 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, 1009 .fops = &pixpaper_fops, 1010 .name = "pixpaper", 1011 .desc = "DRM driver for PIXPAPER e-ink", 1012 .major = 1, 1013 .minor = 0, 1014 DRM_GEM_SHMEM_DRIVER_OPS, 1015 DRM_FBDEV_SHMEM_DRIVER_OPS, 1016 }; 1017 1018 static const struct drm_mode_config_funcs pixpaper_mode_config_funcs = { 1019 .fb_create = drm_gem_fb_create_with_dirty, 1020 .atomic_check = drm_atomic_helper_check, 1021 .atomic_commit = drm_atomic_helper_commit, 1022 }; 1023 1024 static int pixpaper_probe(struct spi_device *spi) 1025 { 1026 struct device *dev = &spi->dev; 1027 struct pixpaper_panel *panel; 1028 struct drm_device *drm; 1029 int ret; 1030 1031 panel = devm_drm_dev_alloc(dev, &pixpaper_drm_driver, 1032 struct pixpaper_panel, drm); 1033 if (IS_ERR(panel)) 1034 return PTR_ERR(panel); 1035 1036 drm = &panel->drm; 1037 panel->spi = spi; 1038 spi_set_drvdata(spi, panel); 1039 1040 spi->mode = SPI_MODE_0; 1041 spi->bits_per_word = PIXPAPER_SPI_BITS_PER_WORD; 1042 1043 if (!spi->max_speed_hz) { 1044 drm_warn(drm, 1045 "spi-max-frequency not specified in DT, using default %u Hz\n", 1046 PIXPAPER_SPI_SPEED_DEFAULT); 1047 spi->max_speed_hz = PIXPAPER_SPI_SPEED_DEFAULT; 1048 } 1049 1050 ret = spi_setup(spi); 1051 if (ret < 0) { 1052 drm_err(drm, "SPI setup failed: %d\n", ret); 1053 return ret; 1054 } 1055 1056 if (!dev->dma_mask) 1057 dev->dma_mask = &dev->coherent_dma_mask; 1058 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 1059 if (ret) { 1060 drm_err(drm, "Failed to set DMA mask: %d\n", ret); 1061 return ret; 1062 } 1063 1064 panel->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 1065 if (IS_ERR(panel->reset)) 1066 return PTR_ERR(panel->reset); 1067 1068 panel->busy = devm_gpiod_get(dev, "busy", GPIOD_IN); 1069 if (IS_ERR(panel->busy)) 1070 return PTR_ERR(panel->busy); 1071 1072 panel->dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_HIGH); 1073 if (IS_ERR(panel->dc)) 1074 return PTR_ERR(panel->dc); 1075 1076 ret = pixpaper_panel_hw_init(panel); 1077 if (ret) { 1078 drm_err(drm, "Panel hardware initialization failed: %d\n", ret); 1079 return ret; 1080 } 1081 1082 ret = drmm_mode_config_init(drm); 1083 if (ret) 1084 return ret; 1085 drm->mode_config.funcs = &pixpaper_mode_config_funcs; 1086 drm->mode_config.min_width = PIXPAPER_WIDTH; 1087 drm->mode_config.max_width = PIXPAPER_WIDTH; 1088 drm->mode_config.min_height = PIXPAPER_HEIGHT; 1089 drm->mode_config.max_height = PIXPAPER_HEIGHT; 1090 1091 ret = drm_universal_plane_init(drm, &panel->plane, 1, 1092 &pixpaper_plane_funcs, 1093 (const uint32_t[]){ DRM_FORMAT_XRGB8888 }, 1094 1, NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 1095 if (ret) 1096 return ret; 1097 drm_plane_helper_add(&panel->plane, &pixpaper_plane_helper_funcs); 1098 1099 ret = drm_crtc_init_with_planes(drm, &panel->crtc, &panel->plane, NULL, 1100 &pixpaper_crtc_funcs, NULL); 1101 if (ret) 1102 return ret; 1103 drm_crtc_helper_add(&panel->crtc, &pixpaper_crtc_helper_funcs); 1104 1105 ret = drm_encoder_init(drm, &panel->encoder, &pixpaper_encoder_funcs, 1106 DRM_MODE_ENCODER_NONE, NULL); 1107 if (ret) 1108 return ret; 1109 panel->encoder.possible_crtcs = drm_crtc_mask(&panel->crtc); 1110 1111 ret = drm_connector_init(drm, &panel->connector, 1112 &pixpaper_connector_funcs, 1113 DRM_MODE_CONNECTOR_SPI); 1114 if (ret) 1115 return ret; 1116 1117 drm_connector_helper_add(&panel->connector, 1118 &pixpaper_connector_helper_funcs); 1119 drm_connector_attach_encoder(&panel->connector, &panel->encoder); 1120 1121 drm_mode_config_reset(drm); 1122 1123 ret = drm_dev_register(drm, 0); 1124 if (ret) 1125 return ret; 1126 1127 drm_client_setup(drm, NULL); 1128 1129 return 0; 1130 } 1131 1132 static void pixpaper_remove(struct spi_device *spi) 1133 { 1134 struct pixpaper_panel *panel = spi_get_drvdata(spi); 1135 1136 if (!panel) 1137 return; 1138 1139 drm_dev_unplug(&panel->drm); 1140 drm_atomic_helper_shutdown(&panel->drm); 1141 } 1142 1143 static const struct spi_device_id pixpaper_ids[] = { { "pixpaper", 0 }, {} }; 1144 MODULE_DEVICE_TABLE(spi, pixpaper_ids); 1145 1146 static const struct of_device_id pixpaper_dt_ids[] = { 1147 { .compatible = "mayqueen,pixpaper" }, 1148 {} 1149 }; 1150 MODULE_DEVICE_TABLE(of, pixpaper_dt_ids); 1151 1152 static struct spi_driver pixpaper_spi_driver = { 1153 .driver = { 1154 .name = "pixpaper", 1155 .of_match_table = pixpaper_dt_ids, 1156 }, 1157 .id_table = pixpaper_ids, 1158 .probe = pixpaper_probe, 1159 .remove = pixpaper_remove, 1160 }; 1161 1162 module_spi_driver(pixpaper_spi_driver); 1163 1164 MODULE_AUTHOR("LiangCheng Wang"); 1165 MODULE_DESCRIPTION("DRM SPI driver for PIXPAPER e-ink panel"); 1166 MODULE_LICENSE("GPL"); 1167