1 /*
2 Copyright (c) 2011-2012, 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_interface.h"
41 #include <linux/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  *==========================================================================*/
mm_camera_do_mmap(uint32_t size,int * pmemFd)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  *==========================================================================*/
mm_camera_do_munmap(int pmem_fd,void * addr,size_t size)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
mm_camera_do_mmap_ion(int ion_fd,struct ion_allocation_data * alloc,struct ion_fd_data * ion_info_fd,int * mapFd)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 
mm_camera_do_munmap_ion(int ion_fd,struct ion_fd_data * ion_info_fd,void * addr,size_t size)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 ==============================================================*/
mm_camera_dump_image(void * addr,uint32_t size,char * filename)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 
mm_camera_get_msm_frame_len(cam_format_t fmt_type,camera_mode_t mode,int width,int height,int image_type,uint8_t * num_planes,uint32_t plane[])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_BAYER_SBGGR10:
215         *num_planes = 1;
216         plane[0] = PAD_TO_WORD(width * height);
217         size = plane[0];
218         break;
219     case CAMERA_YUV_422_NV16:
220     case CAMERA_YUV_422_NV61:
221       if( image_type == OUTPUT_TYPE_S || image_type == OUTPUT_TYPE_V) {
222         local_height = CEILING16(height);
223       } else {
224         local_height = height;
225       }
226         *num_planes = 2;
227         plane[0] = PAD_TO_WORD(width * height);
228         plane[1] = PAD_TO_WORD(width * height);
229         size = plane[0] + plane[1];
230         break;
231     default:
232         CDBG("%s: format %d not supported.\n",
233             __func__, fmt_type);
234         size = 0;
235     }
236     CDBG("%s:fmt=%d,image_type=%d,width=%d,height=%d,frame_len=%d\n",
237         __func__, fmt_type, image_type, width, height, size);
238     return size;
239 }
240 
mm_camera_util_profile(const char * str)241 void mm_camera_util_profile(const char *str)
242 {
243 #if (MM_CAMERA_PROFILE)
244     struct timespec cur_time;
245 
246     clock_gettime(CLOCK_REALTIME, &cur_time);
247     CDBG_HIGH("PROFILE %s: %ld.%09ld\n", str,
248     cur_time.tv_sec, cur_time.tv_nsec);
249 #endif
250 }
251 
252 /*===========================================================================
253  * FUNCTION    - mm_camera_do_mmap_ion -
254  *
255  * DESCRIPTION:
256  *==========================================================================*/
mm_camera_do_mmap_ion(int ion_fd,struct ion_allocation_data * alloc,struct ion_fd_data * ion_info_fd,int * mapFd)257 uint8_t *mm_camera_do_mmap_ion(int ion_fd, struct ion_allocation_data *alloc,
258   struct ion_fd_data *ion_info_fd, int *mapFd)
259 {
260   void *ret; /* returned virtual address */
261   int rc = 0;
262   struct ion_handle_data handle_data;
263 
264   /* to make it page size aligned */
265   alloc->len = (alloc->len + 4095) & (~4095);
266   alloc->align = 4096;
267 
268   rc = ioctl(ion_fd, ION_IOC_ALLOC, alloc);
269   if (rc < 0) {
270     CDBG_ERROR("ION allocation failed %s\n", strerror(errno));
271     goto ION_ALLOC_FAILED;
272   }
273 
274   ion_info_fd->handle = alloc->handle;
275   rc = ioctl(ion_fd, ION_IOC_SHARE, ion_info_fd);
276   if (rc < 0) {
277     CDBG_ERROR("ION map failed %s\n", strerror(errno));
278     goto ION_MAP_FAILED;
279   }
280   *mapFd = ion_info_fd->fd;
281   ret = mmap(NULL,
282     alloc->len,
283     PROT_READ  | PROT_WRITE,
284     MAP_SHARED,
285     *mapFd,
286     0);
287 
288   if (ret == MAP_FAILED) {
289     CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
290     goto ION_MAP_FAILED;
291   }
292 
293   return ret;
294 
295 ION_MAP_FAILED:
296   handle_data.handle = ion_info_fd->handle;
297   ioctl(ion_fd, ION_IOC_FREE, &handle_data);
298 ION_ALLOC_FAILED:
299   return NULL;
300 }
301 
302 /*===========================================================================
303  * FUNCTION    - mm_camera_do_munmap_ion -
304  *
305  * DESCRIPTION:
306  *==========================================================================*/
mm_camera_do_munmap_ion(int ion_fd,struct ion_fd_data * ion_info_fd,void * addr,size_t size)307 int mm_camera_do_munmap_ion (int ion_fd, struct ion_fd_data *ion_info_fd,
308                    void *addr, size_t size)
309 {
310   int rc = 0;
311   rc = munmap(addr, size);
312   close(ion_info_fd->fd);
313 
314   struct ion_handle_data handle_data;
315   handle_data.handle = ion_info_fd->handle;
316   ioctl(ion_fd, ION_IOC_FREE, &handle_data);
317   return rc;
318 }
319