aboutsummaryrefslogtreecommitdiff
path: root/camera/QCamera2/util/QCameraFlash.cpp
diff options
context:
space:
mode:
authorPrateek Chaubey <chaubeyprateek@gmail.com>2018-01-07 20:55:14 +0530
committerDavide Garberi <dade.garberi@gmail.com>2018-01-19 14:09:15 +0100
commit6616278131edd80a12545085e06ee6b0e0a0a788 (patch)
tree0aef88ed11809a9d67f6abe4dc2ff782a14737e2 /camera/QCamera2/util/QCameraFlash.cpp
parentcc4ccf34871da343111bf68d16ba4e4c67cac1dc (diff)
msm8996-common: zuk: Import OSS Camera HAL
Tag: LA.HB.1.3.2-32600-8x96.0 Signed-off-by: Davide Garberi <dade.garberi@gmail.com>
Diffstat (limited to '')
-rw-r--r--camera/QCamera2/util/QCameraFlash.cpp413
1 files changed, 413 insertions, 0 deletions
diff --git a/camera/QCamera2/util/QCameraFlash.cpp b/camera/QCamera2/util/QCameraFlash.cpp
new file mode 100644
index 0000000..db517b6
--- /dev/null
+++ b/camera/QCamera2/util/QCameraFlash.cpp
@@ -0,0 +1,413 @@
+/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+// System dependencies
+#include <stdio.h>
+#include <fcntl.h>
+#include <media/msm_cam_sensor.h>
+
+// Camera dependencies
+#include "HAL3/QCamera3HWI.h"
+#include "QCameraFlash.h"
+
+extern "C" {
+#include "mm_camera_dbg.h"
+}
+
+#define STRING_LENGTH_OF_64_BIT_NUMBER 21
+
+volatile uint32_t gCamHal3LogLevel = 1;
+
+namespace qcamera {
+
+/*===========================================================================
+ * FUNCTION : getInstance
+ *
+ * DESCRIPTION: Get and create the QCameraFlash singleton.
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraFlash& QCameraFlash::getInstance()
+{
+ static QCameraFlash flashInstance;
+ return flashInstance;
+}
+
+/*===========================================================================
+ * FUNCTION : QCameraFlash
+ *
+ * DESCRIPTION: default constructor of QCameraFlash
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraFlash::QCameraFlash() : m_callbacks(NULL)
+{
+ memset(&m_flashOn, 0, sizeof(m_flashOn));
+ memset(&m_cameraOpen, 0, sizeof(m_cameraOpen));
+ for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
+ m_flashFds[pos] = -1;
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : ~QCameraFlash
+ *
+ * DESCRIPTION: deconstructor of QCameraFlash
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+QCameraFlash::~QCameraFlash()
+{
+ for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
+ if (m_flashFds[pos] >= 0)
+ {
+ setFlashMode(pos, false);
+ close(m_flashFds[pos]);
+ m_flashFds[pos] = -1;
+ }
+ }
+}
+
+/*===========================================================================
+ * FUNCTION : registerCallbacks
+ *
+ * DESCRIPTION: provide flash module with reference to callbacks to framework
+ *
+ * PARAMETERS : None
+ *
+ * RETURN : None
+ *==========================================================================*/
+int32_t QCameraFlash::registerCallbacks(
+ const camera_module_callbacks_t* callbacks)
+{
+ int32_t retVal = 0;
+ m_callbacks = callbacks;
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : initFlash
+ *
+ * DESCRIPTION: Reserve and initialize the flash unit associated with a
+ * given camera id. This function is blocking until the
+ * operation completes or fails. Each flash unit can be "inited"
+ * by only one process at a time.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EBUSY : The flash unit or the resource needed to turn on the
+ * the flash is busy, typically because the flash is
+ * already in use.
+ * -EINVAL : No flash present at camera_id.
+ *==========================================================================*/
+int32_t QCameraFlash::initFlash(const int camera_id)
+{
+ int32_t retVal = 0;
+ bool hasFlash = false;
+ char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
+ char flashPath[QCAMERA_MAX_FILEPATH_LENGTH] = "/dev/";
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ return -EINVAL;
+ }
+
+ QCamera3HardwareInterface::getFlashInfo(camera_id,
+ hasFlash,
+ flashNode);
+
+ strlcat(flashPath,
+ flashNode,
+ sizeof(flashPath));
+
+ if (!hasFlash) {
+ LOGE("No flash available for camera id: %d",
+ camera_id);
+ retVal = -EINVAL;
+ } else if (m_cameraOpen[camera_id]) {
+ LOGE("Camera in use for camera id: %d",
+ camera_id);
+ retVal = -EBUSY;
+ } else if (m_flashFds[camera_id] >= 0) {
+ LOGD("Flash is already inited for camera id: %d",
+ camera_id);
+ } else {
+ m_flashFds[camera_id] = open(flashPath, O_RDWR | O_NONBLOCK);
+
+ if (m_flashFds[camera_id] < 0) {
+ LOGE("Unable to open node '%s'",
+ flashPath);
+ retVal = -EBUSY;
+ } else {
+ struct msm_flash_cfg_data_t cfg;
+ struct msm_flash_init_info_t init_info;
+ memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
+ memset(&init_info, 0, sizeof(struct msm_flash_init_info_t));
+ init_info.flash_driver_type = FLASH_DRIVER_DEFAULT;
+ cfg.cfg.flash_init_info = &init_info;
+ cfg.cfg_type = CFG_FLASH_INIT;
+ retVal = ioctl(m_flashFds[camera_id],
+ VIDIOC_MSM_FLASH_CFG,
+ &cfg);
+ if (retVal < 0) {
+ LOGE("Unable to init flash for camera id: %d",
+ camera_id);
+ close(m_flashFds[camera_id]);
+ m_flashFds[camera_id] = -1;
+ }
+
+ /* wait for PMIC to init */
+ usleep(5000);
+ }
+ }
+
+ LOGD("X, retVal = %d", retVal);
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : setFlashMode
+ *
+ * DESCRIPTION: Turn on or off the flash associated with a given handle.
+ * This function is blocking until the operation completes or
+ * fails.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash
+ * @on : Whether to turn flash on (true) or off (false)
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id, or it is not inited.
+ * -EALREADY: Flash is already in requested state
+ *==========================================================================*/
+int32_t QCameraFlash::setFlashMode(const int camera_id, const bool mode)
+{
+ int32_t retVal = 0;
+ struct msm_flash_cfg_data_t cfg;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (mode == m_flashOn[camera_id]) {
+ LOGD("flash %d is already in requested state: %d",
+ camera_id,
+ mode);
+ retVal = -EALREADY;
+ } else if (m_flashFds[camera_id] < 0) {
+ LOGE("called for uninited flash: %d", camera_id);
+ retVal = -EINVAL;
+ } else {
+ memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
+ for (int i = 0; i < MAX_LED_TRIGGERS; i++)
+ cfg.flash_current[i] = QCAMERA_TORCH_CURRENT_VALUE;
+ cfg.cfg_type = mode ? CFG_FLASH_LOW: CFG_FLASH_OFF;
+
+ retVal = ioctl(m_flashFds[camera_id],
+ VIDIOC_MSM_FLASH_CFG,
+ &cfg);
+ if (retVal < 0) {
+ LOGE("Unable to change flash mode to %d for camera id: %d",
+ mode, camera_id);
+ } else
+ {
+ m_flashOn[camera_id] = mode;
+ }
+ }
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : deinitFlash
+ *
+ * DESCRIPTION: Release the flash unit associated with a given camera
+ * position. This function is blocking until the operation
+ * completes or fails.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id or not inited.
+ *==========================================================================*/
+int32_t QCameraFlash::deinitFlash(const int camera_id)
+{
+ int32_t retVal = 0;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (m_flashFds[camera_id] < 0) {
+ LOGE("called deinitFlash for uninited flash");
+ retVal = -EINVAL;
+ } else {
+ setFlashMode(camera_id, false);
+
+ struct msm_flash_cfg_data_t cfg;
+ cfg.cfg_type = CFG_FLASH_RELEASE;
+ retVal = ioctl(m_flashFds[camera_id],
+ VIDIOC_MSM_FLASH_CFG,
+ &cfg);
+ if (retVal < 0) {
+ LOGE("Failed to release flash for camera id: %d",
+ camera_id);
+ }
+
+ close(m_flashFds[camera_id]);
+ m_flashFds[camera_id] = -1;
+ }
+
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : reserveFlashForCamera
+ *
+ * DESCRIPTION: Give control of the flash to the camera, and notify
+ * framework that the flash has become unavailable.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id or not inited.
+ * -ENOSYS : No callback available for torch_mode_status_change.
+ *==========================================================================*/
+int32_t QCameraFlash::reserveFlashForCamera(const int camera_id)
+{
+ int32_t retVal = 0;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (m_cameraOpen[camera_id]) {
+ LOGD("Flash already reserved for camera id: %d",
+ camera_id);
+ } else {
+ if (m_flashOn[camera_id]) {
+ setFlashMode(camera_id, false);
+ deinitFlash(camera_id);
+ }
+ m_cameraOpen[camera_id] = true;
+
+ bool hasFlash = false;
+ char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
+
+ QCamera3HardwareInterface::getFlashInfo(camera_id,
+ hasFlash,
+ flashNode);
+
+ if (m_callbacks == NULL ||
+ m_callbacks->torch_mode_status_change == NULL) {
+ LOGE("Callback is not defined!");
+ retVal = -ENOSYS;
+ } else if (!hasFlash) {
+ LOGD("Suppressing callback "
+ "because no flash exists for camera id: %d",
+ camera_id);
+ } else {
+ char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
+ snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
+ "%d", camera_id);
+ m_callbacks->torch_mode_status_change(m_callbacks,
+ cameraIdStr,
+ TORCH_MODE_STATUS_NOT_AVAILABLE);
+ }
+ }
+
+ return retVal;
+}
+
+/*===========================================================================
+ * FUNCTION : releaseFlashFromCamera
+ *
+ * DESCRIPTION: Release control of the flash from the camera, and notify
+ * framework that the flash has become available.
+ *
+ * PARAMETERS :
+ * @camera_id : Camera id of the flash.
+ *
+ * RETURN :
+ * 0 : success
+ * -EINVAL : No camera present at camera_id or not inited.
+ * -ENOSYS : No callback available for torch_mode_status_change.
+ *==========================================================================*/
+int32_t QCameraFlash::releaseFlashFromCamera(const int camera_id)
+{
+ int32_t retVal = 0;
+
+ if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
+ LOGE("Invalid camera id: %d", camera_id);
+ retVal = -EINVAL;
+ } else if (!m_cameraOpen[camera_id]) {
+ LOGD("Flash not reserved for camera id: %d",
+ camera_id);
+ } else {
+ m_cameraOpen[camera_id] = false;
+
+ bool hasFlash = false;
+ char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
+
+ QCamera3HardwareInterface::getFlashInfo(camera_id,
+ hasFlash,
+ flashNode);
+
+ if (m_callbacks == NULL ||
+ m_callbacks->torch_mode_status_change == NULL) {
+ LOGE("Callback is not defined!");
+ retVal = -ENOSYS;
+ } else if (!hasFlash) {
+ LOGD("Suppressing callback "
+ "because no flash exists for camera id: %d",
+ camera_id);
+ } else {
+ char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
+ snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
+ "%d", camera_id);
+ m_callbacks->torch_mode_status_change(m_callbacks,
+ cameraIdStr,
+ TORCH_MODE_STATUS_AVAILABLE_OFF);
+ }
+ }
+
+ return retVal;
+}
+
+}; // namespace qcamera