aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-sensor.c
diff options
context:
space:
mode:
authorHelen Koike <helen.koike@collabora.com>2019-08-08 20:27:41 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-08-13 10:40:38 -0400
commit09c41a23a2e2de7ed347251d7079a42de0dd230b (patch)
tree04317b6c35374a578a8df257de210c06c527d71d /drivers/media/platform/vimc/vimc-sensor.c
parent10b1aed6dac01d566b6b3c261a191546c82f0157 (diff)
media: Revert "media: vimc: propagate pixel format in the stream"
This reverts commit b6c61a6c37317efd7327199bfe24770af3d7e799. The requested pixelformat is being propagated from the capture to the tpg in the sensor. This was a bad design choice, as we start having the following issues: * We set a pixelformat in the capture; * We set matching media bus formats in the subdevices pads; * Link validate looks fine (sizes matches, media bus formats matches); * Issue: if some of the subdevice doesn't know how to generate the requested pixelformat in the capture, then stream_on fails. This is bad because capture says it supports that pixelformat, everything looks fine, but it is not, and there is no way to find it out through the links. This patch was implemented so we could request any pixelformat from the pipeline regardeless of the media bus format configured between pads. Not all pixelformat can be mapped into a media bus code (e.g. multiplanar formats), so with this patch we could request those pixelformats from the tpg. Solution: map pixelformats to media bus codes as before, and implement conversions to other pixelformats in the capture to support multiplanar. So first step to this solution is to revert this patch. Signed-off-by: Helen Koike <helen.koike@collabora.com> Signed-off-by: Lucas A. M. Magalhaes <lucmaga@gmail.com> Tested-by: André Almeida <andrealmeid@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/platform/vimc/vimc-sensor.c')
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index c47454cc7f70..6c53b9fc1617 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -55,13 +55,34 @@ static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
55 return 0; 55 return 0;
56} 56}
57 57
58static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
59 struct v4l2_subdev_pad_config *cfg,
60 struct v4l2_subdev_mbus_code_enum *code)
61{
62 const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
63
64 if (!vpix)
65 return -EINVAL;
66
67 code->code = vpix->code;
68
69 return 0;
70}
71
58static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, 72static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
59 struct v4l2_subdev_pad_config *cfg, 73 struct v4l2_subdev_pad_config *cfg,
60 struct v4l2_subdev_frame_size_enum *fse) 74 struct v4l2_subdev_frame_size_enum *fse)
61{ 75{
76 const struct vimc_pix_map *vpix;
77
62 if (fse->index) 78 if (fse->index)
63 return -EINVAL; 79 return -EINVAL;
64 80
81 /* Only accept code in the pix map table */
82 vpix = vimc_pix_map_by_code(fse->code);
83 if (!vpix)
84 return -EINVAL;
85
65 fse->min_width = VIMC_FRAME_MIN_WIDTH; 86 fse->min_width = VIMC_FRAME_MIN_WIDTH;
66 fse->max_width = VIMC_FRAME_MAX_WIDTH; 87 fse->max_width = VIMC_FRAME_MAX_WIDTH;
67 fse->min_height = VIMC_FRAME_MIN_HEIGHT; 88 fse->min_height = VIMC_FRAME_MIN_HEIGHT;
@@ -86,17 +107,14 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
86 107
87static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) 108static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
88{ 109{
89 u32 pixelformat = vsen->ved.stream->producer_pixfmt; 110 const struct vimc_pix_map *vpix =
90 const struct v4l2_format_info *pix_info; 111 vimc_pix_map_by_code(vsen->mbus_format.code);
91
92 pix_info = v4l2_format_info(pixelformat);
93 112
94 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width, 113 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
95 vsen->mbus_format.height, vsen->mbus_format.field); 114 vsen->mbus_format.height, vsen->mbus_format.field);
96 tpg_s_bytesperline(&vsen->tpg, 0, 115 tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
97 vsen->mbus_format.width * pix_info->bpp[0]);
98 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height); 116 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
99 tpg_s_fourcc(&vsen->tpg, pixelformat); 117 tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
100 /* TODO: add support for V4L2_FIELD_ALTERNATE */ 118 /* TODO: add support for V4L2_FIELD_ALTERNATE */
101 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false); 119 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
102 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace); 120 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
@@ -107,6 +125,13 @@ static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
107 125
108static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) 126static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
109{ 127{
128 const struct vimc_pix_map *vpix;
129
130 /* Only accept code in the pix map table */
131 vpix = vimc_pix_map_by_code(fmt->code);
132 if (!vpix)
133 fmt->code = fmt_default.code;
134
110 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, 135 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
111 VIMC_FRAME_MAX_WIDTH) & ~1; 136 VIMC_FRAME_MAX_WIDTH) & ~1;
112 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, 137 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
@@ -126,9 +151,6 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
126 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); 151 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
127 struct v4l2_mbus_framefmt *mf; 152 struct v4l2_mbus_framefmt *mf;
128 153
129 if (!vimc_mbus_code_supported(fmt->format.code))
130 fmt->format.code = fmt_default.code;
131
132 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 154 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
133 /* Do not change the format while stream is on */ 155 /* Do not change the format while stream is on */
134 if (vsen->frame) 156 if (vsen->frame)
@@ -161,7 +183,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
161 183
162static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { 184static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
163 .init_cfg = vimc_sen_init_cfg, 185 .init_cfg = vimc_sen_init_cfg,
164 .enum_mbus_code = vimc_enum_mbus_code, 186 .enum_mbus_code = vimc_sen_enum_mbus_code,
165 .enum_frame_size = vimc_sen_enum_frame_size, 187 .enum_frame_size = vimc_sen_enum_frame_size,
166 .get_fmt = vimc_sen_get_fmt, 188 .get_fmt = vimc_sen_get_fmt,
167 .set_fmt = vimc_sen_set_fmt, 189 .set_fmt = vimc_sen_set_fmt,
@@ -183,8 +205,7 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
183 container_of(sd, struct vimc_sen_device, sd); 205 container_of(sd, struct vimc_sen_device, sd);
184 206
185 if (enable) { 207 if (enable) {
186 u32 pixelformat = vsen->ved.stream->producer_pixfmt; 208 const struct vimc_pix_map *vpix;
187 const struct v4l2_format_info *pix_info;
188 unsigned int frame_size; 209 unsigned int frame_size;
189 210
190 if (vsen->kthread_sen) 211 if (vsen->kthread_sen)
@@ -192,8 +213,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
192 return 0; 213 return 0;
193 214
194 /* Calculate the frame size */ 215 /* Calculate the frame size */
195 pix_info = v4l2_format_info(pixelformat); 216 vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
196 frame_size = vsen->mbus_format.width * pix_info->bpp[0] * 217 frame_size = vsen->mbus_format.width * vpix->bpp *
197 vsen->mbus_format.height; 218 vsen->mbus_format.height;
198 219
199 /* 220 /*