upate:更新双目sensor驱动

This commit is contained in:
2025-03-06 20:04:44 +08:00
parent e265e27c69
commit 2077a3997d
20 changed files with 44204 additions and 8790 deletions

View File

@@ -110,4 +110,8 @@ config SENSOR_F37P_MIPI
config SENSOR_OV02B10_MIPI
tristate "use ov02b10_mipi driver"
default n
config SENSOR_SC202CS_MIPI
tristate "use sc202cs_mipi driver"
default n

View File

@@ -24,3 +24,4 @@ obj-$(CONFIG_SENSOR_F355P_DVP) += f355p_dvp.o
obj-$(CONFIG_SENSOR_F37P_DVP) += f37p_dvp.o
obj-$(CONFIG_SENSOR_F37P_MIPI) += f37p_mipi.o
obj-$(CONFIG_SENSOR_OV02B10_MIPI) += ov02b10_mipi.o
obj-$(CONFIG_SENSOR_SC202CS_MIPI) += sc202cs_mipi.o

View File

@@ -178,4 +178,5 @@ extern struct sensor_fuc_core f355p_dvp_core;
extern struct sensor_fuc_core f355p_core;
extern struct sensor_fuc_core bf2257cs_core;
extern struct sensor_fuc_core ov02b10_core;
extern struct sensor_fuc_core sc202cs_core;
#endif /*__CAMERA__H__*/

View File

