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