ADDED THE FIMC1 STUFF FOR NOTHING
[exynos_camera.git] / exynos_camera.c
1 /*
2  * Copyright (C) 2013 Paul Kocialkowski
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <malloc.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <sys/time.h>
26 #include <sys/mman.h>
27 #include <sys/ioctl.h>
28
29 #include <asm/types.h>
30 #include <linux/videodev2.h>
31 #include <videodev2_samsung.h>
32
33 #define LOG_TAG "exynos_camera"
34 #include <utils/Log.h>
35
36 #include "exynos_camera.h"
37
38 /*
39  * Devices configurations
40  */
41
42 struct exynos_camera_preset exynos_camera_presets_galaxys2[] = {
43         {
44                 .name = "M5MO",
45                 .facing = CAMERA_FACING_FRONT,
46                 .orientation = 90,
47                 .rotation = 0,
48                 .hflip = 1,
49                 .vflip = 0,
50         },
51         {
52                 .name = "S5K5BAFX",
53                 .facing = CAMERA_FACING_BACK,
54                 .orientation = 90,
55                 .rotation = 0,
56                 .hflip = 0,
57                 .vflip = 1,
58         },
59 };
60
61 struct exynos_v4l2_node exynos_v4l2_nodes_galaxys2[] = {
62         {
63                 .id = 0,
64                 .node = "/dev/video0",
65         },
66         {
67                 .id = 1,
68                 .node = "/dev/video1",
69         },
70         {
71                 .id = 2,
72                 .node = "/dev/video2",
73         },
74 };
75
76 struct exynox_camera_config exynos_camera_config_galaxys2 = {
77         .presets = (struct exynos_camera_preset *) &exynos_camera_presets_galaxys2,
78         .presets_count = 2,
79         .v4l2_nodes = (struct exynos_v4l2_node *) &exynos_v4l2_nodes_galaxys2,
80         .v4l2_nodes_count = 3,
81 };
82
83 /*
84  * Exynos Params
85  */
86
87 /*
88 -> always alloc params string (strdup)
89 -> register internally with set (but with a _register function)
90 -> unregister it all at the same time (but with a _unregister function)
91 -> at set, look if there is already one, if not, add to the end of the list and alloc
92 -> if there is one, just free the value (if string) and replace it
93
94
95 set value for a key
96 get value for a key
97 set all the values
98 get all the values
99 -> pas oublier les negatifs
100
101 */
102
103
104
105 /*
106  * Exynos Camera
107  */
108
109 struct exynox_camera_config *exynos_camera_config =
110         &exynos_camera_config_galaxys2;
111
112 int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
113 {
114         if (exynos_camera == NULL)
115                 return -EINVAL;
116
117         exynos_param_string_set(exynos_camera, "picture-format", "jpeg");
118         exynos_param_string_set(exynos_camera, "picture-format-values", "jpeg");
119
120         exynos_param_string_set(exynos_camera, "picture-size", "2560x1920");
121         exynos_param_string_set(exynos_camera, "picture-size-values",
122                 "2560x1920,2048x1536,1600x1200,1280x960,640x480");
123
124         exynos_param_string_set(exynos_camera, "preview-format", "rgb565");
125         exynos_param_string_set(exynos_camera, "preview-format-values", "rgb565");
126         exynos_param_string_set(exynos_camera, "preview-fps-range", "15000,30000");
127         exynos_param_string_set(exynos_camera, "preview-fps-range-values", "(15000,30000)");
128         exynos_param_int_set(exynos_camera, "preview-frame-rate", 15);
129         exynos_param_int_set(exynos_camera, "preview-frame-rate-values", 15);
130         exynos_param_string_set(exynos_camera, "preview-size", "640x480");
131         exynos_param_string_set(exynos_camera, "preview-size-values",
132                 "720x480,640x480,352x288,176x144");
133
134         exynos_param_string_set(exynos_camera, "focus-mode", "auto");
135         exynos_param_string_set(exynos_camera, "focus-mode-values", "auto");
136
137         return 0;
138 }
139
140 int exynos_camera_init(struct exynos_camera *exynos_camera, int id)
141 {
142         char firmware_version[7] = { 0 };
143         struct exynos_v4l2_ext_control control;
144         int rc;
145
146         if (exynos_camera == NULL)
147                 return -EINVAL;
148
149         // Init FIMC1
150         rc = exynos_v4l2_open(exynos_camera, 0);
151         if (rc < 0) {
152                 LOGE("Unable to open v4l2 device");
153                 return -1;
154         }
155
156         rc = exynos_v4l2_querycap_cap(exynos_camera, 0);
157         if (rc < 0) {
158                 LOGE("%s: querycap failed", __func__);
159                 return -1;
160         }
161
162         rc = exynos_v4l2_enum_input(exynos_camera, 0, id);
163         if (rc < 0) {
164                 LOGE("%s: enum input failed", __func__);
165                 return -1;
166         }
167
168         rc = exynos_v4l2_s_input(exynos_camera, 0, id);
169         if (rc < 0) {
170                 LOGE("%s: s input failed", __func__);
171                 return -1;
172         }
173
174         // Init FIMC2
175         rc = exynos_v4l2_open(exynos_camera, 2);
176         if (rc < 0) {
177                 LOGE("Unable to open v4l2 device");
178                 return -1;
179         }
180
181         rc = exynos_v4l2_querycap_cap(exynos_camera, 2);
182         if (rc < 0) {
183                 LOGE("%s: querycap failed", __func__);
184                 return -1;
185         }
186
187         rc = exynos_v4l2_enum_input(exynos_camera, 2, id);
188         if (rc < 0) {
189                 LOGE("%s: enum input failed", __func__);
190                 return -1;
191         }
192
193         rc = exynos_v4l2_s_input(exynos_camera, 2, id);
194         if (rc < 0) {
195                 LOGE("%s: s input failed", __func__);
196                 return -1;
197         }
198
199         // Get firmware information
200         memset(&control, 0, sizeof(control));
201         control.id = V4L2_CID_CAM_SENSOR_FW_VER;
202         control.data.string = firmware_version;
203
204         rc = exynos_v4l2_g_ext_ctrls(exynos_camera, 0, (struct v4l2_ext_control *) &control, 1);
205         if (rc < 0) {
206                 LOGE("%s: g ext ctrls failed", __func__);
207         } else {
208                 LOGD("Firmware version: %s", firmware_version);
209         }
210
211         // Params
212         rc = exynos_camera_params_init(exynos_camera, id);
213         if (rc < 0)
214                 LOGE("%s: Unable to init params", __func__);
215
216         // Gralloc
217         rc = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const struct hw_module_t **) &exynos_camera->gralloc);
218         if (rc)
219                 LOGE("%s: Unable to get gralloc module", __func__);
220
221         return 0;
222 }
223
224 void exynos_camera_deinit(struct exynos_camera *exynos_camera)
225 {
226         int i;
227         int id;
228
229         if (exynos_camera == NULL || exynos_camera->config == NULL)
230                 return;
231
232         for (i=0 ; i < exynos_camera->config->v4l2_nodes_count ; i++) {
233                 id = exynos_camera->config->v4l2_nodes[i].id;
234                 exynos_v4l2_close(exynos_camera, id);
235         }
236 }
237
238
239 int exynos_camera_preview(struct exynos_camera *exynos_camera)
240 {
241         buffer_handle_t *buffer;
242         int stride;
243         void *addr = NULL;
244         int offset;
245
246         void *base;
247         int width, height, fmt;
248         void *base_out;
249         int width_out, height_out, fmt_out;
250
251         int index;
252         int rc;
253
254         if (exynos_camera == NULL)
255                 return -EINVAL;
256
257         exynos_camera->preview_window->dequeue_buffer(exynos_camera->preview_window,
258                 &buffer, &stride);
259         exynos_camera->gralloc->lock(exynos_camera->gralloc, *buffer, GRALLOC_USAGE_SW_WRITE_OFTEN,
260                 0, 0, 640, 480, &addr);
261
262         // FIMC1 V4L2
263 #if 0
264         rc = exynos_v4l2_g_fmt_out(exynos_camera, 1, &width_out, &height_out, &fmt_out);
265         if (rc < 0) {
266                 LOGE("%s: g fmt failed!", __func__);
267                 return -1;
268         }
269
270         width = 640;
271         height = 480;
272         fmt = V4L2_PIX_FMT_NV12;
273
274         if (width_out != width || height_out != height || fmt_out != fmt) {
275                 rc = exynos_v4l2_s_fmt_pix_out(exynos_camera, 1, width, height, fmt);
276                 if (rc < 0) {
277                         LOGE("%s: s fmt failed!", __func__);
278                         return -1;
279                 }
280         }
281
282         rc = exynos_v4l2_s_crop_out(exynos_camera, 1, 0, 0, width, height);
283         if (rc < 0) {
284                 LOGE("%s: s crop failed!", __func__);
285                 return -1;
286         }
287
288         rc = exynos_v4l2_reqbufs_out(exynos_camera, 1, 1);
289         if (rc < 0) {
290                 LOGE("%s: reqbufs failed!", __func__);
291                 return -1;
292         }
293
294         rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_ROTATION, 90);
295         if (rc < 0) {
296                 LOGE("%s: s ctrl failed!", __func__);
297                 return -1;
298         }
299
300         rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_HFLIP, 0);
301         if (rc < 0) {
302                 LOGE("%s: s ctrl failed!", __func__);
303                 return -1;
304         }
305
306         rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_VFLIP, 0);
307         if (rc < 0) {
308                 LOGE("%s: s ctrl failed!", __func__);
309                 return -1;
310         }
311
312         rc = exynos_v4l2_g_fbuf(exynos_camera, 1, &base, &width_out, &height_out, &fmt_out);
313         if (rc < 0) {
314                 LOGE("%s: g fbuf failed!", __func__);
315                 return -1;
316         }
317
318         base = addr;
319
320         if (base_out != base || width_out != width || height_out != height || fmt_out != fmt) {
321                 rc = exynos_v4l2_s_fbuf(exynos_camera, 1, base, width, height, fmt);
322                 if (rc < 0) {
323                         LOGE("%s: s fbuf failed!", __func__);
324                         return -1;
325                 }
326         }
327
328         memset(&fimc_buf, 0, sizeof(fimc_buf));
329         fimc_buf.base[0] = base;
330
331         rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_DST_INFO, (int) &fimc_buf);
332         if (rc < 0) {
333                 LOGE("%s: s ctrl failed!", __func__);
334                 return -1;
335         }
336
337         rc = exynos_v4l2_s_fmt_win(exynos_camera, 1, 0, 0, width, height);
338         if (rc < 0) {
339                 LOGE("%s: s fmt failed!", __func__);
340                 return -1;
341         }
342
343         rc = exynos_v4l2_streamon_out(exynos_camera, 1);
344         if (rc < 0) {
345                 LOGE("%s: streamon failed!", __func__);
346                 return -1;
347         }
348
349         rc = exynos_v4l2_qbuf_out(exynos_camera, 1, 0);
350         if (rc < 0) {
351                 LOGE("%s: qbuf failed!", __func__);
352                 return -1;
353         }
354
355         index = exynos_v4l2_dqbuf_out(exynos_camera, 1);
356         if (index < 0) {
357                 LOGE("%s: dqbuf failed!", __func__);
358                 return -1;
359         }
360
361         rc = exynos_v4l2_streamoff_out(exynos_camera, 1);
362         if (rc < 0) {
363                 LOGE("%s: streamon failed!", __func__);
364                 return -1;
365         }
366 #endif
367         // FIMC0 V4L2
368
369         rc = exynos_v4l2_poll(exynos_camera, 0);
370         if (rc < 0) {
371                 LOGE("%s: poll failed!", __func__);
372                 return -1;
373         } else if (rc == 0) {
374                 LOGE("%s: poll timeout!", __func__);
375                 // TODO: it's probably a good idea to restart everything
376                 return -1;
377         }
378
379         index = exynos_v4l2_dqbuf_cap(exynos_camera, 0);
380         if (index < 0 || index >= exynos_camera->preview_buffers_count) {
381                 LOGE("%s: dqbuf failed!", __func__);
382                 return -1;
383         }
384
385         rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, index);
386         if (rc < 0) {
387                 LOGE("%s: qbuf failed!", __func__);
388                 return -1;
389         }
390
391         // Preview window
392
393         if (addr == NULL) {
394                 LOGE("Unable to get addr");
395                 return -1;
396         }
397         offset = index*640*480*1.5;
398
399         void *frame = (void *) ((int) exynos_camera->preview_memory->data + offset);
400 /*
401             // the code below assumes YUV, not RGB
402             {
403                 int h;
404                 char *src = frame;
405                 char *ptr = (char *)addr;
406
407                 // Copy the Y plane, while observing the stride
408                 for (h = 0; h < height; h++) {
409                     memcpy(ptr, src, width);
410                     ptr += stride;
411                     src += width;
412                 }
413
414                 {
415                     // U
416                     char *v = ptr;
417                     ptr += stride * height / 4;
418                     for (h = 0; h < height / 2; h++) {
419                         memcpy(ptr, src, width / 2);
420                         ptr += stride / 2;
421                         src += width / 2;
422                     }
423                     // V
424                     ptr = v;
425                     for (h = 0; h < height / 2; h++) {
426                         memcpy(ptr, src, width / 2);
427                         ptr += stride / 2;
428                         src += width / 2;
429                     }
430                 }
431             }
432 */
433         memcpy(addr, frame, 640*480*1.5);
434
435         exynos_camera->gralloc->unlock(exynos_camera->gralloc, *buffer);
436
437         exynos_camera->preview_window->enqueue_buffer(exynos_camera->preview_window,
438                 buffer);
439
440         return 0;
441 }
442
443 void *exynos_camera_preview_thread(void *data)
444 {
445         struct exynos_camera *exynos_camera;
446         int rc;
447
448         if (data == NULL)
449                 return NULL;
450
451         exynos_camera = (struct exynos_camera *) data;
452
453         LOGE("%s: Starting thread", __func__);
454         exynos_camera->preview_thread_running = 1;
455
456         // Lock preview lock mutex
457         pthread_mutex_lock(&exynos_camera->preview_lock_mutex);
458
459         while (exynos_camera->preview_enabled == 1) {
460                 pthread_mutex_lock(&exynos_camera->preview_mutex);
461
462                 rc = exynos_camera_preview(exynos_camera);
463                 if (rc < 0) {
464                         LOGE("%s: preview failed!", __func__);
465                         // TODO FIXME WTF REMOVE THAT ASAP
466                         exynos_camera->preview_enabled = 0;
467                 }
468
469                 pthread_mutex_unlock(&exynos_camera->preview_mutex);
470         }
471
472         exynos_camera->preview_thread_running = 0;
473         LOGE("%s: Exiting thread", __func__);
474
475         return NULL;
476 }
477
478
479 /*
480  * Exynos Camera OPS
481  */
482
483 int exynos_camera_set_preview_window(struct camera_device *dev,
484         struct preview_stream_ops *w)
485 {
486         struct exynos_camera *exynos_camera;
487         buffer_handle_t *buffer;
488         int stride;
489         void *addr = NULL;
490
491         int rc;
492
493         LOGD("%s(%p, %p)", __func__, dev, w);
494
495         if (dev == NULL || dev->priv == NULL)
496                 return -EINVAL;
497
498         exynos_camera = (struct exynos_camera *) dev->priv;
499
500         if (w == NULL)
501                 return 0;
502
503         pthread_mutex_lock(&exynos_camera->preview_mutex);
504
505         exynos_camera->preview_window = w;
506
507         if (w->set_buffer_count == NULL || w->set_usage == NULL || w->set_buffers_geometry == NULL)
508                 return -EINVAL;
509
510         if (exynos_camera->preview_buffers_count <= 0) {
511                 LOGE("%s: Invalid preview buffers count", __func__);
512                 goto error;
513         }
514
515         rc = w->set_buffer_count(w, exynos_camera->preview_buffers_count);
516         if (rc) {
517                 LOGE("%s: Unable to set buffer count (%d)", __func__,
518                         exynos_camera->preview_buffers_count);
519                 goto error;
520         }
521
522         rc = w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN);
523         if (rc) {
524                 LOGE("%s: Unable to set usage", __func__);
525                 goto error;
526         }
527
528         // TODO: Get this from params
529         rc = w->set_buffers_geometry(w, 640, 480, HAL_PIXEL_FORMAT_YCrCb_420_SP);
530         if (rc) {
531                 LOGE("%s: Unable to set buffers geometry", __func__);
532                 goto error;
533         }
534
535         pthread_mutex_unlock(&exynos_camera->preview_mutex);
536
537         // Unlock preview lock
538         pthread_mutex_unlock(&exynos_camera->preview_lock_mutex);
539
540         return 0;
541
542 error:
543         pthread_mutex_unlock(&exynos_camera->preview_mutex);
544
545         return -1;
546 }
547
548 void exynos_camera_set_callbacks(struct camera_device *dev,
549         camera_notify_callback notify_cb,
550         camera_data_callback data_cb,
551         camera_data_timestamp_callback data_cb_timestamp,
552         camera_request_memory get_memory,
553         void *user)
554 {
555         struct exynos_camera *exynos_camera;
556
557         LOGD("%s(%p, %p)", __func__, dev, user);
558
559         if (dev == NULL || dev->priv == NULL)
560                 return;
561
562         exynos_camera = (struct exynos_camera *) dev->priv;
563
564         exynos_camera->callbacks.notify = notify_cb;
565         exynos_camera->callbacks.data = data_cb;
566         exynos_camera->callbacks.data_timestamp = data_cb_timestamp;
567         exynos_camera->callbacks.request_memory = get_memory;
568         exynos_camera->callbacks.user = user;
569 }
570
571 void exynos_camera_enable_msg_type(struct camera_device *dev, int32_t msg_type)
572 {
573         LOGD("%s(%p, %d)", __func__, dev, msg_type);
574 }
575
576 void exynos_camera_disable_msg_type(struct camera_device *dev, int32_t msg_type)
577 {
578         LOGD("%s(%p, %d)", __func__, dev, msg_type);
579 }
580
581 int exynos_camera_msg_type_enabled(struct camera_device *dev, int32_t msg_type)
582 {
583         LOGD("%s(%p, %d)", __func__, dev, msg_type);
584
585         return 0;
586 }
587
588 int exynos_camera_start_preview(struct camera_device *dev)
589 {
590         struct exynos_camera *exynos_camera;
591         struct v4l2_streamparm streamparm;
592         unsigned int fmt;
593         int width, height, fps, frame_size;
594         int fd;
595
596         pthread_attr_t thread_attr;
597
598         int id;
599         int rc;
600         int i;
601
602         LOGD("%s(%p)", __func__, dev);
603
604         if (dev == NULL || dev->priv == NULL)
605                 return -EINVAL;
606
607         exynos_camera = (struct exynos_camera *) dev->priv;
608
609         if (exynos_camera->config == NULL || exynos_camera->config->presets == NULL ||
610                 exynos_camera->camera_id >= exynos_camera->config->presets_count)
611                 return -EINVAL;
612
613         // V4L2
614
615         fmt = V4L2_PIX_FMT_NV21;
616
617         rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, fmt);
618         if (rc < 0) {
619                 LOGE("%s: enum fmt failed!", __func__);
620                 return -1;
621         }
622
623         width = 640;
624         height = 480;
625
626         rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, fmt);
627         if (rc < 0) {
628                 LOGE("%s: s fmt failed!", __func__);
629                 return -1;
630         }
631
632         rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CACHEABLE, 1);
633         if (rc < 0) {
634                 LOGE("%s: s ctrl failed!", __func__);
635                 return -1;
636         }
637
638         rc = exynos_v4l2_reqbufs_cap(exynos_camera, 0, 8);
639         if (rc < 0) {
640                 LOGE("%s: s ctrl failed!", __func__);
641                 return -1;
642         }
643
644         exynos_camera->preview_buffers_count = rc;
645         LOGD("Found %d buffers available!", exynos_camera->preview_buffers_count);
646
647         fps = 0;
648         memset(&streamparm, 0, sizeof(streamparm));
649         streamparm.parm.capture.timeperframe.numerator = 1;
650         streamparm.parm.capture.timeperframe.denominator = fps;
651
652         rc = exynos_v4l2_s_parm_cap(exynos_camera, 0, &streamparm);
653         if (rc < 0) {
654                 LOGE("%s: s parm failed!", __func__);
655                 return -1;
656         }
657
658         for (i=0 ; i < exynos_camera->preview_buffers_count ; i++) {
659                 rc = exynos_v4l2_querybuf_cap(exynos_camera, 0, i);
660                 if (rc < 0) {
661                         LOGE("%s: querybuf failed!", __func__);
662                         return -1;
663                 }
664         }
665
666         frame_size = 640 * 480 * 1.5;
667
668         if (exynos_camera->callbacks.request_memory != NULL) {
669                 fd = exynos_v4l2_find_fd(exynos_camera, 0);
670                 if (fd < 0) {
671                         LOGE("%s: Unable to find v4l2 fd", __func__);
672                         return -1;
673                 }
674
675                 if (exynos_camera->preview_memory != NULL && exynos_camera->preview_memory->release != NULL)
676                         exynos_camera->preview_memory->release(exynos_camera->preview_memory);
677
678                 exynos_camera->preview_memory =
679                         exynos_camera->callbacks.request_memory(fd, 
680                                 frame_size, exynos_camera->preview_buffers_count, 0);
681                 if (exynos_camera->preview_memory == NULL) {
682                         LOGE("%s: memory request failed!", __func__);
683                         return -1;
684                 }
685         } else {
686                 LOGE("%s: No memory request function!", __func__);
687                 return -1;
688         }
689
690         for (i=0 ; i < exynos_camera->preview_buffers_count ; i++) {
691                 rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, i);
692                 if (rc < 0) {
693                         LOGE("%s: qbuf failed!", __func__);
694                         return -1;
695                 }
696         }
697
698         id = exynos_camera->camera_id;
699
700         rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_ROTATION,
701                 exynos_camera->config->presets[i].rotation);
702         if (rc < 0) {
703                 LOGE("%s: s ctrl failed!", __func__);
704                 return -1;
705         }
706
707         rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_HFLIP,
708                 exynos_camera->config->presets[id].hflip);
709         if (rc < 0) {
710                 LOGE("%s: s ctrl failed!", __func__);
711                 return -1;
712         }
713
714         rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_VFLIP,
715                 exynos_camera->config->presets[id].vflip);
716         if (rc < 0) {
717                 LOGE("%s: s ctrl failed!", __func__);
718                 return -1;
719         }
720
721         rc = exynos_v4l2_streamon_cap(exynos_camera, 0);
722         if (rc < 0) {
723                 LOGE("%s: streamon failed!", __func__);
724                 return -1;
725         }
726
727         // Init FIMC1
728         rc = exynos_v4l2_open(exynos_camera, 1);
729         if (rc < 0) {
730                 LOGE("Unable to open v4l2 device");
731                 return -1;
732         }
733
734         // Thread
735
736         pthread_mutex_init(&exynos_camera->preview_mutex, NULL);
737         pthread_mutex_init(&exynos_camera->preview_lock_mutex, NULL);
738
739         // Lock preview lock
740         pthread_mutex_lock(&exynos_camera->preview_lock_mutex);
741
742         pthread_attr_init(&thread_attr);
743         pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
744
745         exynos_camera->preview_enabled = 1;
746
747         rc = pthread_create(&exynos_camera->preview_thread, &thread_attr,
748                 exynos_camera_preview_thread, (void *) exynos_camera);
749         if (rc < 0) {
750                 LOGE("%s: Unable to create thread", __func__);
751                 return -1;
752         }
753
754         return 0;
755 }
756
757 void exynos_camera_stop_preview(struct camera_device *dev)
758 {
759         struct exynos_camera *exynos_camera;
760         int rc;
761         int i;
762
763         LOGD("%s(%p)", __func__, dev);
764
765         if (dev == NULL || dev->priv == NULL)
766                 return;
767
768         exynos_camera = (struct exynos_camera *) dev->priv;
769
770         if (!exynos_camera->preview_enabled)
771                 return;
772
773         exynos_camera->preview_enabled = 0;
774
775         // Unlock preview lock
776         pthread_mutex_unlock(&exynos_camera->preview_lock_mutex);
777
778         pthread_mutex_lock(&exynos_camera->preview_mutex);
779
780         // Wait for the thread to end
781         for (i=0 ; i < 10 ; i++) {
782                 if (!exynos_camera->preview_thread_running)
783                         break;
784
785                 usleep(1000);
786         }
787
788         rc = exynos_v4l2_streamoff_cap(exynos_camera, 0);
789         if (rc < 0) {
790                 LOGE("%s: streamoff failed!", __func__);
791         }
792
793         if (exynos_camera->preview_memory != NULL && exynos_camera->preview_memory->release != NULL) {
794                 exynos_camera->preview_memory->release(exynos_camera->preview_memory);
795                 exynos_camera->preview_memory = NULL;
796         }
797
798         pthread_mutex_unlock(&exynos_camera->preview_mutex);
799 }
800
801 int exynos_camera_preview_enabled(struct camera_device *dev)
802 {
803         struct exynos_camera *exynos_camera;
804
805         LOGD("%s(%p)", __func__, dev);
806
807         if (dev == NULL || dev->priv == NULL)
808                 return -EINVAL;
809
810         exynos_camera = (struct exynos_camera *) dev->priv;
811
812         return exynos_camera->preview_enabled;
813 }
814
815 int exynos_camera_store_meta_data_in_buffers(struct camera_device *dev,
816         int enable)
817 {
818         LOGD("%s(%p, %d)", __func__, dev, enable);
819
820         return 0;
821 }
822
823 int exynos_camera_start_recording(struct camera_device *dev)
824 {
825         LOGD("%s(%p)", __func__, dev);
826
827         return 0;
828 }
829
830 void exynos_camera_stop_recording(struct camera_device *dev)
831 {
832         LOGD("%s(%p)", __func__, dev);
833 }
834
835 int exynos_camera_recording_enabled(struct camera_device *dev)
836 {
837         LOGD("%s(%p)", __func__, dev);
838
839         return 0;
840 }
841
842 void exynos_camera_release_recording_frame(struct camera_device *dev,
843         const void *opaque)
844 {
845         LOGD("%s(%p, %p)", __func__, dev, opaque);
846 }
847
848 int exynos_camera_auto_focus(struct camera_device *dev)
849 {
850         LOGD("%s(%p)", __func__, dev);
851
852         return 0;
853 }
854
855 int exynos_camera_cancel_auto_focus(struct camera_device *dev)
856 {
857         LOGD("%s(%p)", __func__, dev);
858
859         return 0;
860 }
861
862 int exynos_camera_take_picture(struct camera_device *dev)
863 {
864         LOGD("%s(%p)", __func__, dev);
865
866         return 0;
867 }
868
869 int exynos_camera_cancel_picture(struct camera_device *dev)
870 {
871         LOGD("%s(%p)", __func__, dev);
872
873         return 0;
874 }
875
876 int exynos_camera_set_parameters(struct camera_device *dev,
877         const char *params)
878 {
879         struct exynos_camera *exynos_camera;
880         int rc;
881
882         LOGD("%s(%p, %s)", __func__, dev, params);
883
884         if (dev == NULL || dev->priv == NULL || params == NULL)
885                 return -EINVAL;
886
887         exynos_camera = (struct exynos_camera *) dev->priv;
888
889         rc = exynos_params_string_set(exynos_camera, (char *) params);
890         if (rc < 0) {
891                 LOGE("%s: Unable to set params string", __func__);
892                 return -1;
893         }
894
895         return 0;
896 }
897
898 char *exynos_camera_get_parameters(struct camera_device *dev)
899 {
900         struct exynos_camera *exynos_camera;
901         char *params;
902
903         LOGD("%s(%p)", __func__, dev);
904
905         if (dev == NULL || dev->priv == NULL)
906                 return NULL;
907
908         exynos_camera = (struct exynos_camera *) dev->priv;
909
910         params = exynos_params_string_get(exynos_camera);
911         if (params == NULL) {
912                 LOGE("%s: Couldn't find any param", __func__);
913                 return strdup("");
914         }
915
916         return params;
917 }
918
919 void exynos_camera_put_parameters(struct camera_device *dev, char *params)
920 {
921         LOGD("%s(%p)", __func__, dev);
922
923         if (params != NULL)
924                 free(params);
925 }
926
927 int exynos_camera_send_command(struct camera_device *dev,
928         int32_t cmd, int32_t arg1, int32_t arg2)
929 {
930         LOGD("%s(%p, %d, %d, %d)", __func__, dev, cmd, arg1, arg2);
931
932         return 0;
933 }
934
935 void exynos_camera_release(struct camera_device *dev)
936 {
937         LOGD("%s(%p)", __func__, dev);
938 }
939
940 int exynos_camera_dump(struct camera_device *dev, int fd)
941 {
942         LOGD("%s(%p, %d)", __func__, dev, fd);
943
944         return 0;
945 }
946
947 /*
948  * Interface
949  */
950
951 struct camera_device_ops exynos_camera_ops = {
952         .set_preview_window = exynos_camera_set_preview_window,
953         .set_callbacks = exynos_camera_set_callbacks,
954         .enable_msg_type = exynos_camera_enable_msg_type,
955         .disable_msg_type = exynos_camera_disable_msg_type,
956         .msg_type_enabled = exynos_camera_msg_type_enabled,
957         .start_preview = exynos_camera_start_preview,
958         .stop_preview = exynos_camera_stop_preview,
959         .preview_enabled = exynos_camera_preview_enabled,
960         .store_meta_data_in_buffers = exynos_camera_store_meta_data_in_buffers,
961         .start_recording = exynos_camera_start_recording,
962         .stop_recording = exynos_camera_stop_recording,
963         .recording_enabled = exynos_camera_recording_enabled,
964         .release_recording_frame = exynos_camera_release_recording_frame,
965         .auto_focus = exynos_camera_auto_focus,
966         .cancel_auto_focus = exynos_camera_cancel_auto_focus,
967         .take_picture = exynos_camera_take_picture,
968         .cancel_picture = exynos_camera_cancel_picture,
969         .set_parameters = exynos_camera_set_parameters,
970         .get_parameters = exynos_camera_get_parameters,
971         .put_parameters = exynos_camera_put_parameters,
972         .send_command = exynos_camera_send_command,
973         .release = exynos_camera_release,
974         .dump = exynos_camera_dump,
975 };
976
977 int exynos_camera_close(hw_device_t *device)
978 {
979         struct camera_device *camera_device;
980         struct exynos_camera *exynos_camera;
981
982         LOGD("%s(%p)", __func__, device);
983
984         if (device == NULL)
985                 return -EINVAL;
986
987         camera_device = (struct camera_device *) device;
988
989         if (camera_device->priv != NULL) {
990                 exynos_camera = (struct exynos_camera *) camera_device->priv;
991                 exynos_camera_deinit(exynos_camera);
992
993                 free(exynos_camera);
994         }
995
996         free(camera_device);
997
998         return 0;
999 }
1000
1001 int exynos_camera_open(const struct hw_module_t* module, const char *camera_id,
1002         struct hw_device_t** device)
1003 {
1004         struct camera_device *camera_device = NULL;
1005         struct exynos_camera *exynos_camera = NULL;
1006         int id;
1007         int rc;
1008
1009         LOGD("%s(%p, %s, %p)", __func__, module, camera_id, device);
1010
1011         if (module == NULL || camera_id == NULL || device == NULL)
1012                 return -EINVAL;
1013
1014         id = atoi(camera_id);
1015         if (id < 0)
1016                 return -EINVAL;
1017
1018         exynos_camera = calloc(1, sizeof(struct exynos_camera));
1019         exynos_camera->config = exynos_camera_config;
1020
1021         if (exynos_camera->config->presets_count > EXYNOS_CAMERA_MAX_PRESETS_COUNT ||
1022                 exynos_camera->config->v4l2_nodes_count > EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT)
1023                 goto error_preset;
1024
1025         if (id >= exynos_camera->config->presets_count)
1026                 goto error_preset;
1027
1028         exynos_camera->camera_id = id;
1029
1030         rc = exynos_camera_init(exynos_camera, id);
1031         if (rc < 0) {
1032                 LOGE("%s: Unable to init camera", __func__);
1033                 goto error;
1034         }
1035
1036         camera_device = calloc(1, sizeof(struct camera_device));
1037         camera_device->common.tag = HARDWARE_DEVICE_TAG;
1038         camera_device->common.version = 0;
1039         camera_device->common.module = (struct hw_module_t *) module;
1040         camera_device->common.close = exynos_camera_close;
1041
1042         camera_device->ops = &exynos_camera_ops;
1043         camera_device->priv = exynos_camera;
1044
1045         *device = (struct hw_device_t *) &(camera_device->common);
1046
1047         return 0;
1048
1049 error:
1050         exynos_camera_deinit(exynos_camera);
1051
1052 error_device:
1053         if (camera_device != NULL)
1054                 free(camera_device);
1055
1056 error_preset:
1057         if (exynos_camera != NULL)
1058                 free(exynos_camera);
1059
1060         return -1;
1061 }
1062
1063 int exynos_camera_get_number_of_cameras(void)
1064 {
1065         LOGD("%s()", __func__);
1066
1067         if (exynos_camera_config == NULL || exynos_camera_config->presets == NULL) {
1068                 LOGE("%s: Unable to find proper camera config", __func__);
1069                 return -1;
1070         }
1071
1072         return exynos_camera_config->presets_count;
1073 }
1074
1075 int exynos_camera_get_camera_info(int id, struct camera_info *info)
1076 {
1077         LOGD("%s(%d, %p)", __func__, id, info);
1078
1079         if (id < 0 || info == NULL)
1080                 return -EINVAL;
1081
1082         if (exynos_camera_config == NULL || exynos_camera_config->presets == NULL) {
1083                 LOGE("%s: Unable to find proper camera config", __func__);
1084                 return -1;
1085         }
1086
1087         if (id >= exynos_camera_config->presets_count)
1088                 return -EINVAL;
1089
1090         LOGD("Selected camera: %s", exynos_camera_config->presets[id].name);
1091
1092         info->facing = exynos_camera_config->presets[id].facing;
1093         info->orientation = exynos_camera_config->presets[id].orientation;
1094
1095         return 0;
1096 }
1097
1098 struct hw_module_methods_t exynos_camera_module_methods = {
1099         .open = exynos_camera_open,
1100 };
1101
1102 struct camera_module HAL_MODULE_INFO_SYM = {
1103         .common = {
1104                 .tag = HARDWARE_MODULE_TAG,
1105                 .version_major = 1,
1106                 .version_minor = 0,
1107                 .id = CAMERA_HARDWARE_MODULE_ID,
1108                 .name = "Exynos Camera",
1109                 .author = "Paul Kocialkowski",
1110                 .methods = &exynos_camera_module_methods,
1111         },
1112         .get_number_of_cameras = exynos_camera_get_number_of_cameras,
1113         .get_camera_info = exynos_camera_get_camera_info,
1114 };