media: i2c: gc2145: fix cts PIC_SIZE_ERR

fix following cts stuck:
android.hardware.cts.CameraTest#testVideoSnapshot
error log:
rkisp1: CIF_ISP_PIC_SIZE_ERROR (0x00000001)
rkisp1: isp icr v_statr err: 0x48
rkisp1: Too many isp error, stop isp!

Change-Id: Icd1102a045eb6b6eef631be8fe1968e6b74408b3
Signed-off-by: Wang Panzhenzhuan <randy.wang@rock-chips.com>
This commit is contained in:
Wang Panzhenzhuan
2019-04-03 16:40:55 +08:00
committed by Tao Huang
parent f9768f08f3
commit 5b397694df

View File

@@ -164,7 +164,7 @@ static const struct sensor_register gc2145_dvp_init_regs[] = {
{0x20, 0x03},
{0x21, 0x40},
{0x22, 0xa0},
{0x24, 0x16},
{0x24, 0x3f},
{0x25, 0x01},
{0x26, 0x10},
{0x2d, 0x60},
@@ -1821,6 +1821,8 @@ static int gc2145_write(struct i2c_client *client, u8 reg, u8 val)
u8 buf[2];
int ret;
dev_dbg(&client->dev, "write reg(0x%x val:0x%x)!\n", reg, val);
buf[0] = reg & 0xFF;
buf[1] = val;
@@ -2097,7 +2099,10 @@ static int gc2145_s_stream(struct v4l2_subdev *sd, int on)
struct gc2145 *gc2145 = to_gc2145(sd);
int ret = 0;
dev_dbg(&client->dev, "%s: on: %d\n", __func__, on);
dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
gc2145->frame_size->width,
gc2145->frame_size->height,
gc2145->frame_size->fps);
mutex_lock(&gc2145->lock);
@@ -2110,23 +2115,8 @@ static int gc2145_s_stream(struct v4l2_subdev *sd, int on)
/* Stop Streaming Sequence */
gc2145_set_streaming(gc2145, on);
gc2145->streaming = on;
if (!IS_ERR(gc2145->pwdn_gpio)) {
gpiod_set_value_cansleep(gc2145->pwdn_gpio, 1);
usleep_range(2000, 5000);
}
goto unlock;
}
if (!IS_ERR(gc2145->pwdn_gpio)) {
gpiod_set_value_cansleep(gc2145->pwdn_gpio, 0);
usleep_range(2000, 5000);
}
if (gc2145->bus_cfg.bus_type == V4L2_MBUS_CSI2)
ret = gc2145_write_array(client, gc2145_mipi_init_regs);
else
ret = gc2145_write_array(client, gc2145_dvp_init_regs);
if (ret)
goto unlock;
ret = gc2145_write_array(client, gc2145->frame_size->regs);
if (ret)
@@ -2231,13 +2221,18 @@ static int gc2145_s_frame_interval(struct v4l2_subdev *sd,
fi->interval.numerator, fi->interval.denominator);
mutex_lock(&gc2145->lock);
if (gc2145->format.width == 1600)
goto unlock;
fps = DIV_ROUND_CLOSEST(fi->interval.denominator,
fi->interval.numerator);
mf = gc2145->format;
__gc2145_try_frame_size_fps(gc2145, &mf, &size, fps);
if (gc2145->frame_size != size) {
dev_info(&client->dev, "%s match wxh@FPS is %dx%d@%d\n",
__func__, size->width, size->height, size->fps);
ret = gc2145_write_array(client, size->regs);
if (ret)
goto unlock;
@@ -2320,6 +2315,50 @@ static long gc2145_compat_ioctl32(struct v4l2_subdev *sd,
}
#endif
static int gc2145_init(struct v4l2_subdev *sd, u32 val)
{
int ret;
struct gc2145 *gc2145 = to_gc2145(sd);
struct i2c_client *client = gc2145->client;
dev_info(&client->dev, "%s(%d)\n", __func__, __LINE__);
/* soft reset */
ret = gc2145_write(client, 0xfe, 0xf0);
if (gc2145->bus_cfg.bus_type == V4L2_MBUS_CSI2)
ret = gc2145_write_array(client, gc2145_mipi_init_regs);
else
ret = gc2145_write_array(client, gc2145_dvp_init_regs);
return ret;
}
static int gc2145_power(struct v4l2_subdev *sd, int on)
{
int ret;
struct gc2145 *gc2145 = to_gc2145(sd);
struct i2c_client *client = gc2145->client;
struct device *dev = &gc2145->client->dev;
dev_info(&client->dev, "%s(%d) on(%d)\n", __func__, __LINE__, on);
if (on) {
if (!IS_ERR(gc2145->pwdn_gpio)) {
gpiod_set_value_cansleep(gc2145->pwdn_gpio, 0);
usleep_range(2000, 5000);
}
ret = gc2145_init(sd, 0);
usleep_range(10000, 20000);
if (ret)
dev_err(dev, "init error\n");
} else {
if (!IS_ERR(gc2145->pwdn_gpio)) {
gpiod_set_value_cansleep(gc2145->pwdn_gpio, 1);
usleep_range(2000, 5000);
}
}
return 0;
}
static const struct v4l2_subdev_core_ops gc2145_subdev_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
@@ -2328,6 +2367,7 @@ static const struct v4l2_subdev_core_ops gc2145_subdev_core_ops = {
#ifdef CONFIG_COMPAT
.compat_ioctl32 = gc2145_compat_ioctl32,
#endif
.s_power = gc2145_power,
};
static const struct v4l2_subdev_video_ops gc2145_subdev_video_ops = {
@@ -2393,6 +2433,7 @@ static int __gc2145_power_on(struct gc2145 *gc2145)
int ret;
struct device *dev = &gc2145->client->dev;
dev_info(dev, "%s(%d)\n", __func__, __LINE__);
if (!IS_ERR(gc2145->reset_gpio)) {
gpiod_set_value_cansleep(gc2145->reset_gpio, 0);
usleep_range(2000, 5000);
@@ -2437,6 +2478,7 @@ static int __gc2145_power_on(struct gc2145 *gc2145)
static void __gc2145_power_off(struct gc2145 *gc2145)
{
dev_info(&gc2145->client->dev, "%s(%d)\n", __func__, __LINE__);
if (!IS_ERR(gc2145->xvclk))
clk_disable_unprepare(gc2145->xvclk);
if (!IS_ERR(gc2145->supplies))