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_camera_led_cfg_t cfg;
    179             cfg.cfgtype = MSM_CAMERA_LED_INIT;
    180             retVal = ioctl(m_flashFds[camera_id],
    181                     VIDIOC_MSM_FLASH_LED_DATA_CFG,
    182                     &cfg);
    183             if (retVal < 0) {
    184                 ALOGE("%s: Unable to init flash for camera id: %d",
    185                         __func__,
    186                         camera_id);
    187                 close(m_flashFds[camera_id]);
    188                 m_flashFds[camera_id] = -1;
    189             }
    190         }
    191     }
    192 
    193     return retVal;
    194 }
    195 
    196 /*===========================================================================
    197  * FUNCTION   : setFlashMode
    198  *
    199  * DESCRIPTION: Turn on or off the flash associated with a given handle.
    200  *              This function is blocking until the operation completes or
    201  *              fails.
    202  *
    203  * PARAMETERS :
    204  *   @camera_id  : Camera id of the flash
    205  *   @on         : Whether to turn flash on (true) or off (false)
    206  *
    207  * RETURN     :
    208  *   0        : success
    209  *   -EINVAL  : No camera present at camera_id, or it is not inited.
    210  *   -EALREADY: Flash is already in requested state
    211  *==========================================================================*/
    212 int32_t QCameraFlash::setFlashMode(const int camera_id, const bool mode)
    213 {
    214     int32_t retVal = 0;
    215     struct msm_camera_led_cfg_t cfg;
    216 
    217     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    218         ALOGE("%s: Invalid camera id: %d", __func__, camera_id);
    219         retVal = -EINVAL;
    220     } else if (mode == m_flashOn[camera_id]) {
    221         CDBG("%s: flash %d is already in requested state: %d",
    222                 __func__,
    223                 camera_id,
    224                 mode);
    225         retVal = -EALREADY;
    226     } else if (m_flashFds[camera_id] < 0) {
    227         ALOGE("%s: called for uninited flash: %d", __func__, camera_id);
    228         retVal = -EINVAL;
    229     }  else {
    230         cfg.cfgtype = mode ? MSM_CAMERA_LED_LOW : MSM_CAMERA_LED_OFF;
    231         retVal = ioctl(m_flashFds[camera_id],
    232                 VIDIOC_MSM_FLASH_LED_DATA_CFG,
    233                 &cfg);
    234         if (retVal == 0) {
    235             m_flashOn[camera_id] = mode;
    236         }
    237     }
    238     return retVal;
    239 }
    240 
    241 /*===========================================================================
    242  * FUNCTION   : deinitFlash
    243  *
    244  * DESCRIPTION: Release the flash unit associated with a given camera
    245  *              position. This function is blocking until the operation
    246  *              completes or fails.
    247  *
    248  * PARAMETERS :
    249  *   @camera_id : Camera id of the flash.
    250  *
    251  * RETURN     :
    252  *   0        : success
    253  *   -EINVAL  : No camera present at camera_id or not inited.
    254  *==========================================================================*/
    255 int32_t QCameraFlash::deinitFlash(const int camera_id)
    256 {
    257     int32_t retVal = 0;
    258 
    259     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    260         ALOGE("%s: Invalid camera id: %d", __func__, camera_id);
    261         retVal = -EINVAL;
    262     } else if (m_flashFds[camera_id] < 0) {
    263         ALOGE("%s: called deinitFlash for uninited flash", __func__);
    264         retVal = -EINVAL;
    265     } else {
    266         setFlashMode(camera_id, false);
    267 
    268         struct msm_camera_led_cfg_t cfg;
    269         cfg.cfgtype = MSM_CAMERA_LED_RELEASE;
    270         retVal = ioctl(m_flashFds[camera_id],
    271                 VIDIOC_MSM_FLASH_LED_DATA_CFG,
    272                 &cfg);
    273         if (retVal < 0) {
    274             ALOGE("%s: Failed to release flash for camera id: %d",
    275                     __func__,
    276                     camera_id);
    277         }
    278 
    279         close(m_flashFds[camera_id]);
    280         m_flashFds[camera_id] = -1;
    281     }
    282 
    283     return retVal;
    284 }
    285 
    286 /*===========================================================================
    287  * FUNCTION   : reserveFlashForCamera
    288  *
    289  * DESCRIPTION: Give control of the flash to the camera, and notify
    290  *              framework that the flash has become unavailable.
    291  *
    292  * PARAMETERS :
    293  *   @camera_id : Camera id of the flash.
    294  *
    295  * RETURN     :
    296  *   0        : success
    297  *   -EINVAL  : No camera present at camera_id or not inited.
    298  *   -ENOSYS  : No callback available for torch_mode_status_change.
    299  *==========================================================================*/
    300 int32_t QCameraFlash::reserveFlashForCamera(const int camera_id)
    301 {
    302     int32_t retVal = 0;
    303 
    304     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    305         ALOGE("%s: Invalid camera id: %d", __func__, camera_id);
    306         retVal = -EINVAL;
    307     } else if (m_cameraOpen[camera_id]) {
    308         CDBG("%s: Flash already reserved for camera id: %d",
    309                 __func__,
    310                 camera_id);
    311     } else {
    312         if (m_flashOn[camera_id]) {
    313             setFlashMode(camera_id, false);
    314             deinitFlash(camera_id);
    315         }
    316         m_cameraOpen[camera_id] = true;
    317 
    318         bool hasFlash = false;
    319         char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
    320 
    321         QCamera3HardwareInterface::getFlashInfo(camera_id,
    322                 hasFlash,
    323                 flashNode);
    324 
    325         if (m_callbacks == NULL ||
    326                 m_callbacks->torch_mode_status_change == NULL) {
    327             ALOGE("%s: Callback is not defined!", __func__);
    328             retVal = -ENOSYS;
    329         } else if (!hasFlash) {
    330             CDBG("%s: Suppressing callback "
    331                     "because no flash exists for camera id: %d",
    332                     __func__,
    333                     camera_id);
    334         } else {
    335             char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
    336             snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
    337                     "%d", camera_id);
    338             m_callbacks->torch_mode_status_change(m_callbacks,
    339                     cameraIdStr,
    340                     TORCH_MODE_STATUS_NOT_AVAILABLE);
    341         }
    342     }
    343 
    344     return retVal;
    345 }
    346 
    347 /*===========================================================================
    348  * FUNCTION   : releaseFlashFromCamera
    349  *
    350  * DESCRIPTION: Release control of the flash from the camera, and notify
    351  *              framework that the flash has become available.
    352  *
    353  * PARAMETERS :
    354  *   @camera_id : Camera id of the flash.
    355  *
    356  * RETURN     :
    357  *   0        : success
    358  *   -EINVAL  : No camera present at camera_id or not inited.
    359  *   -ENOSYS  : No callback available for torch_mode_status_change.
    360  *==========================================================================*/
    361 int32_t QCameraFlash::releaseFlashFromCamera(const int camera_id)
    362 {
    363     int32_t retVal = 0;
    364 
    365     if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
    366         ALOGE("%s: Invalid camera id: %d", __func__, camera_id);
    367         retVal = -EINVAL;
    368     } else if (!m_cameraOpen[camera_id]) {
    369         CDBG("%s: Flash not reserved for camera id: %d",
    370                 __func__,
    371                 camera_id);
    372     } else {
    373         m_cameraOpen[camera_id] = false;
    374 
    375         bool hasFlash = false;
    376         char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
    377 
    378         QCamera3HardwareInterface::getFlashInfo(camera_id,
    379                 hasFlash,
    380                 flashNode);
    381 
    382         if (m_callbacks == NULL ||
    383                 m_callbacks->torch_mode_status_change == NULL) {
    384             ALOGE("%s: Callback is not defined!", __func__);
    385             retVal = -ENOSYS;
    386         } else if (!hasFlash) {
    387             CDBG("%s: Suppressing callback "
    388                     "because no flash exists for camera id: %d",
    389                     __func__,
    390                     camera_id);
    391         } else {
    392             char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
    393             snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
    394                     "%d", camera_id);
    395             m_callbacks->torch_mode_status_change(m_callbacks,
    396                     cameraIdStr,
    397                     TORCH_MODE_STATUS_AVAILABLE_OFF);
    398         }
    399     }
    400 
    401     return retVal;
    402 }
    403 
    404 }; // namespace qcamera
    405