upate:更新双目sensor驱动
This commit is contained in:
161
lichee/linux-4.9/drivers/media/platform/sunxi-vin/modules/sensor/sc202cs_mipi.c
Normal file → Executable file
161
lichee/linux-4.9/drivers/media/platform/sunxi-vin/modules/sensor/sc202cs_mipi.c
Normal file → Executable file
@@ -74,6 +74,10 @@ MODULE_LICENSE("GPL");
|
||||
#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
|
||||
|
||||
#define MCLK (24*1000*1000)
|
||||
|
||||
@@ -331,32 +335,21 @@ static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val)
|
||||
{
|
||||
data_type 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;
|
||||
|
||||
if (exp_val == info->exp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (SC202CS == 1)
|
||||
exphigh = (unsigned char)(0xf & (exp_val >> 12)); // upper 4 bits
|
||||
expmid = (unsigned char)(0xff & (exp_val >> 4)); // middle 7 bits
|
||||
explow = (unsigned char)(0xf0 & (exp_val << 4)); // lower 4 bits
|
||||
sensor_write(sd, 0x3e02, explow); //[7:4]
|
||||
sensor_write(sd, 0x3e01, expmid); //[7:0]
|
||||
sensor_write(sd, 0x3e00, exphigh); //[3:0]
|
||||
#else
|
||||
exphigh = (unsigned char)(exp_val >> 8);
|
||||
explow = (unsigned char)(exp_val & 0xFF);
|
||||
expmid = 0;
|
||||
sensor_write(sd, 0x3e01, exphigh);
|
||||
exphigh = (unsigned char) (0x0f & (exp_val>>16));
|
||||
expmid = (unsigned char) (0xff & (exp_val>>8));
|
||||
explow = (unsigned char) (0xf0 & (exp_val<<0));
|
||||
sensor_write(sd, 0x3e02, explow);
|
||||
sensor_write(sd, 0x3e01, expmid);
|
||||
sensor_write(sd, 0x3e00, exphigh);
|
||||
|
||||
#else
|
||||
exphigh = (unsigned char) (0x0f & (exp_val>>16));
|
||||
expmid = (unsigned char) (0xff & (exp_val>>8));
|
||||
explow = (unsigned char) (0xf0 & (exp_val<<0));
|
||||
sensor_write(sd, 0x3e02, explow);
|
||||
sensor_write(sd, 0x3e01, expmid);
|
||||
sensor_write(sd, 0x3e00, exphigh);
|
||||
#endif
|
||||
|
||||
sensor_dbg("%s():%d, exp_val = %d\n", __func__, __LINE__, exp_val);
|
||||
@@ -373,56 +366,96 @@ static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char analog_Gain_Reg[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f};
|
||||
|
||||
static int setSensorGain(struct v4l2_subdev *sd, 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(sd, 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(sd, DIG_GAIN, 0x00);
|
||||
sensor_write(sd, 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(sd, DIG_GAIN, 0x01);
|
||||
sensor_write(sd, 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(sd, DIG_GAIN, 0x01);
|
||||
sensor_write(sd, DIG_FINE_GAIN, 0xfc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sensor_s_gain(struct v4l2_subdev *sd, int gain_val)
|
||||
{
|
||||
struct sensor_info *info = to_state(sd);
|
||||
//sensor_dbg("%s():%d. info:%p, gain_val:%d\n", __func__, __LINE__, info, gain_val);
|
||||
if (gain_val == info->gain) {
|
||||
return 0;
|
||||
}
|
||||
sensor_dbg("%s():%d. info:%p, gain_val:%d\n", __func__, __LINE__, info, gain_val);
|
||||
info->gain = gain_val;
|
||||
int tem_gain_val;
|
||||
|
||||
return 0;
|
||||
|
||||
// if (gain_val < 1 * 16)
|
||||
// gain_val = 16;
|
||||
if (gain_val > 16 * 16 - 1)
|
||||
gain_val = 16 * 16 - 1;
|
||||
|
||||
if (gain_val < 32) {
|
||||
sensor_write(sd, 0x3314, 0x1e);
|
||||
sensor_write(sd, 0x3317, 0x10);
|
||||
//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 {
|
||||
sensor_write(sd, 0x3314, 0x4f);
|
||||
sensor_write(sd, 0x3317, 0x0f);
|
||||
}
|
||||
tem_gain_val = tem_gain_val / 16;
|
||||
}
|
||||
|
||||
if (gain_val < 32) {
|
||||
sensor_write(sd, 0x3e08, 0x03);
|
||||
sensor_write(sd, 0x3e09, gain_val);
|
||||
} else if (gain_val >= 32 && gain_val < 64) {
|
||||
sensor_write(sd, 0x3e08, 0x07);
|
||||
sensor_write(sd, 0x3e09, gain_val >> 1);
|
||||
} else if (gain_val >= 64 && gain_val < 128) {
|
||||
sensor_write(sd, 0x3e08, 0x0f);
|
||||
sensor_write(sd, 0x3e09, gain_val >> 2);
|
||||
} else if (gain_val >= 128) {
|
||||
sensor_write(sd, 0x3e08, 0x1f);
|
||||
sensor_write(sd, 0x3e09, gain_val >> 3);
|
||||
}
|
||||
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);
|
||||
|
||||
sensor_dbg("drv sensor_s_gain(%d)\n", gain_val);
|
||||
setSensorGain(sd, tem_gain_val);
|
||||
info->gain = gain_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sc202cs_sensor_vts;
|
||||
static int sensor_s_exp_gain(struct v4l2_subdev *sd,
|
||||
struct sensor_exp_gain *exp_gain)
|
||||
{
|
||||
struct sensor_info *info = to_state(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int shutter = 0, frame_length = 0;
|
||||
|
||||
sensor_dbg("(%d, %d)\n", exp_gain->exp_val, exp_gain->gain_val);
|
||||
|
||||
|
||||
shutter = exp_gain->exp_val >> 4;
|
||||
if (shutter > sc202cs_sensor_vts - 8)
|
||||
frame_length = shutter + 8;
|
||||
else
|
||||
frame_length = sc202cs_sensor_vts;
|
||||
|
||||
|
||||
sensor_dbg("shutter = %d, frame_length = %d\n", shutter, frame_length);
|
||||
sensor_write(sd, 0x320e, (frame_length >> 8));
|
||||
sensor_write(sd, 0x320f, (frame_length & 0xff));
|
||||
|
||||
|
||||
sensor_s_exp(sd, exp_gain->exp_val);
|
||||
sensor_s_gain(sd, exp_gain->gain_val);
|
||||
info->exp = exp_gain->exp_val;
|
||||
info->gain = exp_gain->gain_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -466,7 +499,7 @@ static int sensor_s_hflip(struct v4l2_subdev *sd, int enable)
|
||||
|
||||
static int sensor_get_fmt_mbus_core(struct v4l2_subdev *sd, int *code)
|
||||
{
|
||||
*code = MEDIA_BUS_FMT_SRGGB10_1X10; // gc2053 support change the rgb format by itself
|
||||
*code = MEDIA_BUS_FMT_SBGGR10_1X10;//MEDIA_BUS_FMT_SRGGB10_1X10; // gc2053 support change the rgb format by itself
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -727,7 +760,7 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
static struct sensor_format_struct sensor_formats[] = {
|
||||
{
|
||||
.desc = "Raw RGB Bayer",
|
||||
.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, /*.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, */
|
||||
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,//MEDIA_BUS_FMT_SRGGB10_1X10, /*.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, */
|
||||
.regs = sensor_fmt_raw,
|
||||
.regs_size = ARRAY_SIZE(sensor_fmt_raw),
|
||||
.bpp = 1
|
||||
@@ -746,16 +779,16 @@ static struct sensor_win_size sensor_win_sizes[] = {
|
||||
.height = 1200, //
|
||||
.hoffset = 0,
|
||||
.voffset = 0,
|
||||
.hts = 2200,
|
||||
.hts = 1920,
|
||||
.vts = 1250,
|
||||
.pclk = 74250000,
|
||||
.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 = 128 << 4,
|
||||
.gain_max = 64 << 4,
|
||||
.regs = sensor_normal_regs,
|
||||
.regs_size = ARRAY_SIZE(sensor_normal_regs),
|
||||
.set_size = NULL,
|
||||
@@ -885,7 +918,7 @@ static int sensor_reg_init(struct sensor_info *info)
|
||||
|
||||
info->width = wsize->width;
|
||||
info->height = wsize->height;
|
||||
|
||||
sc202cs_sensor_vts = wsize->vts;
|
||||
exp_gain.exp_val = EXPOSURE_DEFAULT;
|
||||
exp_gain.gain_val = GAIN_DEFAULT;
|
||||
sensor_s_exp_gain(sd, &exp_gain);
|
||||
@@ -1037,6 +1070,8 @@ static int sensor_probe(struct i2c_client *client,
|
||||
//info->combo_mode = CMB_PHYA_OFFSET2 | MIPI_NORMAL_MODE;
|
||||
info->stream_seq = MIPI_BEFORE_SENSOR;
|
||||
info->af_first_flag = 1;
|
||||
//info->time_hs = 0x11;
|
||||
info->deskew = 0x02;
|
||||
info->exp = 0;
|
||||
info->gain = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user