Home | History | Annotate | Download | only in util
      1 /* Copyright (c) 2015-2016, 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 
     30 // System dependencies
     31 #include <stdio.h>
     32 #include <fcntl.h>
     33 #include <media/msm_cam_sensor.h>
     34 
     35 // Camera dependencies
     36 #include "HAL3/QCamera3HWI.h"
     37 #include "QCameraFlash.h"
     38 
     39 extern "C" {
     40 #include "mm_camera_dbg.h"
     41 }
     42 
     43 #define STRING_LENGTH_OF_64_BIT_NUMBER 21
     44 
     45 volatile uint32_t gCamHal3LogLevel = 1;
     46 
     47 namespace qcamera {
     48 
     49 /*===========================================================================
     50  * FUNCTION   : getInstance
     51  *
     52  * DESCRIPTION: Get and create the QCameraFlash singleton.
     53  *
     54  * PARAMETERS : None
     55  *
     56  * RETURN     : None
     57  *==========================================================================*/
     58 QCameraFlash& QCameraFlash::getInstance()
     59 {
     60     static QCameraFlash flashInstance;
     61     return flashInstance;
     62 }
     63 
     64 /*===========================================================================
     65  * FUNCTION   : QCameraFlash
     66  *
     67  * DESCRIPTION: default constructor of QCameraFlash
     68  *
     69  * PARAMETERS : None
     70  *
     71  * RETURN     : None
     72  *==========================================================================*/
     73 QCameraFlash::QCameraFlash() : m_callbacks(NULL)
     74 {
     75     memset(&m_flashOn, 0, sizeof(m_flashOn));
     76     memset(&m_cameraOpen, 0, sizeof(m_cameraOpen));
     77     for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
     78         m_flashFds[pos] = -1;
     79     }
     80 }
     81 
     82 /*===========================================================================
     83  * FUNCTION   : ~QCameraFlash
     84  *
     85  * DESCRIPTION: deconstructor of QCameraFlash
     86  *
     87  * PARAMETERS : None
     88  *
     89  * RETURN     : None
     90  *==========================================================================*/
     91 QCameraFlash::~QCameraFlash()
     92 {
     93     for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
     94         if (m_flashFds[pos] >= 0)
     95             {
     96                 setFlashMode(pos, false);
     97                 close(m_flashFds[pos]);
     98                 m_flashFds[pos] = -1;
     99             }
    100     }
    101 }
    102 
    103 /*===========================================================================
    104  * FUNCTION   : registerCallbacks
    105  *
    106  * DESCRIPTION: provide flash module with reference to callbacks to framework
    107  *
    108  * PARAMETERS : None
    109  *
    110  * RETURN     : None
    111  *==========================================================================*/
    112 int32_t QCameraFlash::registerCallbacks(
    113         const camera_module_callbacks_t* callbacks)
    114 {
    115     int32_t retVal = 0;
    116     m_callbacks = callbacks;
    117     return retVal;
    118 }
    119 
    120 /*===========================================================================
    121  * FUNCTION   : initFlash
    122  *
    123  * DESCRIPTION: Reserve and initialize the flash unit associated with a
    124  *              given camera id. This function is blocking until the
    125  *              operation completes or fails. Each flash unit can be "inited"
    126  *              by only one process at a time.
    127  *
    128  * PARAMETERS :
    129  *   @camera_id : Camera id of the flash.
    130  *
    131  * RETURN     :
    132  *   0        : success
    133  *   -EBUSY   : The flash unit or the resource needed to turn on the
    134  *              the flash is busy, typically because the flash is
    135  *              already in use.
    136  *   -EINVAL  : No flash present at camera_id.
    137  *==========================================================================*/
    138 int32_t QCameraFlash::initFlash(const int camera_id)
    139 {
    140     int32_t retVal = 0;
    141     bool hasFlash = false;
    142     char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
    143     char flashPath[QCAMERA_MAX_FILEPATH_LENGTH] = "/dev/";
    144 
    145     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    146         LOGE("Invalid camera id: %d", camera_id);
    147         return -EINVAL;
    148     }
    149 
    150     QCamera3HardwareInterface::getFlashInfo(camera_id,
    151             hasFlash,
    152             flashNode);
    153 
    154     strlcat(flashPath,
    155             flashNode,
    156             sizeof(flashPath));
    157 
    158     if (!hasFlash) {
    159         LOGE("No flash available for camera id: %d",
    160                 camera_id);
    161         retVal = -ENOSYS;
    162     } else if (m_cameraOpen[camera_id]) {
    163         LOGE("Camera in use for camera id: %d",
    164                 camera_id);
    165         retVal = -EBUSY;
    166     } else if (m_flashFds[camera_id] >= 0) {
    167         LOGD("Flash is already inited for camera id: %d",
    168                 camera_id);
    169     } else {
    170         m_flashFds[camera_id] = open(flashPath, O_RDWR | O_NONBLOCK);
    171 
    172         if (m_flashFds[camera_id] < 0) {
    173             LOGE("Unable to open node '%s'",
    174                     flashPath);
    175             retVal = -EBUSY;
    176         } else {
    177             struct msm_flash_cfg_data_t cfg;
    178             struct msm_flash_init_info_t init_info;
    179             memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
    180             memset(&init_info, 0, sizeof(struct msm_flash_init_info_t));
    181             init_info.flash_driver_type = FLASH_DRIVER_DEFAULT;
    182             cfg.cfg.flash_init_info = &init_info;
    183             cfg.cfg_type = CFG_FLASH_INIT;
    184             retVal = ioctl(m_flashFds[camera_id],
    185                     VIDIOC_MSM_FLASH_CFG,
    186                     &cfg);
    187             if (retVal < 0) {
    188                 LOGE("Unable to init flash for camera id: %d",
    189                         camera_id);
    190                 close(m_flashFds[camera_id]);
    191                 m_flashFds[camera_id] = -1;
    192             }
    193 
    194             /* wait for PMIC to init */
    195             usleep(5000);
    196         }
    197     }
    198 
    199     LOGD("X, retVal = %d", retVal);
    200     return retVal;
    201 }
    202 
    203 /*===========================================================================
    204  * FUNCTION   : setFlashMode
    205  *
    206  * DESCRIPTION: Turn on or off the flash associated with a given handle.
    207  *              This function is blocking until the operation completes or
    208  *              fails.
    209  *
    210  * PARAMETERS :
    211  *   @camera_id  : Camera id of the flash
    212  *   @on         : Whether to turn flash on (true) or off (false)
    213  *
    214  * RETURN     :
    215  *   0        : success
    216  *   -EINVAL  : No camera present at camera_id, or it is not inited.
    217  *   -EALREADY: Flash is already in requested state
    218  *==========================================================================*/
    219 int32_t QCameraFlash::setFlashMode(const int camera_id, const bool mode)
    220 {
    221     int32_t retVal = 0;
    222     struct msm_flash_cfg_data_t cfg;
    223 
    224     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    225         LOGE("Invalid camera id: %d", camera_id);
    226         retVal = -EINVAL;
    227     } else if (mode == m_flashOn[camera_id]) {
    228         LOGD("flash %d is already in requested state: %d",
    229                 camera_id,
    230                 mode);
    231         retVal = -EALREADY;
    232     } else if (m_flashFds[camera_id] < 0) {
    233         LOGE("called for uninited flash: %d", camera_id);
    234         retVal = -EINVAL;
    235     }  else {
    236         memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
    237         for (int i = 0; i < MAX_LED_TRIGGERS; i++)
    238             cfg.flash_current[i] = QCAMERA_TORCH_CURRENT_VALUE;
    239         cfg.cfg_type = mode ? CFG_FLASH_LOW: CFG_FLASH_OFF;
    240 
    241         retVal = ioctl(m_flashFds[camera_id],
    242                         VIDIOC_MSM_FLASH_CFG,
    243                         &cfg);
    244         if (retVal < 0) {
    245             LOGE("Unable to change flash mode to %d for camera id: %d",
    246                      mode, camera_id);
    247         } else
    248         {
    249             m_flashOn[camera_id] = mode;
    250         }
    251     }
    252     return retVal;
    253 }
    254 
    255 /*===========================================================================
    256  * FUNCTION   : deinitFlash
    257  *
    258  * DESCRIPTION: Release the flash unit associated with a given camera
    259  *              position. This function is blocking until the operation
    260  *              completes or fails.
    261  *
    262  * PARAMETERS :
    263  *   @camera_id : Camera id of the flash.
    264  *
    265  * RETURN     :
    266  *   0        : success
    267  *   -EINVAL  : No camera present at camera_id or not inited.
    268  *==========================================================================*/
    269 int32_t QCameraFlash::deinitFlash(const int camera_id)
    270 {
    271     int32_t retVal = 0;
    272 
    273     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    274         LOGE("Invalid camera id: %d", camera_id);
    275         retVal = -EINVAL;
    276     } else if (m_flashFds[camera_id] < 0) {
    277         LOGE("called deinitFlash for uninited flash");
    278         retVal = -EINVAL;
    279     } else {
    280         setFlashMode(camera_id, false);
    281 
    282         struct msm_flash_cfg_data_t cfg;
    283         cfg.cfg_type = CFG_FLASH_RELEASE;
    284         retVal = ioctl(m_flashFds[camera_id],
    285                 VIDIOC_MSM_FLASH_CFG,
    286                 &cfg);
    287         if (retVal < 0) {
    288             LOGE("Failed to release flash for camera id: %d",
    289                     camera_id);
    290         }
    291 
    292         close(m_flashFds[camera_id]);
    293         m_flashFds[camera_id] = -1;
    294     }
    295 
    296     return retVal;
    297 }
    298 
    299 /*===========================================================================
    300  * FUNCTION   : reserveFlashForCamera
    301  *
    302  * DESCRIPTION: Give control of the flash to the camera, and notify
    303  *              framework that the flash has become unavailable.
    304  *
    305  * PARAMETERS :
    306  *   @camera_id : Camera id of the flash.
    307  *
    308  * RETURN     :
    309  *   0        : success
    310  *   -EINVAL  : No camera present at camera_id or not inited.
    311  *   -ENOSYS  : No callback available for torch_mode_status_change.
    312  *==========================================================================*/
    313 int32_t QCameraFlash::reserveFlashForCamera(const int camera_id)
    314 {
    315     int32_t retVal = 0;
    316 
    317     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    318         LOGE("Invalid camera id: %d", camera_id);
    319         retVal = -EINVAL;
    320     } else if (m_cameraOpen[camera_id]) {
    321         LOGD("Flash already reserved for camera id: %d",
    322                 camera_id);
    323     } else {
    324         if (m_flashOn[camera_id]) {
    325             setFlashMode(camera_id, false);
    326             deinitFlash(camera_id);
    327         }
    328         m_cameraOpen[camera_id] = true;
    329 
    330         bool hasFlash = false;
    331         char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
    332 
    333         QCamera3HardwareInterface::getFlashInfo(camera_id,
    334                 hasFlash,
    335                 flashNode);
    336 
    337         if (m_callbacks == NULL ||
    338                 m_callbacks->torch_mode_status_change == NULL) {
    339             LOGE("Callback is not defined!");
    340             retVal = -ENOSYS;
    341         } else if (!hasFlash) {
    342             LOGD("Suppressing callback "
    343                     "because no flash exists for camera id: %d",
    344                     camera_id);
    345         } else {
    346             char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
    347             snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
    348                     "%d", camera_id);
    349             m_callbacks->torch_mode_status_change(m_callbacks,
    350                     cameraIdStr,
    351                     TORCH_MODE_STATUS_NOT_AVAILABLE);
    352         }
    353     }
    354 
    355     return retVal;
    356 }
    357 
    358 /*===========================================================================
    359  * FUNCTION   : releaseFlashFromCamera
    360  *
    361  * DESCRIPTION: Release control of the flash from the camera, and notify
    362  *              framework that the flash has become available.
    363  *
    364  * PARAMETERS :
    365  *   @camera_id : Camera id of the flash.
    366  *
    367  * RETURN     :
    368  *   0        : success
    369  *   -EINVAL  : No camera present at camera_id or not inited.
    370  *   -ENOSYS  : No callback available for torch_mode_status_change.
    371  *==========================================================================*/
    372 int32_t QCameraFlash::releaseFlashFromCamera(const int camera_id)
    373 {
    374     int32_t retVal = 0;
    375 
    376     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    377         LOGE("Invalid camera id: %d", camera_id);
    378         retVal = -EINVAL;
    379     } else if (!m_cameraOpen[camera_id]) {
    380         LOGD("Flash not reserved for camera id: %d",
    381                 camera_id);
    382     } else {
    383         m_cameraOpen[camera_id] = false;
    384 
    385         bool hasFlash = false;
    386         char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
    387 
    388         QCamera3HardwareInterface::getFlashInfo(camera_id,
    389                 hasFlash,
    390                 flashNode);
    391 
    392         if (m_callbacks == NULL ||
    393                 m_callbacks->torch_mode_status_change == NULL) {
    394             LOGE("Callback is not defined!");
    395             retVal = -ENOSYS;
    396         } else if (!hasFlash) {
    397             LOGD("Suppressing callback "
    398                     "because no flash exists for camera id: %d",
    399                     camera_id);
    400         } else {
    401             char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
    402             snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
    403                     "%d", camera_id);
    404             m_callbacks->torch_mode_status_change(m_callbacks,
    405                     cameraIdStr,
    406                     TORCH_MODE_STATUS_AVAILABLE_OFF);
    407         }
    408     }
    409 
    410     return retVal;
    411 }
    412 
    413 }; // namespace qcamera
    414