aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-sensor.c
diff options
context:
space:
mode:
authorHelen Fornazier <helen.koike@collabora.com>2019-03-13 14:29:37 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-04-22 10:58:51 -0400
commitb6c61a6c37317efd7327199bfe24770af3d7e799 (patch)
treec130cfb12c25543104b880a12d039ccac03ffa12 /drivers/media/platform/vimc/vimc-sensor.c
parentd82b921a7a8a00ec31ba76287245ec663534df9b (diff)
media: vimc: propagate pixel format in the stream
Media bus codes were being mapped to pixelformats, which causes a limitation on vimc because not all pixelformats can be mapped to media bus codes. Also, media bus codes are an internal configuration from the device. Userspace only assures media bus codes matches between pads and expects the image in a given pixelformat. So we can allow almost any media bus format to be configured between pads, except for debayer that expects a media bus code of type bayer in the sink pad. [hverkuil-cisco@xs4all.nl: drop use of v4l2_get_fourcc_name: not yet available] [hverkuil-cisco@xs4all.nl: made vimc_mbus_list static] Signed-off-by: Helen Koike <helen.koike@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, 15 insertions, 36 deletions
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index d7891d3bbeaa..081e54204c9f 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -65,34 +65,13 @@ static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
65 return 0; 65 return 0;
66} 66}
67 67
68static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
69 struct v4l2_subdev_pad_config *cfg,
70 struct v4l2_subdev_mbus_code_enum *code)
71{
72 const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
73
74 if (!vpix)
75 return -EINVAL;
76
77 code->code = vpix->code;
78
79 return 0;
80}
81
82static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, 68static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
83 struct v4l2_subdev_pad_config *cfg, 69 struct v4l2_subdev_pad_config *cfg,
84 struct v4l2_subdev_frame_size_enum *fse) 70 struct v4l2_subdev_frame_size_enum *fse)
85{ 71{
86 const struct vimc_pix_map *vpix;
87
88 if (fse->index) 72 if (fse->index)
89 return -EINVAL; 73 return -EINVAL;
90 74
91 /* Only accept code in the pix map table */
92 vpix = vimc_pix_map_by_code(fse->code);
93 if (!vpix)
94 return -EINVAL;
95
96 fse->min_width = VIMC_FRAME_MIN_WIDTH; 75 fse->min_width = VIMC_FRAME_MIN_WIDTH;
97 fse->max_width = VIMC_FRAME_MAX_WIDTH; 76 fse->max_width = VIMC_FRAME_MAX_WIDTH;
98 fse->min_height = VIMC_FRAME_MIN_HEIGHT; 77 fse->min_height = VIMC_FRAME_MIN_HEIGHT;
@@ -117,14 +96,17 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
117 96
118static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) 97static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
119{ 98{
120 const struct vimc_pix_map *vpix = 99 u32 pixelformat = vsen->ved.stream->producer_pixfmt;
121 vimc_pix_map_by_code(vsen->mbus_format.code); 100 const struct v4l2_format_info *pix_info;
101
102 pix_info = v4l2_format_info(pixelformat);
122 103
123 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width, 104 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
124 vsen->mbus_format.height, vsen->mbus_format.field); 105 vsen->mbus_format.height, vsen->mbus_format.field);
125 tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp); 106 tpg_s_bytesperline(&vsen->tpg, 0,
107 vsen->mbus_format.width * pix_info->bpp[0]);
126 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height); 108 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
127 tpg_s_fourcc(&vsen->tpg, vpix->pixelformat); 109 tpg_s_fourcc(&vsen->tpg, pixelformat);
128 /* TODO: add support for V4L2_FIELD_ALTERNATE */ 110 /* TODO: add support for V4L2_FIELD_ALTERNATE */
129 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false); 111 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
130 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace); 112 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
@@ -135,13 +117,6 @@ static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
135 117
136static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) 118static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
137{ 119{
138 const struct vimc_pix_map *vpix;
139
140 /* Only accept code in the pix map table */
141 vpix = vimc_pix_map_by_code(fmt->code);
142 if (!vpix)
143 fmt->code = fmt_default.code;
144
145 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, 120 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
146 VIMC_FRAME_MAX_WIDTH) & ~1; 121 VIMC_FRAME_MAX_WIDTH) & ~1;
147 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, 122 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
@@ -161,6 +136,9 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
161 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); 136 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
162 struct v4l2_mbus_framefmt *mf; 137 struct v4l2_mbus_framefmt *mf;
163 138
139 if (!vimc_mbus_code_supported(fmt->format.code))
140 fmt->format.code = fmt_default.code;
141
164 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 142 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
165 /* Do not change the format while stream is on */ 143 /* Do not change the format while stream is on */
166 if (vsen->frame) 144 if (vsen->frame)
@@ -193,7 +171,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
193 171
194static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { 172static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
195 .init_cfg = vimc_sen_init_cfg, 173 .init_cfg = vimc_sen_init_cfg,
196 .enum_mbus_code = vimc_sen_enum_mbus_code, 174 .enum_mbus_code = vimc_enum_mbus_code,
197 .enum_frame_size = vimc_sen_enum_frame_size, 175 .enum_frame_size = vimc_sen_enum_frame_size,
198 .get_fmt = vimc_sen_get_fmt, 176 .get_fmt = vimc_sen_get_fmt,
199 .set_fmt = vimc_sen_set_fmt, 177 .set_fmt = vimc_sen_set_fmt,
@@ -215,7 +193,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
215 container_of(sd, struct vimc_sen_device, sd); 193 container_of(sd, struct vimc_sen_device, sd);
216 194
217 if (enable) { 195 if (enable) {
218 const struct vimc_pix_map *vpix; 196 u32 pixelformat = vsen->ved.stream->producer_pixfmt;
197 const struct v4l2_format_info *pix_info;
219 unsigned int frame_size; 198 unsigned int frame_size;
220 199
221 if (vsen->kthread_sen) 200 if (vsen->kthread_sen)
@@ -223,8 +202,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
223 return 0; 202 return 0;
224 203
225 /* Calculate the frame size */ 204 /* Calculate the frame size */
226 vpix = vimc_pix_map_by_code(vsen->mbus_format.code); 205 pix_info = v4l2_format_info(pixelformat);
227 frame_size = vsen->mbus_format.width * vpix->bpp * 206 frame_size = vsen->mbus_format.width * pix_info->bpp[0] *
228 vsen->mbus_format.height; 207 vsen->mbus_format.height;
229 208
230 /* 209 /*