android13/hardware/rockchip/camera/common/FlashLight.cpp

308 lines
9.9 KiB
C++

/*
* Copyright (C) 2014-2017 Intel Corporation.
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "FlashLight"
#include <sys/stat.h>
#include "LogHelper.h"
#include <FlashLight.h>
#include "PlatformData.h"
namespace android {
namespace camera2 {
FlashLight& FlashLight::getInstance()
{
static FlashLight flashInstance;
return flashInstance;
}
FlashLight::FlashLight() : mCallbacks(NULL)
{
for (int camid = 0; camid< MAX_NUM_CAMERA; camid++) {
for (int flindex = 0; flindex < MAX_NUM_FLASH_OF_ONE_MODULE; flindex++) {
mFlashFds[camid][flindex] = -1;
mCameraOpen[camid] = false;
mFlashOn[camid][flindex] = false;
}
}
}
FlashLight::~FlashLight()
{
for (int camid = 0; camid< MAX_NUM_CAMERA; camid++) {
for (int flindex = 0; flindex < MAX_NUM_FLASH_OF_ONE_MODULE; flindex++) {
if (mFlashFds[camid][flindex] >= 0)
{
setFlashMode(camid, flindex, false);
close(mFlashFds[camid][flindex]);
mFlashFds[camid][flindex] = -1;
}
}
}
}
int32_t FlashLight::getFlashLightInfo(
const int cameraId, bool &hasFlash,
const char* (&flashNode)[MAX_NUM_FLASH_OF_ONE_MODULE]) {
int32_t retVal = 0;
hasFlash = false;
const CameraHWInfo* camHwInfo = PlatformData::getCameraHWInfo();
CheckError(!camHwInfo, -EINVAL, "@%s, camera hw info was not uninitialized",
__FUNCTION__);
const struct SensorDriverDescriptor* sensorInfo = camHwInfo->getSensorDrvDes(cameraId);
CheckError(!sensorInfo, -EINVAL, "@%s, camera sensor info was not uninitialized",
__FUNCTION__);
int flash_num = sensorInfo->mFlashNum;
for (int i = 0; i < flash_num; i++) {
const std::string& node = sensorInfo->mModuleFlashDevName[i];
flashNode[i] = node.c_str();
}
hasFlash = flash_num > 0 ? true : false;
LOGD("@%s : hasFlash %d, flashNode[0]: %s, flashNode[1]: %s",
__FUNCTION__, hasFlash, flashNode[0], flashNode[1]);
return retVal;
}
int32_t FlashLight::setCallbacks(
const camera_module_callbacks_t* callbacks)
{
int32_t retVal = 0;
mCallbacks = callbacks;
return retVal;
}
int32_t FlashLight::init(const int cameraId)
{
int32_t retVal = 0;
bool hasFlash = false;
const char* flashPath[MAX_NUM_FLASH_OF_ONE_MODULE]
= {NULL, NULL};
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
return -EINVAL;
}
getFlashLightInfo(cameraId, hasFlash, flashPath);
if (!hasFlash) {
LOGE("%s: No flash available for camera id: %d", __FUNCTION__, cameraId);
retVal = -ENOSYS;
} else if (mCameraOpen[cameraId]) {
LOGE("%s: Camera in use for camera id: %d", __FUNCTION__, cameraId);
retVal = -EBUSY;
} else if (mFlashFds[cameraId][0] >= 0) {
LOGD("%s: Flash is already inited for camera id: %d", __FUNCTION__, cameraId);
} else {
for (int i = 0; i < MAX_NUM_FLASH_OF_ONE_MODULE; i++) {
if (flashPath[i]) {
if (mFlashFds[cameraId][i] == -1)
mFlashFds[cameraId][i] = open(flashPath[i], O_RDWR | O_NONBLOCK);
if (mFlashFds[cameraId][i] < 0) {
LOGE("%s: Unable to open node '%s'", __FUNCTION__, flashPath[i]);
retVal = -EBUSY;
break;
}
}
}
}
LOGD("@%s : retval = %d", __FUNCTION__, retVal);
return retVal;
}
int32_t FlashLight::deinit(const int cameraId)
{
int32_t retVal = 0;
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
retVal = -EINVAL;
} else {
for (int i = 0; i < MAX_NUM_FLASH_OF_ONE_MODULE; i++) {
if (mFlashFds[cameraId][i] >= 0) {
setFlashMode(cameraId, i, false);
close(mFlashFds[cameraId][i]);
mFlashFds[cameraId][i] = -1;
}
}
}
return retVal;
}
int32_t FlashLight::setFlashMode(const int cameraId, const bool mode)
{
int32_t retVal = 0;
LOGD("@%s : cameraId %d, mode %d", __FUNCTION__, cameraId, mode);
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
retVal = -EINVAL;
} else if (mode == mFlashOn[cameraId][0]) {
LOGD("%s: flash %d is already in requested state: %d", __FUNCTION__, cameraId, mode);
retVal = -EALREADY;
} else if (mFlashFds[cameraId][0] < 0) {
LOGE("%s: called for uninited flash: %d", __FUNCTION__, cameraId);
retVal = -EINVAL;
} else {
for (int i = 0; i < MAX_NUM_FLASH_OF_ONE_MODULE; i++) {
if (mFlashFds[cameraId][i] >= 0) {
retVal |= setFlashMode(cameraId, i, mode);
}
}
}
return retVal;
}
int32_t FlashLight::setFlashMode(const int cameraId, int flashIdx, const bool mode)
{
int32_t retVal = 0;
LOGD("@%s : cameraId %d, mode %d", __FUNCTION__, cameraId, mode);
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
retVal = -ENOSYS;
} else if (mode == mFlashOn[cameraId][flashIdx]) {
LOGD("%s: flash %d is already in requested state: %d", __FUNCTION__, cameraId, mode);
retVal = -EALREADY;
} else if (mFlashFds[cameraId][flashIdx] < 0) {
LOGE("%s: called for uninited flash: %d", __FUNCTION__, cameraId);
retVal = -ENOSYS;
} else {
struct v4l2_control control;
struct v4l2_queryctrl qctrl;
memset(&control, 0, sizeof(control));
memset(&qctrl, 0, sizeof(qctrl));
qctrl.id = V4L2_CID_FLASH_TORCH_INTENSITY;
if (ioctl(mFlashFds[cameraId][flashIdx], VIDIOC_QUERYCTRL, &qctrl) < 0) {
LOGE("@%s : query falsh torch power failed", __FUNCTION__);
return -ENOSYS;
}
LOGD(" qctrl.flags(0x%08x)", qctrl.flags);
if (qctrl.flags != V4L2_CTRL_FLAG_READ_ONLY) {
control.id = V4L2_CID_FLASH_TORCH_INTENSITY;
control.value = qctrl.default_value;
if (ioctl(mFlashFds[cameraId][flashIdx], VIDIOC_S_CTRL, &control, 0) < 0) {
LOGE("@%s : set flash intensity failed, may be not support set torch intensity.", __FUNCTION__);
return -ENOSYS;
}
}
memset(&control, 0, sizeof(control));
control.id = V4L2_CID_FLASH_LED_MODE;
control.value = mode ? V4L2_FLASH_LED_MODE_TORCH : V4L2_FLASH_LED_MODE_NONE;
if (ioctl(mFlashFds[cameraId][flashIdx], VIDIOC_S_CTRL, &control, 0) < 0) {
LOGE("@%s : set flash mode %d failed", __FUNCTION__, mode);
return -ENOSYS;
}
LOGI("@%s : set flash mode %d sucess", __FUNCTION__, mode);
mFlashOn[cameraId][flashIdx] = mode;
}
return retVal;
}
int32_t FlashLight::reserveFlashForCamera(const int cameraId)
{
int32_t retVal = 0;
if (cameraId < 0 || cameraId >= MAX_NUM_CAMERA) {
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
retVal = -EINVAL;
} else if (mCameraOpen[cameraId]) {
LOGD("%s: Flash already reserved for camera id: %d", __FUNCTION__,
cameraId);
} else {
deinit(cameraId);
mCameraOpen[cameraId] = true;
bool hasFlash = false;
const char* flashPath[MAX_NUM_FLASH_OF_ONE_MODULE]
= {NULL, NULL};
getFlashLightInfo(cameraId, hasFlash, flashPath);
if (mCallbacks == NULL ||
mCallbacks->torch_mode_status_change == NULL) {
LOGE("%s: Callback is not defined!", __FUNCTION__);
retVal = -ENOSYS;
} else if (!hasFlash) {
LOGD("%s: no flash exists for camera id: %d", __FUNCTION__, cameraId);
} else {
char cameraIdStr[1];
snprintf(cameraIdStr, 1, "%d", cameraId);
mCallbacks->torch_mode_status_change(mCallbacks,
cameraIdStr,
TORCH_MODE_STATUS_NOT_AVAILABLE);
}
}
return retVal;
}
int32_t FlashLight::releaseFlashFromCamera(const int cameraId)
{
int32_t retVal = 0;
if (cameraId < 0 || cameraId >= MAX_NUM_FLASH_OF_ONE_MODULE) {
LOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
retVal = -EINVAL;
} else if (!mCameraOpen[cameraId]) {
LOGD("%s: Flash not reserved for camera id: %d", __FUNCTION__, cameraId);
} else {
mCameraOpen[cameraId] = false;
bool hasFlash = false;
const char* flashPath[MAX_NUM_FLASH_OF_ONE_MODULE]
= {NULL, NULL};
getFlashLightInfo(cameraId, hasFlash, flashPath);
if (mCallbacks == NULL ||
mCallbacks->torch_mode_status_change == NULL) {
LOGE("%s: Callback is not defined!", __FUNCTION__);
retVal = -ENOSYS;
} else if (!hasFlash) {
LOGD("%s: no flash exists for camera id: %d", __FUNCTION__, cameraId);
} else {
char cameraIdStr[1];
snprintf(cameraIdStr, 1, "%d", cameraId);
mCallbacks->torch_mode_status_change(mCallbacks,
cameraIdStr,
TORCH_MODE_STATUS_AVAILABLE_OFF);
}
}
return retVal;
}
} /* namespace camera2 */
} /* namespace android */