1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18* @file CameraHal.cpp
19*
20* This file maps the Camera Hardware Interface to V4L2.
21*
22*/
23
24#define LOG_TAG "CameraHAL"
25
26#include <utils/threads.h>
27
28#include "CameraHal.h"
29#include "CameraProperties.h"
30#include "TICameraParameters.h"
31
32
33static android::CameraProperties gCameraProperties;
34static android::CameraHal* gCameraHals[MAX_CAMERAS_SUPPORTED];
35static unsigned int gCamerasOpen = 0;
36static android::Mutex gCameraHalDeviceLock;
37
38static int camera_device_open(const hw_module_t* module, const char* name,
39                hw_device_t** device);
40static int camera_device_close(hw_device_t* device);
41static int camera_get_number_of_cameras(void);
42static int camera_get_camera_info(int camera_id, struct camera_info *info);
43
44static struct hw_module_methods_t camera_module_methods = {
45        open: camera_device_open
46};
47
48camera_module_t HAL_MODULE_INFO_SYM = {
49    common: {
50         tag: HARDWARE_MODULE_TAG,
51         version_major: 1,
52         version_minor: 0,
53         id: CAMERA_HARDWARE_MODULE_ID,
54         name: "TI OMAP CameraHal Module",
55         author: "TI",
56         methods: &camera_module_methods,
57         dso: NULL, /* remove compilation warnings */
58         reserved: {0}, /* remove compilation warnings */
59    },
60    get_number_of_cameras: camera_get_number_of_cameras,
61    get_camera_info: camera_get_camera_info,
62};
63
64typedef struct ti_camera_device {
65    camera_device_t base;
66    /* TI specific "private" data can go here (base.priv) */
67    int cameraid;
68} ti_camera_device_t;
69
70
71/*******************************************************************
72 * implementation of camera_device_ops functions
73 *******************************************************************/
74
75int camera_set_preview_window(struct camera_device * device,
76        struct preview_stream_ops *window)
77{
78    int rv = -EINVAL;
79    ti_camera_device_t* ti_dev = NULL;
80
81    ALOGV("%s", __FUNCTION__);
82
83    if(!device)
84        return rv;
85
86    ti_dev = (ti_camera_device_t*) device;
87
88    rv = gCameraHals[ti_dev->cameraid]->setPreviewWindow(window);
89
90    return rv;
91}
92
93void camera_set_callbacks(struct camera_device * device,
94        camera_notify_callback notify_cb,
95        camera_data_callback data_cb,
96        camera_data_timestamp_callback data_cb_timestamp,
97        camera_request_memory get_memory,
98        void *user)
99{
100    ti_camera_device_t* ti_dev = NULL;
101
102    ALOGV("%s", __FUNCTION__);
103
104    if(!device)
105        return;
106
107    ti_dev = (ti_camera_device_t*) device;
108
109    gCameraHals[ti_dev->cameraid]->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
110}
111
112void camera_enable_msg_type(struct camera_device * device, int32_t msg_type)
113{
114    ti_camera_device_t* ti_dev = NULL;
115
116    ALOGV("%s", __FUNCTION__);
117
118    if(!device)
119        return;
120
121    ti_dev = (ti_camera_device_t*) device;
122
123    gCameraHals[ti_dev->cameraid]->enableMsgType(msg_type);
124}
125
126void camera_disable_msg_type(struct camera_device * device, int32_t msg_type)
127{
128    ti_camera_device_t* ti_dev = NULL;
129
130    ALOGV("%s", __FUNCTION__);
131
132    if(!device)
133        return;
134
135    ti_dev = (ti_camera_device_t*) device;
136
137    gCameraHals[ti_dev->cameraid]->disableMsgType(msg_type);
138}
139
140int camera_msg_type_enabled(struct camera_device * device, int32_t msg_type)
141{
142    ti_camera_device_t* ti_dev = NULL;
143
144    ALOGV("%s", __FUNCTION__);
145
146    if(!device)
147        return 0;
148
149    ti_dev = (ti_camera_device_t*) device;
150
151    return gCameraHals[ti_dev->cameraid]->msgTypeEnabled(msg_type);
152}
153
154int camera_start_preview(struct camera_device * device)
155{
156    int rv = -EINVAL;
157    ti_camera_device_t* ti_dev = NULL;
158
159    ALOGV("%s", __FUNCTION__);
160
161    if(!device)
162        return rv;
163
164    ti_dev = (ti_camera_device_t*) device;
165
166    rv = gCameraHals[ti_dev->cameraid]->startPreview();
167
168    return rv;
169}
170
171void camera_stop_preview(struct camera_device * device)
172{
173    ti_camera_device_t* ti_dev = NULL;
174
175    ALOGV("%s", __FUNCTION__);
176
177    if(!device)
178        return;
179
180    ti_dev = (ti_camera_device_t*) device;
181
182    gCameraHals[ti_dev->cameraid]->stopPreview();
183}
184
185int camera_preview_enabled(struct camera_device * device)
186{
187    int rv = -EINVAL;
188    ti_camera_device_t* ti_dev = NULL;
189
190    ALOGV("%s", __FUNCTION__);
191
192    if(!device)
193        return rv;
194
195    ti_dev = (ti_camera_device_t*) device;
196
197    rv = gCameraHals[ti_dev->cameraid]->previewEnabled();
198    return rv;
199}
200
201int camera_store_meta_data_in_buffers(struct camera_device * device, int enable)
202{
203    int rv = -EINVAL;
204    ti_camera_device_t* ti_dev = NULL;
205
206    ALOGV("%s", __FUNCTION__);
207
208    if(!device)
209        return rv;
210
211    ti_dev = (ti_camera_device_t*) device;
212
213    //  TODO: meta data buffer not current supported
214    rv = gCameraHals[ti_dev->cameraid]->storeMetaDataInBuffers(enable);
215    return rv;
216    //return enable ? android::INVALID_OPERATION: android::OK;
217}
218
219int camera_start_recording(struct camera_device * device)
220{
221    int rv = -EINVAL;
222    ti_camera_device_t* ti_dev = NULL;
223
224    ALOGV("%s", __FUNCTION__);
225
226    if(!device)
227        return rv;
228
229    ti_dev = (ti_camera_device_t*) device;
230
231    rv = gCameraHals[ti_dev->cameraid]->startRecording();
232    return rv;
233}
234
235void camera_stop_recording(struct camera_device * device)
236{
237    ti_camera_device_t* ti_dev = NULL;
238
239    ALOGV("%s", __FUNCTION__);
240
241    if(!device)
242        return;
243
244    ti_dev = (ti_camera_device_t*) device;
245
246    gCameraHals[ti_dev->cameraid]->stopRecording();
247}
248
249int camera_recording_enabled(struct camera_device * device)
250{
251    int rv = -EINVAL;
252    ti_camera_device_t* ti_dev = NULL;
253
254    ALOGV("%s", __FUNCTION__);
255
256    if(!device)
257        return rv;
258
259    ti_dev = (ti_camera_device_t*) device;
260
261    rv = gCameraHals[ti_dev->cameraid]->recordingEnabled();
262    return rv;
263}
264
265void camera_release_recording_frame(struct camera_device * device,
266                const void *opaque)
267{
268    ti_camera_device_t* ti_dev = NULL;
269
270    ALOGV("%s", __FUNCTION__);
271
272    if(!device)
273        return;
274
275    ti_dev = (ti_camera_device_t*) device;
276
277    gCameraHals[ti_dev->cameraid]->releaseRecordingFrame(opaque);
278}
279
280int camera_auto_focus(struct camera_device * device)
281{
282    int rv = -EINVAL;
283    ti_camera_device_t* ti_dev = NULL;
284
285    ALOGV("%s", __FUNCTION__);
286
287    if(!device)
288        return rv;
289
290    ti_dev = (ti_camera_device_t*) device;
291
292    rv = gCameraHals[ti_dev->cameraid]->autoFocus();
293    return rv;
294}
295
296int camera_cancel_auto_focus(struct camera_device * device)
297{
298    int rv = -EINVAL;
299    ti_camera_device_t* ti_dev = NULL;
300
301    ALOGV("%s", __FUNCTION__);
302
303    if(!device)
304        return rv;
305
306    ti_dev = (ti_camera_device_t*) device;
307
308    rv = gCameraHals[ti_dev->cameraid]->cancelAutoFocus();
309    return rv;
310}
311
312int camera_take_picture(struct camera_device * device)
313{
314    int rv = -EINVAL;
315    ti_camera_device_t* ti_dev = NULL;
316
317    ALOGV("%s", __FUNCTION__);
318
319    if(!device)
320        return rv;
321
322    ti_dev = (ti_camera_device_t*) device;
323
324    rv = gCameraHals[ti_dev->cameraid]->takePicture();
325    return rv;
326}
327
328int camera_cancel_picture(struct camera_device * device)
329{
330    int rv = -EINVAL;
331    ti_camera_device_t* ti_dev = NULL;
332
333    ALOGV("%s", __FUNCTION__);
334
335    if(!device)
336        return rv;
337
338    ti_dev = (ti_camera_device_t*) device;
339
340    rv = gCameraHals[ti_dev->cameraid]->cancelPicture();
341    return rv;
342}
343
344int camera_set_parameters(struct camera_device * device, const char *params)
345{
346    int rv = -EINVAL;
347    ti_camera_device_t* ti_dev = NULL;
348
349    ALOGV("%s", __FUNCTION__);
350
351    if(!device)
352        return rv;
353
354    ti_dev = (ti_camera_device_t*) device;
355
356    rv = gCameraHals[ti_dev->cameraid]->setParameters(params);
357    return rv;
358}
359
360char* camera_get_parameters(struct camera_device * device)
361{
362    char* param = NULL;
363    ti_camera_device_t* ti_dev = NULL;
364
365    ALOGV("%s", __FUNCTION__);
366
367    if(!device)
368        return NULL;
369
370    ti_dev = (ti_camera_device_t*) device;
371
372    param = gCameraHals[ti_dev->cameraid]->getParameters();
373
374    return param;
375}
376
377static void camera_put_parameters(struct camera_device *device, char *parms)
378{
379    ti_camera_device_t* ti_dev = NULL;
380
381    ALOGV("%s", __FUNCTION__);
382
383    if(!device)
384        return;
385
386    ti_dev = (ti_camera_device_t*) device;
387
388    gCameraHals[ti_dev->cameraid]->putParameters(parms);
389}
390
391int camera_send_command(struct camera_device * device,
392            int32_t cmd, int32_t arg1, int32_t arg2)
393{
394    int rv = -EINVAL;
395    ti_camera_device_t* ti_dev = NULL;
396
397    ALOGV("%s", __FUNCTION__);
398
399    if(!device)
400        return rv;
401
402    ti_dev = (ti_camera_device_t*) device;
403
404    rv = gCameraHals[ti_dev->cameraid]->sendCommand(cmd, arg1, arg2);
405    return rv;
406}
407
408void camera_release(struct camera_device * device)
409{
410    ti_camera_device_t* ti_dev = NULL;
411
412    ALOGV("%s", __FUNCTION__);
413
414    if(!device)
415        return;
416
417    ti_dev = (ti_camera_device_t*) device;
418
419    gCameraHals[ti_dev->cameraid]->release();
420}
421
422int camera_dump(struct camera_device * device, int fd)
423{
424    int rv = -EINVAL;
425    ti_camera_device_t* ti_dev = NULL;
426
427    if(!device)
428        return rv;
429
430    ti_dev = (ti_camera_device_t*) device;
431
432    rv = gCameraHals[ti_dev->cameraid]->dump(fd);
433    return rv;
434}
435
436extern "C" void heaptracker_free_leaked_memory(void);
437
438int camera_device_close(hw_device_t* device)
439{
440    int ret = 0;
441    ti_camera_device_t* ti_dev = NULL;
442
443    ALOGV("%s", __FUNCTION__);
444
445    android::Mutex::Autolock lock(gCameraHalDeviceLock);
446
447    if (!device) {
448        ret = -EINVAL;
449        goto done;
450    }
451
452    ti_dev = (ti_camera_device_t*) device;
453
454    if (ti_dev) {
455        if (gCameraHals[ti_dev->cameraid]) {
456            delete gCameraHals[ti_dev->cameraid];
457            gCameraHals[ti_dev->cameraid] = NULL;
458            gCamerasOpen--;
459        }
460
461        if (ti_dev->base.ops) {
462            free(ti_dev->base.ops);
463        }
464        free(ti_dev);
465    }
466done:
467#ifdef HEAPTRACKER
468    heaptracker_free_leaked_memory();
469#endif
470    return ret;
471}
472
473/*******************************************************************
474 * implementation of camera_module functions
475 *******************************************************************/
476
477/* open device handle to one of the cameras
478 *
479 * assume camera service will keep singleton of each camera
480 * so this function will always only be called once per camera instance
481 */
482
483int camera_device_open(const hw_module_t* module, const char* name,
484                hw_device_t** device)
485{
486    int rv = 0;
487    int num_cameras = 0;
488    int cameraid;
489    ti_camera_device_t* camera_device = NULL;
490    camera_device_ops_t* camera_ops = NULL;
491    android::CameraHal* camera = NULL;
492    android::CameraProperties::Properties* properties = NULL;
493
494    android::Mutex::Autolock lock(gCameraHalDeviceLock);
495
496    CAMHAL_LOGI("camera_device open");
497
498    if (name != NULL) {
499        cameraid = atoi(name);
500        num_cameras = gCameraProperties.camerasSupported();
501
502        if(cameraid > num_cameras)
503        {
504            ALOGE("camera service provided cameraid out of bounds, "
505                    "cameraid = %d, num supported = %d",
506                    cameraid, num_cameras);
507            rv = -EINVAL;
508            goto fail;
509        }
510
511        if(gCamerasOpen >= MAX_SIMUL_CAMERAS_SUPPORTED)
512        {
513            ALOGE("maximum number of cameras already open");
514            rv = -ENOMEM;
515            goto fail;
516        }
517
518        camera_device = (ti_camera_device_t*)malloc(sizeof(*camera_device));
519        if(!camera_device)
520        {
521            ALOGE("camera_device allocation fail");
522            rv = -ENOMEM;
523            goto fail;
524        }
525
526        camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));
527        if(!camera_ops)
528        {
529            ALOGE("camera_ops allocation fail");
530            rv = -ENOMEM;
531            goto fail;
532        }
533
534        memset(camera_device, 0, sizeof(*camera_device));
535        memset(camera_ops, 0, sizeof(*camera_ops));
536
537        camera_device->base.common.tag = HARDWARE_DEVICE_TAG;
538        camera_device->base.common.version = 0;
539        camera_device->base.common.module = (hw_module_t *)(module);
540        camera_device->base.common.close = camera_device_close;
541        camera_device->base.ops = camera_ops;
542
543        camera_ops->set_preview_window = camera_set_preview_window;
544        camera_ops->set_callbacks = camera_set_callbacks;
545        camera_ops->enable_msg_type = camera_enable_msg_type;
546        camera_ops->disable_msg_type = camera_disable_msg_type;
547        camera_ops->msg_type_enabled = camera_msg_type_enabled;
548        camera_ops->start_preview = camera_start_preview;
549        camera_ops->stop_preview = camera_stop_preview;
550        camera_ops->preview_enabled = camera_preview_enabled;
551        camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;
552        camera_ops->start_recording = camera_start_recording;
553        camera_ops->stop_recording = camera_stop_recording;
554        camera_ops->recording_enabled = camera_recording_enabled;
555        camera_ops->release_recording_frame = camera_release_recording_frame;
556        camera_ops->auto_focus = camera_auto_focus;
557        camera_ops->cancel_auto_focus = camera_cancel_auto_focus;
558        camera_ops->take_picture = camera_take_picture;
559        camera_ops->cancel_picture = camera_cancel_picture;
560        camera_ops->set_parameters = camera_set_parameters;
561        camera_ops->get_parameters = camera_get_parameters;
562        camera_ops->put_parameters = camera_put_parameters;
563        camera_ops->send_command = camera_send_command;
564        camera_ops->release = camera_release;
565        camera_ops->dump = camera_dump;
566
567        *device = &camera_device->base.common;
568
569        // -------- TI specific stuff --------
570
571        camera_device->cameraid = cameraid;
572
573        if(gCameraProperties.getProperties(cameraid, &properties) < 0)
574        {
575            ALOGE("Couldn't get camera properties");
576            rv = -ENOMEM;
577            goto fail;
578        }
579
580        camera = new android::CameraHal(cameraid);
581
582        if(!camera)
583        {
584            ALOGE("Couldn't create instance of CameraHal class");
585            rv = -ENOMEM;
586            goto fail;
587        }
588
589        if(properties && (camera->initialize(properties) != android::NO_ERROR))
590        {
591            ALOGE("Couldn't initialize camera instance");
592            rv = -ENODEV;
593            goto fail;
594        }
595
596        gCameraHals[cameraid] = camera;
597        gCamerasOpen++;
598    }
599
600    return rv;
601
602fail:
603    if(camera_device) {
604        free(camera_device);
605        camera_device = NULL;
606    }
607    if(camera_ops) {
608        free(camera_ops);
609        camera_ops = NULL;
610    }
611    if(camera) {
612        delete camera;
613        camera = NULL;
614    }
615    *device = NULL;
616    return rv;
617}
618
619int camera_get_number_of_cameras(void)
620{
621    int num_cameras = MAX_CAMERAS_SUPPORTED;
622
623    // TODO(XXX): Ducati is not loaded yet when camera service gets here
624    //  Lets revisit this later to see if we can somehow get this working
625#if 0
626    // this going to be the first call from camera service
627    // initialize camera properties here...
628    if(gCameraProperties.initialize() != android::NO_ERROR)
629    {
630        CAMHAL_LOGEA("Unable to create or initialize CameraProperties");
631        return NULL;
632    }
633
634    num_cameras = gCameraProperties.camerasSupported();
635#endif
636
637    return num_cameras;
638}
639
640int camera_get_camera_info(int camera_id, struct camera_info *info)
641{
642    int rv = 0;
643    int face_value = CAMERA_FACING_BACK;
644    int orientation = 0;
645    const char *valstr = NULL;
646    android::CameraProperties::Properties* properties = NULL;
647
648    // this going to be the first call from camera service
649    // initialize camera properties here...
650    if(gCameraProperties.initialize() != android::NO_ERROR)
651    {
652        CAMHAL_LOGEA("Unable to create or initialize CameraProperties");
653        return NULL;
654    }
655
656    //Get camera properties for camera index
657    if(gCameraProperties.getProperties(camera_id, &properties) < 0)
658    {
659        ALOGE("Couldn't get camera properties");
660        rv = -EINVAL;
661        goto end;
662    }
663
664    if(properties)
665    {
666        valstr = properties->get(android::CameraProperties::FACING_INDEX);
667        if(valstr != NULL)
668        {
669            if (strcmp(valstr, (const char *) android::TICameraParameters::FACING_FRONT) == 0)
670            {
671                face_value = CAMERA_FACING_FRONT;
672            }
673            else if (strcmp(valstr, (const char *) android::TICameraParameters::FACING_BACK) == 0)
674            {
675                face_value = CAMERA_FACING_BACK;
676            }
677         }
678
679         valstr = properties->get(android::CameraProperties::ORIENTATION_INDEX);
680         if(valstr != NULL)
681         {
682             orientation = atoi(valstr);
683         }
684    }
685    else
686    {
687        CAMHAL_LOGEB("getProperties() returned a NULL property set for Camera id %d", camera_id);
688    }
689
690    info->facing = face_value;
691    info->orientation = orientation;
692
693end:
694    return rv;
695}
696
697
698
699
700
701