1 /* Copyright (c) 2011, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 /*#error uncomment this for compiler test!*/
30 
31 //#define ALOG_NDEBUG 0
32 #define ALOG_NIDEBUG 0
33 #define LOG_TAG "QualcommCamera"
34 #include <utils/Log.h>
35 #include <utils/threads.h>
36 #include <fcntl.h>
37 #include <sys/mman.h>
38 
39 #include "QCameraHAL.h"
40 /* include QCamera Hardware Interface Header*/
41 #include "QualcommCamera2.h"
42 //#include "QualcommCameraHardware.h"
43 //#include <camera/CameraHardwareInterface.h>
44 
45 extern "C" {
46 #include <sys/time.h>
47 }
48 
49 /* HAL function implementation goes here*/
50 
51 /**
52  * The functions need to be provided by the camera HAL.
53  *
54  * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
55  * and openCameraHardware() is 0 to N-1.
56  */
57 
58 static hw_module_methods_t camera_module_methods = {
59     .open = camera_device_open,
60 };
61 
62 static hw_module_t camera_common  = {
63   .tag = HARDWARE_MODULE_TAG,
64   .version_major = 0,
65   .version_minor = 01,
66   .id = CAMERA_HARDWARE_MODULE_ID,
67   .name = "Qcamera",
68   .author ="Qcom",
69   .methods = &camera_module_methods,
70   .dso = NULL,
71   //reserved[0]:  0,
72 };
73 camera_module_t HAL_MODULE_INFO_SYM = {
74   .common = camera_common,
75   .get_number_of_cameras = get_number_of_cameras,
76   .get_camera_info = get_camera_info,
77 };
78 
79 camera_device_ops_t camera_ops = {
80   .set_preview_window =         android::set_preview_window,
81   .set_callbacks =              android::set_CallBacks,
82   .enable_msg_type =            android::enable_msg_type,
83   .disable_msg_type =           android::disable_msg_type,
84   .msg_type_enabled =           android::msg_type_enabled,
85 
86   .start_preview =              android::start_preview,
87   .stop_preview =               android::stop_preview,
88   .preview_enabled =            android::preview_enabled,
89   .store_meta_data_in_buffers = android::store_meta_data_in_buffers,
90 
91   .start_recording =           android::start_recording,
92   .stop_recording =            android::stop_recording,
93   .recording_enabled =         android::recording_enabled,
94   .release_recording_frame =   android::release_recording_frame,
95 
96   .auto_focus =                android::auto_focus,
97   .cancel_auto_focus =         android::cancel_auto_focus,
98 
99   .take_picture =              android::take_picture,
100   .cancel_picture =            android::cancel_picture,
101 
102   .set_parameters =            android::set_parameters,
103   .get_parameters =            android::get_parameters,
104   .put_parameters =            android::put_parameters,
105   .send_command =              android::send_command,
106 
107   .release =                   android::release,
108   .dump =                      android::dump,
109 };
110 
111 namespace android {
112 
113 typedef struct {
114   camera_device hw_dev;
115   //sp<CameraHardwareInterface> hardware;
116   QCameraHardwareInterface *hardware;
117   int camera_released;
118   int cameraId;
119   //QCameraParameters parameters;
120 } camera_hardware_t;
121 
122 typedef struct {
123   camera_memory_t mem;
124   int32_t msgType;
125   sp<IMemory> dataPtr;
126   void* user;
127   unsigned int index;
128 } q_cam_memory_t;
129 
util_get_Hal_obj(struct camera_device * device)130 QCameraHardwareInterface *util_get_Hal_obj( struct camera_device * device)
131 {
132     QCameraHardwareInterface *hardware = NULL;
133     if(device && device->priv){
134         camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
135         hardware = camHal->hardware;
136     }
137     return hardware;
138 }
139 
140 #if 0
141 QCameraParameters* util_get_HAL_parameter( struct camera_device * device)
142 {
143     QCameraParameters *param = NULL;
144     if(device && device->priv){
145         camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
146         param = &(camHal->parameters);
147     }
148     return param;
149 }
150 #endif
get_number_of_cameras()151 extern "C" int get_number_of_cameras()
152 {
153     /* try to query every time we get the call!*/
154 
155     ALOGV("Q%s: E", __func__);
156     return android::HAL_getNumberOfCameras( );
157 }
158 
get_camera_info(int camera_id,struct camera_info * info)159 extern "C" int get_camera_info(int camera_id, struct camera_info *info)
160 {
161     int rc = -1;
162     ALOGV("Q%s: E", __func__);
163     if(info) {
164         struct CameraInfo camInfo;
165         memset(&camInfo, -1, sizeof (struct CameraInfo));
166         android::HAL_getCameraInfo(camera_id, &camInfo);
167         if (camInfo.facing >= 0) {
168             rc = 0;
169             info->facing = camInfo.facing;
170             info->orientation = camInfo.orientation;
171         }
172     }
173     ALOGV("Q%s: X", __func__);
174     return rc;
175 }
176 
177 static pthread_mutex_t camera_session_lock = PTHREAD_MUTEX_INITIALIZER;
178 static unsigned int QCameraSession = 0;
179 
180 /* HAL should return NULL if it fails to open camera hardware. */
camera_device_open(const struct hw_module_t * module,const char * id,struct hw_device_t ** hw_device)181 extern "C" int  camera_device_open(
182   const struct hw_module_t* module, const char* id,
183           struct hw_device_t** hw_device)
184 {
185     int rc = -1;
186     int mode = 0; // TODO: need to add 3d/2d mode, etc
187     camera_device *device = NULL;
188 
189     pthread_mutex_lock(&camera_session_lock);
190 
191     //Return -EUSERS to framework if multiple camera instances detected.
192     if(QCameraSession) {
193        ALOGE("%s Multiple camera open instances are not supported",__func__);
194        pthread_mutex_unlock(&camera_session_lock);
195        return -EUSERS;
196     }
197     if(module && id && hw_device) {
198         int cameraId = atoi(id);
199 
200         if (!strcmp(module->name, camera_common.name)) {
201             camera_hardware_t *camHal =
202                 (camera_hardware_t *) malloc(sizeof (camera_hardware_t));
203             if(!camHal) {
204                 *hw_device = NULL;
205                 ALOGE("%s:  end in no mem", __func__);
206                 pthread_mutex_unlock(&camera_session_lock);
207                 return rc;
208             }
209             /* we have the camera_hardware obj malloced */
210             memset(camHal, 0, sizeof (camera_hardware_t));
211             camHal->hardware = new QCameraHardwareInterface(cameraId, mode); //HAL_openCameraHardware(cameraId);
212             if (camHal->hardware && camHal->hardware->isCameraReady()) {
213                 camHal->cameraId = cameraId;
214                 device = &camHal->hw_dev;
215                 device->common.close = close_camera_device;
216                 device->ops = &camera_ops;
217                 device->priv = (void *)camHal;
218                 QCameraSession++;
219                 rc =  0;
220             } else {
221                 if (camHal->hardware) {
222                     delete camHal->hardware;
223                     camHal->hardware = NULL;
224                 }
225                 free(camHal);
226                 device = NULL;
227             }
228         }
229     }
230     /* pass actual hw_device ptr to framework. This amkes that we actally be use memberof() macro */
231     *hw_device = (hw_device_t*)&device->common;
232     ALOGV("%s:  end rc %d", __func__, rc);
233     pthread_mutex_unlock(&camera_session_lock);
234     return rc;
235 }
236 
close_camera_device(hw_device_t * hw_dev)237 extern "C"  int close_camera_device( hw_device_t *hw_dev)
238 {
239     ALOGV("Q%s: device =%p E", __func__, hw_dev);
240     int rc =  -1;
241     camera_device_t *device = (camera_device_t *)hw_dev;
242 
243     pthread_mutex_lock(&camera_session_lock);
244 
245     if(device) {
246         camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
247         if(camHal ) {
248             QCameraHardwareInterface *hardware = util_get_Hal_obj( device);
249             if(!camHal->camera_released) {
250                 if(hardware != NULL) {
251                     hardware->release( );
252                 }
253             }
254             if (QCameraSession)
255                 QCameraSession--;
256             if(hardware != NULL)
257                 delete hardware;
258             free(camHal);
259         }
260         rc = 0;
261     }
262 
263     pthread_mutex_unlock(&camera_session_lock);
264     return rc;
265 }
266 
267 
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)268 int set_preview_window(struct camera_device * device,
269         struct preview_stream_ops *window)
270 {
271     int rc = -1;
272     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
273 
274     if(hardware != NULL) {
275         rc = hardware->setPreviewWindow(window);
276     }
277     return rc;
278 }
279 
set_CallBacks(struct camera_device * device,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)280 void set_CallBacks(struct camera_device * device,
281         camera_notify_callback notify_cb,
282         camera_data_callback data_cb,
283         camera_data_timestamp_callback data_cb_timestamp,
284         camera_request_memory get_memory,
285         void *user)
286 {
287     ALOGV("Q%s: E", __func__);
288     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
289     if(hardware != NULL){
290         hardware->setCallbacks(notify_cb,data_cb, data_cb_timestamp, get_memory, user);
291     }
292 }
293 
enable_msg_type(struct camera_device * device,int32_t msg_type)294 void enable_msg_type(struct camera_device * device, int32_t msg_type)
295 {
296     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
297     if(hardware != NULL){
298         hardware->enableMsgType(msg_type);
299     }
300 }
301 
disable_msg_type(struct camera_device * device,int32_t msg_type)302 void disable_msg_type(struct camera_device * device, int32_t msg_type)
303 {
304     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
305     ALOGV("Q%s: E", __func__);
306     if(hardware != NULL){
307         hardware->disableMsgType(msg_type);
308     }
309 }
310 
msg_type_enabled(struct camera_device * device,int32_t msg_type)311 int msg_type_enabled(struct camera_device * device, int32_t msg_type)
312 {
313     ALOGV("Q%s: E", __func__);
314     int rc = -1;
315     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
316     if(hardware != NULL){
317         rc = hardware->msgTypeEnabled(msg_type);
318     }
319     return rc;
320 }
321 
start_preview(struct camera_device * device)322 int start_preview(struct camera_device * device)
323 {
324     ALOGV("Q%s: E", __func__);
325     int rc = -1;
326     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
327     if(hardware != NULL){
328         rc = hardware->startPreview( );
329     }
330     ALOGV("Q%s: X", __func__);
331     return rc;
332 }
333 
stop_preview(struct camera_device * device)334 void stop_preview(struct camera_device * device)
335 {
336     ALOGV("Q%s: E", __func__);
337     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
338     if(hardware != NULL){
339         hardware->stopPreview( );
340     }
341 }
342 
preview_enabled(struct camera_device * device)343 int preview_enabled(struct camera_device * device)
344 {
345     ALOGV("Q%s: E", __func__);
346     int rc = -1;
347     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
348     if(hardware != NULL){
349         rc = hardware->previewEnabled( );
350     }
351     return rc;
352 }
353 
store_meta_data_in_buffers(struct camera_device * device,int enable)354 int store_meta_data_in_buffers(struct camera_device * device, int enable)
355 {
356     ALOGV("Q%s: E", __func__);
357     int rc = -1;
358     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
359     if(hardware != NULL){
360       rc = hardware->storeMetaDataInBuffers(enable);
361     }
362     return rc;
363 }
364 
start_recording(struct camera_device * device)365 int start_recording(struct camera_device * device)
366 {
367     ALOGV("Q%s: E", __func__);
368     int rc = -1;
369     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
370     if(hardware != NULL){
371         rc = hardware->startRecording( );
372     }
373     return rc;
374 }
375 
stop_recording(struct camera_device * device)376 void stop_recording(struct camera_device * device)
377 {
378     ALOGV("Q%s: E", __func__);
379     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
380     if(hardware != NULL){
381         hardware->stopRecording( );
382     }
383 }
384 
recording_enabled(struct camera_device * device)385 int recording_enabled(struct camera_device * device)
386 {
387     ALOGV("Q%s: E", __func__);
388     int rc = -1;
389     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
390     if(hardware != NULL){
391         rc = hardware->recordingEnabled( );
392     }
393     return rc;
394 }
395 
release_recording_frame(struct camera_device * device,const void * opaque)396 void release_recording_frame(struct camera_device * device,
397                 const void *opaque)
398 {
399     ALOGV("Q%s: E", __func__);
400     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
401     if(hardware != NULL){
402         hardware->releaseRecordingFrame(opaque);
403     }
404 }
405 
auto_focus(struct camera_device * device)406 int auto_focus(struct camera_device * device)
407 {
408     ALOGV("Q%s: E", __func__);
409     int rc = -1;
410     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
411     if(hardware != NULL){
412         rc = hardware->autoFocus( );
413     }
414     return rc;
415 }
416 
cancel_auto_focus(struct camera_device * device)417 int cancel_auto_focus(struct camera_device * device)
418 {
419     ALOGV("Q%s: E", __func__);
420     int rc = -1;
421     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
422     if(hardware != NULL){
423         rc = hardware->cancelAutoFocus( );
424     }
425     return rc;
426 }
427 
take_picture(struct camera_device * device)428 int take_picture(struct camera_device * device)
429 {
430     ALOGV("Q%s: E", __func__);
431     int rc = -1;
432     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
433     if(hardware != NULL){
434         rc = hardware->takePicture( );
435     }
436     return rc;
437 }
438 
cancel_picture(struct camera_device * device)439 int cancel_picture(struct camera_device * device)
440 
441 {
442     ALOGV("Q%s: E", __func__);
443     int rc = -1;
444     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
445     if(hardware != NULL){
446         rc = hardware->cancelPicture( );
447     }
448     return rc;
449 }
450 
set_parameters(struct camera_device * device,const char * parms)451 int set_parameters(struct camera_device * device, const char *parms)
452 
453 {
454     ALOGV("Q%s: E", __func__);
455     int rc = -1;
456     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
457     if(hardware != NULL && parms){
458         //QCameraParameters param;// = util_get_HAL_parameter(device);
459         //String8 str = String8(parms);
460 
461         //param.unflatten(str);
462         rc = hardware->setParameters(parms);
463         //rc = 0;
464   }
465   return rc;
466 }
467 
get_parameters(struct camera_device * device)468 char* get_parameters(struct camera_device * device)
469 {
470     ALOGV("Q%s: E", __func__);
471     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
472     if(hardware != NULL){
473 		char *parms = NULL;
474         hardware->getParameters(&parms);
475 		return parms;
476     }
477     return NULL;
478 }
479 
put_parameters(struct camera_device * device,char * parm)480 void put_parameters(struct camera_device * device, char *parm)
481 
482 {
483     ALOGV("Q%s: E", __func__);
484     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
485     if(hardware != NULL){
486       hardware->putParameters(parm);
487     }
488 }
489 
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)490 int send_command(struct camera_device * device,
491             int32_t cmd, int32_t arg1, int32_t arg2)
492 {
493     ALOGV("Q%s: E", __func__);
494     int rc = -1;
495     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
496     if(hardware != NULL){
497         rc = hardware->sendCommand( cmd, arg1, arg2);
498     }
499     return rc;
500 }
501 
release(struct camera_device * device)502 void release(struct camera_device * device)
503 {
504     ALOGV("Q%s: E", __func__);
505     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
506     if(hardware != NULL){
507         camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
508         hardware->release( );
509         camHal->camera_released = true;
510     }
511 }
512 
dump(struct camera_device * device,int fd)513 int dump(struct camera_device * device, int fd)
514 {
515     ALOGV("Q%s: E", __func__);
516     int rc = -1;
517     QCameraHardwareInterface *hardware = util_get_Hal_obj(device);
518     if(hardware != NULL){
519         rc = hardware->dump( fd );
520       //rc = 0;
521     }
522     return rc;
523 }
524 
525 }; // namespace android
526