blob: 3d075043417216884aecf6c5d9d316ba86f2001a [file] [log] [blame]
/*
* 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 "LensHw"
#include <string>
#include "LensHw.h"
#include "v4l2device.h"
#include "MediaController.h"
#include "MediaEntity.h"
#include "LogHelper.h"
#include "Camera3GFXFormat.h"
#include "RKISP1CameraCapInfo.h"
namespace android {
namespace camera2 {
LensHw::LensHw(int cameraId, std::shared_ptr<MediaController> mediaCtl):
mCameraId(cameraId),
mMediaCtl(mediaCtl),
mLastLensPosition(0),
mCurrentOisState(false),
mLensMovementStartTime(0)
{
LOG1("@%s", __FUNCTION__);
CLEAR(mLensInput);
}
LensHw::~LensHw() {
LOG1("@%s", __FUNCTION__);
}
status_t LensHw::init()
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
std::string entityName;
std::shared_ptr<MediaEntity> mediaEntity = nullptr;
const RKISP1CameraCapInfo * cap = getRKISP1CameraCapInfo(mCameraId);
entityName = cap->getMediaCtlEntityName("lens");
if (entityName == "none") {
LOGE("%s: No lens found", __FUNCTION__);
return UNKNOWN_ERROR;
} else {
status = mMediaCtl->getMediaEntity(mediaEntity, entityName.c_str());
if (mediaEntity == nullptr || status != NO_ERROR) {
LOGE("%s, Could not retrieve Media Entity %s", __FUNCTION__, entityName.c_str());
return UNKNOWN_ERROR;
}
status = setLens(mediaEntity);
if (status != NO_ERROR) {
LOGE("%s: Cannot set lens subDev", __FUNCTION__);
return status;
}
}
return NO_ERROR;
}
status_t LensHw::setLens(std::shared_ptr<MediaEntity> entity)
{
LOG1("@%s", __FUNCTION__);
if (entity->getType() != SUBDEV_LENS) {
LOGE("%s is not sensor subdevice", entity->getName());
return BAD_VALUE;
}
std::shared_ptr<V4L2Subdevice> lens;
entity->getDevice((std::shared_ptr<V4L2DeviceBase>&) lens);
mLensSubdev = lens;
return NO_ERROR;
}
int LensHw::moveFocusToPosition(int position) // focus with absolute value
{
LOG2("@%s: %d", __FUNCTION__, position);
mLastLensPosition = position;
// we use same clock as the timestamps from the buffers where
// the statistics are provided. This is a monotonic clock in microsenconds
mLensMovementStartTime = systemTime()/1000;
return mLensSubdev->setControl(V4L2_CID_FOCUS_ABSOLUTE,
position, "focus absolute");
}
int LensHw::moveFocusToBySteps(int steps) // focus with relative value
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->setControl(V4L2_CID_FOCUS_RELATIVE,
steps, "focus steps");
}
int LensHw::getFocusPosition(int &position)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->getControl(V4L2_CID_FOCUS_ABSOLUTE, &position);
}
int LensHw::getFocusStatus(int &status)
{
LOG2("@%s", __FUNCTION__);
// TODO make a v4l2 implementation
UNUSED(status);
return NO_ERROR;
}
int LensHw::startAutoFocus(void)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->setControl(V4L2_CID_AUTO_FOCUS_START, 1, "af start");
}
int LensHw::stopAutoFocus(void)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->setControl(V4L2_CID_AUTO_FOCUS_STOP, 0, "af stop");
}
int LensHw::getAutoFocusStatus(int &status)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->getControl(V4L2_CID_AUTO_FOCUS_STATUS,
reinterpret_cast<int*>(&status));
}
int LensHw::setAutoFocusRange(int value)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->setControl(V4L2_CID_AUTO_FOCUS_RANGE,
value, "set af range");
}
int LensHw::getAutoFocusRange(int &value)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->getControl(V4L2_CID_AUTO_FOCUS_RANGE, &value);
}
// ZOOM
int LensHw::moveZoomToPosition(int position)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->setControl(V4L2_CID_ZOOM_ABSOLUTE,
position, "zoom absolute");
}
int LensHw::moveZoomToBySteps(int steps)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->setControl(V4L2_CID_ZOOM_RELATIVE,
steps, "zoom steps");
}
int LensHw::getZoomPosition(int &position)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->getControl(V4L2_CID_ZOOM_ABSOLUTE, &position);
}
int LensHw::moveZoomContinuous(int position)
{
LOG2("@%s", __FUNCTION__);
return mLensSubdev->setControl(V4L2_CID_ZOOM_CONTINUOUS,
position, "continuous zoom");
}
int LensHw::getCurrentCameraId(void)
{
LOG1("@%s, id: %d", __FUNCTION__, mCameraId);
return mCameraId;
}
const char* LensHw::getLensName(void)
{
return mLensInput.name;
}
int LensHw::enableOis(bool enable)
{
// Avoid enabling OIS for every frame
if (enable == mCurrentOisState)
return OK;
if (CC_UNLIKELY(mLensSubdev == nullptr)) {
LOGE("No lens subdev attached");
return UNKNOWN_ERROR;
}
LOG1("@%s %s", __FUNCTION__, enable ? "ON" : "OFF");
mLensSubdev->setControl(V4L2_CID_IMAGE_STABILIZATION,
enable ? 1 : 0, "optical image stabilization");
// ignore error to avoid constant update of the control.
mCurrentOisState = enable;
return OK;
}
/**
* getLatestPosition
*
* returns the latest position commanded to the lens actuator and when this
* was issued.
* This method does not query the driver.
*
* \param: lensPosition[OUT]: lens position last applied
* \param: time[OUT]: time in micro seconds when the lens move command was sent.
*/
status_t
LensHw::getLatestPosition(int *lensPosition, long long unsigned int *time)
{
if (CC_LIKELY(lensPosition != nullptr)) {
*lensPosition = mLastLensPosition;
}
if (CC_LIKELY(time != nullptr)) {
*time = mLensMovementStartTime;
}
return OK;
}
} // namespace camera2
} // namespace android