Commit 9a761e43 authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab

[media] exynos4-is: Add Exynos4x12 FIMC-IS driver

This patch adds a set of core files of the Exynos4x12 FIMC-IS
V4L2 driver. This includes main functionality like allocating
memory, loading the firmware, FIMC-IS register interface and
host CPU <-> IS command and error code definitions.
The driver currently exposes a single subdev named FIMC-IS-ISP,
which corresponds to the FIMC-IS ISP and DRC IP blocks.
The FIMC-IS-ISP subdev currently supports only a subset of user
controls. For other controls we need several extensions at the
V4L2 API. The supported standard controls are:
brightness, contrast, saturation, hue, sharpness, 3a_lock,
exposure_time_absolute, white_balance_auto_preset,
iso_sensitivity, iso_sensitivity_auto, exposure_metering_mode.
Signed-off-by: default avatarYounghwan Joo <yhwan.joo@samsung.com>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent c6e8d96d
/*
* Samsung Exynos4x12 FIMC-IS (Imaging Subsystem) driver
*
* FIMC-IS command set definitions
*
* 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.
*/
#ifndef FIMC_IS_CMD_H_
#define FIMC_IS_CMD_H_
#define FIMC_IS_COMMAND_VER 110 /* FIMC-IS command set version 1.10 */
/* Enumeration of commands beetween the FIMC-IS and the host processor. */
/* HOST to FIMC-IS */
#define HIC_PREVIEW_STILL 0x0001
#define HIC_PREVIEW_VIDEO 0x0002
#define HIC_CAPTURE_STILL 0x0003
#define HIC_CAPTURE_VIDEO 0x0004
#define HIC_STREAM_ON 0x0005
#define HIC_STREAM_OFF 0x0006
#define HIC_SET_PARAMETER 0x0007
#define HIC_GET_PARAMETER 0x0008
#define HIC_SET_TUNE 0x0009
#define HIC_GET_STATUS 0x000b
/* Sensor part */
#define HIC_OPEN_SENSOR 0x000c
#define HIC_CLOSE_SENSOR 0x000d
#define HIC_SIMMIAN_INIT 0x000e
#define HIC_SIMMIAN_WRITE 0x000f
#define HIC_SIMMIAN_READ 0x0010
#define HIC_POWER_DOWN 0x0011
#define HIC_GET_SET_FILE_ADDR 0x0012
#define HIC_LOAD_SET_FILE 0x0013
#define HIC_MSG_CONFIG 0x0014
#define HIC_MSG_TEST 0x0015
/* FIMC-IS to HOST */
#define IHC_GET_SENSOR_NUM 0x1000
#define IHC_SET_SHOT_MARK 0x1001
/* parameter1: frame number */
/* parameter2: confidence level (smile 0~100) */
/* parameter3: confidence level (blink 0~100) */
#define IHC_SET_FACE_MARK 0x1002
/* parameter1: coordinate count */
/* parameter2: coordinate buffer address */
#define IHC_FRAME_DONE 0x1003
/* parameter1: frame start number */
/* parameter2: frame count */
#define IHC_AA_DONE 0x1004
#define IHC_NOT_READY 0x1005
#define IH_REPLY_DONE 0x2000
#define IH_REPLY_NOT_DONE 0x2001
enum fimc_is_scenario {
IS_SC_PREVIEW_STILL,
IS_SC_PREVIEW_VIDEO,
IS_SC_CAPTURE_STILL,
IS_SC_CAPTURE_VIDEO,
IS_SC_MAX
};
enum fimc_is_sub_scenario {
IS_SC_SUB_DEFAULT,
IS_SC_SUB_PS_VTCALL,
IS_SC_SUB_CS_VTCALL,
IS_SC_SUB_PV_VTCALL,
IS_SC_SUB_CV_VTCALL,
};
struct is_common_regs {
u32 hicmd;
u32 hic_sensorid;
u32 hic_param[4];
u32 reserved1[4];
u32 ihcmd;
u32 ihc_sensorid;
u32 ihc_param[4];
u32 reserved2[4];
u32 isp_sensor_id;
u32 isp_param[2];
u32 reserved3[1];
u32 scc_sensor_id;
u32 scc_param[2];
u32 reserved4[1];
u32 dnr_sensor_id;
u32 dnr_param[2];
u32 reserved5[1];
u32 scp_sensor_id;
u32 scp_param[2];
u32 reserved6[29];
} __packed;
struct is_mcuctl_reg {
u32 mcuctl;
u32 bboar;
u32 intgr0;
u32 intcr0;
u32 intmr0;
u32 intsr0;
u32 intmsr0;
u32 intgr1;
u32 intcr1;
u32 intmr1;
u32 intsr1;
u32 intmsr1;
u32 intcr2;
u32 intmr2;
u32 intsr2;
u32 intmsr2;
u32 gpoctrl;
u32 cpoenctlr;
u32 gpictlr;
u32 reserved[0xd];
struct is_common_regs common;
} __packed;
#endif /* FIMC_IS_CMD_H_ */
This diff is collapsed.
/*
* Samsung Exynos4 SoC series FIMC-IS slave interface driver
*
* FIMC-IS error code definition
*
* Copyright (C) 2011 - 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.
*/
#ifndef FIMC_IS_ERR_H_
#define FIMC_IS_ERR_H_
#define IS_ERROR_VER 011 /* IS ERROR VERSION 0.11 */
enum {
IS_ERROR_NONE,
/* General 1 ~ 99 */
IS_ERROR_INVALID_COMMAND,
IS_ERROR_REQUEST_FAIL,
IS_ERROR_INVALID_SCENARIO,
IS_ERROR_INVALID_SENSORID,
IS_ERROR_INVALID_MODE_CHANGE,
IS_ERROR_INVALID_MAGIC_NUMBER,
IS_ERROR_INVALID_SETFILE_HDR,
IS_ERROR_BUSY,
IS_ERROR_SET_PARAMETER,
IS_ERROR_INVALID_PATH,
IS_ERROR_OPEN_SENSOR_FAIL,
IS_ERROR_ENTRY_MSG_THREAD_DOWN,
IS_ERROR_ISP_FRAME_END_NOT_DONE,
IS_ERROR_DRC_FRAME_END_NOT_DONE,
IS_ERROR_SCALERC_FRAME_END_NOT_DONE,
IS_ERROR_ODC_FRAME_END_NOT_DONE,
IS_ERROR_DIS_FRAME_END_NOT_DONE,
IS_ERROR_TDNR_FRAME_END_NOT_DONE,
IS_ERROR_SCALERP_FRAME_END_NOT_DONE,
IS_ERROR_WAIT_STREAM_OFF_NOT_DONE,
IS_ERROR_NO_MSG_IS_RECEIVED,
IS_ERROR_SENSOR_MSG_FAIL,
IS_ERROR_ISP_MSG_FAIL,
IS_ERROR_DRC_MSG_FAIL,
IS_ERROR_SCALERC_MSG_FAIL,
IS_ERROR_ODC_MSG_FAIL,
IS_ERROR_DIS_MSG_FAIL,
IS_ERROR_TDNR_MSG_FAIL,
IS_ERROR_SCALERP_MSG_FAIL,
IS_ERROR_LHFD_MSG_FAIL,
IS_ERROR_LHFD_INTERNAL_STOP,
/* Sensor 100 ~ 199 */
IS_ERROR_SENSOR_PWRDN_FAIL = 100,
IS_ERROR_SENSOR_STREAM_ON_FAIL,
IS_ERROR_SENSOR_STREAM_OFF_FAIL,
/* ISP 200 ~ 299 */
IS_ERROR_ISP_PWRDN_FAIL = 200,
IS_ERROR_ISP_MULTIPLE_INPUT,
IS_ERROR_ISP_ABSENT_INPUT,
IS_ERROR_ISP_ABSENT_OUTPUT,
IS_ERROR_ISP_NONADJACENT_OUTPUT,
IS_ERROR_ISP_FORMAT_MISMATCH,
IS_ERROR_ISP_WIDTH_MISMATCH,
IS_ERROR_ISP_HEIGHT_MISMATCH,
IS_ERROR_ISP_BITWIDTH_MISMATCH,
IS_ERROR_ISP_FRAME_END_TIME_OUT,
/* DRC 300 ~ 399 */
IS_ERROR_DRC_PWRDN_FAIL = 300,
IS_ERROR_DRC_MULTIPLE_INPUT,
IS_ERROR_DRC_ABSENT_INPUT,
IS_ERROR_DRC_NONADJACENT_INPUT,
IS_ERROR_DRC_ABSENT_OUTPUT,
IS_ERROR_DRC_NONADJACENT_OUTPUT,
IS_ERROR_DRC_FORMAT_MISMATCH,
IS_ERROR_DRC_WIDTH_MISMATCH,
IS_ERROR_DRC_HEIGHT_MISMATCH,
IS_ERROR_DRC_BITWIDTH_MISMATCH,
IS_ERROR_DRC_FRAME_END_TIME_OUT,
/* SCALERC 400 ~ 499 */
IS_ERROR_SCALERC_PWRDN_FAIL = 400,
/* ODC 500 ~ 599 */
IS_ERROR_ODC_PWRDN_FAIL = 500,
/* DIS 600 ~ 699 */
IS_ERROR_DIS_PWRDN_FAIL = 600,
/* TDNR 700 ~ 799 */
IS_ERROR_TDNR_PWRDN_FAIL = 700,
/* SCALERC 800 ~ 899 */
IS_ERROR_SCALERP_PWRDN_FAIL = 800,
/* FD 900 ~ 999 */
IS_ERROR_FD_PWRDN_FAIL = 900,
IS_ERROR_FD_MULTIPLE_INPUT,
IS_ERROR_FD_ABSENT_INPUT,
IS_ERROR_FD_NONADJACENT_INPUT,
IS_ERROR_LHFD_FRAME_END_TIME_OUT,
IS_ERROR_UNKNOWN = 1000,
};
#define IS_ERROR_TIME_OUT_FLAG 0x80000000
/* Set parameter error enum */
enum fimc_is_error {
/* Common error (0~99) */
ERROR_COMMON_NONE = 0,
ERROR_COMMON_CMD = 1, /* Invalid command */
ERROR_COMMON_PARAMETER = 2, /* Invalid parameter */
/* setfile is not loaded before adjusting */
ERROR_COMMON_SETFILE_LOAD = 3,
/* setfile is not Adjusted before runnng. */
ERROR_COMMON_SETFILE_ADJUST = 4,
/* Index of setfile is not valid (0~MAX_SETFILE_NUM-1) */
ERROR_COMMON_SETFILE_INDEX = 5,
/* Input path can be changed in ready state(stop) */
ERROR_COMMON_INPUT_PATH = 6,
/* IP can not start if input path is not set */
ERROR_COMMON_INPUT_INIT = 7,
/* Output path can be changed in ready state (stop) */
ERROR_COMMON_OUTPUT_PATH = 8,
/* IP can not start if output path is not set */
ERROR_COMMON_OUTPUT_INIT = 9,
ERROR_CONTROL_NONE = ERROR_COMMON_NONE,
ERROR_CONTROL_BYPASS = 11, /* Enable or Disable */
ERROR_OTF_INPUT_NONE = ERROR_COMMON_NONE,
ERROR_OTF_INPUT_CMD = 21,
/* invalid format (DRC: YUV444, FD: YUV444, 422, 420) */
ERROR_OTF_INPUT_FORMAT = 22,
/* invalid width (DRC: 128~8192, FD: 32~8190) */
ERROR_OTF_INPUT_WIDTH = 23,
/* invalid height (DRC: 64~8192, FD: 16~8190) */
ERROR_OTF_INPUT_HEIGHT = 24,
/* invalid bit-width (DRC: 8~12bits, FD: 8bit) */
ERROR_OTF_INPUT_BIT_WIDTH = 25,
/* invalid FrameTime for ISP */
ERROR_OTF_INPUT_USER_FRAMETIIME = 26,
ERROR_DMA_INPUT_NONE = ERROR_COMMON_NONE,
/* invalid width (DRC: 128~8192, FD: 32~8190) */
ERROR_DMA_INPUT_WIDTH = 31,
/* invalid height (DRC: 64~8192, FD: 16~8190) */
ERROR_DMA_INPUT_HEIGHT = 32,
/* invalid format (DRC: YUV444 or YUV422, FD: YUV444, 422, 420) */
ERROR_DMA_INPUT_FORMAT = 33,
/* invalid bit-width (DRC: 8~12bit, FD: 8bit) */
ERROR_DMA_INPUT_BIT_WIDTH = 34,
/* invalid order(DRC: YYCbCrorYCbYCr, FD:NO,YYCbCr,YCbYCr,CbCr,CrCb) */
ERROR_DMA_INPUT_ORDER = 35,
/* invalid palne (DRC: 3, FD: 1, 2, 3) */
ERROR_DMA_INPUT_PLANE = 36,
ERROR_OTF_OUTPUT_NONE = ERROR_COMMON_NONE,
/* invalid width (DRC: 128~8192) */
ERROR_OTF_OUTPUT_WIDTH = 41,
/* invalid height (DRC: 64~8192) */
ERROR_OTF_OUTPUT_HEIGHT = 42,
/* invalid format (DRC: YUV444) */
ERROR_OTF_OUTPUT_FORMAT = 43,
/* invalid bit-width (DRC: 8~12bits) */
ERROR_OTF_OUTPUT_BIT_WIDTH = 44,
ERROR_DMA_OUTPUT_NONE = ERROR_COMMON_NONE,
ERROR_DMA_OUTPUT_WIDTH = 51, /* invalid width */
ERROR_DMA_OUTPUT_HEIGHT = 52, /* invalid height */
ERROR_DMA_OUTPUT_FORMAT = 53, /* invalid format */
ERROR_DMA_OUTPUT_BIT_WIDTH = 54, /* invalid bit-width */
ERROR_DMA_OUTPUT_PLANE = 55, /* invalid plane */
ERROR_DMA_OUTPUT_ORDER = 56, /* invalid order */
ERROR_GLOBAL_SHOTMODE_NONE = ERROR_COMMON_NONE,
/* SENSOR Error(100~199) */
ERROR_SENSOR_NONE = ERROR_COMMON_NONE,
ERROR_SENSOR_I2C_FAIL = 101,
ERROR_SENSOR_INVALID_FRAMERATE,
ERROR_SENSOR_INVALID_EXPOSURETIME,
ERROR_SENSOR_INVALID_SIZE,
ERROR_SENSOR_INVALID_SETTING,
ERROR_SENSOR_ACTURATOR_INIT_FAIL,
ERROR_SENSOR_INVALID_AF_POS,
ERROR_SENSOR_UNSUPPORT_FUNC,
ERROR_SENSOR_UNSUPPORT_PERI,
ERROR_SENSOR_UNSUPPORT_AF,
/* ISP Error (200~299) */
ERROR_ISP_AF_NONE = ERROR_COMMON_NONE,
ERROR_ISP_AF_BUSY = 201,
ERROR_ISP_AF_INVALID_COMMAND = 202,
ERROR_ISP_AF_INVALID_MODE = 203,
ERROR_ISP_FLASH_NONE = ERROR_COMMON_NONE,
ERROR_ISP_AWB_NONE = ERROR_COMMON_NONE,
ERROR_ISP_IMAGE_EFFECT_NONE = ERROR_COMMON_NONE,
ERROR_ISP_ISO_NONE = ERROR_COMMON_NONE,
ERROR_ISP_ADJUST_NONE = ERROR_COMMON_NONE,
ERROR_ISP_METERING_NONE = ERROR_COMMON_NONE,
ERROR_ISP_AFC_NONE = ERROR_COMMON_NONE,
/* DRC Error (300~399) */
/* FD Error (400~499) */
ERROR_FD_NONE = ERROR_COMMON_NONE,
/* Invalid max number (1~16) */
ERROR_FD_CONFIG_MAX_NUMBER_STATE = 401,
ERROR_FD_CONFIG_MAX_NUMBER_INVALID = 402,
ERROR_FD_CONFIG_YAW_ANGLE_STATE = 403,
ERROR_FD_CONFIG_YAW_ANGLE_INVALID = 404,
ERROR_FD_CONFIG_ROLL_ANGLE_STATE = 405,
ERROR_FD_CONFIG_ROLL_ANGLE_INVALID = 406,
ERROR_FD_CONFIG_SMILE_MODE_INVALID = 407,
ERROR_FD_CONFIG_BLINK_MODE_INVALID = 408,
ERROR_FD_CONFIG_EYES_DETECT_INVALID = 409,
ERROR_FD_CONFIG_MOUTH_DETECT_INVALID = 410,
ERROR_FD_CONFIG_ORIENTATION_STATE = 411,
ERROR_FD_CONFIG_ORIENTATION_INVALID = 412,
ERROR_FD_CONFIG_ORIENTATION_VALUE_INVALID = 413,
/* PARAM_FdResultStr can be only applied in ready-state or stream off */
ERROR_FD_RESULT = 414,
/* PARAM_FdModeStr can be only applied in ready-state or stream off */
ERROR_FD_MODE = 415,
/* Scaler Error (500 ~ 599) */
ERROR_SCALER_NO_NONE = ERROR_COMMON_NONE,
ERROR_SCALER_DMA_OUTSEL = 501,
ERROR_SCALER_H_RATIO = 502,
ERROR_SCALER_V_RATIO = 503,
ERROR_SCALER_IMAGE_EFFECT = 510,
ERROR_SCALER_ROTATE = 520,
ERROR_SCALER_FLIP = 521,
};
const char * const fimc_is_strerr(unsigned int error);
const char * const fimc_is_param_strerr(unsigned int error);
#endif /* FIMC_IS_ERR_H_ */
/*
* Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
*
* Copyright (C) 2012 - 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.
*/
#include <linux/delay.h>
#include "fimc-is.h"
#include "fimc-is-command.h"
#include "fimc-is-regs.h"
#include "fimc-is-sensor.h"
void fimc_is_fw_clear_irq1(struct fimc_is *is, unsigned int nr)
{
mcuctl_write(1UL << nr, is, MCUCTL_REG_INTCR1);
}
void fimc_is_fw_clear_irq2(struct fimc_is *is)
{
u32 cfg = mcuctl_read(is, MCUCTL_REG_INTSR2);
mcuctl_write(cfg, is, MCUCTL_REG_INTCR2);
}
void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is)
{
mcuctl_write(INTGR0_INTGD(0), is, MCUCTL_REG_INTGR0);
}
int fimc_is_hw_wait_intsr0_intsd0(struct fimc_is *is)
{
unsigned int timeout = 2000;
u32 cfg, status;
cfg = mcuctl_read(is, MCUCTL_REG_INTSR0);
status = INTSR0_GET_INTSD(0, cfg);
while (status) {
cfg = mcuctl_read(is, MCUCTL_REG_INTSR0);
status = INTSR0_GET_INTSD(0, cfg);
if (timeout == 0) {
dev_warn(&is->pdev->dev, "%s timeout\n",
__func__);
return -ETIME;
}
timeout--;
udelay(1);
}
return 0;
}
int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is)
{
unsigned int timeout = 2000;
u32 cfg, status;
cfg = mcuctl_read(is, MCUCTL_REG_INTMSR0);
status = INTMSR0_GET_INTMSD(0, cfg);
while (status) {
cfg = mcuctl_read(is, MCUCTL_REG_INTMSR0);
status = INTMSR0_GET_INTMSD(0, cfg);
if (timeout == 0) {
dev_warn(&is->pdev->dev, "%s timeout\n",
__func__);
return -ETIME;
}
timeout--;
udelay(1);
}
return 0;
}
int fimc_is_hw_set_param(struct fimc_is *is)
{
struct is_config_param *cfg = &is->cfg_param[is->scenario_id];
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_SET_PARAMETER, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
mcuctl_write(is->scenario_id, is, MCUCTL_REG_ISSR(2));
mcuctl_write(atomic_read(&cfg->p_region_num), is, MCUCTL_REG_ISSR(3));
mcuctl_write(cfg->p_region_index1, is, MCUCTL_REG_ISSR(4));
mcuctl_write(cfg->p_region_index2, is, MCUCTL_REG_ISSR(5));
fimc_is_hw_set_intgr0_gd0(is);
return 0;
}
int fimc_is_hw_set_tune(struct fimc_is *is)
{
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_SET_TUNE, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
mcuctl_write(is->h2i_cmd.entry_id, is, MCUCTL_REG_ISSR(2));
fimc_is_hw_set_intgr0_gd0(is);
return 0;
}
#define FIMC_IS_MAX_PARAMS 4
int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num_args)
{
int i;
if (num_args > FIMC_IS_MAX_PARAMS)
return -EINVAL;
is->i2h_cmd.num_args = num_args;
for (i = 0; i < FIMC_IS_MAX_PARAMS; i++) {
if (i < num_args)
is->i2h_cmd.args[i] = mcuctl_read(is,
MCUCTL_REG_ISSR(12 + i));
else
is->i2h_cmd.args[i] = 0;
}
return 0;
}
void fimc_is_hw_set_sensor_num(struct fimc_is *is)
{
pr_debug("setting sensor index to: %d\n", is->sensor_index);
mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2));
mcuctl_write(FIMC_IS_SENSOR_NUM, is, MCUCTL_REG_ISSR(3));
}
void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index)
{
if (is->sensor_index != index)
return;
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_CLOSE_SENSOR, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(2));
fimc_is_hw_set_intgr0_gd0(is);
}
void fimc_is_hw_get_setfile_addr(struct fimc_is *is)
{
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_GET_SET_FILE_ADDR, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
fimc_is_hw_set_intgr0_gd0(is);
}
void fimc_is_hw_load_setfile(struct fimc_is *is)
{
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_LOAD_SET_FILE, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
fimc_is_hw_set_intgr0_gd0(is);
}
int fimc_is_hw_change_mode(struct fimc_is *is)
{
const u8 cmd[] = {
HIC_PREVIEW_STILL, HIC_PREVIEW_VIDEO,
HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO,
};
if (WARN_ON(is->scenario_id > ARRAY_SIZE(cmd)))
return -EINVAL;
mcuctl_write(cmd[is->scenario_id], is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
mcuctl_write(is->setfile.sub_index, is, MCUCTL_REG_ISSR(2));
fimc_is_hw_set_intgr0_gd0(is);
return 0;
}
void fimc_is_hw_stream_on(struct fimc_is *is)
{
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_STREAM_ON, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
mcuctl_write(0, is, MCUCTL_REG_ISSR(2));
fimc_is_hw_set_intgr0_gd0(is);
}
void fimc_is_hw_stream_off(struct fimc_is *is)
{
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_STREAM_OFF, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
fimc_is_hw_set_intgr0_gd0(is);
}
void fimc_is_hw_subip_power_off(struct fimc_is *is)
{
fimc_is_hw_wait_intmsr0_intmsd0(is);
mcuctl_write(HIC_POWER_DOWN, is, MCUCTL_REG_ISSR(0));
mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
fimc_is_hw_set_intgr0_gd0(is);
}
int fimc_is_itf_s_param(struct fimc_is *is, bool update)
{
int ret;
if (update)
__is_hw_update_params(is);
fimc_is_mem_barrier();
clear_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
fimc_is_hw_set_param(is);
ret = fimc_is_wait_event(is, IS_ST_BLOCK_CMD_CLEARED, 1,
FIMC_IS_CONFIG_TIMEOUT);
if (ret < 0)
dev_err(&is->pdev->dev, "%s() timeout\n", __func__);
return ret;
}
int fimc_is_itf_mode_change(struct fimc_is *is)
{
int ret;
clear_bit(IS_ST_CHANGE_MODE, &is->state);
fimc_is_hw_change_mode(is);
ret = fimc_is_wait_event(is, IS_ST_CHANGE_MODE, 1,
FIMC_IS_CONFIG_TIMEOUT);
if (!ret < 0)
dev_err(&is->pdev->dev, "%s(): mode change (%d) timeout\n",
__func__, is->scenario_id);
return ret;
}
/*
* Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
*
* Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
* Younghwan Joo <yhwan.joo@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.
*/
#ifndef FIMC_IS_REG_H_
#define FIMC_IS_REG_H_
/* WDT_ISP register */
#define REG_WDT_ISP 0x00170000
/* MCUCTL registers base offset */
#define MCUCTL_BASE 0x00180000
/* MCU Controller Register */
#define MCUCTL_REG_MCUCTRL (MCUCTL_BASE + 0x00)
#define MCUCTRL_MSWRST (1 << 0)
/* Boot Base Offset Address Register */
#define MCUCTL_REG_BBOAR (MCUCTL_BASE + 0x04)
/* Interrupt Generation Register 0 from Host CPU to VIC */
#define MCUCTL_REG_INTGR0 (MCUCTL_BASE + 0x08)
/* __n = 0...9 */
#define INTGR0_INTGC(__n) (1 << ((__n) + 16))
/* __n = 0...5 */
#define INTGR0_INTGD(__n) (1 << (__n))
/* Interrupt Clear Register 0 from Host CPU to VIC */
#define MCUCTL_REG_INTCR0 (MCUCTL_BASE + 0x0c)
/* __n = 0...9 */
#define INTCR0_INTGC(__n) (1 << ((__n) + 16))
/* __n = 0...5 */
#define INTCR0_INTCD(__n) (1 << ((__n) + 16))
/* Interrupt Mask Register 0 from Host CPU to VIC */
#define MCUCTL_REG_INTMR0 (MCUCTL_BASE + 0x10)
/* __n = 0...9 */
#define INTMR0_INTMC(__n) (1 << ((__n) + 16))
/* __n = 0...5 */
#define INTMR0_INTMD(__n) (1 << (__n))
/* Interrupt Status Register 0 from Host CPU to VIC */
#define MCUCTL_REG_INTSR0 (MCUCTL_BASE + 0x14)
/* __n (bit number) = 0...4 */
#define INTSR0_GET_INTSD(x, __n) (((x) >> (__n)) & 0x1)
/* __n (bit number) = 0...9 */
#define INTSR0_GET_INTSC(x, __n) (((x) >> ((__n) + 16)) & 0x1)
/* Interrupt Mask Status Register 0 from Host CPU to VIC */
#define MCUCTL_REG_INTMSR0 (MCUCTL_BASE + 0x18)
/* __n (bit number) = 0...4 */
#define INTMSR0_GET_INTMSD(x, __n) (((x) >> (__n)) & 0x1)
/* __n (bit number) = 0...9 */
#define INTMSR0_GET_INTMSC(x, __n) (((x) >> ((__n) + 16)) & 0x1)
/* Interrupt Generation Register 1 from ISP CPU to Host IC */
#define MCUCTL_REG_INTGR1 (MCUCTL_BASE + 0x1c)
/* __n = 0...9 */
#define INTGR1_INTGC(__n) (1 << (__n))
/* Interrupt Clear Register 1 from ISP CPU to Host IC */
#define MCUCTL_REG_INTCR1 (MCUCTL_BASE + 0x20)
/* __n = 0...9 */
#define INTCR1_INTCC(__n) (1 << (__n))
/* Interrupt Mask Register 1 from ISP CPU to Host IC */
#define MCUCTL_REG_INTMR1 (MCUCTL_BASE + 0x24)
/* __n = 0...9 */
#define INTMR1_INTMC(__n) (1 << (__n))
/* Interrupt Status Register 1 from ISP CPU to Host IC */
#define MCUCTL_REG_INTSR1 (MCUCTL_BASE + 0x28)
/* Interrupt Mask Status Register 1 from ISP CPU to Host IC */
#define MCUCTL_REG_INTMSR1 (MCUCTL_BASE + 0x2c)
/* Interrupt Clear Register 2 from ISP BLK's interrupts to Host IC */
#define MCUCTL_REG_INTCR2 (MCUCTL_BASE + 0x30)
/* __n = 0...5 */
#define INTCR2_INTCC(__n) (1 << ((__n) + 16))
/* Interrupt Mask Register 2 from ISP BLK's interrupts to Host IC */
#define MCUCTL_REG_INTMR2 (MCUCTL_BASE + 0x34)
/* __n = 0...25 */
#define INTMR2_INTMCIS(__n) (1 << (__n))
/* Interrupt Status Register 2 from ISP BLK's interrupts to Host IC */
#define MCUCTL_REG_INTSR2 (MCUCTL_BASE + 0x38)
/* Interrupt Mask Status Register 2 from ISP BLK's interrupts to Host IC */
#define MCUCTL_REG_INTMSR2 (MCUCTL_BASE + 0x3c)
/* General Purpose Output Control Register (0~17) */
#define MCUCTL_REG_GPOCTLR (MCUCTL_BASE + 0x40)
/* __n = 0...17 */
#define GPOCTLR_GPOG(__n) (1 << (__n))
/* General Purpose Pad Output Enable Register (0~17) */
#define MCUCTL_REG_GPOENCTLR (MCUCTL_BASE + 0x44)
/* __n = 0...17 */
#define GPOENCTLR_GPOEN(__n) (1 << (__n))
/* General Purpose Input Control Register (0~17) */
#define MCUCTL_REG_GPICTLR (MCUCTL_BASE + 0x48)
/* Shared registers between ISP CPU and the host CPU - ISSRxx */
/* ISSR(1): Command Host -> IS */
/* ISSR(1): Sensor ID for Command, ISSR2...5 = Parameter 1...4 */
/* ISSR(10): Reply IS -> Host */
/* ISSR(11): Sensor ID for Reply, ISSR12...15 = Parameter 1...4 */
/* ISSR(20): ISP_FRAME_DONE : SENSOR ID */
/* ISSR(21): ISP_FRAME_DONE : PARAMETER 1 */
/* ISSR(24): SCALERC_FRAME_DONE : SENSOR ID */
/* ISSR(25): SCALERC_FRAME_DONE : PARAMETER 1 */
/* ISSR(28): 3DNR_FRAME_DONE : SENSOR ID */
/* ISSR(29): 3DNR_FRAME_DONE : PARAMETER 1 */
/* ISSR(32): SCALERP_FRAME_DONE : SENSOR ID */
/* ISSR(33): SCALERP_FRAME_DONE : PARAMETER 1 */
/* __n = 0...63 */
#define MCUCTL_REG_ISSR(__n) (MCUCTL_BASE + 0x80 + ((__n) * 4))
/* PMU ISP register offsets */
#define REG_CMU_RESET_ISP_SYS_PWR_REG 0x1174
#define REG_CMU_SYSCLK_ISP_SYS_PWR_REG 0x13b8
#define REG_PMU_ISP_ARM_SYS 0x1050
#define REG_PMU_ISP_ARM_CONFIGURATION 0x2280
#define REG_PMU_ISP_ARM_STATUS 0x2284
#define REG_PMU_ISP_ARM_OPTION 0x2288
void fimc_is_fw_clear_irq1(struct fimc_is *is, unsigned int bit);
void fimc_is_fw_clear_irq2(struct fimc_is *is);
int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num);
void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is);
int fimc_is_hw_wait_intsr0_intsd0(struct fimc_is *is);
int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is);
void fimc_is_hw_set_sensor_num(struct fimc_is *is);
void fimc_is_hw_stream_on(struct fimc_is *is);
void fimc_is_hw_stream_off(struct fimc_is *is);
int fimc_is_hw_set_param(struct fimc_is *is);
int fimc_is_hw_change_mode(struct fimc_is *is);
void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index);
void fimc_is_hw_get_setfile_addr(struct fimc_is *is);
void fimc_is_hw_load_setfile(struct fimc_is *is);
void fimc_is_hw_subip_power_off(struct fimc_is *is);
int fimc_is_itf_s_param(struct fimc_is *is, bool update);
int fimc_is_itf_mode_change(struct fimc_is *is);
#endif /* FIMC_IS_REG_H_ */
This diff is collapsed.
/*
* 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.
*/
#ifndef FIMC_IS_H_
#define FIMC_IS_H_
#include <asm/barrier.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/sizes.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <media/videobuf2-core.h>
#include <media/v4l2-ctrls.h>
#include "fimc-isp.h"
#include "fimc-is-command.h"
#include "fimc-is-sensor.h"
#include "fimc-is-param.h"
#include "fimc-is-regs.h"
#define FIMC_IS_DRV_NAME "exynos4-fimc-is"
#define FIMC_IS_FW_FILENAME "fimc_is_fw.bin"
#define FIMC_IS_SETFILE_6A3 "setfile.bin"
#define FIMC_IS_FW_LOAD_TIMEOUT 1000 /* ms */
#define FIMC_IS_POWER_ON_TIMEOUT 1000 /* us */
#define FIMC_IS_SENSOR_NUM 2
/* Memory definitions */
#define FIMC_IS_CPU_MEM_SIZE (0xa00000)
#define FIMC_IS_CPU_BASE_MASK ((1 << 26) - 1)
#define FIMC_IS_REGION_SIZE 0x5000
#define FIMC_IS_DEBUG_REGION_OFFSET 0x0084b000
#define FIMC_IS_SHARED_REGION_OFFSET 0x008c0000
#define FIMC_IS_FW_INFO_LEN 31
#define FIMC_IS_FW_VER_LEN 7
#define FIMC_IS_FW_DESC_LEN (FIMC_IS_FW_INFO_LEN + \
FIMC_IS_FW_VER_LEN)
#define FIMC_IS_SETFILE_INFO_LEN 39
#define FIMC_IS_EXTRA_MEM_SIZE (FIMC_IS_EXTRA_FW_SIZE + \
FIMC_IS_EXTRA_SETFILE_SIZE + 0x1000)
#define FIMC_IS_EXTRA_FW_SIZE 0x180000
#define FIMC_IS_EXTRA_SETFILE_SIZE 0x4b000
/* TODO: revisit */
#define FIMC_IS_FW_ADDR_MASK ((1 << 26) - 1)
#define FIMC_IS_FW_SIZE_MAX (SZ_4M)
#define FIMC_IS_FW_SIZE_MIN (SZ_32K)
#define ATCLK_MCUISP_FREQUENCY 100000000UL
#define ACLK_AXI_FREQUENCY 100000000UL
enum {
ISS_CLK_PPMUISPX,
ISS_CLK_PPMUISPMX,
ISS_CLK_LITE0,
ISS_CLK_LITE1,
ISS_CLK_MPLL,
ISS_CLK_SYSREG,
ISS_CLK_ISP,
ISS_CLK_DRC,
ISS_CLK_FD,
ISS_CLK_MCUISP,
ISS_CLK_UART,
ISS_GATE_CLKS_MAX,
ISS_CLK_ISP_DIV0 = ISS_GATE_CLKS_MAX,
ISS_CLK_ISP_DIV1,
ISS_CLK_MCUISP_DIV0,
ISS_CLK_MCUISP_DIV1,
ISS_CLK_ACLK200,
ISS_CLK_ACLK200_DIV,
ISS_CLK_ACLK400MCUISP,
ISS_CLK_ACLK400MCUISP_DIV,
ISS_CLKS_MAX
};
/* The driver's internal state flags */
enum {
IS_ST_IDLE,
IS_ST_PWR_ON,
IS_ST_A5_PWR_ON,
IS_ST_FW_LOADED,
IS_ST_OPEN_SENSOR,
IS_ST_SETFILE_LOADED,
IS_ST_INIT_DONE,
IS_ST_STREAM_ON,
IS_ST_STREAM_OFF,
IS_ST_CHANGE_MODE,
IS_ST_BLOCK_CMD_CLEARED,
IS_ST_SET_ZOOM,
IS_ST_PWR_SUBIP_ON,
IS_ST_END,
};
enum af_state {
FIMC_IS_AF_IDLE = 0,
FIMC_IS_AF_SETCONFIG = 1,
FIMC_IS_AF_RUNNING = 2,
FIMC_IS_AF_LOCK = 3,
FIMC_IS_AF_ABORT = 4,
FIMC_IS_AF_FAILED = 5,
};
enum af_lock_state {
FIMC_IS_AF_UNLOCKED = 0,
FIMC_IS_AF_LOCKED = 2
};
enum ae_lock_state {
FIMC_IS_AE_UNLOCKED = 0,
FIMC_IS_AE_LOCKED = 1
};
enum awb_lock_state {
FIMC_IS_AWB_UNLOCKED = 0,
FIMC_IS_AWB_LOCKED = 1
};
enum {
IS_METERING_CONFIG_CMD,
IS_METERING_CONFIG_WIN_POS_X,
IS_METERING_CONFIG_WIN_POS_Y,
IS_METERING_CONFIG_WIN_WIDTH,
IS_METERING_CONFIG_WIN_HEIGHT,
IS_METERING_CONFIG_MAX
};
struct is_setfile {
const struct firmware *info;
int state;
u32 sub_index;
u32 base;
size_t size;
};
struct is_fd_result_header {
u32 offset;
u32 count;
u32 index;
u32 curr_index;
u32 width;
u32 height;
};
struct is_af_info {
u16 mode;
u32 af_state;
u32 af_lock_state;
u32 ae_lock_state;
u32 awb_lock_state;
u16 pos_x;
u16 pos_y;
u16 prev_pos_x;
u16 prev_pos_y;
u16 use_af;
};
struct fimc_is_firmware {
const struct firmware *f_w;
dma_addr_t paddr;
void *vaddr;
unsigned int size;
char info[FIMC_IS_FW_INFO_LEN + 1];
char version[FIMC_IS_FW_VER_LEN + 1];
char setfile_info[FIMC_IS_SETFILE_INFO_LEN + 1];
u8 state;
};
struct fimc_is_memory {
/* physical base address */
dma_addr_t paddr;
/* virtual base address */
void *vaddr;
/* total length */
unsigned int size;
};
#define FIMC_IS_I2H_MAX_ARGS 12
struct i2h_cmd {
u32 cmd;
u32 sensor_id;
u16 num_args;
u32 args[FIMC_IS_I2H_MAX_ARGS];
};
struct h2i_cmd {
u16 cmd_type;
u32 entry_id;
};
#define FIMC_IS_DEBUG_MSG 0x3f
#define FIMC_IS_DEBUG_LEVEL 3
struct fimc_is_setfile {
const struct firmware *info;
unsigned int state;
unsigned int size;
u32 sub_index;
u32 base;
};
struct is_config_param {
struct global_param global;
struct sensor_param sensor;
struct isp_param isp;
struct drc_param drc;
struct fd_param fd;
atomic_t p_region_num;
unsigned long p_region_index1;
unsigned long p_region_index2;
};
/**
* struct fimc_is - fimc-is data structure
* @pdev: pointer to FIMC-IS platform device
* @pctrl: pointer to pinctrl structure for this device
* @v4l2_dev: pointer to top the level v4l2_device
* @alloc_ctx: videobuf2 memory allocator context
* @lock: mutex serializing video device and the subdev operations
* @slock: spinlock protecting this data structure and the hw registers
* @clocks: FIMC-LITE gate clock
* @regs: MCUCTL mmapped registers region
* @pmu_regs: PMU ISP mmapped registers region
* @irq_queue: interrupt handling waitqueue
* @lpm: low power mode flag
* @state: internal driver's state flags
*/
struct fimc_is {
struct platform_device *pdev;
struct pinctrl *pctrl;
struct v4l2_device *v4l2_dev;
struct fimc_is_firmware fw;
struct fimc_is_memory memory;
struct firmware *f_w;
struct fimc_isp isp;
struct fimc_is_sensor *sensor;
struct fimc_is_setfile setfile;
struct vb2_alloc_ctx *alloc_ctx;
struct v4l2_ctrl_handler ctrl_handler;
struct mutex lock;
spinlock_t slock;
struct clk *clocks[ISS_CLKS_MAX];
bool clk_init;
void __iomem *regs;
void __iomem *pmu_regs;
int irq;
wait_queue_head_t irq_queue;
u8 lpm;
unsigned long state;
unsigned int sensor_index;
struct i2h_cmd i2h_cmd;
struct h2i_cmd h2i_cmd;
struct is_fd_result_header fd_header;
struct is_config_param cfg_param[IS_SC_MAX];
struct is_region *is_p_region;
dma_addr_t is_dma_p_region;
struct is_share_region *is_shared_region;
struct is_af_info af;
u32 scenario_id;
struct dentry *debugfs_entry;
};
static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp)
{
return container_of(isp, struct fimc_is, isp);
}
static inline void fimc_is_mem_barrier(void)
{
mb();
}
static inline void fimc_is_set_param_bit(struct fimc_is *is, int num)
{
struct is_config_param *cfg = &is->cfg_param[is->scenario_id];
if (num >= 32)
set_bit(num - 32, &cfg->p_region_index2);
else
set_bit(num, &cfg->p_region_index1);
}
static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd)
{
is->is_p_region->parameter.isp.control.cmd = cmd;
}
static inline void mcuctl_write(u32 v, struct fimc_is *is, unsigned int offset)
{
writel(v, is->regs + offset);
}
static inline u32 mcuctl_read(struct fimc_is *is, unsigned int offset)
{
return readl(is->regs + offset);
}
static inline void pmuisp_write(u32 v, struct fimc_is *is, unsigned int offset)
{
writel(v, is->pmu_regs + offset);
}
static inline u32 pmuisp_read(struct fimc_is *is, unsigned int offset)
{
return readl(is->pmu_regs + offset);
}
int fimc_is_wait_event(struct fimc_is *is, unsigned long bit,
unsigned int state, unsigned int timeout);
int fimc_is_cpu_set_power(struct fimc_is *is, int on);
int fimc_is_start_firmware(struct fimc_is *is);
int fimc_is_hw_initialize(struct fimc_is *is);
void fimc_is_log_dump(const char *level, const void *buf, size_t len);
#endif /* FIMC_IS_H_ */
This diff is collapsed.
/*
* Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
*
* Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
* Younghwan Joo <yhwan.joo@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.
*/
#ifndef FIMC_ISP_H_
#define FIMC_ISP_H_
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include <media/media-entity.h>
#include <media/videobuf2-core.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
#include <media/s5p_fimc.h>
/* FIXME: revisit these constraints */
#define FIMC_ISP_SINK_WIDTH_MIN (16 + 8)
#define FIMC_ISP_SINK_HEIGHT_MIN (12 + 8)
#define FIMC_ISP_SOURCE_WIDTH_MIN 8
#define FIMC_ISP_SOURC_HEIGHT_MIN 8
#define FIMC_ISP_CAC_MARGIN_WIDTH 16
#define FIMC_ISP_CAC_MARGIN_HEIGHT 12
#define FIMC_ISP_SINK_WIDTH_MAX (4000 - 16)
#define FIMC_ISP_SINK_HEIGHT_MAX (4000 + 12)
#define FIMC_ISP_SOURCE_WIDTH_MAX 4000
#define FIMC_ISP_SOURC_HEIGHT_MAX 4000
#define FIMC_ISP_NUM_FORMATS 3
#define FIMC_ISP_REQ_BUFS_MIN 2
#define FIMC_ISP_SD_PAD_SINK 0
#define FIMC_ISP_SD_PAD_SRC_FIFO 1
#define FIMC_ISP_SD_PAD_SRC_DMA 2
#define FIMC_ISP_SD_PADS_NUM 3
#define FIMC_ISP_MAX_PLANES 1
/**
* struct fimc_isp_frame - source/target frame properties
* @width: full image width
* @height: full image height
* @rect: crop/composition rectangle
*/
struct fimc_isp_frame {
u16 width;
u16 height;
struct v4l2_rect rect;
};
struct fimc_isp_ctrls {
struct v4l2_ctrl_handler handler;
/* Auto white balance */
struct v4l2_ctrl *auto_wb;
/* Auto ISO control cluster */
struct {
struct v4l2_ctrl *auto_iso;
struct v4l2_ctrl *iso;
};
/* Adjust - contrast */
struct v4l2_ctrl *contrast;
/* Adjust - saturation */
struct v4l2_ctrl *saturation;
/* Adjust - sharpness */
struct v4l2_ctrl *sharpness;
/* Adjust - brightness */
struct v4l2_ctrl *brightness;
/* Adjust - hue */
struct v4l2_ctrl *hue;
/* Auto/manual exposure */
struct v4l2_ctrl *auto_exp;
/* Manual exposure value */
struct v4l2_ctrl *exposure;
/* AE/AWB lock/unlock */
struct v4l2_ctrl *aewb_lock;
/* Exposure metering mode */
struct v4l2_ctrl *exp_metering;
/* AFC */
struct v4l2_ctrl *afc;
/* ISP image effect */
struct v4l2_ctrl *colorfx;
};
/**
* struct fimc_is_video - fimc-is video device structure
* @vdev: video_device structure
* @type: video device type (CAPTURE/OUTPUT)
* @pad: video device media (sink) pad
* @pending_buf_q: pending buffers queue head
* @active_buf_q: a queue head of buffers scheduled in hardware
* @vb_queue: vb2 buffer queue
* @active_buf_count: number of video buffers scheduled in hardware
* @frame_count: counter of frames dequeued to user space
* @reqbufs_count: number of buffers requested with REQBUFS ioctl
* @format: current pixel format
*/
struct fimc_is_video {
struct video_device vdev;
enum v4l2_buf_type type;
struct media_pad pad;
struct list_head pending_buf_q;
struct list_head active_buf_q;
struct vb2_queue vb_queue;
unsigned int frame_count;
unsigned int reqbufs_count;
int streaming;
unsigned long payload[FIMC_ISP_MAX_PLANES];
const struct fimc_fmt *format;
};
/**
* struct fimc_isp - FIMC-IS ISP data structure
* @pdev: pointer to FIMC-IS platform device
* @alloc_ctx: videobuf2 memory allocator context
* @subdev: ISP v4l2_subdev
* @subdev_pads: the ISP subdev media pads
* @ctrl_handler: v4l2 controls handler
* @test_pattern: test pattern controls
* @pipeline: video capture pipeline data structure
* @video_lock: mutex serializing video device and the subdev operations
* @fmt: pointer to color format description structure
* @payload: image size in bytes (w x h x bpp)
* @inp_frame: camera input frame structure
* @out_frame: DMA output frame structure
* @source_subdev_grp_id: group id of remote source subdev
* @cac_margin_x: horizontal CAC margin in pixels
* @cac_margin_y: vertical CAC margin in pixels
* @state: driver state flags
* @video_capture: the ISP block video capture device
*/
struct fimc_isp {
struct platform_device *pdev;
struct vb2_alloc_ctx *alloc_ctx;
struct v4l2_subdev subdev;
struct media_pad subdev_pads[FIMC_ISP_SD_PADS_NUM];
struct v4l2_mbus_framefmt subdev_fmt;
struct v4l2_ctrl *test_pattern;
struct fimc_isp_ctrls ctrls;
struct mutex video_lock;
struct mutex subdev_lock;
struct fimc_isp_frame inp_frame;
struct fimc_isp_frame out_frame;
unsigned int source_subdev_grp_id;
unsigned int cac_margin_x;
unsigned int cac_margin_y;
unsigned long state;
struct fimc_is_video video_capture;
};
#define ctrl_to_fimc_isp(_ctrl) \
container_of(ctrl->handler, struct fimc_isp, ctrls.handler)
struct fimc_is;
int fimc_isp_subdev_create(struct fimc_isp *isp);
void fimc_isp_subdev_destroy(struct fimc_isp *isp);
void fimc_isp_irq_handler(struct fimc_is *is);
int fimc_is_create_controls(struct fimc_isp *isp);
int fimc_is_delete_controls(struct fimc_isp *isp);
const struct fimc_fmt *fimc_isp_find_format(const u32 *pixelformat,
const u32 *mbus_code, int index);
#endif /* FIMC_ISP_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment