Home | History | Annotate | Download | only in libgscaler
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * Copyright@ Samsung Electronics Co. LTD
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 /*!
     19  * \file      exynos_gscaler.c
     20  * \brief     header file for Gscaler HAL
     21  * \author    ShinWon Lee (shinwon.lee (at) samsung.com)
     22  * \date      2012/01/09
     23  *
     24  * <b>Revision History: </b>
     25  * - 2012.01.09 : ShinWon Lee(shinwon.lee (at) samsung.com) \n
     26  *   Create
     27  *
     28  * - 2012.02.07 : ShinWon Lee(shinwon.lee (at) samsung.com) \n
     29  *   Change file name to exynos_gscaler.h
     30  *
     31  * - 2012.02.09 : Sangwoo, Parkk(sw5771.park (at) samsung.com) \n
     32  *   Use Multiple Gscaler by Multiple Process
     33  *
     34  * - 2012.02.20 : Sangwoo, Park(sw5771.park (at) samsung.com) \n
     35  *   Add exynos_gsc_set_rotation() API
     36  *
     37  * - 2012.02.20 : ShinWon Lee(shinwon.lee (at) samsung.com) \n
     38  *   Add size constrain
     39  *
     40  */
     41 
     42 //#define LOG_NDEBUG 0
     43 #include "exynos_gsc_utils.h"
     44 #include "content_protect.h"
     45 
     46 static int exynos_gsc_m2m_wait_frame_done(void *handle);
     47 static int exynos_gsc_m2m_stop(void *handle);
     48 
     49 static unsigned int m_gsc_get_plane_count(
     50     int v4l_pixel_format)
     51 {
     52     int plane_count = 0;
     53 
     54     switch (v4l_pixel_format) {
     55     case V4L2_PIX_FMT_RGB32:
     56     case V4L2_PIX_FMT_BGR32:
     57     case V4L2_PIX_FMT_RGB24:
     58     case V4L2_PIX_FMT_RGB565:
     59     case V4L2_PIX_FMT_RGB555X:
     60     case V4L2_PIX_FMT_RGB444:
     61     case V4L2_PIX_FMT_YUYV:
     62     case V4L2_PIX_FMT_UYVY:
     63     case V4L2_PIX_FMT_NV16:
     64     case V4L2_PIX_FMT_NV61:
     65         plane_count = 1;
     66         break;
     67     case V4L2_PIX_FMT_NV12M:
     68     case V4L2_PIX_FMT_NV12MT_16X16:
     69     case V4L2_PIX_FMT_NV12:
     70     case V4L2_PIX_FMT_NV21:
     71     case V4L2_PIX_FMT_NV21M:
     72         plane_count = 2;
     73         break;
     74     case V4L2_PIX_FMT_YVU420M:
     75     case V4L2_PIX_FMT_YUV422P:
     76     case V4L2_PIX_FMT_YUV420M:
     77         plane_count = 3;
     78         break;
     79     default:
     80         ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
     81              __func__, v4l_pixel_format);
     82         plane_count = -1;
     83         break;
     84     }
     85 
     86     return plane_count;
     87 }
     88 
     89 static unsigned int m_gsc_get_plane_size(
     90     unsigned int *plane_size,
     91     unsigned int  width,
     92     unsigned int  height,
     93     int           v4l_pixel_format)
     94 {
     95     switch (v4l_pixel_format) {
     96     /* 1 plane */
     97     case V4L2_PIX_FMT_RGB32:
     98     case V4L2_PIX_FMT_BGR32:
     99         plane_size[0] = width * height * 4;
    100         plane_size[1] = 0;
    101         plane_size[2] = 0;
    102         break;
    103     case V4L2_PIX_FMT_RGB24:
    104         plane_size[0] = width * height * 3;
    105         plane_size[1] = 0;
    106         plane_size[2] = 0;
    107         break;
    108     case V4L2_PIX_FMT_RGB565:
    109     case V4L2_PIX_FMT_RGB555X:
    110     case V4L2_PIX_FMT_RGB444:
    111     case V4L2_PIX_FMT_YUYV:
    112     case V4L2_PIX_FMT_UYVY:
    113         plane_size[0] = width * height * 2;
    114         plane_size[1] = 0;
    115         plane_size[2] = 0;
    116         break;
    117     /* 2 planes */
    118     case V4L2_PIX_FMT_NV12M:
    119     case V4L2_PIX_FMT_NV12:
    120     case V4L2_PIX_FMT_NV21:
    121     case V4L2_PIX_FMT_NV21M:
    122         plane_size[0] = width * height;
    123         plane_size[1] = width * (height / 2);
    124         plane_size[2] = 0;
    125         break;
    126     case V4L2_PIX_FMT_NV16:
    127     case V4L2_PIX_FMT_NV61:
    128         plane_size[0] = width * height * 2;
    129         plane_size[1] = 0;
    130         plane_size[2] = 0;
    131         break;
    132     case V4L2_PIX_FMT_NV12MT_16X16:
    133         plane_size[0] = ALIGN(width, 16) * ALIGN(height, 16);
    134         plane_size[1] = ALIGN(width, 16) * ALIGN(height / 2, 8);
    135         plane_size[2] = 0;
    136         break;
    137     /* 3 planes */
    138     case V4L2_PIX_FMT_YVU420M:
    139     case V4L2_PIX_FMT_YUV422P:
    140         plane_size[0] = width * height;
    141         plane_size[1] = (width / 2) * (height / 2);
    142         plane_size[2] = (width / 2) * (height / 2);
    143         break;
    144     default:
    145         ALOGE("%s::unmatched v4l_pixel_format color_space(0x%x)\n",
    146              __func__, v4l_pixel_format);
    147         return -1;
    148         break;
    149     }
    150 
    151     return 0;
    152 }
    153 
    154 static int m_exynos_gsc_multiple_of_n(
    155     int number, int N)
    156 {
    157     int result = number;
    158     switch (N) {
    159     case 1:
    160     case 2:
    161     case 4:
    162     case 8:
    163     case 16:
    164     case 32:
    165     case 64:
    166     case 128:
    167     case 256:
    168         result = (number - (number & (N-1)));
    169         break;
    170     default:
    171         result = number - (number % N);
    172         break;
    173     }
    174     return result;
    175 }
    176 
    177 static bool m_exynos_gsc_check_src_size(
    178     unsigned int *w,      unsigned int *h,
    179     unsigned int *crop_x, unsigned int *crop_y,
    180     unsigned int *crop_w, unsigned int *crop_h,
    181     int v4l2_colorformat)
    182 {
    183     if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) {
    184         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
    185             __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h);
    186         return false;
    187     }
    188 
    189     if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) {
    190         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
    191             __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h);
    192         return false;
    193     }
    194 
    195     switch (v4l2_colorformat) {
    196     // YUV420
    197     case V4L2_PIX_FMT_YUV420M:
    198     case V4L2_PIX_FMT_YVU420M:
    199     case V4L2_PIX_FMT_NV12M:
    200     case V4L2_PIX_FMT_NV12MT:
    201     case V4L2_PIX_FMT_NV21:
    202     case V4L2_PIX_FMT_NV21M:
    203         *w = (*w + 15) & ~15;
    204         *h = (*h + 15) & ~15;
    205         //*w      = m_exynos_gsc_multiple_of_n(*w, 16);
    206         //*h      = m_exynos_gsc_multiple_of_n(*h, 16);
    207         *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4);
    208         *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 4);
    209         break;
    210     // YUV422
    211     case V4L2_PIX_FMT_YUYV:
    212     case V4L2_PIX_FMT_YUV422P:
    213     case V4L2_PIX_FMT_UYVY:
    214     case V4L2_PIX_FMT_NV16:
    215     case V4L2_PIX_FMT_YVYU:
    216     case V4L2_PIX_FMT_VYUY:
    217         *h = (*h + 7) & ~7;
    218         //*h      = m_exynos_gsc_multiple_of_n(*h, 8);
    219         *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 4);
    220         *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2);
    221         break;
    222     // RGB
    223     case V4L2_PIX_FMT_RGB32:
    224     case V4L2_PIX_FMT_RGB24:
    225     case V4L2_PIX_FMT_RGB565:
    226     case V4L2_PIX_FMT_BGR32:
    227     case V4L2_PIX_FMT_RGB555X:
    228     case V4L2_PIX_FMT_RGB444:
    229     default:
    230         *h = (*h + 7) & ~7;
    231         //*h      = m_exynos_gsc_multiple_of_n(*h, 8);
    232         *crop_w = m_exynos_gsc_multiple_of_n(*crop_w, 2);
    233         *crop_h = m_exynos_gsc_multiple_of_n(*crop_h, 2);
    234         break;
    235     }
    236 
    237     return true;
    238 }
    239 
    240 static bool m_exynos_gsc_check_dst_size(
    241     unsigned int *w,      unsigned int *h,
    242     unsigned int *crop_x, unsigned int *crop_y,
    243     unsigned int *crop_w, unsigned int *crop_h,
    244     int v4l2_colorformat,
    245     int rotation)
    246 {
    247     unsigned int *new_w;
    248     unsigned int *new_h;
    249     unsigned int *new_crop_w;
    250     unsigned int *new_crop_h;
    251 
    252         new_w = w;
    253         new_h = h;
    254         new_crop_w = crop_w;
    255         new_crop_h = crop_h;
    256 
    257     if (*w < GSC_MIN_W_SIZE || *h < GSC_MIN_H_SIZE) {
    258         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
    259             __func__, GSC_MIN_W_SIZE, *w, GSC_MIN_H_SIZE, *h);
    260         return false;
    261     }
    262 
    263     if (*crop_w < GSC_MIN_W_SIZE || *crop_h < GSC_MIN_H_SIZE) {
    264         ALOGE("%s::too small size (w : %d < %d) (h : %d < %d)",
    265             __func__, GSC_MIN_W_SIZE,* crop_w, GSC_MIN_H_SIZE, *crop_h);
    266         return false;
    267     }
    268 
    269     switch (v4l2_colorformat) {
    270     // YUV420
    271     case V4L2_PIX_FMT_NV12M:
    272     case V4L2_PIX_FMT_NV12MT:
    273     case V4L2_PIX_FMT_NV21:
    274     case V4L2_PIX_FMT_NV21M:
    275     case V4L2_PIX_FMT_YUV420M:
    276     case V4L2_PIX_FMT_YVU420M:
    277         *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2);
    278         *new_h = m_exynos_gsc_multiple_of_n(*new_h, 2);
    279         break;
    280     // YUV422
    281     case V4L2_PIX_FMT_YUYV:
    282     case V4L2_PIX_FMT_YUV422P:
    283     case V4L2_PIX_FMT_UYVY:
    284     case V4L2_PIX_FMT_NV16:
    285     case V4L2_PIX_FMT_YVYU:
    286     case V4L2_PIX_FMT_VYUY:
    287         *new_w = m_exynos_gsc_multiple_of_n(*new_w, 2);
    288         break;
    289     // RGB
    290     case V4L2_PIX_FMT_RGB32:
    291     case V4L2_PIX_FMT_RGB24:
    292     case V4L2_PIX_FMT_RGB565:
    293     case V4L2_PIX_FMT_BGR32:
    294     case V4L2_PIX_FMT_RGB555X:
    295     case V4L2_PIX_FMT_RGB444:
    296     default:
    297         break;
    298     }
    299 
    300     return true;
    301 }
    302 
    303 static int m_exynos_gsc_output_create(
    304     struct GSC_HANDLE *gsc_handle,
    305     int dev_num,
    306     int out_mode)
    307 {
    308     struct media_device *media0;
    309     struct media_entity *gsc_sd_entity;
    310     struct media_entity *gsc_vd_entity;
    311     struct media_entity *sink_sd_entity;
    312     struct media_link *links;
    313     char node[32];
    314     char devname[32];
    315     unsigned int cap;
    316     int         i;
    317     int         fd = 0;
    318 
    319     Exynos_gsc_In();
    320 
    321     if ((out_mode != GSC_OUT_FIMD) &&
    322         (out_mode != GSC_OUT_TV))
    323         return -1;
    324 
    325     gsc_handle->out_mode = out_mode;
    326     /* GSCX => FIMD_WINX : arbitrary linking is not allowed */
    327     if ((out_mode == GSC_OUT_FIMD) &&
    328         (dev_num > 2))
    329         return -1;
    330 
    331     /* media0 */
    332     sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0);
    333     media0 = exynos_media_open(node);
    334     if (media0 == NULL) {
    335         ALOGE("%s::exynos_media_open failed (node=%s)", __func__, node);
    336         return false;
    337     }
    338 
    339     /* Get the sink subdev entity by name and make the node of sink subdev*/
    340     if (out_mode == GSC_OUT_FIMD)
    341         sprintf(devname, PFX_FIMD_ENTITY, dev_num);
    342     else
    343         sprintf(devname, PFX_MXR_ENTITY, 0);
    344 
    345     sink_sd_entity = exynos_media_get_entity_by_name(media0, devname, strlen(devname));
    346     sink_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
    347     if ( sink_sd_entity->fd < 0) {
    348         ALOGE("%s:: failed to open sink subdev node", __func__);
    349         goto gsc_output_err;
    350     }
    351 
    352     /* get GSC video dev & sub dev entity by name*/
    353     sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num);
    354     gsc_vd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname));
    355 
    356     sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num);
    357     gsc_sd_entity= exynos_media_get_entity_by_name(media0, devname, strlen(devname));
    358 
    359     /* gsc sub-dev open */
    360     sprintf(devname, PFX_GSC_SUBDEV_ENTITY, dev_num);
    361     gsc_sd_entity->fd = exynos_subdev_open_devname(devname, O_RDWR);
    362 
    363     /* setup link : GSC : video device --> sub device */
    364     for (i = 0; i < (int) gsc_vd_entity->num_links; i++) {
    365         links = &gsc_vd_entity->links[i];
    366 
    367         if (links == NULL ||
    368             links->source->entity != gsc_vd_entity ||
    369             links->sink->entity   != gsc_sd_entity) {
    370             continue;
    371         } else if (exynos_media_setup_link(media0,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
    372             ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed",
    373                   __func__, links->source->entity->info.id, links->sink->entity->info.id);
    374             return -1;
    375         }
    376     }
    377 
    378     /* setup link : GSC: sub device --> sink device */
    379     for (i = 0; i < (int) gsc_sd_entity->num_links; i++) {
    380         links = &gsc_sd_entity->links[i];
    381 
    382         if (links == NULL || links->source->entity != gsc_sd_entity ||
    383                              links->sink->entity   != sink_sd_entity) {
    384             continue;
    385         } else if (exynos_media_setup_link(media0,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
    386             ALOGE("%s::exynos_media_setup_link [src.entity=%d->sink.entity=%d] failed",
    387                   __func__, links->source->entity->info.id, links->sink->entity->info.id);
    388             return -1;
    389         }
    390     }
    391 
    392     /* gsc video-dev open */
    393     sprintf(devname, PFX_GSC_VIDEODEV_ENTITY, dev_num);
    394     gsc_vd_entity->fd = exynos_v4l2_open_devname(devname, O_RDWR);
    395     cap = V4L2_CAP_STREAMING |
    396           V4L2_CAP_VIDEO_OUTPUT_MPLANE;
    397 
    398     if (exynos_v4l2_querycap(gsc_vd_entity->fd, cap) == false) {
    399         ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
    400         goto gsc_output_err;
    401     }
    402     gsc_handle->gsc_sd_entity = gsc_sd_entity;
    403     gsc_handle->gsc_vd_entity = gsc_vd_entity;
    404     gsc_handle->sink_sd_entity = sink_sd_entity;
    405     gsc_handle->media0 = media0;
    406 
    407     Exynos_gsc_Out();
    408 
    409     return 0;
    410 
    411 gsc_output_err:
    412     /* to do */
    413     return -1;
    414 
    415 }
    416 
    417 static int m_exynos_gsc_m2m_create(
    418     int dev)
    419 {
    420     int          fd = 0;
    421     int          video_node_num;
    422     unsigned int cap;
    423     char         node[32];
    424 
    425     Exynos_gsc_In();
    426 
    427     switch(dev) {
    428     case 0:
    429         video_node_num = NODE_NUM_GSC_0;
    430         break;
    431     case 1:
    432         video_node_num = NODE_NUM_GSC_1;
    433         break;
    434     case 2:
    435         video_node_num = NODE_NUM_GSC_2;
    436         break;
    437     case 3:
    438         video_node_num = NODE_NUM_GSC_3;
    439         break;
    440     default:
    441         ALOGE("%s::unexpected dev(%d) fail", __func__, dev);
    442         return -1;
    443         break;
    444     }
    445 
    446     sprintf(node, "%s%d", PFX_NODE_GSC, video_node_num);
    447     fd = exynos_v4l2_open(node, O_RDWR);
    448     if (fd < 0) {
    449         ALOGE("%s::exynos_v4l2_open(%s) fail", __func__, node);
    450         return -1;
    451     }
    452 
    453     cap = V4L2_CAP_STREAMING |
    454           V4L2_CAP_VIDEO_OUTPUT_MPLANE |
    455           V4L2_CAP_VIDEO_CAPTURE_MPLANE;
    456 
    457     if (exynos_v4l2_querycap(fd, cap) == false) {
    458         ALOGE("%s::exynos_v4l2_querycap() fail", __func__);
    459         if (0 < fd)
    460             close(fd);
    461         fd = 0;
    462         return -1;
    463     }
    464 
    465     Exynos_gsc_Out();
    466 
    467     return fd;
    468 }
    469 
    470 
    471 static bool m_exynos_gsc_out_destroy(struct GSC_HANDLE *gsc_handle)
    472 {
    473     struct media_link * links;
    474     int i;
    475 
    476     Exynos_gsc_In();
    477 
    478     if (gsc_handle == NULL) {
    479         ALOGE("%s::gsc_handle is NULL", __func__);
    480         return false;
    481     }
    482 
    483     if (gsc_handle->src.stream_on == true) {
    484         if (exynos_gsc_out_stop((void *)gsc_handle) < 0)
    485             ALOGE("%s::exynos_gsc_out_stop() fail", __func__);
    486 
    487             gsc_handle->src.stream_on = false;
    488     }
    489 
    490     /* unlink : gscaler-out --> fimd */
    491         for (i = 0; i < (int) gsc_handle->gsc_sd_entity->num_links; i++) {
    492             links = &gsc_handle->gsc_sd_entity->links[i];
    493 
    494             if (links == NULL || links->source->entity != gsc_handle->gsc_sd_entity ||
    495                                  links->sink->entity   != gsc_handle->sink_sd_entity) {
    496                 continue;
    497             } else if (exynos_media_setup_link(gsc_handle->media0,  links->source,
    498                                                                         links->sink, 0) < 0) {
    499                 ALOGE("%s::exynos_media_setup_unlink [src.entity=%d->sink.entity=%d] failed",
    500                       __func__, links->source->entity->info.id, links->sink->entity->info.id);
    501             }
    502         }
    503 
    504         close(gsc_handle->gsc_vd_entity->fd);
    505         close(gsc_handle->gsc_sd_entity->fd);
    506         gsc_handle->gsc_vd_entity->fd = -1;
    507         gsc_handle->gsc_vd_entity->fd = -1;
    508 
    509         Exynos_gsc_Out();
    510 
    511         return true;
    512 
    513 }
    514 
    515 static bool m_exynos_gsc_destroy(
    516     struct GSC_HANDLE *gsc_handle)
    517 {
    518     Exynos_gsc_In();
    519 
    520     /* just in case, we call stop here because we cannot afford to leave
    521      * secure side protection on if things failed.
    522      */
    523     exynos_gsc_m2m_stop(gsc_handle);
    524 
    525     if (0 < gsc_handle->gsc_fd)
    526         close(gsc_handle->gsc_fd);
    527     gsc_handle->gsc_fd = 0;
    528 
    529     Exynos_gsc_Out();
    530 
    531     return true;
    532 }
    533 
    534 bool m_exynos_gsc_find_and_trylock_and_create(
    535     struct GSC_HANDLE *gsc_handle)
    536 {
    537     int          i                 = 0;
    538     bool         flag_find_new_gsc = false;
    539     unsigned int total_sleep_time  = 0;
    540 
    541     Exynos_gsc_In();
    542 
    543     do {
    544         for (i = 0; i < NUM_OF_GSC_HW; i++) {
    545             // HACK : HWComposer, HDMI uses gscaler with their own code.
    546             //        So, This obj_mutex cannot defense their open()
    547             if (i == 0 || i == 3)
    548                 continue;
    549 
    550             if (exynos_mutex_trylock(gsc_handle->obj_mutex[i]) == true) {
    551 
    552                 // destroy old one.
    553                 m_exynos_gsc_destroy(gsc_handle);
    554 
    555                 // create new one.
    556                 gsc_handle->gsc_id = i;
    557                 gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(i);
    558                 if (gsc_handle->gsc_fd < 0) {
    559                     gsc_handle->gsc_fd = 0;
    560                     exynos_mutex_unlock(gsc_handle->obj_mutex[i]);
    561                     continue;
    562                 }
    563 
    564                 if (gsc_handle->cur_obj_mutex)
    565                     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
    566 
    567                 gsc_handle->cur_obj_mutex = gsc_handle->obj_mutex[i];
    568 
    569                 flag_find_new_gsc = true;
    570                 break;
    571             }
    572         }
    573 
    574         // waiting for another process doesn't use gscaler.
    575         // we need to make decision how to do.
    576         if (flag_find_new_gsc == false) {
    577             usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
    578             total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
    579             ALOGV("%s::waiting for anthere process doens't use gscaler", __func__);
    580         }
    581 
    582     } while(   flag_find_new_gsc == false
    583             && total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
    584 
    585     if (flag_find_new_gsc == false)
    586         ALOGE("%s::we don't have no available gsc.. fail", __func__);
    587 
    588     Exynos_gsc_Out();
    589 
    590     return flag_find_new_gsc;
    591 }
    592 
    593 static bool m_exynos_gsc_set_format(
    594     int              fd,
    595     struct gsc_info *info)
    596 {
    597     Exynos_gsc_In();
    598 
    599     struct v4l2_requestbuffers req_buf;
    600     int                        plane_count;
    601 
    602     plane_count = m_gsc_get_plane_count(info->v4l2_colorformat);
    603     if (plane_count < 0) {
    604         ALOGE("%s::not supported v4l2_colorformat", __func__);
    605         return false;
    606     }
    607 
    608     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_ROTATE, info->rotation) < 0) {
    609         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_ROTATE) fail", __func__);
    610         return false;
    611     }
    612 
    613     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_VFLIP, info->flip_horizontal) < 0) {
    614         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_VFLIP) fail", __func__);
    615         return false;
    616     }
    617 
    618     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_HFLIP, info->flip_vertical) < 0) {
    619         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_HFLIP) fail", __func__);
    620         return false;
    621     }
    622 
    623     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CSC_RANGE, info->csc_range) < 0) {
    624         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE) fail", __func__);
    625         return false;
    626     }
    627     info->format.type = info->buf_type;
    628     info->format.fmt.pix_mp.width       = info->width;
    629     info->format.fmt.pix_mp.height      = info->height;
    630     info->format.fmt.pix_mp.pixelformat = info->v4l2_colorformat;
    631     info->format.fmt.pix_mp.field       = V4L2_FIELD_ANY;
    632     info->format.fmt.pix_mp.num_planes  = plane_count;
    633 
    634     if (exynos_v4l2_s_fmt(fd, &info->format) < 0) {
    635         ALOGE("%s::exynos_v4l2_s_fmt() fail", __func__);
    636         return false;
    637     }
    638 
    639     info->crop.type     = info->buf_type;
    640     info->crop.c.left   = info->crop_left;
    641     info->crop.c.top    = info->crop_top;
    642     info->crop.c.width  = info->crop_width;
    643     info->crop.c.height = info->crop_height;
    644 
    645     if (exynos_v4l2_s_crop(fd, &info->crop) < 0) {
    646         ALOGE("%s::exynos_v4l2_s_crop() fail", __func__);
    647         return false;
    648     }
    649 
    650     if (exynos_v4l2_s_ctrl(fd, V4L2_CID_CACHEABLE, info->cacheable) < 0) {
    651         ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
    652         return false;
    653     }
    654 
    655     req_buf.count  = 1;
    656     req_buf.type   = info->buf_type;
    657     req_buf.memory = V4L2_MEMORY_DMABUF;
    658     if (exynos_v4l2_reqbufs(fd, &req_buf) < 0) {
    659         ALOGE("%s::exynos_v4l2_reqbufs() fail", __func__);
    660         return false;
    661     }
    662 
    663     Exynos_gsc_Out();
    664 
    665     return true;
    666 }
    667 
    668 static bool m_exynos_gsc_set_addr(
    669     int              fd,
    670     struct gsc_info *info)
    671 {
    672     unsigned int i;
    673     unsigned int plane_size[NUM_OF_GSC_PLANES];
    674 
    675     m_gsc_get_plane_size(plane_size,
    676                          info->width,
    677                          info->height,
    678                          info->v4l2_colorformat);
    679 
    680     info->buffer.index    = 0;
    681     info->buffer.flags    = V4L2_BUF_FLAG_USE_SYNC;
    682     info->buffer.type     = info->buf_type;
    683     info->buffer.memory   = V4L2_MEMORY_DMABUF;
    684     info->buffer.m.planes = info->planes;
    685     info->buffer.length   = info->format.fmt.pix_mp.num_planes;
    686     info->buffer.reserved = info->acquireFenceFd;
    687 
    688     for (i = 0; i < info->format.fmt.pix_mp.num_planes; i++) {
    689         info->buffer.m.planes[i].m.fd = (int)info->addr[i];
    690         info->buffer.m.planes[i].length    = plane_size[i];
    691         info->buffer.m.planes[i].bytesused = 0;
    692     }
    693 
    694     if (exynos_v4l2_qbuf(fd, &info->buffer) < 0) {
    695         ALOGE("%s::exynos_v4l2_qbuf() fail", __func__);
    696         return false;
    697     }
    698     info->buffer_queued = true;
    699 
    700     info->releaseFenceFd = info->buffer.reserved;
    701 
    702     return true;
    703 }
    704 
    705 void *exynos_gsc_create(
    706     void)
    707 {
    708     int i     = 0;
    709     int op_id = 0;
    710     char mutex_name[32];
    711 
    712     Exynos_gsc_In();
    713 
    714     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
    715     if (gsc_handle == NULL) {
    716         ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
    717         goto err;
    718     }
    719 
    720     gsc_handle->gsc_fd = 0;
    721     memset(&gsc_handle->src, 0, sizeof(struct gsc_info));
    722     memset(&gsc_handle->dst, 0, sizeof(struct gsc_info));
    723 
    724     gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    725     gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    726 
    727     gsc_handle->op_mutex = NULL;
    728     for (i = 0; i < NUM_OF_GSC_HW; i++)
    729         gsc_handle->obj_mutex[i] = NULL;
    730 
    731     gsc_handle->cur_obj_mutex = NULL;
    732     gsc_handle->flag_local_path = false;
    733     gsc_handle->flag_exclusive_open = false;
    734 
    735     srand(time(NULL));
    736     op_id = rand() % 1000000; // just make random id
    737     sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id);
    738     gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name);
    739     if (gsc_handle->op_mutex == NULL) {
    740         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
    741         goto err;
    742     }
    743 
    744     exynos_mutex_lock(gsc_handle->op_mutex);
    745 
    746     // check if it is available
    747     for (i = 0; i < NUM_OF_GSC_HW; i++) {
    748         sprintf(mutex_name, "%sObject%d", LOG_TAG, i);
    749 
    750         gsc_handle->obj_mutex[i] = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
    751         if (gsc_handle->obj_mutex[i] == NULL) {
    752             ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
    753             goto err;
    754         }
    755     }
    756 
    757     if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) {
    758         ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__);
    759         goto err;
    760     }
    761 
    762     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
    763     exynos_mutex_unlock(gsc_handle->op_mutex);
    764 
    765     return (void *)gsc_handle;
    766 
    767 err:
    768     if (gsc_handle) {
    769         m_exynos_gsc_destroy(gsc_handle);
    770 
    771         if (gsc_handle->cur_obj_mutex)
    772             exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
    773 
    774         for (i = 0; i < NUM_OF_GSC_HW; i++) {
    775             if ((gsc_handle->obj_mutex[i] != NULL) &&
    776                 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
    777                 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
    778                     ALOGE("%s::exynos_mutex_destroy() fail", __func__);
    779             }
    780         }
    781 
    782         if (gsc_handle->op_mutex)
    783             exynos_mutex_unlock(gsc_handle->op_mutex);
    784 
    785         if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
    786             ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
    787 
    788         free(gsc_handle);
    789     }
    790 
    791     Exynos_gsc_Out();
    792 
    793     return NULL;
    794 }
    795 
    796 void *exynos_gsc_reserve(int dev_num)
    797 {
    798     char mutex_name[32];
    799     unsigned int total_sleep_time  = 0;
    800     bool    gsc_flag = false;
    801 
    802     if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) {
    803         ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
    804         return NULL;
    805     }
    806 
    807     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
    808     if (gsc_handle == NULL) {
    809         ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
    810         goto err;
    811     }
    812 
    813     gsc_handle->gsc_fd = -1;
    814     gsc_handle->op_mutex = NULL;
    815     gsc_handle->cur_obj_mutex = NULL;
    816 
    817     sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num);
    818     gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
    819     if (gsc_handle->cur_obj_mutex == NULL) {
    820         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
    821         goto err;
    822     }
    823 
    824     do {
    825         if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) {
    826             gsc_flag = true;
    827             break;
    828         }
    829         usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
    830         total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
    831         ALOGV("%s::waiting for another process to release the requested gscaler", __func__);
    832     } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
    833 
    834     if (gsc_flag == true)
    835          return (void *)gsc_handle;
    836 
    837 err:
    838     if (gsc_handle) {
    839         free(gsc_handle);
    840     }
    841 
    842     return NULL;
    843 }
    844 
    845 void exynos_gsc_release(void *handle)
    846 {
    847     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle;
    848 
    849     if (handle == NULL) {
    850         ALOGE("%s::handle == NULL() fail", __func__);
    851         return;
    852     }
    853 
    854     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
    855     exynos_mutex_destroy(gsc_handle->cur_obj_mutex);
    856     free(gsc_handle);
    857     return;
    858 }
    859 
    860 void *exynos_gsc_create_exclusive(
    861     int dev_num,
    862     int mode,
    863     int out_mode,
    864     int allow_drm)
    865 {
    866     int i     = 0;
    867     int op_id = 0;
    868     char mutex_name[32];
    869     unsigned int total_sleep_time  = 0;
    870     bool    gsc_flag = false;
    871     int ret = 0;
    872 
    873     Exynos_gsc_In();
    874 
    875     if ((dev_num < 0) || (dev_num >= NUM_OF_GSC_HW)) {
    876         ALOGE("%s::fail:: dev_num is not valid(%d) ", __func__, dev_num);
    877         return NULL;
    878     }
    879 
    880     if ((mode < 0) || (mode >= NUM_OF_GSC_HW)) {
    881         ALOGE("%s::fail:: mode is not valid(%d) ", __func__, mode);
    882         return NULL;
    883     }
    884 
    885     /* currently only gscalers 0 and 3 are DRM capable */
    886     if (allow_drm && (dev_num != 0 && dev_num != 3)) {
    887         ALOGE("%s::fail:: gscaler %d does not support drm\n", __func__,
    888               dev_num);
    889         return NULL;
    890     }
    891 
    892     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)malloc(sizeof(struct GSC_HANDLE));
    893     if (gsc_handle == NULL) {
    894         ALOGE("%s::malloc(struct GSC_HANDLE) fail", __func__);
    895         goto err;
    896     }
    897     memset(gsc_handle, 0, sizeof(struct GSC_HANDLE));
    898     gsc_handle->gsc_fd = -1;
    899     gsc_handle->gsc_mode = mode;
    900     gsc_handle->gsc_id = dev_num;
    901     gsc_handle->allow_drm = allow_drm;
    902 
    903     gsc_handle->src.buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    904     gsc_handle->dst.buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    905 
    906     gsc_handle->op_mutex = NULL;
    907     for (i = 0; i < NUM_OF_GSC_HW; i++)
    908         gsc_handle->obj_mutex[i] = NULL;
    909 
    910     gsc_handle->cur_obj_mutex = NULL;
    911     gsc_handle->flag_local_path = false;
    912     gsc_handle->flag_exclusive_open = true;
    913 
    914     srand(time(NULL));
    915     op_id = rand() % 1000000; // just make random id
    916     sprintf(mutex_name, "%sOp%d", LOG_TAG, op_id);
    917     gsc_handle->op_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_PRIVATE, mutex_name);
    918     if (gsc_handle->op_mutex == NULL) {
    919         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
    920         goto err;
    921     }
    922 
    923     exynos_mutex_lock(gsc_handle->op_mutex);
    924 
    925     sprintf(mutex_name, "%sObject%d", LOG_TAG, dev_num);
    926     gsc_handle->cur_obj_mutex = exynos_mutex_create(EXYNOS_MUTEX_TYPE_SHARED, mutex_name);
    927     if (gsc_handle->cur_obj_mutex == NULL) {
    928         ALOGE("%s::exynos_mutex_create(%s) fail", __func__, mutex_name);
    929         goto err;
    930     }
    931 
    932     do {
    933         if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == true) {
    934             if (mode == GSC_M2M_MODE) {
    935                 gsc_handle->gsc_fd = m_exynos_gsc_m2m_create(dev_num);
    936                 if (gsc_handle->gsc_fd < 0) {
    937                     ALOGE("%s::m_exynos_gsc_m2m_create(%i) fail", __func__, dev_num);
    938                     goto err;
    939                 }
    940             } else if (mode == GSC_OUTPUT_MODE) {
    941                 ret = m_exynos_gsc_output_create(gsc_handle, dev_num, out_mode);
    942                 if (ret < 0) {
    943                     ALOGE("%s::m_exynos_gsc_output_create(%i) fail", __func__, dev_num);
    944                     goto err;
    945                 }
    946             }
    947             /*else
    948                 gsc_handle->gsc_fd = m_exynos_gsc_capture_create(dev_num);*/
    949 
    950             gsc_flag = true;
    951             break;
    952         }
    953         usleep(GSC_WAITING_TIME_FOR_TRYLOCK);
    954         total_sleep_time += GSC_WAITING_TIME_FOR_TRYLOCK;
    955         ALOGV("%s::waiting for anthere process doens't use gscaler", __func__);
    956     } while(total_sleep_time < MAX_GSC_WAITING_TIME_FOR_TRYLOCK);
    957 
    958     exynos_mutex_unlock(gsc_handle->op_mutex);
    959     if (gsc_flag == true) {
    960         Exynos_gsc_Out();
    961         return (void *)gsc_handle;
    962         }
    963 
    964 err:
    965     if (gsc_handle) {
    966         m_exynos_gsc_destroy(gsc_handle);
    967 
    968         if (gsc_handle->cur_obj_mutex)
    969             exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
    970 
    971         for (i = 0; i < NUM_OF_GSC_HW; i++) {
    972             if ((gsc_handle->obj_mutex[i] != NULL) &&
    973                 (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
    974                 if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
    975                     ALOGE("%s::exynos_mutex_destroy() fail", __func__);
    976             }
    977         }
    978 
    979         if (gsc_handle->op_mutex)
    980             exynos_mutex_unlock(gsc_handle->op_mutex);
    981 
    982         if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
    983             ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
    984 
    985         free(gsc_handle);
    986     }
    987 
    988     Exynos_gsc_Out();
    989 
    990     return NULL;
    991 }
    992 
    993 void exynos_gsc_destroy(
    994     void *handle)
    995 {
    996     int i = 0;
    997     struct GSC_HANDLE *gsc_handle = (struct GSC_HANDLE *)handle;
    998 
    999     Exynos_gsc_In();
   1000 
   1001     if (handle == NULL) {
   1002         ALOGE("%s::handle == NULL() fail", __func__);
   1003         return;
   1004     }
   1005 
   1006     exynos_mutex_lock(gsc_handle->op_mutex);
   1007 
   1008     if (gsc_handle->flag_exclusive_open == false)
   1009         exynos_mutex_lock(gsc_handle->cur_obj_mutex);
   1010 
   1011     if (gsc_handle->gsc_mode == GSC_OUTPUT_MODE)
   1012         m_exynos_gsc_out_destroy(gsc_handle);
   1013     else
   1014         m_exynos_gsc_destroy(gsc_handle);
   1015 
   1016     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
   1017 
   1018     for (i = 0; i < NUM_OF_GSC_HW; i++) {
   1019         if ((gsc_handle->obj_mutex[i] != NULL) &&
   1020             (exynos_mutex_get_created_status(gsc_handle->obj_mutex[i]) == true)) {
   1021             if (exynos_mutex_destroy(gsc_handle->obj_mutex[i]) == false)
   1022                 ALOGE("%s::exynos_mutex_destroy(obj_mutex) fail", __func__);
   1023         }
   1024     }
   1025 
   1026     exynos_mutex_unlock(gsc_handle->op_mutex);
   1027 
   1028     if (exynos_mutex_destroy(gsc_handle->op_mutex) == false)
   1029         ALOGE("%s::exynos_mutex_destroy(op_mutex) fail", __func__);
   1030 
   1031     if (gsc_handle)
   1032         free(gsc_handle);
   1033 
   1034     Exynos_gsc_Out();
   1035 
   1036 }
   1037 
   1038 int exynos_gsc_set_src_format(
   1039     void        *handle,
   1040     unsigned int width,
   1041     unsigned int height,
   1042     unsigned int crop_left,
   1043     unsigned int crop_top,
   1044     unsigned int crop_width,
   1045     unsigned int crop_height,
   1046     unsigned int v4l2_colorformat,
   1047     unsigned int cacheable,
   1048     unsigned int mode_drm)
   1049 {
   1050     Exynos_gsc_In();
   1051 
   1052     struct GSC_HANDLE *gsc_handle;
   1053     gsc_handle = (struct GSC_HANDLE *)handle;
   1054 
   1055     if (handle == NULL) {
   1056         ALOGE("%s::handle == NULL() fail", __func__);
   1057         return -1;
   1058     }
   1059 
   1060     exynos_mutex_lock(gsc_handle->op_mutex);
   1061 
   1062     gsc_handle->src.width            = width;
   1063     gsc_handle->src.height           = height;
   1064     gsc_handle->src.crop_left        = crop_left;
   1065     gsc_handle->src.crop_top         = crop_top;
   1066     gsc_handle->src.crop_width       = crop_width;
   1067     gsc_handle->src.crop_height      = crop_height;
   1068     gsc_handle->src.v4l2_colorformat = v4l2_colorformat;
   1069     gsc_handle->src.cacheable        = cacheable;
   1070     gsc_handle->src.mode_drm         = mode_drm;
   1071     gsc_handle->src.dirty            = true;
   1072 
   1073 
   1074     exynos_mutex_unlock(gsc_handle->op_mutex);
   1075 
   1076     Exynos_gsc_Out();
   1077 
   1078     return 0;
   1079 }
   1080 
   1081 int exynos_gsc_set_dst_format(
   1082     void        *handle,
   1083     unsigned int width,
   1084     unsigned int height,
   1085     unsigned int crop_left,
   1086     unsigned int crop_top,
   1087     unsigned int crop_width,
   1088     unsigned int crop_height,
   1089     unsigned int v4l2_colorformat,
   1090     unsigned int cacheable,
   1091     unsigned int mode_drm,
   1092     unsigned int narrowRgb)
   1093 {
   1094     Exynos_gsc_In();
   1095 
   1096     struct GSC_HANDLE *gsc_handle;
   1097     gsc_handle = (struct GSC_HANDLE *)handle;
   1098 
   1099     if (handle == NULL) {
   1100         ALOGE("%s::handle == NULL() fail", __func__);
   1101         return -1;
   1102     }
   1103 
   1104     exynos_mutex_lock(gsc_handle->op_mutex);
   1105 
   1106     gsc_handle->dst.width            = width;
   1107     gsc_handle->dst.height           = height;
   1108     gsc_handle->dst.crop_left        = crop_left;
   1109     gsc_handle->dst.crop_top         = crop_top;
   1110     gsc_handle->dst.crop_width       = crop_width;
   1111     gsc_handle->dst.crop_height      = crop_height;
   1112     gsc_handle->dst.v4l2_colorformat = v4l2_colorformat;
   1113     gsc_handle->dst.cacheable        = cacheable;
   1114     gsc_handle->dst.mode_drm         = mode_drm;
   1115     gsc_handle->dst.dirty            = true;
   1116     gsc_handle->dst.csc_range        = !narrowRgb;
   1117 
   1118     exynos_mutex_unlock(gsc_handle->op_mutex);
   1119 
   1120     Exynos_gsc_Out();
   1121     return 0;
   1122 }
   1123 
   1124 int exynos_gsc_set_rotation(
   1125     void *handle,
   1126     int   rotation,
   1127     int   flip_horizontal,
   1128     int   flip_vertical)
   1129 {
   1130     int ret = -1;
   1131     struct GSC_HANDLE *gsc_handle;
   1132     gsc_handle = (struct GSC_HANDLE *)handle;
   1133 
   1134     if (handle == NULL) {
   1135         ALOGE("%s::handle == NULL() fail", __func__);
   1136         return ret;
   1137     }
   1138 
   1139     exynos_mutex_lock(gsc_handle->op_mutex);
   1140 
   1141     int new_rotation = rotation % 360;
   1142 
   1143     if (new_rotation % 90 != 0) {
   1144         ALOGE("%s::rotation(%d) cannot be acceptable fail", __func__, rotation);
   1145         goto done;
   1146     }
   1147 
   1148     if(new_rotation < 0)
   1149         new_rotation = -new_rotation;
   1150 
   1151     gsc_handle->dst.rotation        = new_rotation;
   1152     gsc_handle->dst.flip_horizontal = flip_horizontal;
   1153     gsc_handle->dst.flip_vertical   = flip_vertical;
   1154 
   1155     ret = 0;
   1156 done:
   1157     exynos_mutex_unlock(gsc_handle->op_mutex);
   1158 
   1159     return ret;
   1160 }
   1161 
   1162 int exynos_gsc_set_src_addr(
   1163     void *handle,
   1164     void *addr[3],
   1165     int acquireFenceFd)
   1166 {
   1167     struct GSC_HANDLE *gsc_handle;
   1168     gsc_handle = (struct GSC_HANDLE *)handle;
   1169 
   1170     Exynos_gsc_In();
   1171 
   1172     if (handle == NULL) {
   1173         ALOGE("%s::handle == NULL() fail", __func__);
   1174         return -1;
   1175     }
   1176 
   1177     exynos_mutex_lock(gsc_handle->op_mutex);
   1178 
   1179     gsc_handle->src.addr[0] = addr[0];
   1180     gsc_handle->src.addr[1] = addr[1];
   1181     gsc_handle->src.addr[2] = addr[2];
   1182     gsc_handle->src.acquireFenceFd = acquireFenceFd;
   1183 
   1184     exynos_mutex_unlock(gsc_handle->op_mutex);
   1185 
   1186     Exynos_gsc_Out();
   1187 
   1188     return 0;
   1189 }
   1190 
   1191 int exynos_gsc_set_dst_addr(
   1192     void *handle,
   1193     void *addr[3],
   1194     int acquireFenceFd)
   1195 {
   1196     struct GSC_HANDLE *gsc_handle;
   1197     gsc_handle = (struct GSC_HANDLE *)handle;
   1198     int ret = 0;
   1199 
   1200     Exynos_gsc_In();
   1201 
   1202     if (handle == NULL) {
   1203         ALOGE("%s::handle == NULL() fail", __func__);
   1204         return -1;
   1205     }
   1206 
   1207     exynos_mutex_lock(gsc_handle->op_mutex);
   1208 
   1209     gsc_handle->dst.addr[0] = addr[0];
   1210     gsc_handle->dst.addr[1] = addr[1];
   1211     gsc_handle->dst.addr[2] = addr[2];
   1212     gsc_handle->dst.acquireFenceFd = acquireFenceFd;
   1213 
   1214 
   1215     exynos_mutex_unlock(gsc_handle->op_mutex);
   1216 
   1217     Exynos_gsc_Out();
   1218 
   1219     return ret;
   1220 }
   1221 
   1222 static void rotateValueHAL2GSC(unsigned int transform,
   1223     unsigned int *rotate,
   1224     unsigned int *hflip,
   1225     unsigned int *vflip)
   1226 {
   1227     int rotate_flag = transform & 0x7;
   1228     *rotate = 0;
   1229     *hflip = 0;
   1230     *vflip = 0;
   1231 
   1232     switch (rotate_flag) {
   1233     case HAL_TRANSFORM_ROT_90:
   1234         *rotate = 90;
   1235         break;
   1236     case HAL_TRANSFORM_ROT_180:
   1237         *rotate = 180;
   1238         break;
   1239     case HAL_TRANSFORM_ROT_270:
   1240         *rotate = 270;
   1241         break;
   1242     case HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90:
   1243         *rotate = 90;
   1244         *vflip = 1; /* set vflip to compensate the rot & flip order. */
   1245         break;
   1246     case HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90:
   1247         *rotate = 90;
   1248         *hflip = 1; /* set hflip to compensate the rot & flip order. */
   1249         break;
   1250     case HAL_TRANSFORM_FLIP_H:
   1251         *hflip = 1;
   1252          break;
   1253     case HAL_TRANSFORM_FLIP_V:
   1254         *vflip = 1;
   1255          break;
   1256     default:
   1257         break;
   1258     }
   1259 }
   1260 
   1261 static bool get_plane_size(int V4L2_PIX,
   1262     unsigned int * size,
   1263     unsigned int frame_size,
   1264     int src_planes)
   1265 {
   1266     unsigned int frame_ratio = 1;
   1267     int src_bpp    = get_yuv_bpp(V4L2_PIX);
   1268 
   1269     src_planes = (src_planes == -1) ? 1 : src_planes;
   1270     frame_ratio = 8 * (src_planes -1) / (src_bpp - 8);
   1271 
   1272     switch (src_planes) {
   1273     case 1:
   1274         switch (V4L2_PIX) {
   1275         case V4L2_PIX_FMT_BGR32:
   1276         case V4L2_PIX_FMT_RGB32:
   1277             size[0] = frame_size << 2;
   1278             break;
   1279         case V4L2_PIX_FMT_RGB565X:
   1280         case V4L2_PIX_FMT_NV16:
   1281         case V4L2_PIX_FMT_NV61:
   1282         case V4L2_PIX_FMT_YUYV:
   1283         case V4L2_PIX_FMT_UYVY:
   1284         case V4L2_PIX_FMT_VYUY:
   1285         case V4L2_PIX_FMT_YVYU:
   1286             size[0] = frame_size << 1;
   1287             break;
   1288         case V4L2_PIX_FMT_YUV420:
   1289         case V4L2_PIX_FMT_NV12:
   1290         case V4L2_PIX_FMT_NV21:
   1291         case V4L2_PIX_FMT_NV21M:
   1292             size[0] = (frame_size * 3) >> 1;
   1293             break;
   1294         default:
   1295             ALOGE("%s::invalid color type", __func__);
   1296             return false;
   1297             break;
   1298         }
   1299         size[1] = 0;
   1300         size[2] = 0;
   1301         break;
   1302     case 2:
   1303         size[0] = frame_size;
   1304         size[1] = frame_size / frame_ratio;
   1305         size[2] = 0;
   1306         break;
   1307     case 3:
   1308         size[0] = frame_size;
   1309         size[1] = frame_size / frame_ratio;
   1310         size[2] = frame_size / frame_ratio;
   1311         break;
   1312     default:
   1313         ALOGE("%s::invalid color foarmt", __func__);
   1314         return false;
   1315         break;
   1316     }
   1317 
   1318     return true;
   1319 }
   1320 
   1321 int exynos_gsc_m2m_config(void *handle,
   1322     exynos_gsc_img *src_img,
   1323     exynos_gsc_img *dst_img)
   1324 {
   1325     struct GSC_HANDLE *gsc_handle;
   1326     int32_t      src_color_space;
   1327     int32_t      dst_color_space;
   1328     int ret;
   1329     unsigned int rotate;
   1330     unsigned int hflip;
   1331     unsigned int vflip;
   1332 
   1333     Exynos_gsc_In();
   1334 
   1335     gsc_handle = (struct GSC_HANDLE *)handle;
   1336     if (gsc_handle == NULL) {
   1337         ALOGE("%s::gsc_handle == NULL() fail", __func__);
   1338         return -1;
   1339     }
   1340 
   1341     if ((src_img->drmMode && !gsc_handle->allow_drm) ||
   1342         (src_img->drmMode != dst_img->drmMode)) {
   1343         ALOGE("%s::invalid drm state request for gsc%d (s=%d d=%d)",
   1344               __func__, gsc_handle->gsc_id,
   1345               src_img->drmMode, dst_img->drmMode);
   1346         return -1;
   1347     }
   1348 
   1349     src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
   1350     dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
   1351     rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
   1352     exynos_gsc_set_rotation(gsc_handle, rotate, hflip, vflip);
   1353 
   1354     ret = exynos_gsc_set_src_format(gsc_handle,  src_img->fw, src_img->fh,
   1355                                   src_img->x, src_img->y, src_img->w, src_img->h,
   1356                                   src_color_space, src_img->cacheable, src_img->drmMode);
   1357     if (ret < 0) {
   1358         ALOGE("%s: fail: exynos_gsc_set_src_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
   1359             __func__, src_img->fw, src_img->fh, src_img->x, src_img->y, src_img->w, src_img->h,
   1360             src_color_space, src_img->rot);
   1361         return -1;
   1362     }
   1363 
   1364     ret = exynos_gsc_set_dst_format(gsc_handle, dst_img->fw, dst_img->fh,
   1365                                   dst_img->x, dst_img->y, dst_img->w, dst_img->h,
   1366                                   dst_color_space, dst_img->cacheable, dst_img->drmMode,
   1367                                   dst_img->narrowRgb);
   1368     if (ret < 0) {
   1369         ALOGE("%s: fail: exynos_gsc_set_dst_format [fw %d fh %d x %d y %d w %d h %d f %x rot %d]",
   1370             __func__, dst_img->fw, dst_img->fh, dst_img->x, dst_img->y, dst_img->w, dst_img->h,
   1371             src_color_space, dst_img->rot);
   1372         return -1;
   1373     }
   1374 
   1375     Exynos_gsc_Out();
   1376 
   1377     return 0;
   1378 }
   1379 
   1380 int exynos_gsc_out_config(void *handle,
   1381     exynos_gsc_img *src_img,
   1382     exynos_gsc_img *dst_img)
   1383 {
   1384     struct GSC_HANDLE *gsc_handle;
   1385     struct v4l2_format  fmt;
   1386     struct v4l2_crop    crop;
   1387     struct v4l2_requestbuffers reqbuf;
   1388     struct v4l2_subdev_format sd_fmt;
   1389     struct v4l2_subdev_crop   sd_crop;
   1390     int i;
   1391     unsigned int rotate;
   1392     unsigned int hflip;
   1393     unsigned int vflip;
   1394     unsigned int plane_size[NUM_OF_GSC_PLANES];
   1395     bool rgb;
   1396     int csc_range = !dst_img->narrowRgb;
   1397 
   1398     struct v4l2_rect dst_rect;
   1399     int32_t      src_color_space;
   1400     int32_t      dst_color_space;
   1401     int32_t      src_planes;
   1402 
   1403     gsc_handle = (struct GSC_HANDLE *)handle;
   1404      if (gsc_handle == NULL) {
   1405         ALOGE("%s::gsc_handle == NULL() fail", __func__);
   1406         return -1;
   1407     }
   1408 
   1409     Exynos_gsc_In();
   1410 
   1411      if (gsc_handle->src.stream_on != false) {
   1412         ALOGE("Error: Src is already streamed on !!!!");
   1413         return -1;
   1414      }
   1415 
   1416     memcpy(&gsc_handle->src_img, src_img, sizeof(exynos_gsc_img));
   1417     memcpy(&gsc_handle->dst_img, dst_img, sizeof(exynos_gsc_img));
   1418     src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(src_img->format);
   1419     dst_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(dst_img->format);
   1420     src_planes = get_yuv_planes(src_color_space);
   1421     src_planes = (src_planes == -1) ? 1 : src_planes;
   1422     rgb = get_yuv_planes(dst_color_space) == -1;
   1423     rotateValueHAL2GSC(dst_img->rot, &rotate, &hflip, &vflip);
   1424 
   1425     if (m_exynos_gsc_check_src_size(&gsc_handle->src_img.fw, &gsc_handle->src_img.fh,
   1426                                         &gsc_handle->src_img.x, &gsc_handle->src_img.y,
   1427                                         &gsc_handle->src_img.w, &gsc_handle->src_img.h,
   1428                                         src_color_space) == false) {
   1429             ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__);
   1430             return -1;
   1431     }
   1432 
   1433     if (m_exynos_gsc_check_dst_size(&gsc_handle->dst_img.fw, &gsc_handle->dst_img.fh,
   1434                                         &gsc_handle->dst_img.x, &gsc_handle->dst_img.y,
   1435                                         &gsc_handle->dst_img.w, &gsc_handle->dst_img.h,
   1436                                         dst_color_space,
   1437                                         rotate) == false) {
   1438             ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__);
   1439             return -1;
   1440     }
   1441 
   1442     /*set: src v4l2_buffer*/
   1443     gsc_handle->src.src_buf_idx = 0;
   1444     gsc_handle->src.qbuf_cnt = 0;
   1445     /* set format: src pad of GSC sub-dev*/
   1446     sd_fmt.pad   = GSCALER_SUBDEV_PAD_SOURCE;
   1447     sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
   1448     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
   1449         sd_fmt.format.width  = gsc_handle->dst_img.fw;
   1450         sd_fmt.format.height = gsc_handle->dst_img.fh;
   1451     } else {
   1452         sd_fmt.format.width  = gsc_handle->dst_img.w;
   1453         sd_fmt.format.height = gsc_handle->dst_img.h;
   1454     }
   1455     sd_fmt.format.code   = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
   1456                                     V4L2_MBUS_FMT_YUV8_1X24;
   1457     if (exynos_subdev_s_fmt(gsc_handle->gsc_sd_entity->fd, &sd_fmt) < 0) {
   1458             ALOGE("%s::GSC subdev set format failed", __func__);
   1459             return -1;
   1460     }
   1461 
   1462     /* set crop: src crop of GSC sub-dev*/
   1463     sd_crop.pad   = GSCALER_SUBDEV_PAD_SOURCE;
   1464     sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
   1465     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
   1466         sd_crop.rect.left   = gsc_handle->dst_img.x;
   1467         sd_crop.rect.top    = gsc_handle->dst_img.y;
   1468         sd_crop.rect.width  = gsc_handle->dst_img.w;
   1469         sd_crop.rect.height = gsc_handle->dst_img.h;
   1470     } else {
   1471         sd_crop.rect.left   = 0;
   1472         sd_crop.rect.top    = 0;
   1473         sd_crop.rect.width  = gsc_handle->dst_img.w;
   1474         sd_crop.rect.height = gsc_handle->dst_img.h;
   1475     }
   1476     if (exynos_subdev_s_crop(gsc_handle->gsc_sd_entity->fd, &sd_crop) < 0) {
   1477             ALOGE("%s::GSC subdev set crop failed", __func__);
   1478             return -1;
   1479     }
   1480 
   1481     /* sink pad is connected to GSC out */
   1482     /*  set format: sink sub-dev */
   1483     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
   1484         sd_fmt.pad   = FIMD_SUBDEV_PAD_SINK;
   1485         sd_fmt.format.width  = gsc_handle->dst_img.w;
   1486         sd_fmt.format.height = gsc_handle->dst_img.h;
   1487     } else {
   1488         sd_fmt.pad   = MIXER_V_SUBDEV_PAD_SINK;
   1489         sd_fmt.format.width  = gsc_handle->dst_img.w + gsc_handle->dst_img.x*2;
   1490         sd_fmt.format.height = gsc_handle->dst_img.h + gsc_handle->dst_img.y*2;
   1491     }
   1492 
   1493     sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
   1494     sd_fmt.format.code   = rgb ? V4L2_MBUS_FMT_XRGB8888_4X8_LE :
   1495                                     V4L2_MBUS_FMT_YUV8_1X24;
   1496     if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) {
   1497         ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad);
   1498         return -1;
   1499     }
   1500 
   1501     /*  set crop: sink sub-dev */
   1502     if (gsc_handle->out_mode == GSC_OUT_FIMD)
   1503         sd_crop.pad   = FIMD_SUBDEV_PAD_SINK;
   1504     else
   1505         sd_crop.pad   = MIXER_V_SUBDEV_PAD_SINK;
   1506 
   1507     sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
   1508     if (gsc_handle->out_mode == GSC_OUT_FIMD) {
   1509         sd_crop.rect.left   = gsc_handle->dst_img.x;
   1510         sd_crop.rect.top    = gsc_handle->dst_img.y;
   1511         sd_crop.rect.width  = gsc_handle->dst_img.w;
   1512         sd_crop.rect.height = gsc_handle->dst_img.h;
   1513     } else {
   1514         sd_crop.rect.left   = 0;
   1515         sd_crop.rect.top    = 0;
   1516         sd_crop.rect.width  = gsc_handle->dst_img.w;
   1517         sd_crop.rect.height = gsc_handle->dst_img.h;
   1518     }
   1519     if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) {
   1520             ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad);
   1521             return -1;
   1522     }
   1523 
   1524     if (gsc_handle->out_mode != GSC_OUT_FIMD) {
   1525         sd_fmt.pad   = MIXER_V_SUBDEV_PAD_SOURCE;
   1526         sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
   1527         sd_fmt.format.width  = gsc_handle->dst_img.w + gsc_handle->dst_img.x*2;
   1528         sd_fmt.format.height = gsc_handle->dst_img.h + gsc_handle->dst_img.y*2;
   1529         sd_fmt.format.code   = V4L2_MBUS_FMT_XRGB8888_4X8_LE;
   1530         if (exynos_subdev_s_fmt(gsc_handle->sink_sd_entity->fd, &sd_fmt) < 0) {
   1531             ALOGE("%s::sink:set format failed (PAD=%d)", __func__, sd_fmt.pad);
   1532             return -1;
   1533         }
   1534 
   1535         sd_fmt.pad   = MIXER_V_SUBDEV_PAD_SOURCE;
   1536         sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
   1537         sd_crop.rect.left   = gsc_handle->dst_img.x;
   1538         sd_crop.rect.top    = gsc_handle->dst_img.y;
   1539         sd_crop.rect.width  = gsc_handle->dst_img.w;
   1540         sd_crop.rect.height = gsc_handle->dst_img.h;
   1541         if (exynos_subdev_s_crop(gsc_handle->sink_sd_entity->fd, &sd_crop) < 0) {
   1542             ALOGE("%s::sink: subdev set crop failed(PAD=%d)", __func__, sd_crop.pad);
   1543             return -1;
   1544         }
   1545     }
   1546 
   1547     /*set GSC ctrls */
   1548     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_ROTATE, rotate) < 0) {
   1549         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_ROTATE: %d) failed", __func__,  rotate);
   1550         return -1;
   1551     }
   1552 
   1553     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_HFLIP, hflip) < 0) {
   1554         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_HFLIP: %d) failed", __func__,  hflip);
   1555         return -1;
   1556     }
   1557 
   1558     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_VFLIP, vflip) < 0) {
   1559         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_VFLIP: %d) failed", __func__,  vflip);
   1560         return -1;
   1561     }
   1562 
   1563      if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CACHEABLE, 1) < 0) {
   1564         ALOGE("%s:: exynos_v4l2_s_ctrl (V4L2_CID_CACHEABLE: 1) failed", __func__);
   1565         return -1;
   1566     }
   1567 
   1568     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd,
   1569         V4L2_CID_CONTENT_PROTECTION, gsc_handle->src_img.drmMode) < 0) {
   1570         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail", __func__);
   1571         return -1;
   1572     }
   1573 
   1574     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_vd_entity->fd, V4L2_CID_CSC_RANGE,
   1575             csc_range)) {
   1576         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CSC_RANGE: %d) fail", __func__,
   1577                 csc_range);
   1578         return -1;
   1579     }
   1580 
   1581       /* set src format  :GSC video dev*/
   1582     fmt.type  = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1583     fmt.fmt.pix_mp.width            = gsc_handle->src_img.fw;
   1584     fmt.fmt.pix_mp.height           = gsc_handle->src_img.fh;
   1585     fmt.fmt.pix_mp.pixelformat    = src_color_space;
   1586     fmt.fmt.pix_mp.field              = V4L2_FIELD_NONE;
   1587     fmt.fmt.pix_mp.num_planes   = src_planes;
   1588 
   1589     if (exynos_v4l2_s_fmt(gsc_handle->gsc_vd_entity->fd, &fmt) < 0) {
   1590             ALOGE("%s::videodev set format failed", __func__);
   1591             return -1;
   1592     }
   1593 
   1594     /* set src crop info :GSC video dev*/
   1595     crop.type     = fmt.type;
   1596     crop.c.left    = gsc_handle->src_img.x;
   1597     crop.c.top     = gsc_handle->src_img.y;
   1598     crop.c.width  = gsc_handle->src_img.w;
   1599     crop.c.height = gsc_handle->src_img.h;
   1600 
   1601     if (exynos_v4l2_s_crop(gsc_handle->gsc_vd_entity->fd, &crop) < 0) {
   1602         ALOGE("%s::videodev set crop failed", __func__);
   1603         return -1;
   1604     }
   1605 
   1606     reqbuf.type   = fmt.type;
   1607     reqbuf.memory = V4L2_MEMORY_DMABUF;
   1608     reqbuf.count  = MAX_BUFFERS_GSCALER_OUT;
   1609 
   1610     if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) {
   1611         ALOGE("%s::request buffers failed", __func__);
   1612         return -1;
   1613     }
   1614 
   1615     Exynos_gsc_Out();
   1616 
   1617     return 0;
   1618 }
   1619 
   1620 static int exynos_gsc_out_run(void *handle,
   1621     exynos_gsc_img *src_img)
   1622 {
   1623     struct GSC_HANDLE *gsc_handle;
   1624     struct v4l2_plane  planes[NUM_OF_GSC_PLANES];
   1625     struct v4l2_buffer buf;
   1626     int32_t      src_color_space;
   1627     int32_t      src_planes;
   1628     int             i;
   1629     unsigned int plane_size[NUM_OF_GSC_PLANES];
   1630 
   1631     gsc_handle = (struct GSC_HANDLE *)handle;
   1632     if (handle == NULL) {
   1633         ALOGE("%s::handle == NULL() fail", __func__);
   1634         return -1;
   1635     }
   1636 
   1637     /* All buffers have been queued, dequeue one */
   1638     if (gsc_handle->src.qbuf_cnt == MAX_BUFFERS_GSCALER_OUT) {
   1639         memset(&buf, 0, sizeof(struct v4l2_buffer));
   1640         for (i = 0; i < MAX_BUFFERS_GSCALER_OUT; i++)
   1641             memset(&planes[i], 0, sizeof(struct v4l2_plane));
   1642 
   1643         buf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1644         buf.memory   = V4L2_MEMORY_DMABUF;
   1645         buf.length   = src_planes;
   1646         buf.m.planes = planes;
   1647 
   1648         if (exynos_v4l2_dqbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) {
   1649             ALOGE("%s::dequeue buffer failed (index=%d)(mSrcBufNum=%d)", __func__,
   1650                 gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT);
   1651             return -1;
   1652         }
   1653         gsc_handle->src.qbuf_cnt--;
   1654     }
   1655 
   1656     memset(&buf, 0, sizeof(struct v4l2_buffer));
   1657     for (i = 0; i < NUM_OF_GSC_PLANES; i++)
   1658         memset(&planes[i], 0, sizeof(struct v4l2_plane));
   1659 
   1660     src_color_space = HAL_PIXEL_FORMAT_2_V4L2_PIX(gsc_handle->src_img.format);
   1661     src_planes = get_yuv_planes(src_color_space);
   1662     src_planes = (src_planes == -1) ? 1 : src_planes;
   1663 
   1664     buf.type     = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1665     buf.memory   = V4L2_MEMORY_DMABUF;
   1666     buf.flags    = V4L2_BUF_FLAG_USE_SYNC;
   1667     buf.length   = src_planes;
   1668     buf.index    = gsc_handle->src.src_buf_idx;
   1669     buf.m.planes = planes;
   1670     buf.reserved = src_img->acquireFenceFd;
   1671 
   1672     gsc_handle->src.addr[0] = src_img->yaddr;
   1673     gsc_handle->src.addr[1] = src_img->uaddr;
   1674     gsc_handle->src.addr[2] = src_img->vaddr;
   1675 
   1676     if (get_plane_size(src_color_space, plane_size,
   1677         gsc_handle->src_img.fw * gsc_handle->src_img.fh, src_planes) != true) {
   1678         ALOGE("%s:get_plane_size:fail", __func__);
   1679         return -1;
   1680     }
   1681 
   1682     for (i = 0; i < buf.length; i++) {
   1683         buf.m.planes[i].m.fd = (int)gsc_handle->src.addr[i];
   1684         buf.m.planes[i].length    = plane_size[i];
   1685         buf.m.planes[i].bytesused = plane_size[i];
   1686     }
   1687 
   1688     /* Queue the buf */
   1689     if (exynos_v4l2_qbuf(gsc_handle->gsc_vd_entity->fd, &buf) < 0) {
   1690         ALOGE("%s::queue buffer failed (index=%d)(mSrcBufNum=%d)", __func__,
   1691             gsc_handle->src.src_buf_idx, MAX_BUFFERS_GSCALER_OUT);
   1692         return -1;
   1693     }
   1694     gsc_handle->src.src_buf_idx++;
   1695     gsc_handle->src.src_buf_idx = gsc_handle->src.src_buf_idx % MAX_BUFFERS_GSCALER_OUT;
   1696     gsc_handle->src.qbuf_cnt++;
   1697 
   1698     if (gsc_handle->src.stream_on == false) {
   1699         if (exynos_v4l2_streamon(gsc_handle->gsc_vd_entity->fd, buf.type) < 0) {
   1700             ALOGE("%s::stream on failed", __func__);
   1701             return -1;
   1702         }
   1703         gsc_handle->src.stream_on = true;
   1704     }
   1705 
   1706     src_img->releaseFenceFd = buf.reserved;
   1707     return 0;
   1708 }
   1709 
   1710 int exynos_gsc_out_stop(void *handle)
   1711 {
   1712     struct GSC_HANDLE *gsc_handle;
   1713     struct v4l2_requestbuffers reqbuf;
   1714     struct v4l2_buffer buf;
   1715     struct v4l2_plane  planes[NUM_OF_GSC_PLANES];
   1716     int i;
   1717 
   1718     Exynos_gsc_In();
   1719 
   1720     gsc_handle = (struct GSC_HANDLE *)handle;
   1721     if (handle == NULL) {
   1722         ALOGE("%s::handle == NULL() fail", __func__);
   1723         return -1;
   1724     }
   1725 
   1726     if (gsc_handle->src.stream_on == true) {
   1727         if (exynos_v4l2_streamoff(gsc_handle->gsc_vd_entity->fd,
   1728                                 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
   1729             ALOGE("%s::stream off failed", __func__);
   1730             return -1;
   1731         }
   1732         gsc_handle->src.stream_on = false;
   1733     }
   1734 
   1735     gsc_handle->src.src_buf_idx = 0;
   1736     gsc_handle->src.qbuf_cnt = 0;
   1737 
   1738     reqbuf.type   = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1739     reqbuf.memory = V4L2_MEMORY_DMABUF;
   1740     reqbuf.count  = 0;
   1741 
   1742     if (exynos_v4l2_reqbufs(gsc_handle->gsc_vd_entity->fd, &reqbuf) < 0) {
   1743         ALOGE("%s::request buffers failed", __func__);
   1744         return -1;
   1745     }
   1746 
   1747     Exynos_gsc_Out();
   1748 
   1749     return 0;
   1750 }
   1751 
   1752 static int exynos_gsc_m2m_run_core(void *handle)
   1753 {
   1754     struct GSC_HANDLE *gsc_handle;
   1755     bool is_dirty;
   1756     bool is_drm;
   1757 
   1758     gsc_handle = (struct GSC_HANDLE *)handle;
   1759 
   1760     Exynos_gsc_In();
   1761 
   1762     if (handle == NULL) {
   1763         ALOGE("%s::handle == NULL() fail", __func__);
   1764         return -1;
   1765     }
   1766 
   1767     is_dirty = gsc_handle->src.dirty || gsc_handle->dst.dirty;
   1768     is_drm = gsc_handle->src.mode_drm;
   1769 
   1770     if (is_dirty && (gsc_handle->src.mode_drm != gsc_handle->dst.mode_drm)) {
   1771         ALOGE("%s: drm mode mismatch between src and dst, gsc%d (s=%d d=%d)",
   1772               __func__, gsc_handle->gsc_id, gsc_handle->src.mode_drm,
   1773               gsc_handle->dst.mode_drm);
   1774         return -1;
   1775     } else if (is_drm && !gsc_handle->allow_drm) {
   1776         ALOGE("%s: drm mode is not supported on gsc%d", __func__,
   1777               gsc_handle->gsc_id);
   1778         return -1;
   1779     }
   1780 
   1781     if (m_exynos_gsc_check_src_size(&gsc_handle->src.width, &gsc_handle->src.height,
   1782                                     &gsc_handle->src.crop_left, &gsc_handle->src.crop_top,
   1783                                     &gsc_handle->src.crop_width, &gsc_handle->src.crop_height,
   1784                                     gsc_handle->src.v4l2_colorformat) == false) {
   1785         ALOGE("%s::m_exynos_gsc_check_src_size() fail", __func__);
   1786         return -1;
   1787     }
   1788 
   1789     if (m_exynos_gsc_check_dst_size(&gsc_handle->dst.width, &gsc_handle->dst.height,
   1790                                     &gsc_handle->dst.crop_left, &gsc_handle->dst.crop_top,
   1791                                     &gsc_handle->dst.crop_width, &gsc_handle->dst.crop_height,
   1792                                     gsc_handle->dst.v4l2_colorformat,
   1793                                     gsc_handle->dst.rotation) == false) {
   1794         ALOGE("%s::m_exynos_gsc_check_dst_size() fail", __func__);
   1795         return -1;
   1796     }
   1797 
   1798     /* dequeue buffers from previous work if necessary */
   1799     if (gsc_handle->src.stream_on == true) {
   1800         if (exynos_gsc_m2m_wait_frame_done(handle) < 0) {
   1801             ALOGE("%s::exynos_gsc_m2m_wait_frame_done fail", __func__);
   1802             return -1;
   1803         }
   1804     }
   1805 
   1806     /*
   1807      * need to set the content protection flag before doing reqbufs
   1808      * in set_format
   1809      */
   1810     if (is_dirty && gsc_handle->allow_drm && is_drm) {
   1811         if (exynos_v4l2_s_ctrl(gsc_handle->gsc_fd,
   1812                                V4L2_CID_CONTENT_PROTECTION, is_drm) < 0) {
   1813             ALOGE("%s::exynos_v4l2_s_ctrl() fail", __func__);
   1814             return -1;
   1815         }
   1816     }
   1817 
   1818     /*
   1819      * from this point on, we have to ensure to call stop to clean up whatever
   1820      * state we have set.
   1821      */
   1822 
   1823     if (gsc_handle->src.dirty) {
   1824         if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->src) == false) {
   1825             ALOGE("%s::m_exynos_gsc_set_format(src) fail", __func__);
   1826             goto done;
   1827         }
   1828         gsc_handle->src.dirty = false;
   1829     }
   1830 
   1831     if (gsc_handle->dst.dirty) {
   1832         if (m_exynos_gsc_set_format(gsc_handle->gsc_fd, &gsc_handle->dst) == false) {
   1833             ALOGE("%s::m_exynos_gsc_set_format(dst) fail", __func__);
   1834             goto done;
   1835         }
   1836         gsc_handle->dst.dirty = false;
   1837     }
   1838 
   1839     /* if we are enabling drm, make sure to enable hw protection.
   1840      * Need to do this before queuing buffers so that the mmu is reserved
   1841      * and power domain is kept on.
   1842      */
   1843     if (is_dirty && gsc_handle->allow_drm && is_drm) {
   1844         unsigned int protect_id = 0;
   1845 
   1846         if (gsc_handle->gsc_id == 0) {
   1847             protect_id = CP_PROTECT_GSC0;
   1848         } else if (gsc_handle->gsc_id == 3) {
   1849             protect_id = CP_PROTECT_GSC3;
   1850         } else {
   1851             ALOGE("%s::invalid gscaler id %d for content protection", __func__,
   1852                   gsc_handle->gsc_id);
   1853             goto done;
   1854         }
   1855 
   1856         if (CP_Enable_Path_Protection(protect_id) != 0) {
   1857             ALOGE("%s::CP_Enable_Path_Protection failed", __func__);
   1858             goto done;
   1859         }
   1860         gsc_handle->protection_enabled = true;
   1861     }
   1862 
   1863     if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->src) == false) {
   1864         ALOGE("%s::m_exynos_gsc_set_addr(src) fail", __func__);
   1865         goto done;
   1866     }
   1867 
   1868     if (m_exynos_gsc_set_addr(gsc_handle->gsc_fd, &gsc_handle->dst) == false) {
   1869         ALOGE("%s::m_exynos_gsc_set_addr(dst) fail", __func__);
   1870         goto done;
   1871     }
   1872 
   1873     if (gsc_handle->src.stream_on == false) {
   1874         if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) {
   1875             ALOGE("%s::exynos_v4l2_streamon(src) fail", __func__);
   1876             goto done;
   1877         }
   1878         gsc_handle->src.stream_on = true;
   1879     }
   1880 
   1881     if (gsc_handle->dst.stream_on == false) {
   1882         if (exynos_v4l2_streamon(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) {
   1883             ALOGE("%s::exynos_v4l2_streamon(dst) fail", __func__);
   1884             goto done;
   1885         }
   1886         gsc_handle->dst.stream_on = true;
   1887     }
   1888 
   1889     Exynos_gsc_Out();
   1890 
   1891     return 0;
   1892 
   1893 done:
   1894     exynos_gsc_m2m_stop(handle);
   1895     return -1;
   1896 }
   1897 
   1898 static int exynos_gsc_m2m_wait_frame_done(void *handle)
   1899 {
   1900     struct GSC_HANDLE *gsc_handle;
   1901 
   1902     gsc_handle = (struct GSC_HANDLE *)handle;
   1903 
   1904     Exynos_gsc_In();
   1905 
   1906     if (handle == NULL) {
   1907         ALOGE("%s::handle == NULL() fail", __func__);
   1908         return -1;
   1909     }
   1910 
   1911     if ((gsc_handle->src.stream_on == false) || (gsc_handle->dst.stream_on == false)) {
   1912         ALOGE("%s:: src_strean_on or dst_stream_on are false", __func__);
   1913         return -1;
   1914     }
   1915 
   1916     if (gsc_handle->src.buffer_queued) {
   1917         if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->src.buffer) < 0) {
   1918             ALOGE("%s::exynos_v4l2_dqbuf(src) fail", __func__);
   1919             return -1;
   1920         }
   1921         gsc_handle->src.buffer_queued = false;
   1922     }
   1923 
   1924     if (gsc_handle->dst.buffer_queued) {
   1925         if (exynos_v4l2_dqbuf(gsc_handle->gsc_fd, &gsc_handle->dst.buffer) < 0) {
   1926             ALOGE("%s::exynos_v4l2_dqbuf(dst) fail", __func__);
   1927             return -1;
   1928         }
   1929         gsc_handle->dst.buffer_queued = false;
   1930     }
   1931 
   1932     Exynos_gsc_Out();
   1933 
   1934     return 0;
   1935 }
   1936 
   1937 static int exynos_gsc_m2m_stop(void *handle)
   1938 {
   1939     struct GSC_HANDLE *gsc_handle;
   1940     struct v4l2_requestbuffers req_buf;
   1941     int ret = 0;
   1942 
   1943     gsc_handle = (struct GSC_HANDLE *)handle;
   1944 
   1945     Exynos_gsc_In();
   1946 
   1947     if (!gsc_handle->src.stream_on && !gsc_handle->dst.stream_on) {
   1948         /* wasn't streaming, return success */
   1949         return 0;
   1950     } else if (gsc_handle->src.stream_on != gsc_handle->dst.stream_on) {
   1951         ALOGE("%s: invalid state, queue stream state doesn't match (%d != %d)",
   1952               __func__, gsc_handle->src.stream_on, gsc_handle->dst.stream_on);
   1953         ret = -1;
   1954     }
   1955 
   1956     /*
   1957      * we need to plow forward on errors below to make sure that if we had
   1958      * turned on content protection on secure side, we turn it off.
   1959      *
   1960      * also, if we only failed to turn on one of the streams, we'll turn
   1961      * the other one off correctly.
   1962      */
   1963     if (gsc_handle->src.stream_on == true) {
   1964         if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->src.buf_type) < 0) {
   1965             ALOGE("%s::exynos_v4l2_streamoff(src) fail", __func__);
   1966             ret = -1;
   1967         }
   1968         gsc_handle->src.stream_on = false;
   1969     }
   1970 
   1971 
   1972     if (gsc_handle->dst.stream_on == true) {
   1973         if (exynos_v4l2_streamoff(gsc_handle->gsc_fd, gsc_handle->dst.buf_type) < 0) {
   1974             ALOGE("%s::exynos_v4l2_streamoff(dst) fail", __func__);
   1975             ret = -1;
   1976         }
   1977         gsc_handle->dst.stream_on = false;
   1978     }
   1979 
   1980     /* if drm is enabled */
   1981     if (gsc_handle->allow_drm && gsc_handle->protection_enabled) {
   1982         unsigned int protect_id = 0;
   1983 
   1984         if (gsc_handle->gsc_id == 0)
   1985             protect_id = CP_PROTECT_GSC0;
   1986         else if (gsc_handle->gsc_id == 3)
   1987             protect_id = CP_PROTECT_GSC3;
   1988 
   1989         CP_Disable_Path_Protection(protect_id);
   1990         gsc_handle->protection_enabled = false;
   1991     }
   1992 
   1993     if (exynos_v4l2_s_ctrl(gsc_handle->gsc_fd,
   1994                            V4L2_CID_CONTENT_PROTECTION, 0) < 0) {
   1995         ALOGE("%s::exynos_v4l2_s_ctrl(V4L2_CID_CONTENT_PROTECTION) fail",
   1996               __func__);
   1997         ret = -1;
   1998     }
   1999 
   2000     /* src: clear_buf */
   2001     req_buf.count  = 0;
   2002     req_buf.type   = gsc_handle->src.buf_type;
   2003     req_buf.memory = V4L2_MEMORY_DMABUF;
   2004     if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) {
   2005         ALOGE("%s::exynos_v4l2_reqbufs():src: fail", __func__);
   2006         ret = -1;
   2007     }
   2008 
   2009     /* dst: clear_buf */
   2010     req_buf.count  = 0;
   2011     req_buf.type   = gsc_handle->dst.buf_type;
   2012     req_buf.memory = V4L2_MEMORY_DMABUF;
   2013     if (exynos_v4l2_reqbufs(gsc_handle->gsc_fd, &req_buf) < 0) {
   2014         ALOGE("%s::exynos_v4l2_reqbufs():dst: fail", __func__);
   2015         ret = -1;
   2016     }
   2017 
   2018     Exynos_gsc_Out();
   2019 
   2020     return ret;
   2021 }
   2022 
   2023 int exynos_gsc_convert(
   2024     void *handle)
   2025 {
   2026     struct GSC_HANDLE *gsc_handle;
   2027     int ret    = -1;
   2028     gsc_handle = (struct GSC_HANDLE *)handle;
   2029 
   2030     Exynos_gsc_In();
   2031 
   2032     if (handle == NULL) {
   2033         ALOGE("%s::handle == NULL() fail", __func__);
   2034         return -1;
   2035     }
   2036 
   2037     exynos_mutex_lock(gsc_handle->op_mutex);
   2038 
   2039     if (gsc_handle->flag_local_path == true) {
   2040         ALOGE("%s::this exynos_gsc is connected by another hw internaly. So, don't call exynos_gsc_convert()", __func__);
   2041             goto done;
   2042         }
   2043 
   2044     if (exynos_gsc_m2m_run_core(handle) < 0) {
   2045         ALOGE("%s::exynos_gsc_run_core fail", __func__);
   2046             goto done;
   2047         }
   2048 
   2049     if (exynos_gsc_m2m_wait_frame_done(handle) < 0) {
   2050         ALOGE("%s::exynos_gsc_m2m_wait_frame_done", __func__);
   2051         goto done;
   2052     }
   2053 
   2054     if (gsc_handle->src.releaseFenceFd >= 0) {
   2055         close(gsc_handle->src.releaseFenceFd);
   2056         gsc_handle->src.releaseFenceFd = -1;
   2057     }
   2058 
   2059     if (gsc_handle->dst.releaseFenceFd >= 0) {
   2060         close(gsc_handle->dst.releaseFenceFd);
   2061         gsc_handle->dst.releaseFenceFd = -1;
   2062     }
   2063 
   2064     if (exynos_gsc_m2m_stop(handle) < 0) {
   2065         ALOGE("%s::exynos_gsc_m2m_stop", __func__);
   2066         goto done;
   2067     }
   2068 
   2069     ret = 0;
   2070 
   2071 done:
   2072     if (gsc_handle->flag_exclusive_open == false) {
   2073         if (gsc_handle->flag_local_path == false)
   2074             exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
   2075     }
   2076 
   2077     exynos_mutex_unlock(gsc_handle->op_mutex);
   2078 
   2079     Exynos_gsc_Out();
   2080 
   2081     return ret;
   2082 }
   2083 
   2084 int exynos_gsc_m2m_run(void *handle,
   2085     exynos_gsc_img *src_img,
   2086     exynos_gsc_img *dst_img)
   2087 {
   2088     struct GSC_HANDLE *gsc_handle = handle;
   2089     void *addr[3] = {NULL, NULL, NULL};
   2090     int ret = 0;
   2091 
   2092     Exynos_gsc_In();
   2093 
   2094     addr[0] = (void *)src_img->yaddr;
   2095     addr[1] = (void *)src_img->uaddr;
   2096     addr[2] = (void *)src_img->vaddr;
   2097     ret = exynos_gsc_set_src_addr(handle, addr, src_img->acquireFenceFd);
   2098     if (ret < 0) {
   2099         ALOGE("%s::fail: exynos_gsc_set_src_addr[%x %x %x]", __func__,
   2100             (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]);
   2101         return -1;
   2102     }
   2103 
   2104     addr[0] = (void *)dst_img->yaddr;
   2105     addr[1] = (void *)dst_img->uaddr;
   2106     addr[2] = (void *)dst_img->vaddr;
   2107     ret = exynos_gsc_set_dst_addr(handle, addr, dst_img->acquireFenceFd);
   2108     if (ret < 0) {
   2109         ALOGE("%s::fail: exynos_gsc_set_dst_addr[%x %x %x]", __func__,
   2110             (unsigned int)addr[0], (unsigned int)addr[1], (unsigned int)addr[2]);
   2111         return -1;
   2112     }
   2113 
   2114     ret = exynos_gsc_m2m_run_core(handle);
   2115      if (ret < 0) {
   2116         ALOGE("%s::fail: exynos_gsc_m2m_run_core", __func__);
   2117         return -1;
   2118     }
   2119 
   2120     if (src_img->acquireFenceFd >= 0) {
   2121         close(src_img->acquireFenceFd);
   2122         src_img->acquireFenceFd = -1;
   2123     }
   2124 
   2125     if (dst_img->acquireFenceFd >= 0) {
   2126         close(dst_img->acquireFenceFd);
   2127         dst_img->acquireFenceFd = -1;
   2128     }
   2129 
   2130     src_img->releaseFenceFd = gsc_handle->src.releaseFenceFd;
   2131     dst_img->releaseFenceFd = gsc_handle->dst.releaseFenceFd;
   2132 
   2133     Exynos_gsc_Out();
   2134 
   2135     return 0;
   2136 }
   2137 
   2138 int exynos_gsc_config_exclusive(void *handle,
   2139     exynos_gsc_img *src_img,
   2140     exynos_gsc_img *dst_img)
   2141 {
   2142 
   2143     Exynos_gsc_In();
   2144 
   2145      struct GSC_HANDLE *gsc_handle;
   2146     int ret = 0;
   2147     gsc_handle = (struct GSC_HANDLE *)handle;
   2148     if (handle == NULL) {
   2149         ALOGE("%s::handle == NULL() fail", __func__);
   2150         return -1;
   2151     }
   2152 
   2153     switch (gsc_handle->gsc_mode) {
   2154     case GSC_M2M_MODE:
   2155         ret = exynos_gsc_m2m_config(handle, src_img, dst_img);
   2156         break;
   2157     case GSC_OUTPUT_MODE:
   2158         ret = exynos_gsc_out_config(handle, src_img, dst_img);
   2159         break;
   2160     case  GSC_CAPTURE_MODE:
   2161         //to do
   2162         break;
   2163     default:
   2164         break;
   2165     }
   2166 
   2167     Exynos_gsc_Out();
   2168 
   2169     return ret;
   2170 
   2171 }
   2172 
   2173 int exynos_gsc_run_exclusive(void *handle,
   2174     exynos_gsc_img *src_img,
   2175     exynos_gsc_img *dst_img)
   2176 {
   2177     struct GSC_HANDLE *gsc_handle;
   2178     int ret = 0;
   2179 
   2180     Exynos_gsc_In();
   2181 
   2182     gsc_handle = (struct GSC_HANDLE *)handle;
   2183     if (handle == NULL) {
   2184         ALOGE("%s::handle == NULL() fail", __func__);
   2185         return -1;
   2186     }
   2187 
   2188     switch (gsc_handle->gsc_mode) {
   2189     case GSC_M2M_MODE:
   2190         ret = exynos_gsc_m2m_run(handle, src_img, dst_img);
   2191         break;
   2192     case GSC_OUTPUT_MODE:
   2193         ret = exynos_gsc_out_run(handle, src_img);
   2194         break;
   2195     case  GSC_CAPTURE_MODE:
   2196         //to do
   2197         break;
   2198     default:
   2199         break;
   2200     }
   2201 
   2202     Exynos_gsc_Out();
   2203 
   2204     return ret;
   2205 }
   2206 
   2207 int exynos_gsc_wait_frame_done_exclusive(void *handle)
   2208 {
   2209     struct GSC_HANDLE *gsc_handle;
   2210     int ret = 0;
   2211     gsc_handle = (struct GSC_HANDLE *)handle;
   2212 
   2213     Exynos_gsc_In();
   2214 
   2215     if (handle == NULL) {
   2216         ALOGE("%s::handle == NULL() fail", __func__);
   2217         return -1;
   2218     }
   2219 
   2220     if (gsc_handle->gsc_mode == GSC_M2M_MODE)
   2221         ret = exynos_gsc_m2m_wait_frame_done(handle);
   2222 
   2223     Exynos_gsc_Out();
   2224 
   2225     return ret;
   2226 }
   2227 
   2228 int exynos_gsc_stop_exclusive(void *handle)
   2229 {
   2230     struct GSC_HANDLE *gsc_handle;
   2231     int ret = 0;
   2232     gsc_handle = (struct GSC_HANDLE *)handle;
   2233 
   2234     Exynos_gsc_In();
   2235 
   2236     if (handle == NULL) {
   2237         ALOGE("%s::handle == NULL() fail", __func__);
   2238         return -1;
   2239     }
   2240 
   2241     switch (gsc_handle->gsc_mode) {
   2242     case GSC_M2M_MODE:
   2243         ret = exynos_gsc_m2m_stop(handle);
   2244         break;
   2245     case GSC_OUTPUT_MODE:
   2246         ret = exynos_gsc_out_stop(handle);
   2247         break;
   2248     case  GSC_CAPTURE_MODE:
   2249         //to do
   2250         break;
   2251     default:
   2252         break;
   2253     }
   2254 
   2255     Exynos_gsc_Out();
   2256 
   2257     return ret;
   2258 }
   2259 
   2260 int exynos_gsc_connect(
   2261     void *handle,
   2262     void *hw)
   2263 {
   2264     struct GSC_HANDLE *gsc_handle;
   2265     int ret    = -1;
   2266     gsc_handle = (struct GSC_HANDLE *)handle;
   2267 
   2268     Exynos_gsc_In();
   2269 
   2270     if (handle == NULL) {
   2271         ALOGE("%s::handle == NULL() fail", __func__);
   2272         return -1;
   2273     }
   2274 
   2275     exynos_mutex_lock(gsc_handle->op_mutex);
   2276 
   2277     gsc_handle->flag_local_path = true;
   2278 
   2279     if (exynos_mutex_trylock(gsc_handle->cur_obj_mutex) == false) {
   2280         if (m_exynos_gsc_find_and_trylock_and_create(gsc_handle) == false) {
   2281             ALOGE("%s::m_exynos_gsc_find_and_trylock_and_create() fail", __func__);
   2282             goto done;
   2283         }
   2284     }
   2285 
   2286     ret = 0;
   2287 
   2288     Exynos_gsc_Out();
   2289 
   2290 done:
   2291     exynos_mutex_unlock(gsc_handle->op_mutex);
   2292 
   2293     return ret;
   2294 }
   2295 
   2296 int exynos_gsc_disconnect(
   2297     void *handle,
   2298     void *hw)
   2299 {
   2300     struct GSC_HANDLE *gsc_handle;
   2301     gsc_handle = (struct GSC_HANDLE *)handle;
   2302 
   2303     Exynos_gsc_In();
   2304 
   2305     if (handle == NULL) {
   2306         ALOGE("%s::handle == NULL() fail", __func__);
   2307         return -1;
   2308     }
   2309 
   2310     exynos_mutex_lock(gsc_handle->op_mutex);
   2311 
   2312     gsc_handle->flag_local_path = false;
   2313 
   2314     exynos_mutex_unlock(gsc_handle->cur_obj_mutex);
   2315 
   2316     exynos_mutex_unlock(gsc_handle->op_mutex);
   2317 
   2318     Exynos_gsc_Out();
   2319 
   2320     return 0;
   2321 }
   2322