/*
* Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
*
* Authors: Younghwan Joo <yhwan.joo@samsung.com>
* Sylwester Nawrocki <s.nawrocki@samsung.com>
*
* 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.
*/
#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include "fimc-is.h"
#include "fimc-is-command.h"
#include "fimc-is-errno.h"
#include "fimc-is-param.h"
#include "fimc-is-regs.h"
#include "fimc-is-sensor.h"
static void __hw_param_copy(void *dst, void *src)
{
memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE);
}
static void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
{
struct param_global_shotmode *dst, *src;
dst = &is->is_p_region->parameter.global.shotmode;
src = &is->config[is->config_index].global.shotmode;
__hw_param_copy(dst, src);
}
static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
{
struct param_sensor_framerate *dst, *src;
dst = &is->is_p_region->parameter.sensor.frame_rate;
src = &is->config[is->config_index].sensor.frame_rate;
__hw_param_copy(dst, src);
}
int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset)
{
struct is_param_region *par = &is->is_p_region->parameter;
struct chain_config *cfg = &is->config[is->config_index];
switch (offset) {
case PARAM_ISP_CONTROL:
__hw_param_copy(&par->isp.control, &cfg->isp.control);
break;
case PARAM_ISP_OTF_INPUT:
__hw_param_copy(&par->isp.otf_input, &cfg->isp.otf_input);
break;
case PARAM_ISP_DMA1_INPUT:
__hw_param_copy(&par->isp.dma1_input, &cfg->isp.dma1_input);
break;
case PARAM_ISP_DMA2_INPUT:
__hw_param_copy(&par->isp.dma2_input, &cfg->isp.dma2_input);
break;
case PARAM_ISP_AA:
__hw_param_copy(&par->isp.aa, &cfg->isp.aa);
break;
case PARAM_ISP_FLASH:
__hw_param_copy(&par->isp.flash, &cfg->isp.flash);
break;
case PARAM_ISP_AWB:
__hw_param_copy(&par->isp.awb, &cfg->isp.awb);
break;
case PARAM_ISP_IMAGE_EFFECT:
__hw_param_copy(&par->isp.effect, &cfg->isp.effect);
break;
case PARAM_ISP_ISO:
__hw_param_copy(&par->isp.iso, &cfg->isp.iso);
break;
case PARAM_ISP_ADJUST:
__hw_param_copy(&par->isp.adjust, &cfg->isp.adjust);
break;
case PARAM_ISP_METERING:
__hw_param_copy(&par->isp.metering, &cfg->isp.metering);
break;
case PARAM_ISP_AFC:
__hw_param_copy(&par->isp.afc, &cfg->isp.afc);
break;
case PARAM_ISP_OTF_OUTPUT:
__hw_param_copy(&par->isp.otf_output, &cfg->isp.otf_output);
break;
case PARAM_ISP_DMA1_OUTPUT:
__hw_param_copy(&par->isp.dma1_output, &cfg->isp.dma1_output);
break;
case PARAM_ISP_DMA2_OUTPUT:
__hw_param_copy(&par->isp.dma2_output, &cfg->isp.dma2_output);
break;
case PARAM_DRC_CONTROL:
__hw_param_copy(&par->drc.control, &cfg->drc.control);
break;
case PARAM_DRC_OTF_INPUT:
__hw_param_copy(&par->drc.otf_input, &cfg->drc.otf_input);
break;
case PARAM_DRC_DMA_INPUT:
__hw_param_copy(&par->drc.dma_input, &cfg->drc.dma_input);
break;
case PARAM_DRC_OTF_OUTPUT:
__hw_param_copy(&par->drc.otf_output, &cfg->drc.otf_output);
break;
case PARAM_FD_CONTROL:
__hw_param_copy(&par->fd.control, &cfg->fd.control);
break;
case PARAM_FD_OTF_INPUT:
__hw_param_copy(&par->fd.otf_input, &cfg->fd.otf_input);
break;
case PARAM_FD_DMA_INPUT:
__hw_param_copy(&par->fd.dma_input, &cfg->fd.dma_input);
break;
case PARAM_FD_CONFIG:
__hw_param_copy(&par->fd.config, &cfg->fd.config);
break;
default:
return -EINVAL;
}
return 0;
}
unsigned int __get_pending_param_count(struct fimc_is *is)
{
struct chain_config *config = &is->config[is->config_index];
unsigned long flags;
unsigned int count;
spin_lock_irqsave(&is->slock, flags