@@ -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,12 @@ 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+ }
346+ else {
347+ ws_panel_i2c_write (ts , 0xad , 0x01 );
348+ }
236349
237350 return 0 ;
238351}
@@ -328,13 +441,18 @@ static int ws_panel_probe(struct i2c_client *i2c)
328441 .channel = 0 ,
329442 .node = NULL ,
330443 };
444+ const struct ws_panel_data * _ws_panel_data ;
331445 int ret ;
332446
333447 ts = devm_kzalloc (dev , sizeof (* ts ), GFP_KERNEL );
334448 if (!ts )
335449 return - ENOMEM ;
336450
337- ts -> mode = of_device_get_match_data (dev );
451+ _ws_panel_data = of_device_get_match_data (dev );
452+ if (!_ws_panel_data )
453+ return - EINVAL ;
454+
455+ ts -> mode = _ws_panel_data -> mode ;
338456 if (!ts -> mode )
339457 return - EINVAL ;
340458
@@ -396,10 +514,9 @@ static int ws_panel_probe(struct i2c_client *i2c)
396514 */
397515 drm_panel_add (& ts -> base );
398516
399- ts -> dsi -> mode_flags = MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_MODE_VIDEO |
400- MIPI_DSI_CLOCK_NON_CONTINUOUS ;
517+ ts -> dsi -> mode_flags = _ws_panel_data -> mode_flags ;
401518 ts -> dsi -> format = MIPI_DSI_FMT_RGB888 ;
402- ts -> dsi -> lanes = 2 ;
519+ ts -> dsi -> lanes = _ws_panel_data -> lanes ;
403520
404521 ret = devm_mipi_dsi_attach (dev , ts -> dsi );
405522
@@ -432,40 +549,46 @@ static void ws_panel_shutdown(struct i2c_client *i2c)
432549static const struct of_device_id ws_panel_of_ids [] = {
433550 {
434551 .compatible = "waveshare,2.8inch-panel" ,
435- .data = & ws_panel_2_8_mode ,
552+ .data = & ws_panel_2_8_data ,
436553 }, {
437554 .compatible = "waveshare,3.4inch-panel" ,
438- .data = & ws_panel_3_4_mode ,
555+ .data = & ws_panel_3_4_data ,
439556 }, {
440557 .compatible = "waveshare,4.0inch-panel" ,
441- .data = & ws_panel_4_0_mode ,
558+ .data = & ws_panel_4_0_data ,
442559 }, {
443560 .compatible = "waveshare,7.0inch-c-panel" ,
444- .data = & ws_panel_7_0_c_mode ,
561+ .data = & ws_panel_7_0_c_data ,
445562 }, {
446563 .compatible = "waveshare,7.9inch-panel" ,
447- .data = & ws_panel_7_9_mode ,
564+ .data = & ws_panel_7_9_data ,
448565 }, {
449566 .compatible = "waveshare,8.0inch-panel" ,
450- .data = & ws_panel_10_1_mode ,
567+ .data = & ws_panel_10_1_data ,
451568 }, {
452569 .compatible = "waveshare,10.1inch-panel" ,
453- .data = & ws_panel_10_1_mode ,
570+ .data = & ws_panel_10_1_data ,
454571 }, {
455572 .compatible = "waveshare,11.9inch-panel" ,
456- .data = & ws_panel_11_9_mode ,
573+ .data = & ws_panel_11_9_data ,
457574 }, {
458575 .compatible = "waveshare,4inch-panel" ,
459- .data = & ws_panel_4_mode ,
576+ .data = & ws_panel_4_data ,
460577 }, {
461578 .compatible = "waveshare,5.0inch-panel" ,
462- .data = & ws_panel_5_0_mode ,
579+ .data = & ws_panel_5_0_data ,
463580 }, {
464581 .compatible = "waveshare,6.25inch-panel" ,
465- .data = & ws_panel_6_25_mode ,
582+ .data = & ws_panel_6_25_data ,
466583 }, {
467584 .compatible = "waveshare,8.8inch-panel" ,
468- .data = & ws_panel_8_8_mode ,
585+ .data = & ws_panel_8_8_data ,
586+ }, {
587+ .compatible = "waveshare,13.3inch-4lane-panel" ,
588+ .data = & ws_panel_13_3_4lane_data ,
589+ }, {
590+ .compatible = "waveshare,13.3inch-2lane-panel" ,
591+ .data = & ws_panel_13_3_2lane_data ,
469592 }, {
470593 /* sentinel */
471594 }
0 commit comments