diff options
author | Helen Fornazier <helen.koike@collabora.com> | 2019-03-13 14:29:37 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2019-04-22 10:58:51 -0400 |
commit | b6c61a6c37317efd7327199bfe24770af3d7e799 (patch) | |
tree | c130cfb12c25543104b880a12d039ccac03ffa12 /drivers/media/platform/vimc/vimc-sensor.c | |
parent | d82b921a7a8a00ec31ba76287245ec663534df9b (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.c | 51 |
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 | ||
68 | static 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 | |||
82 | static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, | 68 | static 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 | ||
118 | static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) | 97 | static 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 | ||
136 | static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) | 118 | static 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 | ||
194 | static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { | 172 | static 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 | /* |