@@ -32,6 +32,12 @@ struct ws_panel {
3232 enum drm_panel_orientation orientation ;
3333};
3434
35+ struct ws_panel_data {
36+ const struct drm_display_mode * mode ;
37+ int lanes ;
38+ unsigned long mode_flags ;
39+ };
40+
3541/* 2.8inch 480x640
3642 * https://www.waveshare.com/product/raspberry-pi/displays/2.8inch-dsi-lcd.htm
3743 */
@@ -47,6 +53,12 @@ static const struct drm_display_mode ws_panel_2_8_mode = {
4753 .vtotal = 640 + 150 + 50 + 150 ,
4854};
4955
56+ static const struct ws_panel_data ws_panel_2_8_data = {
57+ .mode = & ws_panel_2_8_mode ,
58+ .lanes = 2 ,
59+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
60+ };
61+
5062/* 3.4inch 800x800 Round
5163 * https://www.waveshare.com/product/displays/lcd-oled/3.4inch-dsi-lcd-c.htm
5264 */
@@ -62,6 +74,12 @@ static const struct drm_display_mode ws_panel_3_4_mode = {
6274 .vtotal = 800 + 8 + 4 + 16 ,
6375};
6476
77+ static const struct ws_panel_data ws_panel_3_4_data = {
78+ .mode = & ws_panel_3_4_mode ,
79+ .lanes = 2 ,
80+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
81+ };
82+
6583/* 4.0inch 480x800
6684 * https://www.waveshare.com/product/raspberry-pi/displays/4inch-dsi-lcd.htm
6785 */
@@ -77,6 +95,12 @@ static const struct drm_display_mode ws_panel_4_0_mode = {
7795 .vtotal = 800 + 20 + 100 + 20 ,
7896};
7997
98+ static const struct ws_panel_data ws_panel_4_0_data = {
99+ .mode = & ws_panel_4_0_mode ,
100+ .lanes = 2 ,
101+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
102+ };
103+
80104/* 7.0inch C 1024x600
81105 * https://www.waveshare.com/product/raspberry-pi/displays/lcd-oled/7inch-dsi-lcd-c-with-case-a.htm
82106 */
@@ -92,6 +116,12 @@ static const struct drm_display_mode ws_panel_7_0_c_mode = {
92116 .vtotal = 600 + 10 + 10 + 10 ,
93117};
94118
119+ static const struct ws_panel_data ws_panel_7_0_c_data = {
120+ .mode = & ws_panel_7_0_c_mode ,
121+ .lanes = 2 ,
122+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
123+ };
124+
95125/* 7.9inch 400x1280
96126 * https://www.waveshare.com/product/raspberry-pi/displays/7.9inch-dsi-lcd.htm
97127 */
@@ -107,6 +137,12 @@ static const struct drm_display_mode ws_panel_7_9_mode = {
107137 .vtotal = 1280 + 20 + 10 + 20 ,
108138};
109139
140+ static const struct ws_panel_data ws_panel_7_9_data = {
141+ .mode = & ws_panel_7_9_mode ,
142+ .lanes = 2 ,
143+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
144+ };
145+
110146/* 8.0inch or 10.1inch 1280x800
111147 * https://www.waveshare.com/product/raspberry-pi/displays/8inch-dsi-lcd-c.htm
112148 * https://www.waveshare.com/product/raspberry-pi/displays/10.1inch-dsi-lcd-c.htm
@@ -123,6 +159,12 @@ static const struct drm_display_mode ws_panel_10_1_mode = {
123159 .vtotal = 800 + 40 + 48 + 40 ,
124160};
125161
162+ static const struct ws_panel_data ws_panel_10_1_data = {
163+ .mode = & ws_panel_10_1_mode ,
164+ .lanes = 2 ,
165+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
166+ };
167+
126168/* 11.9inch 320x1480
127169 * https://www.waveshare.com/product/raspberry-pi/displays/11.9inch-dsi-lcd.htm
128170 */
@@ -138,6 +180,12 @@ static const struct drm_display_mode ws_panel_11_9_mode = {
138180 .vtotal = 1480 + 60 + 60 + 60 ,
139181};
140182
183+ static const struct ws_panel_data ws_panel_11_9_data = {
184+ .mode = & ws_panel_11_9_mode ,
185+ .lanes = 2 ,
186+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
187+ };
188+
141189static const struct drm_display_mode ws_panel_4_mode = {
142190 .clock = 50000 ,
143191 .hdisplay = 720 ,
@@ -150,6 +198,12 @@ static const struct drm_display_mode ws_panel_4_mode = {
150198 .vtotal = 720 + 8 + 4 + 16 ,
151199};
152200
201+ static const struct ws_panel_data ws_panel_4_data = {
202+ .mode = & ws_panel_4_mode ,
203+ .lanes = 2 ,
204+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
205+ };
206+
153207/* 5.0inch 720x1280
154208 * https://www.waveshare.com/5inch-dsi-lcd-d.htm
155209 */
@@ -165,6 +219,12 @@ static const struct drm_display_mode ws_panel_5_0_mode = {
165219 .vtotal = 1280 + 20 + 20 + 20 ,
166220};
167221
222+ static const struct ws_panel_data ws_panel_5_0_data = {
223+ .mode = & ws_panel_5_0_mode ,
224+ .lanes = 2 ,
225+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
226+ };
227+
168228/* 6.25inch 720x1560
169229 * https://www.waveshare.com/6.25inch-dsi-lcd.htm
170230 */
@@ -180,6 +240,12 @@ static const struct drm_display_mode ws_panel_6_25_mode = {
180240 .vtotal = 1560 + 20 + 20 + 20 ,
181241};
182242
243+ static const struct ws_panel_data ws_panel_6_25_data = {
244+ .mode = & ws_panel_6_25_mode ,
245+ .lanes = 2 ,
246+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
247+ };
248+
183249/* 8.8inch 480x1920
184250 * https://www.waveshare.com/8.8inch-dsi-lcd.htm
185251 */
@@ -195,6 +261,48 @@ static const struct drm_display_mode ws_panel_8_8_mode = {
195261 .vtotal = 1920 + 20 + 20 + 20 ,
196262};
197263
264+ static const struct ws_panel_data ws_panel_8_8_data = {
265+ .mode = & ws_panel_8_8_mode ,
266+ .lanes = 2 ,
267+ .mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS ,
268+ };
269+
270+ static const struct drm_display_mode ws_panel_13_3_4lane_mode = {
271+ .clock = 148500 ,
272+ .hdisplay = 1920 ,
273+ .hsync_start = 1920 + 88 ,
274+ .hsync_end = 1920 + 88 + 44 ,
275+ .htotal = 1920 + 88 + 44 + 148 ,
276+ .vdisplay = 1080 ,
277+ .vsync_start = 1080 + 4 ,
278+ .vsync_end = 1080 + 4 + 5 ,
279+ .vtotal = 1080 + 4 + 5 + 36 ,
280+ };
281+
282+ static const struct ws_panel_data ws_panel_13_3_4lane_data = {
283+ .mode = & ws_panel_13_3_4lane_mode ,
284+ .lanes = 4 ,
285+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM ,
286+ };
287+
288+ static const struct drm_display_mode ws_panel_13_3_2lane_mode = {
289+ .clock = 83333 ,
290+ .hdisplay = 1920 ,
291+ .hsync_start = 1920 + 88 ,
292+ .hsync_end = 1920 + 88 + 44 ,
293+ .htotal = 1920 + 88 + 44 + 148 ,
294+ .vdisplay = 1080 ,
295+ .vsync_start = 1080 + 4 ,
296+ .vsync_end = 1080 + 4 + 5 ,
297+ .vtotal = 1080 + 4 + 5 + 36 ,
298+ };
299+
300+ static const struct ws_panel_data ws_panel_13_3_2lane_data = {
301+ .mode = & ws_panel_13_3_2lane_mode ,
302+ .lanes = 2 ,
303+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM ,
304+ };
305+
198306static struct ws_panel * panel_to_ts (struct drm_panel * panel )
199307{
200308 return container_of (panel , struct ws_panel , base );
@@ -232,7 +340,10 @@ static int ws_panel_enable(struct drm_panel *panel)
232340{
233341 struct ws_panel * ts = panel_to_ts (panel );
234342
235- ws_panel_i2c_write (ts , 0xad , 0x01 );
343+ if (ts -> mode == & ws_panel_13_3_2lane_mode )
344+ ws_panel_i2c_write (ts , 0xad , 0x02 );
345+ else
346+ ws_panel_i2c_write (ts , 0xad , 0x01 );
236347
237348 return 0 ;
238349}
@@ -328,13 +439,18 @@ static int ws_panel_probe(struct i2c_client *i2c)
328439 .channel = 0 ,
329440 .node = NULL ,
330441 };
442+ const struct ws_panel_data * _ws_panel_data ;
331443 int ret ;
332444
333445 ts = devm_kzalloc (dev , sizeof (* ts ), GFP_KERNEL );
334446 if (!ts )
335447 return - ENOMEM ;
336448
337- ts -> mode = of_device_get_match_data (dev );
449+ _ws_panel_data = of_device_get_match_data (dev );
450+ if (!_ws_panel_data )
451+ return - EINVAL ;
452+
453+ ts -> mode = _ws_panel_data -> mode ;
338454 if (!ts -> mode )
339455 return - EINVAL ;
340456
@@ -396,10 +512,9 @@ static int ws_panel_probe(struct i2c_client *i2c)
396512 */
397513 drm_panel_add (& ts -> base );
398514
399- ts -> dsi -> mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
400- MIPI_DSI_CLOCK_NON_CONTINUOUS ;
515+ ts -> dsi -> mode_flags = _ws_panel_data -> mode_flags ;
401516 ts -> dsi -> format = MIPI_DSI_FMT_RGB888 ;
402- ts -> dsi -> lanes = 2 ;
517+ ts -> dsi -> lanes = _ws_panel_data -> lanes ;
403518
404519 ret = devm_mipi_dsi_attach (dev , ts -> dsi );
405520
@@ -432,40 +547,46 @@ static void ws_panel_shutdown(struct i2c_client *i2c)
432547static const struct of_device_id ws_panel_of_ids [] = {
433548 {
434549 .compatible = "waveshare,2.8inch-panel" ,
435- .data = & ws_panel_2_8_mode ,
550+ .data = & ws_panel_2_8_data ,
436551 }, {
437552 .compatible = "waveshare,3.4inch-panel" ,
438- .data = & ws_panel_3_4_mode ,
553+ .data = & ws_panel_3_4_data ,
439554 }, {
440555 .compatible = "waveshare,4.0inch-panel" ,
441- .data = & ws_panel_4_0_mode ,
556+ .data = & ws_panel_4_0_data ,
442557 }, {
443558 .compatible = "waveshare,7.0inch-c-panel" ,
444- .data = & ws_panel_7_0_c_mode ,
559+ .data = & ws_panel_7_0_c_data ,
445560 }, {
446561 .compatible = "waveshare,7.9inch-panel" ,
447- .data = & ws_panel_7_9_mode ,
562+ .data = & ws_panel_7_9_data ,
448563 }, {
449564 .compatible = "waveshare,8.0inch-panel" ,
450- .data = & ws_panel_10_1_mode ,
565+ .data = & ws_panel_10_1_data ,
451566 }, {
452567 .compatible = "waveshare,10.1inch-panel" ,
453- .data = & ws_panel_10_1_mode ,
568+ .data = & ws_panel_10_1_data ,
454569 }, {
455570 .compatible = "waveshare,11.9inch-panel" ,
456- .data = & ws_panel_11_9_mode ,
571+ .data = & ws_panel_11_9_data ,
457572 }, {
458573 .compatible = "waveshare,4inch-panel" ,
459- .data = & ws_panel_4_mode ,
574+ .data = & ws_panel_4_data ,
460575 }, {
461576 .compatible = "waveshare,5.0inch-panel" ,
462- .data = & ws_panel_5_0_mode ,
577+ .data = & ws_panel_5_0_data ,
463578 }, {
464579 .compatible = "waveshare,6.25inch-panel" ,
465- .data = & ws_panel_6_25_mode ,
580+ .data = & ws_panel_6_25_data ,
466581 }, {
467582 .compatible = "waveshare,8.8inch-panel" ,
468- .data = & ws_panel_8_8_mode ,
583+ .data = & ws_panel_8_8_data ,
584+ }, {
585+ .compatible = "waveshare,13.3inch-4lane-panel" ,
586+ .data = & ws_panel_13_3_4lane_data ,
587+ }, {
588+ .compatible = "waveshare,13.3inch-2lane-panel" ,
589+ .data = & ws_panel_13_3_2lane_data ,
469590 }, {
470591 /* sentinel */
471592 }
0 commit comments