624 lines
16 KiB
C
624 lines
16 KiB
C
|
/*
|
||
|
* Samsung Exynos SoC series FIMC-IS driver
|
||
|
*
|
||
|
* exynos5 fimc-is group manager functions
|
||
|
*
|
||
|
* Copyright (c) 2016 Samsung Electronics Co., Ltd
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License version 2 as
|
||
|
* published by the Free Software Foundation.
|
||
|
*/
|
||
|
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/delay.h>
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/errno.h>
|
||
|
#include <linux/interrupt.h>
|
||
|
#include <linux/device.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <video/videonode.h>
|
||
|
#include <asm/cacheflush.h>
|
||
|
#include <asm/pgtable.h>
|
||
|
#include <linux/firmware.h>
|
||
|
#include <linux/dma-mapping.h>
|
||
|
#include <linux/scatterlist.h>
|
||
|
#include <linux/videodev2.h>
|
||
|
#include <linux/videodev2_exynos_camera.h>
|
||
|
#include <linux/v4l2-mediabus.h>
|
||
|
#include <linux/bug.h>
|
||
|
|
||
|
#include "fimc-is-hw.h"
|
||
|
#include "fimc-is-core.h"
|
||
|
#include "fimc-is-type.h"
|
||
|
#include "fimc-is-err.h"
|
||
|
#include "fimc-is-video.h"
|
||
|
#include "fimc-is-framemgr.h"
|
||
|
#include "fimc-is-groupmgr.h"
|
||
|
#include "fimc-is-devicemgr.h"
|
||
|
#include "fimc-is-device-ischain.h"
|
||
|
#include "fimc-is-hw-control.h"
|
||
|
#ifdef SUPPORT_REMOSAIC_CROP_ZOOM
|
||
|
#include "fimc-is-param.h"
|
||
|
#include "fimc-is-device-sensor-peri.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef CONFIG_USE_SENSOR_GROUP
|
||
|
struct fimc_is_group *get_ischain_leader_group(struct fimc_is_device_ischain *device)
|
||
|
{
|
||
|
struct fimc_is_group *leader_group;
|
||
|
|
||
|
leader_group = device->groupmgr->leader[device->instance];
|
||
|
|
||
|
if ((leader_group->device_type == FIMC_IS_DEVICE_SENSOR)
|
||
|
&& (leader_group->next)
|
||
|
&& (!test_bit(FIMC_IS_GROUP_OTF_INPUT, &leader_group->next->state))) {
|
||
|
leader_group = leader_group->next;
|
||
|
}
|
||
|
|
||
|
return leader_group;
|
||
|
}
|
||
|
|
||
|
static void do_sensor_tag(unsigned long data)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
u32 stream;
|
||
|
unsigned long flags, framemgr_flag;
|
||
|
struct fimc_is_framemgr *framemgr;
|
||
|
struct v4l2_subdev *subdev;
|
||
|
struct camera2_node ldr_node = {0, };
|
||
|
struct fimc_is_device_sensor *sensor;
|
||
|
struct devicemgr_sensor_tag_data *tag_data;
|
||
|
struct fimc_is_group *group;
|
||
|
struct fimc_is_frame *frame;
|
||
|
struct fimc_is_group_task *gtask;
|
||
|
|
||
|
tag_data = (struct devicemgr_sensor_tag_data *)data;
|
||
|
stream = tag_data->stream;
|
||
|
sensor = tag_data->devicemgr->sensor[stream];
|
||
|
group = tag_data->group;
|
||
|
subdev = sensor->subdev_csi;
|
||
|
gtask = &sensor->groupmgr->gtask[group->id];
|
||
|
|
||
|
mgrdbgs(5, " start sensor tag(%s)\n", group->device, group, frame,
|
||
|
in_softirq() ? "S" : "H");
|
||
|
|
||
|
if (unlikely(test_bit(FIMC_IS_GROUP_FORCE_STOP, &group->state))) {
|
||
|
mgwarn(" cancel by fstop", group, group);
|
||
|
goto p_err;
|
||
|
}
|
||
|
|
||
|
if (unlikely(test_bit(FIMC_IS_GTASK_REQUEST_STOP, >ask->state))) {
|
||
|
mgerr(" cancel by gstop", group, group);
|
||
|
goto p_err;
|
||
|
}
|
||
|
|
||
|
framemgr = GET_HEAD_GROUP_FRAMEMGR(group);
|
||
|
if (!framemgr) {
|
||
|
merr("framemgr is NULL", group);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
framemgr_e_barrier_irqs(framemgr, 0, framemgr_flag);
|
||
|
frame = find_frame(framemgr, FS_PROCESS, frame_fcount, (void *)(ulong)tag_data->fcount);
|
||
|
|
||
|
if (!frame) {
|
||
|
frame_manager_print_queues(framemgr);
|
||
|
merr("[F%d] There's no frame in processing." \
|
||
|
"Can't sync sensor and ischain buffer anymore..",
|
||
|
group, tag_data->fcount);
|
||
|
framemgr_x_barrier_irqr(framemgr, 0, framemgr_flag);
|
||
|
return;
|
||
|
}
|
||
|
framemgr_x_barrier_irqr(framemgr, 0, framemgr_flag);
|
||
|
|
||
|
ldr_node = frame->shot_ext->node_group.leader;
|
||
|
|
||
|
ret = fimc_is_sensor_group_tag(sensor, frame, &ldr_node);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_sensor_group_tag is fail(%d)", group, ret);
|
||
|
goto p_err;
|
||
|
}
|
||
|
|
||
|
if (sensor->fcount >= frame->fcount) {
|
||
|
merr("late sensor tag. DMA will be canceled. (%d != %d)",
|
||
|
group, sensor->fcount, frame->fcount);
|
||
|
fimc_is_sensor_dma_cancel(sensor);
|
||
|
|
||
|
mginfo("[F%d] Start CANCEL Other subdev frame\n", group->device, group, frame->fcount);
|
||
|
flags = fimc_is_group_lock(group, group->device_type, true);
|
||
|
fimc_is_group_subdev_cancel(group, frame, group->device_type, FS_PROCESS, true);
|
||
|
fimc_is_group_unlock(group, flags, group->device_type, true);
|
||
|
mginfo("[F%d] End CANCEL Other subdev frame\n", group->device, group, frame->fcount);
|
||
|
}
|
||
|
|
||
|
mgrdbgs(5, " finish sensor tag(%s)\n", group->device, group, frame,
|
||
|
in_softirq() ? "S" : "H");
|
||
|
|
||
|
p_err:
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_probe(struct fimc_is_devicemgr *devicemgr)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_open(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
u32 stream = 0;
|
||
|
u32 group_id;
|
||
|
struct fimc_is_core *core;
|
||
|
struct fimc_is_group *group = NULL;
|
||
|
struct fimc_is_device_sensor *sensor;
|
||
|
struct fimc_is_device_ischain *ischain;
|
||
|
|
||
|
FIMC_BUG(!devicemgr);
|
||
|
FIMC_BUG(!device);
|
||
|
|
||
|
switch (type) {
|
||
|
case FIMC_IS_DEVICE_SENSOR:
|
||
|
sensor = (struct fimc_is_device_sensor *)device;
|
||
|
group = &sensor->group_sensor;
|
||
|
core = sensor->private_data;
|
||
|
|
||
|
FIMC_BUG(!core);
|
||
|
FIMC_BUG(!group);
|
||
|
FIMC_BUG(!sensor->vctx);
|
||
|
FIMC_BUG(!GET_VIDEO(sensor->vctx));
|
||
|
|
||
|
/* get the stream id */
|
||
|
for (stream = 0; stream < FIMC_IS_STREAM_COUNT; ++stream) {
|
||
|
ischain = &core->ischain[stream];
|
||
|
if (!test_bit(FIMC_IS_ISCHAIN_OPEN, &ischain->state))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
FIMC_BUG(stream >= FIMC_IS_STREAM_COUNT);
|
||
|
|
||
|
/* init group's device information */
|
||
|
devicemgr->sensor[stream] = sensor;
|
||
|
group->instance = stream;
|
||
|
group->device = ischain;
|
||
|
group_id = GROUP_ID_SS0 + GET_SSX_ID(GET_VIDEO(sensor->vctx));
|
||
|
|
||
|
ret = fimc_is_group_open(sensor->groupmgr,
|
||
|
group,
|
||
|
group_id,
|
||
|
sensor->vctx);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_group_open is fail(%d)", ischain, ret);
|
||
|
ret = -EINVAL;
|
||
|
goto p_err;
|
||
|
}
|
||
|
|
||
|
sensor->vctx->next_device = ischain;
|
||
|
break;
|
||
|
case FIMC_IS_DEVICE_ISCHAIN:
|
||
|
ischain = (struct fimc_is_device_ischain *)device;
|
||
|
stream = ischain->instance;
|
||
|
|
||
|
devicemgr->ischain[stream] = ischain;
|
||
|
break;
|
||
|
default:
|
||
|
err("device type(%d) is invalid", type);
|
||
|
BUG();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p_err:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_binding(struct fimc_is_devicemgr *devicemgr,
|
||
|
struct fimc_is_device_sensor *sensor,
|
||
|
struct fimc_is_device_ischain *ischain,
|
||
|
enum fimc_is_device_type type)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct fimc_is_group *group = NULL;
|
||
|
struct fimc_is_group *child_group;
|
||
|
|
||
|
switch (type) {
|
||
|
case FIMC_IS_DEVICE_SENSOR:
|
||
|
if (test_bit(FIMC_IS_SENSOR_STAND_ALONE, &sensor->state)) {
|
||
|
/* in case of sensor driving */
|
||
|
ischain->sensor = sensor;
|
||
|
sensor->ischain = ischain;
|
||
|
|
||
|
/* Clear ischain device all state */
|
||
|
ischain->state = 0;
|
||
|
|
||
|
/*
|
||
|
* Forcely set the ischain's state to "Opened"
|
||
|
* Because if it's sensor driving mode, ischain was not opened from HAL.
|
||
|
*/
|
||
|
set_bit(FIMC_IS_ISCHAIN_OPEN, &ischain->state);
|
||
|
|
||
|
ret = fimc_is_groupmgr_init(sensor->groupmgr, ischain);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_groupmgr_init is fail(%d)", ischain, ret);
|
||
|
ret = -EINVAL;
|
||
|
goto p_err;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case FIMC_IS_DEVICE_ISCHAIN:
|
||
|
if (sensor &&
|
||
|
!test_bit(FIMC_IS_ISCHAIN_REPROCESSING, &ischain->state)) {
|
||
|
group = &sensor->group_sensor;
|
||
|
FIMC_BUG(group->instance != ischain->instance);
|
||
|
|
||
|
child_group = GET_HEAD_GROUP_IN_DEVICE(FIMC_IS_DEVICE_ISCHAIN, group);
|
||
|
if (child_group) {
|
||
|
info("[%d/%d] sensor otf output set\n",
|
||
|
sensor->instance, ischain->instance);
|
||
|
set_bit(FIMC_IS_SENSOR_OTF_OUTPUT, &sensor->state);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
err("device type(%d) is invalid", type);
|
||
|
BUG();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p_err:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_start(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct fimc_is_group *group;
|
||
|
struct fimc_is_device_sensor *sensor;
|
||
|
|
||
|
switch (type) {
|
||
|
case FIMC_IS_DEVICE_SENSOR:
|
||
|
sensor = (struct fimc_is_device_sensor *)device;
|
||
|
group = &sensor->group_sensor;
|
||
|
|
||
|
if (!test_bit(FIMC_IS_SENSOR_STAND_ALONE, &sensor->state) && sensor->ischain) {
|
||
|
ret = fimc_is_ischain_start_wrap(sensor->ischain, group);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_ischain_start_wrap is fail(%d)", sensor->ischain, ret);
|
||
|
ret = -EINVAL;
|
||
|
goto p_err;
|
||
|
}
|
||
|
} else {
|
||
|
ret = fimc_is_groupmgr_start(sensor->groupmgr, group->device);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_groupmgr_start is fail(%d)", group->device, ret);
|
||
|
ret = -EINVAL;
|
||
|
goto p_err;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (IS_ENABLED(CHAIN_TAG_SENSOR_IN_SOFTIRQ_CONTEXT)) {
|
||
|
struct fimc_is_group *child_group
|
||
|
= GET_HEAD_GROUP_IN_DEVICE(FIMC_IS_DEVICE_ISCHAIN, group);
|
||
|
|
||
|
/* only in case of OTF, uses tasklet */
|
||
|
if (sensor->ischain && child_group)
|
||
|
tasklet_init(&devicemgr->tasklet[group->instance], do_sensor_tag,
|
||
|
(unsigned long)&devicemgr->tag_data[group->instance]);
|
||
|
}
|
||
|
break;
|
||
|
case FIMC_IS_DEVICE_ISCHAIN:
|
||
|
break;
|
||
|
default:
|
||
|
err("device type(%d) is invalid", type);
|
||
|
BUG();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p_err:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_stop(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct fimc_is_group *group;
|
||
|
struct fimc_is_device_sensor *sensor;
|
||
|
|
||
|
switch (type) {
|
||
|
case FIMC_IS_DEVICE_SENSOR:
|
||
|
sensor = (struct fimc_is_device_sensor *)device;
|
||
|
group = &sensor->group_sensor;
|
||
|
|
||
|
if (IS_ENABLED(CHAIN_TAG_SENSOR_IN_SOFTIRQ_CONTEXT)) {
|
||
|
struct fimc_is_group *child_group
|
||
|
= GET_HEAD_GROUP_IN_DEVICE(FIMC_IS_DEVICE_ISCHAIN, group);
|
||
|
|
||
|
if (sensor->ischain && child_group)
|
||
|
tasklet_kill(&devicemgr->tasklet[group->instance]);
|
||
|
}
|
||
|
|
||
|
if (!test_bit(FIMC_IS_SENSOR_STAND_ALONE, &sensor->state) && sensor->ischain) {
|
||
|
ret = fimc_is_ischain_stop_wrap(sensor->ischain, group);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_ischain_stop_wrap is fail(%d)", sensor->ischain, ret);
|
||
|
ret = -EINVAL;
|
||
|
goto p_err;
|
||
|
}
|
||
|
} else {
|
||
|
ret = fimc_is_groupmgr_stop(sensor->groupmgr, group->device);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_groupmgr_stop is fail(%d)", group->device, ret);
|
||
|
ret = -EINVAL;
|
||
|
goto p_err;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case FIMC_IS_DEVICE_ISCHAIN:
|
||
|
break;
|
||
|
default:
|
||
|
err("device type(%d) is invalid", type);
|
||
|
BUG();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p_err:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_close(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct fimc_is_group *group;
|
||
|
struct fimc_is_device_sensor *sensor;
|
||
|
|
||
|
switch (type) {
|
||
|
case FIMC_IS_DEVICE_SENSOR:
|
||
|
sensor = (struct fimc_is_device_sensor *)device;
|
||
|
|
||
|
FIMC_BUG(!sensor);
|
||
|
|
||
|
group = &sensor->group_sensor;
|
||
|
|
||
|
ret = fimc_is_group_close(sensor->groupmgr, group);
|
||
|
if (ret)
|
||
|
merr("fimc_is_group_close is fail", sensor);
|
||
|
|
||
|
/*
|
||
|
* Forcely set the ischain's state to "Not Opened"
|
||
|
* Because if it's sensor driving mode, ischain was not opened from HAL.
|
||
|
*/
|
||
|
if (test_bit(FIMC_IS_SENSOR_STAND_ALONE, &sensor->state) && sensor->ischain)
|
||
|
clear_bit(FIMC_IS_ISCHAIN_OPEN, &sensor->ischain->state);
|
||
|
break;
|
||
|
case FIMC_IS_DEVICE_ISCHAIN:
|
||
|
break;
|
||
|
default:
|
||
|
err("device type(%d) is invalid", type);
|
||
|
BUG();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_shot_callback(struct fimc_is_group *group,
|
||
|
struct fimc_is_frame *frame,
|
||
|
u32 fcount,
|
||
|
enum fimc_is_device_type type)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
unsigned long flags;
|
||
|
struct fimc_is_group *child_group;
|
||
|
struct camera2_node ldr_node = {0, };
|
||
|
struct fimc_is_devicemgr *devicemgr;
|
||
|
struct devicemgr_sensor_tag_data *tag_data;
|
||
|
u32 stream;
|
||
|
|
||
|
switch (type) {
|
||
|
case FIMC_IS_DEVICE_SENSOR:
|
||
|
child_group = GET_HEAD_GROUP_IN_DEVICE(FIMC_IS_DEVICE_ISCHAIN, group);
|
||
|
|
||
|
PROGRAM_COUNT(9);
|
||
|
|
||
|
mgrdbgs(1, " DEVICE SHOT CALLBACK(%d) %s\n", group->device,
|
||
|
group, frame, frame->index, child_group ? "OTF" : "M2M");
|
||
|
|
||
|
/* OTF */
|
||
|
/* FIMC_IS_SENSOR_OTF_OUTPUT bit needs to check also.
|
||
|
* because this bit can be cleared for not operate child_group_shot at remosaic sensor mode
|
||
|
*/
|
||
|
if (child_group && test_bit(FIMC_IS_SENSOR_OTF_OUTPUT, &group->device->sensor->state)) {
|
||
|
child_group->shot_callback(child_group->device, frame);
|
||
|
/* M2M */
|
||
|
} else {
|
||
|
ret = fimc_is_sensor_group_tag(group->device->sensor, frame, &ldr_node);
|
||
|
if (ret) {
|
||
|
merr("fimc_is_sensor_group_tag is fail(%d)", group, ret);
|
||
|
mginfo("[F%d] Start CANCEL Other subdev frame\n", group->device, group, frame->fcount);
|
||
|
flags = fimc_is_group_lock(group, group->device_type, true);
|
||
|
fimc_is_group_subdev_cancel(group, frame, group->device_type, FS_PROCESS, true);
|
||
|
fimc_is_group_subdev_cancel(group, frame, group->device_type, FS_REQUEST, false);
|
||
|
fimc_is_group_unlock(group, flags, group->device_type, true);
|
||
|
mginfo("[F%d] End CANCEL Other subdev frame\n", group->device, group, frame->fcount);
|
||
|
ret = -EINVAL;
|
||
|
goto p_err;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PROGRAM_COUNT(10);
|
||
|
|
||
|
break;
|
||
|
case FIMC_IS_DEVICE_ISCHAIN:
|
||
|
/* Only for sensor group with OTF */
|
||
|
if (group->head->device_type != FIMC_IS_DEVICE_SENSOR ||
|
||
|
frame->type != SHOT_TYPE_EXTERNAL)
|
||
|
break;
|
||
|
|
||
|
devicemgr = group->device->devicemgr;
|
||
|
stream = group->instance;
|
||
|
|
||
|
tag_data = &devicemgr->tag_data[stream];
|
||
|
tag_data->fcount = fcount;
|
||
|
tag_data->devicemgr = devicemgr;
|
||
|
tag_data->group = &devicemgr->sensor[stream]->group_sensor;
|
||
|
tag_data->stream = stream;
|
||
|
|
||
|
if (IS_ENABLED(CHAIN_TAG_SENSOR_IN_SOFTIRQ_CONTEXT)) {
|
||
|
mgrdbgs(1, " schedule sensor tag tasklet\n", group->device, group, frame);
|
||
|
tasklet_schedule(&devicemgr->tasklet[stream]);
|
||
|
} else { /* (hard)IRQ context */
|
||
|
do_sensor_tag((unsigned long)tag_data);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
mgerr("device type(%d) is invalid", group, group, group->device_type);
|
||
|
BUG();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p_err:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_shot_done(struct fimc_is_group *group,
|
||
|
struct fimc_is_frame *ldr_frame,
|
||
|
u32 status)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
unsigned long flags;
|
||
|
|
||
|
/* skip in case of the sensor -> 3AA M2M case */
|
||
|
if (group->device_type == FIMC_IS_DEVICE_ISCHAIN)
|
||
|
return ret;
|
||
|
|
||
|
/* if error happened, cancel the sensor's subdev frames */
|
||
|
if (status) {
|
||
|
mginfo("[F%d] Start CANCEL Other subdev frame\n", group->device, group, ldr_frame->fcount);
|
||
|
flags = fimc_is_group_lock(group, group->device_type, false);
|
||
|
fimc_is_group_subdev_cancel(group, ldr_frame, group->device_type, FS_PROCESS, true);
|
||
|
fimc_is_group_subdev_cancel(group, ldr_frame, group->device_type, FS_REQUEST, false);
|
||
|
fimc_is_group_unlock(group, flags, group->device_type, false);
|
||
|
mginfo("[F%d] End CANCEL Other subdev frame\n", group->device, group, ldr_frame->fcount);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
#ifdef SUPPORT_REMOSAIC_CROP_ZOOM
|
||
|
void fimc_is_devicemgr_sensor_mode_change(struct fimc_is_group *group,
|
||
|
struct fimc_is_frame *frame)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct fimc_is_device_sensor *sensor;
|
||
|
struct crop_zoom_uctl *crop_zoom_ctrl;
|
||
|
struct seamless_mode_change_info mode_change;
|
||
|
|
||
|
if (!group || !frame) {
|
||
|
err("Invalid argument. group(%p) frame(%d)", group, frame);
|
||
|
return;
|
||
|
} else if (!frame->shot_ext) {
|
||
|
err("[F%d] shot_ext is NULL.", frame->fcount);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
sensor = group->device->sensor;
|
||
|
crop_zoom_ctrl = &frame->shot_ext->shot.uctl.cropzoomUd;
|
||
|
|
||
|
mgrdbgs(1, "sensor_mode_change. size(%dx%d) fps(%d) ex_mode(%d)\n",
|
||
|
group->device, group, frame,
|
||
|
crop_zoom_ctrl->width,
|
||
|
crop_zoom_ctrl->height,
|
||
|
crop_zoom_ctrl->fps,
|
||
|
crop_zoom_ctrl->ex_mode);
|
||
|
|
||
|
if (sensor->ex_mode == crop_zoom_ctrl->ex_mode)
|
||
|
return;
|
||
|
|
||
|
if (crop_zoom_ctrl->width == 0 || crop_zoom_ctrl->height == 0 ||
|
||
|
crop_zoom_ctrl->fps == 0)
|
||
|
return;
|
||
|
|
||
|
mode_change.width = crop_zoom_ctrl->width;
|
||
|
mode_change.height= crop_zoom_ctrl->height;
|
||
|
mode_change.fps= crop_zoom_ctrl->fps;
|
||
|
mode_change.ex_mode= crop_zoom_ctrl->ex_mode;
|
||
|
|
||
|
ret = fimc_is_sensor_peri_s_mode_change(sensor, &mode_change);
|
||
|
if (ret)
|
||
|
err("failed to set mode change(%d)", ret);
|
||
|
}
|
||
|
#endif//SUPPORT_REMOSAIC_CROP_ZOOM
|
||
|
#else
|
||
|
struct fimc_is_group *get_ischain_leader_group(struct fimc_is_device_ischain *device)
|
||
|
{
|
||
|
return device->groupmgr->leader[device->instance];
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_probe(struct fimc_is_devicemgr *devicemgr)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_open(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_binding(struct fimc_is_devicemgr *devicemgr,
|
||
|
struct fimc_is_device_sensor *sensor,
|
||
|
struct fimc_is_device_ischain *ischain,
|
||
|
enum fimc_is_device_type type)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_start(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_stop(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_close(struct fimc_is_devicemgr *devicemgr,
|
||
|
void *device, enum fimc_is_device_type type)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_shot_callback(struct fimc_is_group *group,
|
||
|
struct fimc_is_frame *frame,
|
||
|
u32 fcount,
|
||
|
enum fimc_is_device_type type)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int fimc_is_devicemgr_shot_done(struct fimc_is_group *group,
|
||
|
struct fimc_is_frame *ldr_frame,
|
||
|
u32 status)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
#ifdef SUPPORT_REMOSAIC_CROP_ZOOM
|
||
|
void fimc_is_devicemgr_sensor_mode_change(struct fimc_is_group *group,
|
||
|
struct fimc_is_frame *frame)
|
||
|
{
|
||
|
/* No ops */
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|