update code - sleep mode, keyeventnode, eglib
[apps/home/charging-animation.git] / src / chg_drmd.c
1 /*
2 Copyright 2012  Samsung Electronics Co., Ltd
3
4 Licensed under the Flora License, Version 1.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8     http://www.tizenopensource.org/license
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 #define _GNU_SOURCE
18 #define __USE_GNU
19 #include <string.h>
20 #include <unistd.h>
21 #include "chg_common.h"
22 #include "chg_drmd.h"
23 #include "chg_env.h"
24
25 /*-----------------------------------------------------------------------------
26   find_connector()
27  ----------------------------------------------------------------------------*/
28 static int find_connector(st_drmdi *drmdi, int type)
29 {
30         int i;
31         int fd;
32         drmModeConnectorPtr connector=NULL;
33         drmModeEncoderPtr encoder=NULL;
34         drmModeCrtcPtr crtc;
35         drmModeResPtr res_mode;
36
37         if (drmdi == NULL)
38                 return -1;
39
40         fd = drmdi->fd;
41         res_mode = drmdi->res_mode;
42
43         for(i=0; i<res_mode->count_connectors; i++) {
44                 connector =drmModeGetConnector(fd, res_mode->connectors[i]);
45                 if(connector->connector_type == type)
46                         break;
47
48                 drmModeFreeConnector(connector);
49                 connector = NULL;
50         }
51
52         if(!connector) {
53                 LOGD("[find_connector] Cannot find connector:%d\n", type);
54                 return -1;
55         }
56
57         if(connector->connection != DRM_MODE_CONNECTED) {
58                 LOGD("[find_connector] connector is not connected (%d)\n",
59                         (int)connector->connection);
60                 return -1;
61         }
62
63         /* find default encoder */
64         encoder = drmModeGetEncoder(fd, connector->encoder_id);
65         if(!encoder) {
66                 LOGD("[find_connector] Cannot get encoder:%d\n", type);
67                 return -1;
68         }
69
70         /* find default crtc */
71         crtc = drmModeGetCrtc(fd, encoder->crtc_id);
72         if(!crtc) {
73                 LOGD("[find_connector] Cannot get CRTC\n");
74                 return -1;
75         }
76
77         drmdi->connector = connector;
78         drmdi->encoder = encoder;
79         drmdi->crtc = crtc;
80
81         return 0;
82 }
83
84 /*-----------------------------------------------------------------------------
85   create_framebuffer()
86  ----------------------------------------------------------------------------*/
87 static int create_framebuffer(st_drmdi *drmdi)
88 {
89         unsigned int attrs[]={
90                 KMS_WIDTH,   0,
91                 KMS_HEIGHT,  0,
92                 KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8,
93                 KMS_TERMINATE_PROP_LIST
94         };
95
96         /* Create kms bo */
97         attrs[1] = drmdi->connector->modes[0].hdisplay;
98         attrs[3] = drmdi->connector->modes[0].vdisplay;
99
100         if(kms_bo_create(drmdi->kms, attrs, &drmdi->bo)) {
101                 LOGD("[create_framebuffer] Cannot create kms bo\n");
102                 return -1;
103         }
104
105         drmdi->bo_width = drmdi->connector->modes[0].hdisplay;
106         drmdi->bo_height = drmdi->connector->modes[0].vdisplay;
107         kms_bo_get_prop(drmdi->bo, KMS_PITCH, &drmdi->bo_stride);
108         kms_bo_get_prop(drmdi->bo, KMS_HANDLE, &drmdi->bo_handle);
109
110         /* add drm framebuffer */
111         if(drmModeAddFB(drmdi->fd, drmdi->bo_width, drmdi->bo_height,
112                 24, 32, drmdi->bo_stride, drmdi->bo_handle, &drmdi->fb_id)) {
113                 LOGD("[create_framebuffer] Cannot add drm fb\n");
114                 return -1;
115         }
116
117         return 0;
118 }
119
120 /*-----------------------------------------------------------------------------
121   set_mode()
122  ----------------------------------------------------------------------------*/
123 static int set_drm_mode(st_drmdi *drmdi)
124 {
125         if(drmModeSetCrtc(drmdi->fd
126                         , drmdi->crtc->crtc_id
127                         , drmdi->fb_id
128                         , 0, 0
129                         , &drmdi->connector->connector_id, 1
130                         , drmdi->connector->modes)) {
131                 LOGD("[set_drm_mode] Cannot set drm mode\n");
132                 return -1;
133         }
134
135         return 0;
136 }
137
138 /*-----------------------------------------------------------------------------
139   init_drm()
140  ----------------------------------------------------------------------------*/
141 static void free_drm_res(st_drmdi *drmdi)
142 {
143         if(drmdi->connector)
144                 drmModeFreeConnector(drmdi->connector);
145
146         if(drmdi->encoder)
147                 drmModeFreeEncoder(drmdi->encoder);
148
149         if(drmdi->crtc)
150                 drmModeFreeCrtc(drmdi->crtc);
151
152         if(drmdi->res_mode)
153                 drmModeFreeResources(drmdi->res_mode);
154
155         if(drmdi->fb_id)
156                 drmModeRmFB(drmdi->fd, drmdi->fb_id);
157
158         if(drmdi->bo)
159                 kms_bo_destroy(&drmdi->bo);
160
161         if(drmdi->kms)
162                 kms_destroy(&drmdi->kms);
163
164         drmClose(drmdi->fd);
165 }
166
167 /*-----------------------------------------------------------------------------
168   drmd_open()
169  ----------------------------------------------------------------------------*/
170 int drmd_open(st_drmdi *drmdi)
171 {
172         drm_magic_t magic;
173         drmVBlank vbl;
174         void *ptr;
175         int ret;
176
177         if (drmdi == NULL) {
178                 LOGD("[drmd_open] drmdi is NULL\n");
179                 return -1;
180         }
181
182         memset(drmdi, 0x00, sizeof(st_drmdi));
183
184         drmdi->fd = drmOpen(chg_env_str[EN_ENV_DEV_DRM_NAME], NULL);
185         if(drmdi->fd<0) {
186                 LOGD("[drmd_open] Cannot open drm:%s\n",
187                         chg_env_str[EN_ENV_DEV_DRM_NAME]);
188                 return -1;
189         }
190
191         drmdi->driver_name = drmGetDeviceNameFromFd(drmdi->fd);
192         LOGD("[drmd_open] Init DRM(name:%s, fd:%d)...OK\n",
193                 drmdi->driver_name, drmdi->fd);
194
195         /* Auth DRM */
196         if(drmGetMagic(drmdi->fd, &magic)) {
197                 LOGD("[drmd_open] Cannot get magic\n");
198                 goto drm_err_exit;
199         }
200
201         if(drmAuthMagic(drmdi->fd, magic)) {
202                 LOGD("[drmd_open] Cannot auth magic\n");
203                 goto drm_err_exit;
204         }
205
206         /* Create KMS */
207         if(kms_create(drmdi->fd, &drmdi->kms)) {
208                 LOGD("[drmd_open] Cannot create kms\n");
209                 goto drm_err_exit;
210         }
211
212         /* Get drmmode resource */
213         drmdi->res_mode = drmModeGetResources(drmdi->fd);
214         if(!drmdi->res_mode) {
215                 LOGD("[drmd_open] Cannot get drmmode resources\n");
216                 goto drm_err_exit;
217         }
218
219         ret = find_connector(drmdi, DRM_MODE_CONNECTOR_LVDS);
220         if(ret < 0) {
221                 LOGD("[drmd_open] Cannot get default(LVDS) connector\n");
222                 goto drm_err_exit;
223         }
224
225         /* Create framebuffer */
226         ret = create_framebuffer(drmdi);
227         if(ret < 0) {
228                 LOGD("[drmd_open] Cannot create frame buffer\n");
229                 goto drm_err_exit;
230         }
231
232         if (kms_bo_map(drmdi->bo, &ptr)) {
233                 LOGD("[drmd_open] kms_bo_map() failed. \n");
234                 goto drm_err_exit;
235         }
236         drmdi->fb_buf = ptr;
237         drmdi->dpms_mode = DPMSModeOn;
238         memset(ptr, 0x00, drmdi->bo_stride * drmdi->bo_height);
239
240         /* Set mode */
241         ret = set_drm_mode(drmdi);
242         if(ret < 0) {
243                 LOGD("[drmd_open] Cannot set drm mode\n");
244                 goto drm_err_exit;
245         }
246
247         return 0;
248
249 drm_err_exit:
250         free_drm_res(drmdi);
251         return -1;
252 }
253
254 /*-----------------------------------------------------------------------------
255   drmd_close()
256  ----------------------------------------------------------------------------*/
257 void drmd_close(st_drmdi *drmdi)
258 {
259         kms_bo_unmap(drmdi->bo);
260         free_drm_res(drmdi);
261 }
262
263 /*-----------------------------------------------------------------------------
264   drmd_set_dpms_mode()
265  ----------------------------------------------------------------------------*/
266 static int drmd_set_dpms_mode(st_drmdi *drmdi, int dpms_mode)
267 {
268         int i;
269         drmModeConnectorPtr connector;
270
271         if (drmdi == NULL) {
272                 LOGD("[drmd_set_dpms_mode] drmdi is NULL\n");
273                 return -1;
274         }
275
276         connector = drmdi->connector;
277
278         if (dpms_mode == DPMSModeStandby || dpms_mode == DPMSModeSuspend) {
279                 LOGD("[drmd_set_dpms_mode] dmps_mode %s is not supported.\n",
280                         (dpms_mode == DPMSModeStandby)?
281                         "DPMSModeStandby":"DPMSModeSuspend");
282                 return -1;
283         }
284
285         for (i = 0; i < connector->count_props; i++) {
286                 drmModePropertyPtr props;
287                 props = drmModeGetProperty (drmdi->fd, connector->props[i]);
288                 if (!props)
289                         continue;
290
291                 if (!strcmp(props->name, "DPMS")) {
292                         int _tmp_dpms = dpms_mode;
293                         switch (dpms_mode) {
294                         case DPMSModeOn:
295                                 if (drmdi->dpms_mode == DPMSModeOn) {
296                                         drmModeFreeProperty (props);
297                                         return 0;
298                                 }
299
300                                 /* lcd on */
301                                 _tmp_dpms = DPMSModeOn;
302                                 drmdi->dpms_mode = DPMSModeOn;
303                                 break;
304
305                         case DPMSModeOff:
306                                 if (drmdi->dpms_mode == DPMSModeOff) {
307                                         drmModeFreeProperty(props);
308                                         return 0;
309                                 }
310
311                                 /* lcd off */
312                                 _tmp_dpms = DPMSModeOff;
313                                 drmdi->dpms_mode = DPMSModeOff;
314                                 break;
315                         default:
316                                 return -1;
317                         }
318
319                         drmModeConnectorSetProperty(drmdi->fd,
320                                 connector->connector_id,
321                                 props->prop_id,
322                                 _tmp_dpms);
323
324                         drmModeFreeProperty(props);
325                         return 0;
326                 }
327
328                 drmModeFreeProperty(props);
329         }
330
331         return -1;
332 }
333
334 /*-----------------------------------------------------------------------------
335   drmd_lcd_on()
336  ----------------------------------------------------------------------------*/
337 int drmd_lcd_on(st_drmdi *drmdi)
338 {
339         int ret;
340
341         ret = drmd_set_dpms_mode(drmdi, DPMSModeOn);
342         if (ret < 0) {
343                 LOGD("[drmd_lcd_on] drmd_set_dpms_mode() fail.\n");
344                 return -1;
345         }
346
347         return 0;
348 }
349
350 /*-----------------------------------------------------------------------------
351   drmd_lcd_off()
352  ----------------------------------------------------------------------------*/
353 int drmd_lcd_off(st_drmdi *drmdi)
354 {
355         int ret;
356
357         ret = drmd_set_dpms_mode(drmdi, DPMSModeOff);
358         if (ret < 0) {
359                 LOGD("[drmd_lcd_off] drmd_set_dpms_mode() fail.\n");
360                 return -1;
361         }
362
363         return 0;
364 }
365