Home | History | Annotate | Download | only in mm-camera-interface
      1 /*
      2 Copyright (c) 2011, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are
      6 met:
      7     * Redistributions of source code must retain the above copyright
      8       notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above
     10       copyright notice, this list of conditions and the following
     11       disclaimer in the documentation and/or other materials provided
     12       with the distribution.
     13     * Neither the name of The Linux Foundation nor the names of its
     14       contributors may be used to endorse or promote products derived
     15       from this software without specific prior written permission.
     16 
     17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <sys/mman.h>
     31 #include <fcntl.h>
     32 #include <stdio.h>
     33 #include <unistd.h>
     34 #include <stdlib.h>
     35 #include <ctype.h>
     36 #include <errno.h>
     37 #include <string.h>
     38 #include "mm_camera_dbg.h"
     39 #include <time.h>
     40 #include "mm_camera_interface2.h"
     41 #include <linux/msm_ion.h>
     42 
     43 #define MM_CAMERA_PROFILE 1
     44 
     45 struct file;
     46 struct inode;
     47 struct vm_area_struct;
     48 
     49 /*===========================================================================
     50  * FUNCTION    - do_mmap -
     51  *
     52  * DESCRIPTION:  retured virtual addresss
     53  *==========================================================================*/
     54 uint8_t *mm_camera_do_mmap(uint32_t size, int *pmemFd)
     55 {
     56     void *ret; /* returned virtual address */
     57     int  pmem_fd = open("/dev/pmem_adsp", O_RDWR|O_SYNC);
     58 
     59     if (pmem_fd <= 0) {
     60         CDBG("do_mmap: Open device /dev/pmem_adsp failed!\n");
     61         return NULL;
     62     }
     63     /* to make it page size aligned */
     64     size = (size + 4095) & (~4095);
     65   ret = mmap(NULL,
     66     size,
     67     PROT_READ  | PROT_WRITE,
     68     MAP_SHARED,
     69     pmem_fd,
     70     0);
     71     if (ret == MAP_FAILED) {
     72         CDBG("do_mmap: pmem mmap() failed: %s (%d)\n", strerror(errno), errno);
     73         close(pmem_fd);
     74         return NULL;
     75     }
     76     CDBG("do_mmap: pmem mmap fd %d ptr %p len %u\n", pmem_fd, ret, size);
     77     *pmemFd = pmem_fd;
     78     return(uint8_t *)ret;
     79 }
     80 
     81 /*===========================================================================
     82  * FUNCTION    - do_munmap -
     83  *
     84  * DESCRIPTION:
     85  *==========================================================================*/
     86 int mm_camera_do_munmap(int pmem_fd, void *addr, size_t size)
     87 {
     88     int rc;
     89 
     90     if (pmem_fd <= 0) {
     91         CDBG("%s:invalid fd=%d\n", __func__, pmem_fd);
     92         return -1;
     93     }
     94     size = (size + 4095) & (~4095);
     95     CDBG("munmapped size = %d, virt_addr = 0x%p\n",
     96     size, addr);
     97     rc = (munmap(addr, size));
     98     close(pmem_fd);
     99     CDBG("do_mmap: pmem munmap fd %d ptr %p len %u rc %d\n", pmem_fd, addr,
    100     size, rc);
    101     return rc;
    102 }
    103 
    104 #ifdef USE_ION
    105 uint8_t *mm_camera_do_mmap_ion(int ion_fd, struct ion_allocation_data *alloc,
    106 		     struct ion_fd_data *ion_info_fd, int *mapFd)
    107 {
    108   void *ret; /* returned virtual address */
    109   int rc = 0;
    110   struct ion_handle_data handle_data;
    111 
    112   /* to make it page size aligned */
    113   alloc->len = (alloc->len + 4095) & (~4095);
    114 
    115   rc = ioctl(ion_fd, ION_IOC_ALLOC, alloc);
    116   if (rc < 0) {
    117     CDBG_ERROR("ION allocation failed\n");
    118     goto ION_ALLOC_FAILED;
    119   }
    120 
    121   ion_info_fd->handle = alloc->handle;
    122   rc = ioctl(ion_fd, ION_IOC_SHARE, ion_info_fd);
    123   if (rc < 0) {
    124     CDBG_ERROR("ION map failed %s\n", strerror(errno));
    125     goto ION_MAP_FAILED;
    126   }
    127   *mapFd = ion_info_fd->fd;
    128   ret = mmap(NULL,
    129     alloc->len,
    130     PROT_READ  | PROT_WRITE,
    131     MAP_SHARED,
    132     *mapFd,
    133     0);
    134 
    135   if (ret == MAP_FAILED) {
    136     CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
    137     goto ION_MAP_FAILED;
    138   }
    139 
    140   return ret;
    141 
    142 ION_MAP_FAILED:
    143   handle_data.handle = ion_info_fd->handle;
    144   ioctl(ion_fd, ION_IOC_FREE, &handle_data);
    145 ION_ALLOC_FAILED:
    146   return NULL;
    147 }
    148 
    149 int mm_camera_do_munmap_ion (int ion_fd, struct ion_fd_data *ion_info_fd,
    150                    void *addr, size_t size)
    151 {
    152   int rc = 0;
    153   rc = munmap(addr, size);
    154   close(ion_info_fd->fd);
    155 
    156   struct ion_handle_data handle_data;
    157   handle_data.handle = ion_info_fd->handle;
    158   ioctl(ion_fd, ION_IOC_FREE, &handle_data);
    159   return rc;
    160 }
    161 #endif
    162 
    163 /*============================================================
    164    FUNCTION mm_camera_dump_image
    165    DESCRIPTION:
    166 ==============================================================*/
    167 int mm_camera_dump_image(void *addr, uint32_t size, char *filename)
    168 {
    169   int file_fd = open(filename, O_RDWR | O_CREAT, 0777);
    170 
    171   if (file_fd < 0) {
    172     CDBG_HIGH("%s: cannot open file\n", __func__);
    173 		return -1;
    174 	} else
    175     write(file_fd, addr, size);
    176   close(file_fd);
    177 	CDBG("%s: %s, size=%d\n", __func__, filename, size);
    178 	return 0;
    179 }
    180 
    181 uint32_t mm_camera_get_msm_frame_len(cam_format_t fmt_type,
    182                                      camera_mode_t mode,
    183                                      int width,
    184                                      int height,
    185                                      int image_type,
    186                                      uint8_t *num_planes,
    187                                      uint32_t plane[])
    188 {
    189     uint32_t size;
    190     *num_planes = 0;
    191     int local_height;
    192 
    193     switch (fmt_type) {
    194     case CAMERA_YUV_420_NV12:
    195     case CAMERA_YUV_420_NV21:
    196         *num_planes = 2;
    197         if(CAMERA_MODE_3D == mode) {
    198             size = (uint32_t)(PAD_TO_2K(width*height)*3/2);
    199             plane[0] = PAD_TO_WORD(width*height);
    200         } else {
    201             if (image_type == OUTPUT_TYPE_V) {
    202                 plane[0] = PAD_TO_2K(width * height);
    203                 plane[1] = PAD_TO_2K(width * height/2);
    204             } else if (image_type == OUTPUT_TYPE_P) {
    205                 plane[0] = PAD_TO_WORD(width * height);
    206                 plane[1] = PAD_TO_WORD(width * height/2);
    207             } else {
    208                 plane[0] = PAD_TO_WORD(width * CEILING16(height));
    209                 plane[1] = PAD_TO_WORD(width * CEILING16(height)/2);
    210             }
    211             size = plane[0] + plane[1];
    212         }
    213         break;
    214     case CAMERA_YUV_420_YV12:
    215         if (CAMERA_MODE_3D == mode) {
    216           *num_planes = 1;
    217           size = (uint32_t)(PAD_TO_2K(width*height)*3/2);
    218           plane[0] = PAD_TO_WORD(width*height);
    219         } else {
    220           *num_planes = 3;
    221           plane[0] = PAD_TO_2K(CEILING16(width) * height);
    222           plane[1] = PAD_TO_2K(CEILING16(width/2) * height/2);
    223           plane[2] = PAD_TO_2K(CEILING16(width/2) * height/2);
    224           size = plane[0] + plane[1] + plane[2];
    225        }
    226        break;
    227     case CAMERA_BAYER_SBGGR10:
    228         *num_planes = 1;
    229         plane[0] = PAD_TO_WORD(width * height);
    230         size = plane[0];
    231         break;
    232     case CAMERA_YUV_422_YUYV:
    233         *num_planes = 1;
    234         plane[0] = PAD_TO_WORD(width * height);
    235         size = plane[0];
    236         break;
    237     case CAMERA_YUV_422_NV16:
    238     case CAMERA_YUV_422_NV61:
    239       if( image_type == OUTPUT_TYPE_S || image_type == OUTPUT_TYPE_V) {
    240         local_height = CEILING16(height);
    241       } else {
    242         local_height = height;
    243       }
    244         *num_planes = 2;
    245         plane[0] = PAD_TO_WORD(width * height);
    246         plane[1] = PAD_TO_WORD(width * height);
    247         size = plane[0] + plane[1];
    248         break;
    249     default:
    250         CDBG("%s: format %d not supported.\n",
    251             __func__, fmt_type);
    252         size = 0;
    253     }
    254     CDBG("%s:fmt=%d,image_type=%d,width=%d,height=%d,frame_len=%d\n",
    255         __func__, fmt_type, image_type, width, height, size);
    256     return size;
    257 }
    258 
    259 void mm_camera_util_profile(const char *str)
    260 {
    261 #if (MM_CAMERA_PROFILE)
    262     struct timespec cur_time;
    263 
    264     clock_gettime(CLOCK_REALTIME, &cur_time);
    265     CDBG_HIGH("PROFILE %s: %ld.%09ld\n", str,
    266     cur_time.tv_sec, cur_time.tv_nsec);
    267 #endif
    268 }
    269 
    270 /*===========================================================================
    271  * FUNCTION    - mm_camera_do_mmap_ion -
    272  *
    273  * DESCRIPTION:
    274  *==========================================================================*/
    275 uint8_t *mm_camera_do_mmap_ion(int ion_fd, struct ion_allocation_data *alloc,
    276   struct ion_fd_data *ion_info_fd, int *mapFd)
    277 {
    278   void *ret; /* returned virtual address */
    279   int rc = 0;
    280   struct ion_handle_data handle_data;
    281 
    282   /* to make it page size aligned */
    283   alloc->len = (alloc->len + 4095) & (~4095);
    284 
    285   rc = ioctl(ion_fd, ION_IOC_ALLOC, alloc);
    286   if (rc < 0) {
    287     CDBG_ERROR("ION allocation failed %s\n", strerror(errno));
    288     goto ION_ALLOC_FAILED;
    289   }
    290 
    291   ion_info_fd->handle = alloc->handle;
    292   rc = ioctl(ion_fd, ION_IOC_SHARE, ion_info_fd);
    293   if (rc < 0) {
    294     CDBG_ERROR("ION map failed %s\n", strerror(errno));
    295     goto ION_MAP_FAILED;
    296   }
    297   *mapFd = ion_info_fd->fd;
    298   ret = mmap(NULL,
    299     alloc->len,
    300     PROT_READ  | PROT_WRITE,
    301     MAP_SHARED,
    302     *mapFd,
    303     0);
    304 
    305   if (ret == MAP_FAILED) {
    306     CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
    307     goto ION_MAP_FAILED;
    308   }
    309 
    310   return ret;
    311 
    312 ION_MAP_FAILED:
    313   handle_data.handle = ion_info_fd->handle;
    314   ioctl(ion_fd, ION_IOC_FREE, &handle_data);
    315 ION_ALLOC_FAILED:
    316   return NULL;
    317 }
    318 
    319 /*===========================================================================
    320  * FUNCTION    - mm_camera_do_munmap_ion -
    321  *
    322  * DESCRIPTION:
    323  *==========================================================================*/
    324 int mm_camera_do_munmap_ion (int ion_fd, struct ion_fd_data *ion_info_fd,
    325                    void *addr, size_t size)
    326 {
    327   int rc = 0;
    328   rc = munmap(addr, size);
    329   close(ion_info_fd->fd);
    330 
    331   struct ion_handle_data handle_data;
    332   handle_data.handle = ion_info_fd->handle;
    333   ioctl(ion_fd, ION_IOC_FREE, &handle_data);
    334   return rc;
    335 }
    336