xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * MIPI-DSI based s6e3ha2 AMOLED 5.7 inch panel driver.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6*4882a593Smuzhiyun  * Donghwa Lee <dh09.lee@samsung.com>
7*4882a593Smuzhiyun  * Hyungwon Hwang <human.hwang@samsung.com>
8*4882a593Smuzhiyun  * Hoegeun Kwon <hoegeun.kwon@samsung.com>
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/backlight.h>
12*4882a593Smuzhiyun #include <linux/delay.h>
13*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/of_device.h>
16*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <drm/drm_mipi_dsi.h>
19*4882a593Smuzhiyun #include <drm/drm_modes.h>
20*4882a593Smuzhiyun #include <drm/drm_panel.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define S6E3HA2_MIN_BRIGHTNESS		0
23*4882a593Smuzhiyun #define S6E3HA2_MAX_BRIGHTNESS		100
24*4882a593Smuzhiyun #define S6E3HA2_DEFAULT_BRIGHTNESS	80
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define S6E3HA2_NUM_GAMMA_STEPS		46
27*4882a593Smuzhiyun #define S6E3HA2_GAMMA_CMD_CNT		35
28*4882a593Smuzhiyun #define S6E3HA2_VINT_STATUS_MAX		10
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun static const u8 gamma_tbl[S6E3HA2_NUM_GAMMA_STEPS][S6E3HA2_GAMMA_CMD_CNT] = {
31*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x82, 0x83,
32*4882a593Smuzhiyun 	  0x85, 0x88, 0x8b, 0x8b, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8c,
33*4882a593Smuzhiyun 	  0x94, 0x84, 0xb1, 0xaf, 0x8e, 0xcf, 0xad, 0xc9, 0x00, 0x00, 0x00,
34*4882a593Smuzhiyun 	  0x00, 0x00 },
35*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x84, 0x84,
36*4882a593Smuzhiyun 	  0x85, 0x87, 0x8b, 0x8a, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8a,
37*4882a593Smuzhiyun 	  0x93, 0x84, 0xb0, 0xae, 0x8e, 0xc9, 0xa8, 0xc5, 0x00, 0x00, 0x00,
38*4882a593Smuzhiyun 	  0x00, 0x00 },
39*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
40*4882a593Smuzhiyun 	  0x85, 0x86, 0x8a, 0x8a, 0x84, 0x88, 0x81, 0x84, 0x8a, 0x88, 0x8a,
41*4882a593Smuzhiyun 	  0x91, 0x84, 0xb1, 0xae, 0x8b, 0xd5, 0xb2, 0xcc, 0x00, 0x00, 0x00,
42*4882a593Smuzhiyun 	  0x00, 0x00 },
43*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
44*4882a593Smuzhiyun 	  0x85, 0x86, 0x8a, 0x8a, 0x84, 0x87, 0x81, 0x84, 0x8a, 0x87, 0x8a,
45*4882a593Smuzhiyun 	  0x91, 0x85, 0xae, 0xac, 0x8a, 0xc3, 0xa3, 0xc0, 0x00, 0x00, 0x00,
46*4882a593Smuzhiyun 	  0x00, 0x00 },
47*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x85, 0x85,
48*4882a593Smuzhiyun 	  0x86, 0x85, 0x88, 0x89, 0x84, 0x89, 0x82, 0x84, 0x87, 0x85, 0x8b,
49*4882a593Smuzhiyun 	  0x91, 0x88, 0xad, 0xab, 0x8a, 0xb7, 0x9b, 0xb6, 0x00, 0x00, 0x00,
50*4882a593Smuzhiyun 	  0x00, 0x00 },
51*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
52*4882a593Smuzhiyun 	  0x85, 0x86, 0x89, 0x8a, 0x84, 0x89, 0x83, 0x83, 0x86, 0x84, 0x8b,
53*4882a593Smuzhiyun 	  0x90, 0x84, 0xb0, 0xae, 0x8b, 0xce, 0xad, 0xc8, 0x00, 0x00, 0x00,
54*4882a593Smuzhiyun 	  0x00, 0x00 },
55*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
56*4882a593Smuzhiyun 	  0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x89,
57*4882a593Smuzhiyun 	  0x8f, 0x84, 0xac, 0xaa, 0x89, 0xb1, 0x98, 0xaf, 0x00, 0x00, 0x00,
58*4882a593Smuzhiyun 	  0x00, 0x00 },
59*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
60*4882a593Smuzhiyun 	  0x85, 0x86, 0x88, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8c,
61*4882a593Smuzhiyun 	  0x91, 0x86, 0xac, 0xaa, 0x89, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
62*4882a593Smuzhiyun 	  0x00, 0x00 },
63*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
64*4882a593Smuzhiyun 	  0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x88,
65*4882a593Smuzhiyun 	  0x8b, 0x82, 0xad, 0xaa, 0x8a, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
66*4882a593Smuzhiyun 	  0x00, 0x00 },
67*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
68*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8a,
69*4882a593Smuzhiyun 	  0x8e, 0x84, 0xae, 0xac, 0x89, 0xda, 0xb7, 0xd0, 0x00, 0x00, 0x00,
70*4882a593Smuzhiyun 	  0x00, 0x00 },
71*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
72*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x80, 0x83, 0x82, 0x8b,
73*4882a593Smuzhiyun 	  0x8e, 0x85, 0xac, 0xaa, 0x89, 0xc8, 0xaa, 0xc1, 0x00, 0x00, 0x00,
74*4882a593Smuzhiyun 	  0x00, 0x00 },
75*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
76*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x89, 0x81, 0x85, 0x81, 0x84, 0x86, 0x84, 0x8c,
77*4882a593Smuzhiyun 	  0x8c, 0x84, 0xa9, 0xa8, 0x87, 0xa3, 0x92, 0xa1, 0x00, 0x00, 0x00,
78*4882a593Smuzhiyun 	  0x00, 0x00 },
79*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
80*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x89, 0x84, 0x86, 0x83, 0x80, 0x83, 0x81, 0x8c,
81*4882a593Smuzhiyun 	  0x8d, 0x84, 0xaa, 0xaa, 0x89, 0xce, 0xaf, 0xc5, 0x00, 0x00, 0x00,
82*4882a593Smuzhiyun 	  0x00, 0x00 },
83*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
84*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x89, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
85*4882a593Smuzhiyun 	  0x8c, 0x84, 0xa8, 0xa8, 0x88, 0xb5, 0x9f, 0xb0, 0x00, 0x00, 0x00,
86*4882a593Smuzhiyun 	  0x00, 0x00 },
87*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
88*4882a593Smuzhiyun 	  0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
89*4882a593Smuzhiyun 	  0x8b, 0x84, 0xab, 0xa8, 0x86, 0xd4, 0xb4, 0xc9, 0x00, 0x00, 0x00,
90*4882a593Smuzhiyun 	  0x00, 0x00 },
91*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
92*4882a593Smuzhiyun 	  0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x84, 0x84, 0x85, 0x8b,
93*4882a593Smuzhiyun 	  0x8a, 0x83, 0xa6, 0xa5, 0x84, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
94*4882a593Smuzhiyun 	  0x00, 0x00 },
95*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
96*4882a593Smuzhiyun 	  0x86, 0x85, 0x86, 0x86, 0x82, 0x85, 0x81, 0x82, 0x83, 0x84, 0x8e,
97*4882a593Smuzhiyun 	  0x8b, 0x83, 0xa4, 0xa3, 0x8a, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
98*4882a593Smuzhiyun 	  0x00, 0x00 },
99*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
100*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8e,
101*4882a593Smuzhiyun 	  0x8b, 0x83, 0xa4, 0xa2, 0x86, 0xc1, 0xa9, 0xb7, 0x00, 0x00, 0x00,
102*4882a593Smuzhiyun 	  0x00, 0x00 },
103*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
104*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8d,
105*4882a593Smuzhiyun 	  0x89, 0x82, 0xa2, 0xa1, 0x84, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
106*4882a593Smuzhiyun 	  0x00, 0x00 },
107*4882a593Smuzhiyun 	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
108*4882a593Smuzhiyun 	  0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x83, 0x83, 0x85, 0x8c,
109*4882a593Smuzhiyun 	  0x87, 0x7f, 0xa2, 0x9d, 0x88, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
110*4882a593Smuzhiyun 	  0x00, 0x00 },
111*4882a593Smuzhiyun 	{ 0x00, 0xbb, 0x00, 0xc5, 0x00, 0xb4, 0x87, 0x86, 0x86, 0x84, 0x83,
112*4882a593Smuzhiyun 	  0x86, 0x87, 0x87, 0x87, 0x80, 0x82, 0x7f, 0x86, 0x86, 0x88, 0x8a,
113*4882a593Smuzhiyun 	  0x84, 0x7e, 0x9d, 0x9c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
114*4882a593Smuzhiyun 	  0x00, 0x00 },
115*4882a593Smuzhiyun 	{ 0x00, 0xbd, 0x00, 0xc7, 0x00, 0xb7, 0x87, 0x85, 0x85, 0x84, 0x83,
116*4882a593Smuzhiyun 	  0x86, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x83, 0x84, 0x85, 0x8a,
117*4882a593Smuzhiyun 	  0x85, 0x7e, 0x9c, 0x9b, 0x85, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
118*4882a593Smuzhiyun 	  0x00, 0x00 },
119*4882a593Smuzhiyun 	{ 0x00, 0xc0, 0x00, 0xca, 0x00, 0xbb, 0x87, 0x86, 0x85, 0x83, 0x83,
120*4882a593Smuzhiyun 	  0x85, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x84, 0x85, 0x86, 0x89,
121*4882a593Smuzhiyun 	  0x83, 0x7d, 0x9c, 0x99, 0x87, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
122*4882a593Smuzhiyun 	  0x00, 0x00 },
123*4882a593Smuzhiyun 	{ 0x00, 0xc4, 0x00, 0xcd, 0x00, 0xbe, 0x87, 0x86, 0x85, 0x83, 0x83,
124*4882a593Smuzhiyun 	  0x86, 0x85, 0x85, 0x87, 0x81, 0x82, 0x80, 0x82, 0x82, 0x83, 0x8a,
125*4882a593Smuzhiyun 	  0x85, 0x7f, 0x9f, 0x9b, 0x86, 0xb4, 0xa1, 0xac, 0x00, 0x00, 0x00,
126*4882a593Smuzhiyun 	  0x00, 0x00 },
127*4882a593Smuzhiyun 	{ 0x00, 0xc7, 0x00, 0xd0, 0x00, 0xc2, 0x87, 0x85, 0x85, 0x83, 0x82,
128*4882a593Smuzhiyun 	  0x85, 0x85, 0x85, 0x86, 0x82, 0x83, 0x80, 0x82, 0x82, 0x84, 0x87,
129*4882a593Smuzhiyun 	  0x86, 0x80, 0x9e, 0x9a, 0x87, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
130*4882a593Smuzhiyun 	  0x00, 0x00 },
131*4882a593Smuzhiyun 	{ 0x00, 0xca, 0x00, 0xd2, 0x00, 0xc5, 0x87, 0x85, 0x84, 0x82, 0x82,
132*4882a593Smuzhiyun 	  0x84, 0x85, 0x85, 0x86, 0x81, 0x82, 0x7f, 0x82, 0x82, 0x84, 0x88,
133*4882a593Smuzhiyun 	  0x86, 0x81, 0x9d, 0x98, 0x86, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
134*4882a593Smuzhiyun 	  0x00, 0x00 },
135*4882a593Smuzhiyun 	{ 0x00, 0xce, 0x00, 0xd6, 0x00, 0xca, 0x86, 0x85, 0x84, 0x83, 0x83,
136*4882a593Smuzhiyun 	  0x85, 0x84, 0x84, 0x85, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x89,
137*4882a593Smuzhiyun 	  0x86, 0x81, 0x9c, 0x97, 0x86, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
138*4882a593Smuzhiyun 	  0x00, 0x00 },
139*4882a593Smuzhiyun 	{ 0x00, 0xd1, 0x00, 0xd9, 0x00, 0xce, 0x86, 0x84, 0x83, 0x83, 0x82,
140*4882a593Smuzhiyun 	  0x85, 0x85, 0x85, 0x86, 0x81, 0x83, 0x81, 0x82, 0x82, 0x83, 0x86,
141*4882a593Smuzhiyun 	  0x83, 0x7f, 0x99, 0x95, 0x86, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
142*4882a593Smuzhiyun 	  0x00, 0x00 },
143*4882a593Smuzhiyun 	{ 0x00, 0xd4, 0x00, 0xdb, 0x00, 0xd1, 0x86, 0x85, 0x83, 0x83, 0x82,
144*4882a593Smuzhiyun 	  0x85, 0x84, 0x84, 0x85, 0x80, 0x83, 0x82, 0x80, 0x80, 0x81, 0x87,
145*4882a593Smuzhiyun 	  0x84, 0x81, 0x98, 0x93, 0x85, 0xae, 0x9c, 0xa8, 0x00, 0x00, 0x00,
146*4882a593Smuzhiyun 	  0x00, 0x00 },
147*4882a593Smuzhiyun 	{ 0x00, 0xd8, 0x00, 0xde, 0x00, 0xd6, 0x86, 0x84, 0x83, 0x81, 0x81,
148*4882a593Smuzhiyun 	  0x83, 0x85, 0x85, 0x85, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x86,
149*4882a593Smuzhiyun 	  0x84, 0x80, 0x98, 0x91, 0x85, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
150*4882a593Smuzhiyun 	  0x00, 0x00 },
151*4882a593Smuzhiyun 	{ 0x00, 0xdc, 0x00, 0xe2, 0x00, 0xda, 0x85, 0x84, 0x83, 0x82, 0x82,
152*4882a593Smuzhiyun 	  0x84, 0x84, 0x84, 0x85, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83,
153*4882a593Smuzhiyun 	  0x82, 0x7f, 0x99, 0x93, 0x86, 0x94, 0x8b, 0x92, 0x00, 0x00, 0x00,
154*4882a593Smuzhiyun 	  0x00, 0x00 },
155*4882a593Smuzhiyun 	{ 0x00, 0xdf, 0x00, 0xe5, 0x00, 0xde, 0x85, 0x84, 0x82, 0x82, 0x82,
156*4882a593Smuzhiyun 	  0x84, 0x83, 0x83, 0x84, 0x81, 0x81, 0x80, 0x83, 0x82, 0x84, 0x82,
157*4882a593Smuzhiyun 	  0x81, 0x7f, 0x99, 0x92, 0x86, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
158*4882a593Smuzhiyun 	  0x00, 0x00 },
159*4882a593Smuzhiyun 	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
160*4882a593Smuzhiyun 	  0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x83, 0x83, 0x84, 0x80,
161*4882a593Smuzhiyun 	  0x81, 0x7c, 0x99, 0x92, 0x87, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
162*4882a593Smuzhiyun 	  0x00, 0x00 },
163*4882a593Smuzhiyun 	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x85, 0x84, 0x83, 0x81, 0x81,
164*4882a593Smuzhiyun 	  0x82, 0x82, 0x82, 0x83, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
165*4882a593Smuzhiyun 	  0x82, 0x80, 0x91, 0x8d, 0x83, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
166*4882a593Smuzhiyun 	  0x00, 0x00 },
167*4882a593Smuzhiyun 	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
168*4882a593Smuzhiyun 	  0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
169*4882a593Smuzhiyun 	  0x81, 0x7f, 0x91, 0x8c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
170*4882a593Smuzhiyun 	  0x00, 0x00 },
171*4882a593Smuzhiyun 	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
172*4882a593Smuzhiyun 	  0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x82,
173*4882a593Smuzhiyun 	  0x82, 0x7f, 0x94, 0x89, 0x84, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
174*4882a593Smuzhiyun 	  0x00, 0x00 },
175*4882a593Smuzhiyun 	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
176*4882a593Smuzhiyun 	  0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x83,
177*4882a593Smuzhiyun 	  0x82, 0x7f, 0x91, 0x85, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
178*4882a593Smuzhiyun 	  0x00, 0x00 },
179*4882a593Smuzhiyun 	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
180*4882a593Smuzhiyun 	  0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x83, 0x82, 0x84, 0x83,
181*4882a593Smuzhiyun 	  0x82, 0x7f, 0x90, 0x84, 0x81, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
182*4882a593Smuzhiyun 	  0x00, 0x00 },
183*4882a593Smuzhiyun 	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x80, 0x80,
184*4882a593Smuzhiyun 	  0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x81, 0x81,
185*4882a593Smuzhiyun 	  0x82, 0x83, 0x7e, 0x80, 0x7c, 0xa4, 0x97, 0x9f, 0x00, 0x00, 0x00,
186*4882a593Smuzhiyun 	  0x00, 0x00 },
187*4882a593Smuzhiyun 	{ 0x00, 0xe9, 0x00, 0xec, 0x00, 0xe8, 0x84, 0x83, 0x82, 0x81, 0x81,
188*4882a593Smuzhiyun 	  0x82, 0x82, 0x82, 0x83, 0x7f, 0x7f, 0x7f, 0x81, 0x80, 0x82, 0x83,
189*4882a593Smuzhiyun 	  0x83, 0x84, 0x79, 0x7c, 0x79, 0xb1, 0xa0, 0xaa, 0x00, 0x00, 0x00,
190*4882a593Smuzhiyun 	  0x00, 0x00 },
191*4882a593Smuzhiyun 	{ 0x00, 0xed, 0x00, 0xf0, 0x00, 0xec, 0x83, 0x83, 0x82, 0x80, 0x80,
192*4882a593Smuzhiyun 	  0x81, 0x82, 0x82, 0x82, 0x7f, 0x7f, 0x7e, 0x81, 0x81, 0x82, 0x80,
193*4882a593Smuzhiyun 	  0x81, 0x81, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
194*4882a593Smuzhiyun 	  0x00, 0x00 },
195*4882a593Smuzhiyun 	{ 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xf1, 0x83, 0x82, 0x82, 0x80, 0x80,
196*4882a593Smuzhiyun 	  0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7d,
197*4882a593Smuzhiyun 	  0x7e, 0x7f, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
198*4882a593Smuzhiyun 	  0x00, 0x00 },
199*4882a593Smuzhiyun 	{ 0x00, 0xf6, 0x00, 0xf7, 0x00, 0xf5, 0x82, 0x82, 0x81, 0x80, 0x80,
200*4882a593Smuzhiyun 	  0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x82,
201*4882a593Smuzhiyun 	  0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
202*4882a593Smuzhiyun 	  0x00, 0x00 },
203*4882a593Smuzhiyun 	{ 0x00, 0xfa, 0x00, 0xfb, 0x00, 0xfa, 0x81, 0x81, 0x81, 0x80, 0x80,
204*4882a593Smuzhiyun 	  0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
205*4882a593Smuzhiyun 	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
206*4882a593Smuzhiyun 	  0x00, 0x00 },
207*4882a593Smuzhiyun 	{ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
208*4882a593Smuzhiyun 	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
209*4882a593Smuzhiyun 	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
210*4882a593Smuzhiyun 	  0x00, 0x00 },
211*4882a593Smuzhiyun 	{ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
212*4882a593Smuzhiyun 	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
213*4882a593Smuzhiyun 	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
214*4882a593Smuzhiyun 	  0x00, 0x00 }
215*4882a593Smuzhiyun };
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = {
218*4882a593Smuzhiyun 	0x18, 0x19, 0x1a, 0x1b, 0x1c,
219*4882a593Smuzhiyun 	0x1d, 0x1e, 0x1f, 0x20, 0x21
220*4882a593Smuzhiyun };
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun enum s6e3ha2_type {
223*4882a593Smuzhiyun 	HA2_TYPE,
224*4882a593Smuzhiyun 	HF2_TYPE,
225*4882a593Smuzhiyun };
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun struct s6e3ha2_panel_desc {
228*4882a593Smuzhiyun 	const struct drm_display_mode *mode;
229*4882a593Smuzhiyun 	enum s6e3ha2_type type;
230*4882a593Smuzhiyun };
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun struct s6e3ha2 {
233*4882a593Smuzhiyun 	struct device *dev;
234*4882a593Smuzhiyun 	struct drm_panel panel;
235*4882a593Smuzhiyun 	struct backlight_device *bl_dev;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	struct regulator_bulk_data supplies[2];
238*4882a593Smuzhiyun 	struct gpio_desc *reset_gpio;
239*4882a593Smuzhiyun 	struct gpio_desc *enable_gpio;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	const struct s6e3ha2_panel_desc *desc;
242*4882a593Smuzhiyun };
243*4882a593Smuzhiyun 
s6e3ha2_dcs_write(struct s6e3ha2 * ctx,const void * data,size_t len)244*4882a593Smuzhiyun static int s6e3ha2_dcs_write(struct s6e3ha2 *ctx, const void *data, size_t len)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	return mipi_dsi_dcs_write_buffer(dsi, data, len);
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun #define s6e3ha2_dcs_write_seq_static(ctx, seq...) do {	\
252*4882a593Smuzhiyun 	static const u8 d[] = { seq };			\
253*4882a593Smuzhiyun 	int ret;					\
254*4882a593Smuzhiyun 	ret = s6e3ha2_dcs_write(ctx, d, ARRAY_SIZE(d));	\
255*4882a593Smuzhiyun 	if (ret < 0)					\
256*4882a593Smuzhiyun 		return ret;				\
257*4882a593Smuzhiyun } while (0)
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun #define s6e3ha2_call_write_func(ret, func) do {	\
260*4882a593Smuzhiyun 	ret = (func);				\
261*4882a593Smuzhiyun 	if (ret < 0)				\
262*4882a593Smuzhiyun 		return ret;			\
263*4882a593Smuzhiyun } while (0)
264*4882a593Smuzhiyun 
s6e3ha2_test_key_on_f0(struct s6e3ha2 * ctx)265*4882a593Smuzhiyun static int s6e3ha2_test_key_on_f0(struct s6e3ha2 *ctx)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a);
268*4882a593Smuzhiyun 	return 0;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
s6e3ha2_test_key_off_f0(struct s6e3ha2 * ctx)271*4882a593Smuzhiyun static int s6e3ha2_test_key_off_f0(struct s6e3ha2 *ctx)
272*4882a593Smuzhiyun {
273*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0xa5, 0xa5);
274*4882a593Smuzhiyun 	return 0;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun 
s6e3ha2_test_key_on_fc(struct s6e3ha2 * ctx)277*4882a593Smuzhiyun static int s6e3ha2_test_key_on_fc(struct s6e3ha2 *ctx)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a);
280*4882a593Smuzhiyun 	return 0;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
s6e3ha2_test_key_off_fc(struct s6e3ha2 * ctx)283*4882a593Smuzhiyun static int s6e3ha2_test_key_off_fc(struct s6e3ha2 *ctx)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0xa5, 0xa5);
286*4882a593Smuzhiyun 	return 0;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
s6e3ha2_single_dsi_set(struct s6e3ha2 * ctx)289*4882a593Smuzhiyun static int s6e3ha2_single_dsi_set(struct s6e3ha2 *ctx)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67);
292*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xf9, 0x09);
293*4882a593Smuzhiyun 	return 0;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun 
s6e3ha2_freq_calibration(struct s6e3ha2 * ctx)296*4882a593Smuzhiyun static int s6e3ha2_freq_calibration(struct s6e3ha2 *ctx)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xfd, 0x1c);
299*4882a593Smuzhiyun 	if (ctx->desc->type == HF2_TYPE)
300*4882a593Smuzhiyun 		s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67, 0x40, 0xc5);
301*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20, 0x39);
302*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0xa0);
303*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20);
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	if (ctx->desc->type == HA2_TYPE)
306*4882a593Smuzhiyun 		s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x12, 0x62,
307*4882a593Smuzhiyun 						  0x40, 0x80, 0xc0, 0x28, 0x28,
308*4882a593Smuzhiyun 						  0x28, 0x28, 0x39, 0xc5);
309*4882a593Smuzhiyun 	else
310*4882a593Smuzhiyun 		s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x14, 0x6d,
311*4882a593Smuzhiyun 						  0x40, 0x80, 0xc0, 0x28, 0x28,
312*4882a593Smuzhiyun 						  0x28, 0x28, 0x39, 0xc5);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	return 0;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
s6e3ha2_aor_control(struct s6e3ha2 * ctx)317*4882a593Smuzhiyun static int s6e3ha2_aor_control(struct s6e3ha2 *ctx)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xb2, 0x03, 0x10);
320*4882a593Smuzhiyun 	return 0;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
s6e3ha2_caps_elvss_set(struct s6e3ha2 * ctx)323*4882a593Smuzhiyun static int s6e3ha2_caps_elvss_set(struct s6e3ha2 *ctx)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xb6, 0x9c, 0x0a);
326*4882a593Smuzhiyun 	return 0;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
s6e3ha2_acl_off(struct s6e3ha2 * ctx)329*4882a593Smuzhiyun static int s6e3ha2_acl_off(struct s6e3ha2 *ctx)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0x55, 0x00);
332*4882a593Smuzhiyun 	return 0;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
s6e3ha2_acl_off_opr(struct s6e3ha2 * ctx)335*4882a593Smuzhiyun static int s6e3ha2_acl_off_opr(struct s6e3ha2 *ctx)
336*4882a593Smuzhiyun {
337*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xb5, 0x40);
338*4882a593Smuzhiyun 	return 0;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun 
s6e3ha2_test_global(struct s6e3ha2 * ctx)341*4882a593Smuzhiyun static int s6e3ha2_test_global(struct s6e3ha2 *ctx)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x07);
344*4882a593Smuzhiyun 	return 0;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
s6e3ha2_test(struct s6e3ha2 * ctx)347*4882a593Smuzhiyun static int s6e3ha2_test(struct s6e3ha2 *ctx)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xb8, 0x19);
350*4882a593Smuzhiyun 	return 0;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun 
s6e3ha2_touch_hsync_on1(struct s6e3ha2 * ctx)353*4882a593Smuzhiyun static int s6e3ha2_touch_hsync_on1(struct s6e3ha2 *ctx)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xbd, 0x33, 0x11, 0x02,
356*4882a593Smuzhiyun 					0x16, 0x02, 0x16);
357*4882a593Smuzhiyun 	return 0;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun 
s6e3ha2_pentile_control(struct s6e3ha2 * ctx)360*4882a593Smuzhiyun static int s6e3ha2_pentile_control(struct s6e3ha2 *ctx)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xc0, 0x00, 0x00, 0xd8, 0xd8);
363*4882a593Smuzhiyun 	return 0;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun 
s6e3ha2_poc_global(struct s6e3ha2 * ctx)366*4882a593Smuzhiyun static int s6e3ha2_poc_global(struct s6e3ha2 *ctx)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x20);
369*4882a593Smuzhiyun 	return 0;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
s6e3ha2_poc_setting(struct s6e3ha2 * ctx)372*4882a593Smuzhiyun static int s6e3ha2_poc_setting(struct s6e3ha2 *ctx)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x08);
375*4882a593Smuzhiyun 	return 0;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun 
s6e3ha2_pcd_set_off(struct s6e3ha2 * ctx)378*4882a593Smuzhiyun static int s6e3ha2_pcd_set_off(struct s6e3ha2 *ctx)
379*4882a593Smuzhiyun {
380*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xcc, 0x40, 0x51);
381*4882a593Smuzhiyun 	return 0;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
s6e3ha2_err_fg_set(struct s6e3ha2 * ctx)384*4882a593Smuzhiyun static int s6e3ha2_err_fg_set(struct s6e3ha2 *ctx)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xed, 0x44);
387*4882a593Smuzhiyun 	return 0;
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun 
s6e3ha2_hbm_off(struct s6e3ha2 * ctx)390*4882a593Smuzhiyun static int s6e3ha2_hbm_off(struct s6e3ha2 *ctx)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0x53, 0x00);
393*4882a593Smuzhiyun 	return 0;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
s6e3ha2_te_start_setting(struct s6e3ha2 * ctx)396*4882a593Smuzhiyun static int s6e3ha2_te_start_setting(struct s6e3ha2 *ctx)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xb9, 0x10, 0x09, 0xff, 0x00, 0x09);
399*4882a593Smuzhiyun 	return 0;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun 
s6e3ha2_gamma_update(struct s6e3ha2 * ctx)402*4882a593Smuzhiyun static int s6e3ha2_gamma_update(struct s6e3ha2 *ctx)
403*4882a593Smuzhiyun {
404*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x03);
405*4882a593Smuzhiyun 	ndelay(100); /* need for 100ns delay */
406*4882a593Smuzhiyun 	s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x00);
407*4882a593Smuzhiyun 	return 0;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun 
s6e3ha2_get_brightness(struct backlight_device * bl_dev)410*4882a593Smuzhiyun static int s6e3ha2_get_brightness(struct backlight_device *bl_dev)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun 	return bl_dev->props.brightness;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
s6e3ha2_set_vint(struct s6e3ha2 * ctx)415*4882a593Smuzhiyun static int s6e3ha2_set_vint(struct s6e3ha2 *ctx)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	struct backlight_device *bl_dev = ctx->bl_dev;
418*4882a593Smuzhiyun 	unsigned int brightness = bl_dev->props.brightness;
419*4882a593Smuzhiyun 	unsigned char data[] = { 0xf4, 0x8b,
420*4882a593Smuzhiyun 			vint_table[brightness * (S6E3HA2_VINT_STATUS_MAX - 1) /
421*4882a593Smuzhiyun 			S6E3HA2_MAX_BRIGHTNESS] };
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	return s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data));
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun 
s6e3ha2_get_brightness_index(unsigned int brightness)426*4882a593Smuzhiyun static unsigned int s6e3ha2_get_brightness_index(unsigned int brightness)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun 	return (brightness * (S6E3HA2_NUM_GAMMA_STEPS - 1)) /
429*4882a593Smuzhiyun 		S6E3HA2_MAX_BRIGHTNESS;
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun 
s6e3ha2_update_gamma(struct s6e3ha2 * ctx,unsigned int brightness)432*4882a593Smuzhiyun static int s6e3ha2_update_gamma(struct s6e3ha2 *ctx, unsigned int brightness)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun 	struct backlight_device *bl_dev = ctx->bl_dev;
435*4882a593Smuzhiyun 	unsigned int index = s6e3ha2_get_brightness_index(brightness);
436*4882a593Smuzhiyun 	u8 data[S6E3HA2_GAMMA_CMD_CNT + 1] = { 0xca, };
437*4882a593Smuzhiyun 	int ret;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	memcpy(data + 1, gamma_tbl + index, S6E3HA2_GAMMA_CMD_CNT);
440*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret,
441*4882a593Smuzhiyun 				s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data)));
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_gamma_update(ctx));
444*4882a593Smuzhiyun 	bl_dev->props.brightness = brightness;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	return 0;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun 
s6e3ha2_set_brightness(struct backlight_device * bl_dev)449*4882a593Smuzhiyun static int s6e3ha2_set_brightness(struct backlight_device *bl_dev)
450*4882a593Smuzhiyun {
451*4882a593Smuzhiyun 	struct s6e3ha2 *ctx = bl_get_data(bl_dev);
452*4882a593Smuzhiyun 	unsigned int brightness = bl_dev->props.brightness;
453*4882a593Smuzhiyun 	int ret;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	if (brightness < S6E3HA2_MIN_BRIGHTNESS ||
456*4882a593Smuzhiyun 		brightness > bl_dev->props.max_brightness) {
457*4882a593Smuzhiyun 		dev_err(ctx->dev, "Invalid brightness: %u\n", brightness);
458*4882a593Smuzhiyun 		return -EINVAL;
459*4882a593Smuzhiyun 	}
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	if (bl_dev->props.power > FB_BLANK_NORMAL)
462*4882a593Smuzhiyun 		return -EPERM;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
465*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_update_gamma(ctx, brightness));
466*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_aor_control(ctx));
467*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_set_vint(ctx));
468*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	return 0;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun static const struct backlight_ops s6e3ha2_bl_ops = {
474*4882a593Smuzhiyun 	.get_brightness = s6e3ha2_get_brightness,
475*4882a593Smuzhiyun 	.update_status = s6e3ha2_set_brightness,
476*4882a593Smuzhiyun };
477*4882a593Smuzhiyun 
s6e3ha2_panel_init(struct s6e3ha2 * ctx)478*4882a593Smuzhiyun static int s6e3ha2_panel_init(struct s6e3ha2 *ctx)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
481*4882a593Smuzhiyun 	int ret;
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, mipi_dsi_dcs_exit_sleep_mode(dsi));
484*4882a593Smuzhiyun 	usleep_range(5000, 6000);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
487*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_single_dsi_set(ctx));
488*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_fc(ctx));
489*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_freq_calibration(ctx));
490*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_fc(ctx));
491*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	return 0;
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun 
s6e3ha2_power_off(struct s6e3ha2 * ctx)496*4882a593Smuzhiyun static int s6e3ha2_power_off(struct s6e3ha2 *ctx)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun 
s6e3ha2_disable(struct drm_panel * panel)501*4882a593Smuzhiyun static int s6e3ha2_disable(struct drm_panel *panel)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun 	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
504*4882a593Smuzhiyun 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
505*4882a593Smuzhiyun 	int ret;
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, mipi_dsi_dcs_enter_sleep_mode(dsi));
508*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, mipi_dsi_dcs_set_display_off(dsi));
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	msleep(40);
511*4882a593Smuzhiyun 	ctx->bl_dev->props.power = FB_BLANK_NORMAL;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	return 0;
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun 
s6e3ha2_unprepare(struct drm_panel * panel)516*4882a593Smuzhiyun static int s6e3ha2_unprepare(struct drm_panel *panel)
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun 	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	return s6e3ha2_power_off(ctx);
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun 
s6e3ha2_power_on(struct s6e3ha2 * ctx)523*4882a593Smuzhiyun static int s6e3ha2_power_on(struct s6e3ha2 *ctx)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun 	int ret;
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
528*4882a593Smuzhiyun 	if (ret < 0)
529*4882a593Smuzhiyun 		return ret;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	msleep(120);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 	gpiod_set_value(ctx->enable_gpio, 0);
534*4882a593Smuzhiyun 	usleep_range(5000, 6000);
535*4882a593Smuzhiyun 	gpiod_set_value(ctx->enable_gpio, 1);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	gpiod_set_value(ctx->reset_gpio, 1);
538*4882a593Smuzhiyun 	usleep_range(5000, 6000);
539*4882a593Smuzhiyun 	gpiod_set_value(ctx->reset_gpio, 0);
540*4882a593Smuzhiyun 	usleep_range(5000, 6000);
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	return 0;
543*4882a593Smuzhiyun }
s6e3ha2_prepare(struct drm_panel * panel)544*4882a593Smuzhiyun static int s6e3ha2_prepare(struct drm_panel *panel)
545*4882a593Smuzhiyun {
546*4882a593Smuzhiyun 	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
547*4882a593Smuzhiyun 	int ret;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	ret = s6e3ha2_power_on(ctx);
550*4882a593Smuzhiyun 	if (ret < 0)
551*4882a593Smuzhiyun 		return ret;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	ret = s6e3ha2_panel_init(ctx);
554*4882a593Smuzhiyun 	if (ret < 0)
555*4882a593Smuzhiyun 		goto err;
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 	ctx->bl_dev->props.power = FB_BLANK_NORMAL;
558*4882a593Smuzhiyun 
559*4882a593Smuzhiyun 	return 0;
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun err:
562*4882a593Smuzhiyun 	s6e3ha2_power_off(ctx);
563*4882a593Smuzhiyun 	return ret;
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun 
s6e3ha2_enable(struct drm_panel * panel)566*4882a593Smuzhiyun static int s6e3ha2_enable(struct drm_panel *panel)
567*4882a593Smuzhiyun {
568*4882a593Smuzhiyun 	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
569*4882a593Smuzhiyun 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
570*4882a593Smuzhiyun 	int ret;
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	/* common setting */
573*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret,
574*4882a593Smuzhiyun 		mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK));
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_f0(ctx));
577*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_on_fc(ctx));
578*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_touch_hsync_on1(ctx));
579*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_pentile_control(ctx));
580*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_poc_global(ctx));
581*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_poc_setting(ctx));
582*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_fc(ctx));
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	/* pcd setting off for TB */
585*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_pcd_set_off(ctx));
586*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_err_fg_set(ctx));
587*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_te_start_setting(ctx));
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	/* brightness setting */
590*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_set_brightness(ctx->bl_dev));
591*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_aor_control(ctx));
592*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_caps_elvss_set(ctx));
593*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_gamma_update(ctx));
594*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_acl_off(ctx));
595*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_acl_off_opr(ctx));
596*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_hbm_off(ctx));
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	/* elvss temp compensation */
599*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_global(ctx));
600*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test(ctx));
601*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, s6e3ha2_test_key_off_f0(ctx));
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	s6e3ha2_call_write_func(ret, mipi_dsi_dcs_set_display_on(dsi));
604*4882a593Smuzhiyun 	ctx->bl_dev->props.power = FB_BLANK_UNBLANK;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	return 0;
607*4882a593Smuzhiyun }
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun static const struct drm_display_mode s6e3ha2_mode = {
610*4882a593Smuzhiyun 	.clock = 222372,
611*4882a593Smuzhiyun 	.hdisplay = 1440,
612*4882a593Smuzhiyun 	.hsync_start = 1440 + 1,
613*4882a593Smuzhiyun 	.hsync_end = 1440 + 1 + 1,
614*4882a593Smuzhiyun 	.htotal = 1440 + 1 + 1 + 1,
615*4882a593Smuzhiyun 	.vdisplay = 2560,
616*4882a593Smuzhiyun 	.vsync_start = 2560 + 1,
617*4882a593Smuzhiyun 	.vsync_end = 2560 + 1 + 1,
618*4882a593Smuzhiyun 	.vtotal = 2560 + 1 + 1 + 15,
619*4882a593Smuzhiyun 	.flags = 0,
620*4882a593Smuzhiyun };
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun static const struct s6e3ha2_panel_desc samsung_s6e3ha2 = {
623*4882a593Smuzhiyun 	.mode = &s6e3ha2_mode,
624*4882a593Smuzhiyun 	.type = HA2_TYPE,
625*4882a593Smuzhiyun };
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun static const struct drm_display_mode s6e3hf2_mode = {
628*4882a593Smuzhiyun 	.clock = 247856,
629*4882a593Smuzhiyun 	.hdisplay = 1600,
630*4882a593Smuzhiyun 	.hsync_start = 1600 + 1,
631*4882a593Smuzhiyun 	.hsync_end = 1600 + 1 + 1,
632*4882a593Smuzhiyun 	.htotal = 1600 + 1 + 1 + 1,
633*4882a593Smuzhiyun 	.vdisplay = 2560,
634*4882a593Smuzhiyun 	.vsync_start = 2560 + 1,
635*4882a593Smuzhiyun 	.vsync_end = 2560 + 1 + 1,
636*4882a593Smuzhiyun 	.vtotal = 2560 + 1 + 1 + 15,
637*4882a593Smuzhiyun 	.flags = 0,
638*4882a593Smuzhiyun };
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun static const struct s6e3ha2_panel_desc samsung_s6e3hf2 = {
641*4882a593Smuzhiyun 	.mode = &s6e3hf2_mode,
642*4882a593Smuzhiyun 	.type = HF2_TYPE,
643*4882a593Smuzhiyun };
644*4882a593Smuzhiyun 
s6e3ha2_get_modes(struct drm_panel * panel,struct drm_connector * connector)645*4882a593Smuzhiyun static int s6e3ha2_get_modes(struct drm_panel *panel,
646*4882a593Smuzhiyun 			     struct drm_connector *connector)
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun 	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
649*4882a593Smuzhiyun 	struct drm_display_mode *mode;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);
652*4882a593Smuzhiyun 	if (!mode) {
653*4882a593Smuzhiyun 		dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
654*4882a593Smuzhiyun 			ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
655*4882a593Smuzhiyun 			drm_mode_vrefresh(ctx->desc->mode));
656*4882a593Smuzhiyun 		return -ENOMEM;
657*4882a593Smuzhiyun 	}
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 	drm_mode_set_name(mode);
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
662*4882a593Smuzhiyun 	drm_mode_probed_add(connector, mode);
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 	connector->display_info.width_mm = 71;
665*4882a593Smuzhiyun 	connector->display_info.height_mm = 125;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	return 1;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun static const struct drm_panel_funcs s6e3ha2_drm_funcs = {
671*4882a593Smuzhiyun 	.disable = s6e3ha2_disable,
672*4882a593Smuzhiyun 	.unprepare = s6e3ha2_unprepare,
673*4882a593Smuzhiyun 	.prepare = s6e3ha2_prepare,
674*4882a593Smuzhiyun 	.enable = s6e3ha2_enable,
675*4882a593Smuzhiyun 	.get_modes = s6e3ha2_get_modes,
676*4882a593Smuzhiyun };
677*4882a593Smuzhiyun 
s6e3ha2_probe(struct mipi_dsi_device * dsi)678*4882a593Smuzhiyun static int s6e3ha2_probe(struct mipi_dsi_device *dsi)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun 	struct device *dev = &dsi->dev;
681*4882a593Smuzhiyun 	struct s6e3ha2 *ctx;
682*4882a593Smuzhiyun 	int ret;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
685*4882a593Smuzhiyun 	if (!ctx)
686*4882a593Smuzhiyun 		return -ENOMEM;
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	mipi_dsi_set_drvdata(dsi, ctx);
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	ctx->dev = dev;
691*4882a593Smuzhiyun 	ctx->desc = of_device_get_match_data(dev);
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	dsi->lanes = 4;
694*4882a593Smuzhiyun 	dsi->format = MIPI_DSI_FMT_RGB888;
695*4882a593Smuzhiyun 	dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	ctx->supplies[0].supply = "vdd3";
698*4882a593Smuzhiyun 	ctx->supplies[1].supply = "vci";
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
701*4882a593Smuzhiyun 				      ctx->supplies);
702*4882a593Smuzhiyun 	if (ret < 0) {
703*4882a593Smuzhiyun 		dev_err(dev, "failed to get regulators: %d\n", ret);
704*4882a593Smuzhiyun 		return ret;
705*4882a593Smuzhiyun 	}
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
708*4882a593Smuzhiyun 	if (IS_ERR(ctx->reset_gpio)) {
709*4882a593Smuzhiyun 		dev_err(dev, "cannot get reset-gpios %ld\n",
710*4882a593Smuzhiyun 			PTR_ERR(ctx->reset_gpio));
711*4882a593Smuzhiyun 		return PTR_ERR(ctx->reset_gpio);
712*4882a593Smuzhiyun 	}
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	ctx->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
715*4882a593Smuzhiyun 	if (IS_ERR(ctx->enable_gpio)) {
716*4882a593Smuzhiyun 		dev_err(dev, "cannot get enable-gpios %ld\n",
717*4882a593Smuzhiyun 			PTR_ERR(ctx->enable_gpio));
718*4882a593Smuzhiyun 		return PTR_ERR(ctx->enable_gpio);
719*4882a593Smuzhiyun 	}
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	ctx->bl_dev = backlight_device_register("s6e3ha2", dev, ctx,
722*4882a593Smuzhiyun 						&s6e3ha2_bl_ops, NULL);
723*4882a593Smuzhiyun 	if (IS_ERR(ctx->bl_dev)) {
724*4882a593Smuzhiyun 		dev_err(dev, "failed to register backlight device\n");
725*4882a593Smuzhiyun 		return PTR_ERR(ctx->bl_dev);
726*4882a593Smuzhiyun 	}
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	ctx->bl_dev->props.max_brightness = S6E3HA2_MAX_BRIGHTNESS;
729*4882a593Smuzhiyun 	ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS;
730*4882a593Smuzhiyun 	ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 	drm_panel_init(&ctx->panel, dev, &s6e3ha2_drm_funcs,
733*4882a593Smuzhiyun 		       DRM_MODE_CONNECTOR_DSI);
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun 	drm_panel_add(&ctx->panel);
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	ret = mipi_dsi_attach(dsi);
738*4882a593Smuzhiyun 	if (ret < 0)
739*4882a593Smuzhiyun 		goto remove_panel;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 	return ret;
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun remove_panel:
744*4882a593Smuzhiyun 	drm_panel_remove(&ctx->panel);
745*4882a593Smuzhiyun 	backlight_device_unregister(ctx->bl_dev);
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 	return ret;
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun 
s6e3ha2_remove(struct mipi_dsi_device * dsi)750*4882a593Smuzhiyun static int s6e3ha2_remove(struct mipi_dsi_device *dsi)
751*4882a593Smuzhiyun {
752*4882a593Smuzhiyun 	struct s6e3ha2 *ctx = mipi_dsi_get_drvdata(dsi);
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	mipi_dsi_detach(dsi);
755*4882a593Smuzhiyun 	drm_panel_remove(&ctx->panel);
756*4882a593Smuzhiyun 	backlight_device_unregister(ctx->bl_dev);
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun 	return 0;
759*4882a593Smuzhiyun }
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun static const struct of_device_id s6e3ha2_of_match[] = {
762*4882a593Smuzhiyun 	{ .compatible = "samsung,s6e3ha2", .data = &samsung_s6e3ha2 },
763*4882a593Smuzhiyun 	{ .compatible = "samsung,s6e3hf2", .data = &samsung_s6e3hf2 },
764*4882a593Smuzhiyun 	{ }
765*4882a593Smuzhiyun };
766*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, s6e3ha2_of_match);
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun static struct mipi_dsi_driver s6e3ha2_driver = {
769*4882a593Smuzhiyun 	.probe = s6e3ha2_probe,
770*4882a593Smuzhiyun 	.remove = s6e3ha2_remove,
771*4882a593Smuzhiyun 	.driver = {
772*4882a593Smuzhiyun 		.name = "panel-samsung-s6e3ha2",
773*4882a593Smuzhiyun 		.of_match_table = s6e3ha2_of_match,
774*4882a593Smuzhiyun 	},
775*4882a593Smuzhiyun };
776*4882a593Smuzhiyun module_mipi_dsi_driver(s6e3ha2_driver);
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
779*4882a593Smuzhiyun MODULE_AUTHOR("Hyungwon Hwang <human.hwang@samsung.com>");
780*4882a593Smuzhiyun MODULE_AUTHOR("Hoegeun Kwon <hoegeun.kwon@samsung.com>");
781*4882a593Smuzhiyun MODULE_DESCRIPTION("MIPI-DSI based s6e3ha2 AMOLED Panel Driver");
782*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
783