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