@@ -0,0 +1,857 @@
/*
* A V4L2 driver for Raw cameras.
*
* Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
*
* Authors: Zhao Wei <zhaowei@allwinnertech.com>
* Liang WeiJie <liangweijie@allwinnertech.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 <hal_timer.h>
#include "../../vin_mipi/combo_common.h"
#include "camera.h"
#include "../../utility/sunxi_camera_v2.h"
#include "../../utility/media-bus-format.h"
#include "../../utility/vin_supply.h"
#define MCLK (24*1000*1000)
#define V4L2_IDENT_SENSOR 0xeb52
/*
* Our nominal (default) frame rate.
*/
#define ID_REG_HIGH 0xf0
#define ID_REG_LOW 0xf1
#define ID_VAL_HIGH ((V4L2_IDENT_SENSOR) >> 8)
#define ID_VAL_LOW ((V4L2_IDENT_SENSOR) & 0xff)
#define SENSOR_FRAME_RATE 30
#define VTS 1250
#define EXPOSURE_MIN 6
#define EXPOSURE_MAX (VTS - 6)
#define EXPOSURE_STEP 1
#define EXPOSURE_DEFAULT 0x0148
#define GAIN_MIN 0x00
#define GAIN_MAX 0xF8
#define GAIN_STEP 1
#define GAIN_DEFAULT 20
#define GAIN_STEP_BASE 128 //mean gain min step is 1/64gain
#define DIG_GAIN 0x3e06
#define DIG_FINE_GAIN 0x3e07
#define ANA_GAIN 0x3e09
/*
* The sc202cs i2c address
*/
#define I2C_ADDR 0x7c//0xdc
#define SENSOR_NUM 0x2
#define SENSOR_NAME "sc202cs_mipi"
#define SENSOR_NAME_2 "sc202cs_mipi_2"
static int sensor_power_count[2];
static int sensor_stream_count[2];
static struct sensor_format_struct *current_win[2];
static struct sensor_format_struct *current_switch_win[2];
#define SENSOR_30FPS 1
#define SENSOR_25FPS 0
#define SENSOR_20FPS 0
#define SENSOR_15FPS 0
/*
* The default register settings
*/
static struct regval_list sensor_default_regs[] = {
};
#if defined CONFIG_ISP_READ_THRESHOLD || defined CONFIG_ISP_ONLY_HARD_LIGHTADC//FULL_SIZE
#if SENSOR_30FPS
static struct regval_list sensor_1600x1200_30_regs[] = {
{0x0103, 0x01},
{0x0100, 0x00},
{0x36e9, 0x80},
{0x36e9, 0x24},
{0x301f, 0x01},
{0x3301, 0xff},
{0x3304, 0x68},
{0x3306, 0x40},
{0x3308, 0x08},
{0x3309, 0xa8},
{0x330b, 0xb0},
{0x330c, 0x18},
{0x330d, 0xff},
{0x330e, 0x20},
{0x331e, 0x59},
{0x331f, 0x99},
{0x3333, 0x10},
{0x335e, 0x06},
{0x335f, 0x08},
{0x3364, 0x1f},
{0x337c, 0x02},
{0x337d, 0x0a},
{0x338f, 0xa0},
{0x3390, 0x01},
{0x3391, 0x03},
{0x3392, 0x1f},
{0x3393, 0xff},
{0x3394, 0xff},
{0x3395, 0xff},
{0x33a2, 0x04},
{0x33ad, 0x0c},
{0x33b1, 0x20},
{0x33b3, 0x38},
{0x33f9, 0x40},
{0x33fb, 0x48},
{0x33fc, 0x0f},
{0x33fd, 0x1f},
{0x349f, 0x03},
{0x34a6, 0x03},
{0x34a7, 0x1f},
{0x34a8, 0x38},
{0x34a9, 0x30},
{0x34ab, 0xb0},
{0x34ad, 0xb0},
{0x34f8, 0x1f},
{0x34f9, 0x20},
{0x3630, 0xa0},
{0x3631, 0x92},
{0x3632, 0x64},
{0x3633, 0x43},
{0x3637, 0x49},
{0x363a, 0x85},
{0x363c, 0x0f},
{0x3650, 0x31},
{0x3670, 0x0d},
{0x3674, 0xc0},
{0x3675, 0xa0},
{0x3676, 0xa0},
{0x3677, 0x92},
{0x3678, 0x96},
{0x3679, 0x9a},
{0x367c, 0x03},
{0x367d, 0x0f},
{0x367e, 0x01},
{0x367f, 0x0f},
{0x3698, 0x83},
{0x3699, 0x86},
{0x369a, 0x8c},
{0x369b, 0x94},
{0x36a2, 0x01},
{0x36a3, 0x03},
{0x36a4, 0x07},
{0x36ae, 0x0f},
{0x36af, 0x1f},
{0x36bd, 0x22},
{0x36be, 0x22},
{0x36bf, 0x22},
{0x36d0, 0x01},
{0x370f, 0x02},
{0x3721, 0x6c},
{0x3722, 0x8d},
{0x3725, 0xc5},
{0x3727, 0x14},
{0x3728, 0x04},
{0x37b7, 0x04},
{0x37b8, 0x04},
{0x37b9, 0x06},
{0x37bd, 0x07},
{0x37be, 0x0f},
{0x3901, 0x02},
{0x3903, 0x40},
{0x3905, 0x8d},
{0x3907, 0x00},
{0x3908, 0x41},
{0x391f, 0x41},
{0x3933, 0x80},
{0x3934, 0x02},
{0x3937, 0x6f},
{0x393a, 0x01},
{0x393d, 0x01},
{0x393e, 0xc0},
{0x39dd, 0x41},
{0x3e00, 0x00},
{0x3e01, 0x4d},
{0x3e02, 0xc0},
{0x3e09, 0x00},
{0x4509, 0x28},
{0x450d, 0x61},
{0x0100, 0x01},
};
#endif
#else //CONFIG_ISP_FAST_CONVERGENCE || CONFIG_ISP_HARD_LIGHTADC
static struct regval_list sensor_480p120_regs[] = {
};
#if SENSOR_30FPS
static struct regval_list sensor_480p120fps_to_1600x1200_30fps[] = {
};
#endif
#endif
/*
* Here we'll try to encapsulate the changes for just the output
* video format.
*
*/
static struct regval_list sensor_fmt_raw[] = {
};
/*
* Code for dealing with controls.
* fill with different sensor module
* different sensor module has different settings here
* if not support the follow function , retrun -EINVAL
*/
#if 0
static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value)
{
struct sensor_info *info = to_state(sd);
*value = info->exp;
sensor_dbg("sensor_get_exposure = %d\n", info->exp);
return 0;
}
static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
{
struct sensor_info *info = to_state(sd);
*value = info->gain;
sensor_dbg("sensor_get_gain = %d\n", info->gain);
return 0;
}
#endif
static int sensor_s_exp(int id, unsigned int exp_val)
{
int explow, expmid, exphigh;
//struct sensor_info *info = to_state(sd);
/*struct vin_md *vind = dev_get_drvdata(sd->v4l2_dev->dev);*/
/*struct vin_core *vinc = vind->vinc[0];*/
if (exp_val > EXPOSURE_MAX << 4)
exp_val = EXPOSURE_MAX << 4;
if (exp_val < 16)
exp_val = 16;
exphigh = (unsigned char) (0x0f & (exp_val>>16));
expmid = (unsigned char) (0xff & (exp_val>>8));
explow = (unsigned char) (0xf0 & (exp_val<<0));
sensor_write(id, 0x3e02, explow);
sensor_write(id, 0x3e01, expmid);
sensor_write(id, 0x3e00, exphigh);
sensor_dbg("%s():%d, exp_val = %d\n", __func__, __LINE__, exp_val);
//info->exp = exp_val;
return 0;
}
static unsigned char analog_Gain_Reg[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f};
static int setSensorGain(int id, int gain)
{
int ana_gain = gain / GAIN_STEP_BASE;
int dig_Gain;
int gain_flag = 1;
if (ana_gain >= 16) {
gain_flag = 4;
} else if (ana_gain >= 8) {
gain_flag = 3;
} else if (ana_gain >= 4) {
gain_flag = 2;
} else if (ana_gain >= 2) {
gain_flag = 1;
} else {
gain_flag = 0;
}
sensor_write(id, ANA_GAIN, analog_Gain_Reg[gain_flag]);
dig_Gain = gain >> gain_flag; //dig_Gain min mean 1/128gain
if (dig_Gain < 2 * GAIN_STEP_BASE) {
//step1/128
sensor_write(id, DIG_GAIN, 0x00);
sensor_write(id, DIG_FINE_GAIN, dig_Gain - GAIN_STEP_BASE + 0x80);
//sensor_print("sensor set analog_gain:0x%02x, dig_gain:0x%02x, dig_fine_gain:0x%02x", analog_Gain_Reg[gain_flag], 0x00, dig_Gain - 128 + 0x80);
} else if (dig_Gain < 4 * GAIN_STEP_BASE) {
//step1/64
sensor_write(id, DIG_GAIN, 0x01);
sensor_write(id, DIG_FINE_GAIN, (dig_Gain - GAIN_STEP_BASE * 2) / 2 + 0x80);
//sensor_print("sensor set analog_gain:0x%02x, dig_gain:0x%02x, dig_fine_gain:0x%02x", analog_Gain_Reg[gain_flag], 0x01, (dig_Gain - 128 * 2) / 2 + 0x80);
} else {
sensor_write(id, DIG_GAIN, 0x01);
sensor_write(id, DIG_FINE_GAIN, 0xfc);
}
return 0;
}
static int sensor_s_gain(int id, int gain_val)
{
int tem_gain_val;
//gain min step is 1/128gain
tem_gain_val = gain_val * GAIN_STEP_BASE;
if ((tem_gain_val - tem_gain_val / 16 * 16) > 0) {
tem_gain_val = tem_gain_val / 16 + 1;
} else {
tem_gain_val = tem_gain_val / 16;
}
sensor_dbg("%s(), L:%d, gain_val:%d, tem_gain_val:%d, info->gain:%d\n",
__func__, __LINE__, gain_val, tem_gain_val, info->gain);
setSensorGain(id, tem_gain_val);
return 0;
}
static int sc202cs_sensor_vts;
static int sensor_s_exp_gain(int id, struct sensor_exp_gain *exp_gain)
{
int exp_val, gain_val;
int shutter = 0, frame_length = 0;
exp_val = exp_gain->exp_val;
gain_val = exp_gain->gain_val;
sensor_s_exp(id, exp_gain->exp_val);
sensor_s_gain(id, exp_gain->gain_val);
return 0;
}
#if 0
static int sensor_flip_status;
static int sensor_s_vflip(int id, int enable)
{
data_type get_value;
data_type set_value;
if (!(enable == 0 || enable == 1))
return -1;
sensor_read(id, 0x00, &get_value);
sensor_dbg("ready to vflip, regs_data = 0x%x\n", get_value);
if (enable) {
set_value = get_value | 0x04;
sensor_flip_status |= 0x04;
} else {
set_value = get_value & 0xFB;
sensor_flip_status &= 0xFB;
}
sensor_write(id, 0x00, set_value);
usleep_range(80000, 100000);
sensor_read(id, 0x00, &get_value);
sensor_dbg("after vflip, regs_data = 0x%x, sensor_flip_status = %d\n",
get_value, sensor_flip_status);
return 0;
}
static int sensor_s_hflip(int id, int enable)
{
data_type get_value;
data_type set_value;
if (!(enable == 0 || enable == 1))
return -1;
sensor_read(id, 0x00, &get_value);
sensor_dbg("ready to hflip, regs_data = 0x%x\n", get_value);
if (enable) {
set_value = get_value | 0x08;
sensor_flip_status |= 0x08;
} else {
set_value = get_value & 0xF7;
sensor_flip_status &= 0xF7;
}
sensor_write(id, 0x00, set_value);
usleep_range(80000, 100000);
sensor_read(id, 0x00, &get_value);
sensor_dbg("after hflip, regs_data = 0x%x, sensor_flip_status = %d\n",
get_value, sensor_flip_status);
return 0;
}
static int sensor_get_fmt_mbus_core(struct v4l2_subdev *sd, int *code)
{
// struct sensor_info *info = to_state(sd);
// data_type get_value = 0, check_value = 0;
// sensor_read(sd, 0x17, &get_value);
// check_value = get_value & 0x03;
// check_value = sensor_flip_status & 0x3;
// sensor_dbg("0x17 = 0x%x, check_value = 0x%x\n", get_value, check_value);
// switch (check_value) {
// case 0x00:
// sensor_dbg("RGGB\n");
// *code = MEDIA_BUS_FMT_SRGGB10_1X10;
// break;
// case 0x01:
// sensor_dbg("GRBG\n");
// *code = MEDIA_BUS_FMT_SGRBG10_1X10;
// break;
// case 0x02:
// sensor_dbg("GBRG\n");
// *code = MEDIA_BUS_FMT_SGBRG10_1X10;
// break;
// case 0x03:
// sensor_dbg("BGGR\n");
// *code = MEDIA_BUS_FMT_SBGGR10_1X10;
// break;
// default:
// *code = info->fmt->mbus_code;
// }
*code = MEDIA_BUS_FMT_SRGGB10_1X10; // sc202cs support change the rgb format by itself
return 0;
}
#endif
/*
* Stuff that knows about the sensor.
*/
static int sensor_power(int id, int on)
{
if (on && (sensor_power_count[id])++ > 0)
return 0;
else if (!on && (sensor_power_count[id] == 0 || --(sensor_power_count[id]) > 0))
return 0;
switch (on) {
case PWR_ON:
sensor_print("PWR_ON!\n");
vin_set_mclk_freq(id, MCLK);
vin_set_mclk(id, 1);
hal_usleep(1000);
//vin_gpio_set_status(id, PWDN, 1);
vin_gpio_set_status(id, RESET, 1);
//vin_gpio_set_status(sd, POWER_EN, 1);
//vin_gpio_write(id, PWDN, CSI_GPIO_LOW);
vin_gpio_write(id, RESET, CSI_GPIO_LOW);
hal_usleep(1000);
//vin_gpio_write(id, PWDN, CSI_GPIO_HIGH);
hal_usleep(1000);
vin_gpio_write(id, RESET, CSI_GPIO_HIGH);
hal_usleep(1000);
break;
case PWR_OFF:
sensor_print("PWR_OFF!\n");
vin_set_mclk(id, 0);
hal_usleep(1000);
// vin_gpio_set_status(id, PWDN, 1);
vin_gpio_set_status(id, RESET, 1);
// vin_gpio_write(id, PWDN, CSI_GPIO_LOW);
vin_gpio_write(id, RESET, CSI_GPIO_LOW);
break;
default:
return -EINVAL;
}
return 0;
}
static int sensor_set_ir(int id, int status)
{
#if 0
vin_gpio_set_status(id, IR_CUT0, 1);
vin_gpio_set_status(id, IR_CUT1, 1);
vin_gpio_set_status(id, IR_LED, 1);
switch (status) {
case IR_DAY:
vin_gpio_write(id, IR_CUT0, CSI_GPIO_HIGH);
vin_gpio_write(id, IR_CUT1, CSI_GPIO_LOW);
vin_gpio_write(id, IR_LED, CSI_GPIO_LOW);
break;
case IR_NIGHT:
vin_gpio_write(id, IR_CUT0, CSI_GPIO_LOW);
vin_gpio_write(id, IR_CUT1, CSI_GPIO_HIGH);
vin_gpio_write(id, IR_LED, CSI_GPIO_HIGH);
break;
default:
return -1;
}
#endif
return 0;
}
#if 0
static int sensor_reset(int id, u32 val)
{
sensor_dbg("%s: val=%d\n", __func__);
switch (val) {
case 0:
vin_gpio_write(id, RESET, CSI_GPIO_HIGH);
hal_usleep(1000);
break;
case 1:
vin_gpio_write(id, RESET, CSI_GPIO_LOW);
hal_usleep(1000);
break;
default:
return -EINVAL;
}
return 0;
}
#endif
static int sensor_detect(int id)
{
data_type rdval;
int eRet;
int times_out = 3;
do {
eRet = sensor_read(id, ID_REG_HIGH, &rdval);
sensor_dbg("eRet:%d, ID_VAL_HIGH:0x%x, times_out:%d\n", eRet, rdval, times_out);
hal_usleep(200);
times_out--;
} while (eRet < 0 && times_out > 0);
sensor_read(id, ID_REG_HIGH, &rdval);
sensor_dbg("ID_VAL_HIGH = %2x, Done!\n", rdval);
if (rdval != ID_VAL_HIGH)
return -ENODEV;
sensor_read(id, ID_REG_LOW, &rdval);
sensor_dbg("ID_VAL_LOW = %2x, Done!\n", rdval);
if (rdval != ID_VAL_LOW)
return -ENODEV;
sensor_dbg("Done!\n");
return 0;
}
static int sensor_init(int id)
{
int ret;
sensor_dbg("sensor_init\n");
/*Make sure it is a target sensor */
ret = sensor_detect(id);
if (ret) {
sensor_err("chip found is not an target chip.\n");
return ret;
}
return 0;
}
/*
* Store information about the video data format.
*/
static struct sensor_format_struct sensor_formats[] = {
#if defined CONFIG_ISP_READ_THRESHOLD || defined CONFIG_ISP_ONLY_HARD_LIGHTADC // FULL_SIZE
#if SENSOR_30FPS
{
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,//MEDIA_BUS_FMT_SRGGB10_1X10, /*.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, */
.width = 1600,
.height = 1200,
.hoffset = 0,
.voffset = 0,
.hts = 1920,
.vts = 1250,
.pclk = 72000000,
.mipi_bps = 371250000,
.fps_fixed = 30,
.bin_factor = 1,
.intg_min = 1 << 4,
.intg_max = (1250 - 8) << 4,
.gain_min = 1 << 4,
.gain_max = 64 << 4,
.offs_h = 0,
.offs_v = 0,
.regs = sensor_1600x1200_30_regs,
.regs_size = ARRAY_SIZE(sensor_1600x1200_30_regs),
}
#endif
#else //CONFIG_ISP_FAST_CONVERGENCE || CONFIG_ISP_HARD_LIGHTADC
{
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
.width = 640,
.height = 480,
.hoffset = 0,
.voffset = 0,
.hts = 1696,
.vts = 525,
.pclk = 106848000,
.mipi_bps = 648 * 1000 * 1000,
.fps_fixed = 120,
.bin_factor = 1,
.intg_min = 1 << 4,
.intg_max = (525 - 16) << 4,
.gain_min = 1 << 4,
.gain_max = 110 << 4,
.offs_h = 0,
.offs_v = 0,
.regs = sensor_480p120_regs,
.regs_size = ARRAY_SIZE(sensor_480p120_regs),
}
#endif
};
static struct sensor_format_struct *sensor_get_format(int id, int isp_id)
{
#if defined CONFIG_ISP_READ_THRESHOLD || defined CONFIG_ISP_ONLY_HARD_LIGHTADC
int ispid = clamp(isp_id, 0, ISP_GET_CFG_NUM - 1);
struct sensor_format_struct *sensor_format = NULL;
int wdr_on = isp_get_cfg[ispid].sensor_wdr_on;
int fps = isp_get_cfg[ispid].sensor_get_fps;
int i;
if (current_win[id])
return current_win[id];
for (i = 0; i < ARRAY_SIZE(sensor_formats); i++) {
if (sensor_formats[i].wdr_mode == wdr_on) {
if (sensor_formats[i].fps_fixed == fps) {
sensor_format = &sensor_formats[i];
sensor_print("fine wdr is %d, fine fps is %d\n", wdr_on, fps);
goto done;
}
}
}
if (sensor_format == NULL) {
for (i = 0; i < ARRAY_SIZE(sensor_formats); i++) {
if (sensor_formats[i].wdr_mode == wdr_on) {
sensor_format = &sensor_formats[i];
isp_get_cfg[ispid].sensor_get_fps = sensor_format->fps_fixed;
sensor_print("fine wdr is %d, use fps is %d\n", wdr_on, sensor_format->fps_fixed);
goto done;
}
}
}
if (sensor_format == NULL) {
sensor_format = &sensor_formats[0];
isp_get_cfg[ispid].sensor_wdr_on = sensor_format->wdr_mode;
isp_get_cfg[ispid].sensor_get_fps = sensor_format->fps_fixed;
sensor_print("use wdr is %d, use fps is %d\n", sensor_format->wdr_mode, sensor_format->fps_fixed);
}
done:
current_win[id] = sensor_format;
return sensor_format;
#else //CONFIG_ISP_FAST_CONVERGENCE || CONFIG_ISP_HARD_LIGHTADC
if (current_win[id])
return current_win[id];
current_win[id] = &sensor_formats[0];
sensor_print("fine wdr is %d, fps is %d\n", sensor_formats[0].wdr_mode, sensor_formats[0].fps_fixed);
return &sensor_formats[0];
#endif
}
static struct sensor_format_struct switch_sensor_formats[] = {
#if defined CONFIG_ISP_FAST_CONVERGENCE || defined CONFIG_ISP_HARD_LIGHTADC
#if SENSOR_30FPS
{
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
.width = 1600,
.height = 1200,//1080,
.hoffset = 0,
.voffset = 0,
.hts = 1920,
.vts = 1250,
.pclk = 72000000,
.mipi_bps = 672 * 1000 * 1000,
.fps_fixed = 30,
.bin_factor = 1,
.intg_min = 1 << 4,
.intg_max = (1250 - 16) << 4,
.gain_min = 1 << 4,
.gain_max = 110 << 4,
.switch_regs = sensor_480p120fps_to_1600x1200_30fps,
.switch_regs_size = ARRAY_SIZE(sensor_480p120fps_to_1600x1200_30fps),
}
#endif
#endif
};
static struct sensor_format_struct *sensor_get_switch_format(int id, int isp_id)
{
#if defined CONFIG_ISP_FAST_CONVERGENCE || defined CONFIG_ISP_HARD_LIGHTADC
int ispid = clamp(isp_id, 0, ISP_GET_CFG_NUM - 1);
struct sensor_format_struct *sensor_format = NULL;
int wdr_on = isp_get_cfg[ispid].sensor_wdr_on;
int fps = isp_get_cfg[ispid].sensor_get_fps;
int i;
if (current_switch_win[id])
return current_switch_win[id];
for (i = 0; i < ARRAY_SIZE(switch_sensor_formats); i++) {
if (switch_sensor_formats[i].wdr_mode == wdr_on) {
if (switch_sensor_formats[i].fps_fixed == fps) {
sensor_format = &switch_sensor_formats[i];
sensor_print("switch fine wdr is %d, fine fps is %d\n", wdr_on, fps);
goto done;
}
}
}
if (sensor_format == NULL) {
for (i = 0; i < ARRAY_SIZE(switch_sensor_formats); i++) {
if (switch_sensor_formats[i].wdr_mode == wdr_on) {
sensor_format = &switch_sensor_formats[i];
isp_get_cfg[ispid].sensor_get_fps = sensor_format->fps_fixed;
sensor_print("switch fine wdr is %d, use fps is %d\n", wdr_on, sensor_format->fps_fixed);
goto done;
}
}
}
if (sensor_format == NULL) {
sensor_format = &switch_sensor_formats[0];
isp_get_cfg[ispid].sensor_wdr_on = sensor_format->wdr_mode;
isp_get_cfg[ispid].sensor_get_fps = sensor_format->fps_fixed;
sensor_print("switch use wdr is %d, use fps is %d\n", sensor_format->wdr_mode, sensor_format->fps_fixed);
}
done:
current_switch_win[id] = sensor_format;
return sensor_format;
#else
return NULL;
#endif
}
static int sensor_g_mbus_config(int id, struct v4l2_mbus_config *cfg, struct mbus_framefmt_res *res)
{
//struct sensor_info *info = to_state(sd);
cfg->type = V4L2_MBUS_CSI2;
cfg->flags = 0 | V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0;
// res->res_time_hs = 0x11;
res->deskew = 2;
return 0;
}
static int sensor_reg_init(int id, int isp_id)
{
int ret = 0;
int ispid = clamp(isp_id, 0, ISP_GET_CFG_NUM - 1);
struct sensor_exp_gain exp_gain;
ret = sensor_write_array(id, sensor_default_regs,
ARRAY_SIZE(sensor_default_regs));
if (ret < 0) {
sensor_err("write sensor_default_regs error\n");
return ret;
}
if (current_win[id]->regs)
ret = sensor_write_array(id, current_win[id]->regs, current_win[id]->regs_size);
if (ret < 0)
return ret;
sc202cs_sensor_vts = current_win[id]->vts;
#if 0
//#if defined CONFIG_ISP_READ_THRESHOLD || defined CONFIG_ISP_FAST_CONVERGENCE
if (ispid == 0) {
exp_gain.exp_val = clamp(*((unsigned int *)ISP0_NORFLASH_SAVE + 2), 16, 1125 << 4);
exp_gain.gain_val = clamp(*((unsigned int *)ISP0_NORFLASH_SAVE + 1), 16, 110 << 4);
} else {
exp_gain.exp_val = clamp(*((unsigned int *)ISP1_NORFLASH_SAVE + 2), 16, 1125 << 4);
exp_gain.gain_val = clamp(*((unsigned int *)ISP1_NORFLASH_SAVE + 1), 16, 110 << 4);
}
#if defined CONFIG_ISP_FAST_CONVERGENCE || defined CONFIG_ISP_HARD_LIGHTADC
temperature_ctrl = 0;
#endif
#endif
exp_gain.exp_val = 0xff0302;
exp_gain.gain_val = 0xff24;
sensor_s_exp_gain(id, &exp_gain);
// sensor_write(id, 0x3e, 0x91);
//#else //CONFIG_ISP_HARD_LIGHTADC
//#endif
//sensor_flip_status = 0x0;
//sensor_dbg("sc202cs_sensor_vts = %d\n", sc202cs_sensor_vts);
return 0;
}
static int sensor_s_stream(int id, int isp_id, int enable)
{
if (enable && sensor_stream_count[id]++ > 0)
return 0;
else if (!enable && (sensor_stream_count[id] == 0 || --sensor_stream_count[id] > 0))
return 0;
sensor_dbg("%s on = %d, 2560*1440 fps: 15\n", __func__, enable);
if (!enable)
return 0;
return sensor_reg_init(id, isp_id);
}
static int sensor_s_switch(int id)
{
#if defined CONFIG_ISP_FAST_CONVERGENCE || defined CONFIG_ISP_HARD_LIGHTADC
struct sensor_exp_gain exp_gain;
int ret = -1;
temperature_ctrl = 1;
sc202cs_sensor_vts = current_switch_win[id]->vts;
if (current_switch_win[id]->switch_regs)
ret = sensor_write_array(id, current_switch_win[id]->switch_regs, current_switch_win[id]->switch_regs_size);
else
sensor_err("cannot find 480p120fps to 1600x1200_%dfps reg\n", current_switch_win[id]->fps_fixed);
if (ret < 0)
return ret;
#endif
return 0;
}
static int sensor_test_i2c(int id)
{
int ret;
sensor_power(id, PWR_ON);
ret = sensor_init(id);
sensor_power(id, PWR_OFF);
return ret;
}
struct sensor_fuc_core sc202cs_core = {
.g_mbus_config = sensor_g_mbus_config,
.sensor_test_i2c = sensor_test_i2c,
.sensor_power = sensor_power,
.s_ir_status = sensor_set_ir,
.s_stream = sensor_s_stream,
.s_switch = sensor_s_switch,
.s_exp_gain = sensor_s_exp_gain,
.sensor_g_format = sensor_get_format,
.sensor_g_switch_format = sensor_get_switch_format,
};

View File

@@ -68,6 +68,9 @@ struct sensor_cfg_array sensor_array[] = {
#ifdef CONFIG_SENSOR_GC2083_MIPI
{"gc2083_mipi", &gc2083_core},
#endif
#ifdef CONFIG_SENSOR_SC202CS_MIPI
{"sc202cs_mipi", &sc202cs_core},
#endif
};
struct sensor_fuc_core *find_sensor_func(char *sensor_name)