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