浏览代码

media: ov5640: fix mode change regression

[ Upstream commit fb98e29ff1ea5a8118265d11f0e03bc8608a49cb ]

fixes: 6949d864776e ("media: ov5640: do not change mode if format or frame interval is unchanged").

Symptom was fuzzy image because of JPEG default format
not being changed according to new format selected, fix this.
Init sequence initialises format to YUV422 UYVY but
sensor->fmt initial value was set to JPEG, fix this.

Signed-off-by: Hugues Fruchet <hugues.fruchet@st.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Hugues Fruchet 7 年之前
父节点
当前提交
7e0a5da540
共有 1 个文件被更改,包括 16 次插入5 次删除
  1. 16 5
      drivers/media/i2c/ov5640.c

+ 16 - 5
drivers/media/i2c/ov5640.c

@@ -223,6 +223,7 @@ struct ov5640_dev {
 	int power_count;
 	int power_count;
 
 
 	struct v4l2_mbus_framefmt fmt;
 	struct v4l2_mbus_framefmt fmt;
+	bool pending_fmt_change;
 
 
 	const struct ov5640_mode_info *current_mode;
 	const struct ov5640_mode_info *current_mode;
 	enum ov5640_frame_rate current_fr;
 	enum ov5640_frame_rate current_fr;
@@ -255,7 +256,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
  * should be identified and removed to speed register load time
  * should be identified and removed to speed register load time
  * over i2c.
  * over i2c.
  */
  */
-
+/* YUV422 UYVY VGA@30fps */
 static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
 static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
 	{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
 	{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
 	{0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
 	{0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
@@ -1968,9 +1969,12 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
 
 
 	if (new_mode != sensor->current_mode) {
 	if (new_mode != sensor->current_mode) {
 		sensor->current_mode = new_mode;
 		sensor->current_mode = new_mode;
-		sensor->fmt = *mbus_fmt;
 		sensor->pending_mode_change = true;
 		sensor->pending_mode_change = true;
 	}
 	}
+	if (mbus_fmt->code != sensor->fmt.code) {
+		sensor->fmt = *mbus_fmt;
+		sensor->pending_fmt_change = true;
+	}
 out:
 out:
 	mutex_unlock(&sensor->lock);
 	mutex_unlock(&sensor->lock);
 	return ret;
 	return ret;
@@ -2544,10 +2548,13 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
 			ret = ov5640_set_mode(sensor, sensor->current_mode);
 			ret = ov5640_set_mode(sensor, sensor->current_mode);
 			if (ret)
 			if (ret)
 				goto out;
 				goto out;
+		}
 
 
+		if (enable && sensor->pending_fmt_change) {
 			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
 			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
 			if (ret)
 			if (ret)
 				goto out;
 				goto out;
+			sensor->pending_fmt_change = false;
 		}
 		}
 
 
 		if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
 		if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
@@ -2642,9 +2649,14 @@ static int ov5640_probe(struct i2c_client *client,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	sensor->i2c_client = client;
 	sensor->i2c_client = client;
+
+	/*
+	 * default init sequence initialize sensor to
+	 * YUV422 UYVY VGA@30fps
+	 */
 	fmt = &sensor->fmt;
 	fmt = &sensor->fmt;
-	fmt->code = ov5640_formats[0].code;
-	fmt->colorspace = ov5640_formats[0].colorspace;
+	fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
+	fmt->colorspace = V4L2_COLORSPACE_SRGB;
 	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
 	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
 	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
 	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
 	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
 	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
@@ -2656,7 +2668,6 @@ static int ov5640_probe(struct i2c_client *client,
 	sensor->current_fr = OV5640_30_FPS;
 	sensor->current_fr = OV5640_30_FPS;
 	sensor->current_mode =
 	sensor->current_mode =
 		&ov5640_mode_data[OV5640_30_FPS][OV5640_MODE_VGA_640_480];
 		&ov5640_mode_data[OV5640_30_FPS][OV5640_MODE_VGA_640_480];
-	sensor->pending_mode_change = true;
 
 
 	sensor->ae_target = 52;
 	sensor->ae_target = 52;