diff options
Diffstat (limited to 'drivers/media/platform/vimc/vimc-scaler.c')
-rw-r--r-- | drivers/media/platform/vimc/vimc-scaler.c | 63 |
1 files changed, 30 insertions, 33 deletions
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index 2028afa4ef7a..8aecf8e92031 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c | |||
@@ -35,6 +35,12 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier"); | |||
35 | #define IS_SRC(pad) (pad) | 35 | #define IS_SRC(pad) (pad) |
36 | #define MAX_ZOOM 8 | 36 | #define MAX_ZOOM 8 |
37 | 37 | ||
38 | static const u32 vimc_sca_supported_pixfmt[] = { | ||
39 | V4L2_PIX_FMT_BGR24, | ||
40 | V4L2_PIX_FMT_RGB24, | ||
41 | V4L2_PIX_FMT_ARGB32, | ||
42 | }; | ||
43 | |||
38 | struct vimc_sca_device { | 44 | struct vimc_sca_device { |
39 | struct vimc_ent_device ved; | 45 | struct vimc_ent_device ved; |
40 | struct v4l2_subdev sd; | 46 | struct v4l2_subdev sd; |
@@ -57,6 +63,16 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = { | |||
57 | .colorspace = V4L2_COLORSPACE_DEFAULT, | 63 | .colorspace = V4L2_COLORSPACE_DEFAULT, |
58 | }; | 64 | }; |
59 | 65 | ||
66 | static bool vimc_sca_is_pixfmt_supported(u32 pixelformat) | ||
67 | { | ||
68 | unsigned int i; | ||
69 | |||
70 | for (i = 0; i < ARRAY_SIZE(vimc_sca_supported_pixfmt); i++) | ||
71 | if (vimc_sca_supported_pixfmt[i] == pixelformat) | ||
72 | return true; | ||
73 | return false; | ||
74 | } | ||
75 | |||
60 | static int vimc_sca_init_cfg(struct v4l2_subdev *sd, | 76 | static int vimc_sca_init_cfg(struct v4l2_subdev *sd, |
61 | struct v4l2_subdev_pad_config *cfg) | 77 | struct v4l2_subdev_pad_config *cfg) |
62 | { | 78 | { |
@@ -76,35 +92,13 @@ static int vimc_sca_init_cfg(struct v4l2_subdev *sd, | |||
76 | return 0; | 92 | return 0; |
77 | } | 93 | } |
78 | 94 | ||
79 | static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd, | ||
80 | struct v4l2_subdev_pad_config *cfg, | ||
81 | struct v4l2_subdev_mbus_code_enum *code) | ||
82 | { | ||
83 | const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index); | ||
84 | |||
85 | /* We don't support bayer format */ | ||
86 | if (!vpix || vpix->bayer) | ||
87 | return -EINVAL; | ||
88 | |||
89 | code->code = vpix->code; | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, | 95 | static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, |
95 | struct v4l2_subdev_pad_config *cfg, | 96 | struct v4l2_subdev_pad_config *cfg, |
96 | struct v4l2_subdev_frame_size_enum *fse) | 97 | struct v4l2_subdev_frame_size_enum *fse) |
97 | { | 98 | { |
98 | const struct vimc_pix_map *vpix; | ||
99 | |||
100 | if (fse->index) | 99 | if (fse->index) |
101 | return -EINVAL; | 100 | return -EINVAL; |
102 | 101 | ||
103 | /* Only accept code in the pix map table in non bayer format */ | ||
104 | vpix = vimc_pix_map_by_code(fse->code); | ||
105 | if (!vpix || vpix->bayer) | ||
106 | return -EINVAL; | ||
107 | |||
108 | fse->min_width = VIMC_FRAME_MIN_WIDTH; | 102 | fse->min_width = VIMC_FRAME_MIN_WIDTH; |
109 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; | 103 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; |
110 | 104 | ||
@@ -141,13 +135,6 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd, | |||
141 | 135 | ||
142 | static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) | 136 | static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) |
143 | { | 137 | { |
144 | const struct vimc_pix_map *vpix; | ||
145 | |||
146 | /* Only accept code in the pix map table in non bayer format */ | ||
147 | vpix = vimc_pix_map_by_code(fmt->code); | ||
148 | if (!vpix || vpix->bayer) | ||
149 | fmt->code = sink_fmt_default.code; | ||
150 | |||
151 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, | 138 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, |
152 | VIMC_FRAME_MAX_WIDTH) & ~1; | 139 | VIMC_FRAME_MAX_WIDTH) & ~1; |
153 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, | 140 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, |
@@ -166,6 +153,9 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, | |||
166 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); | 153 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); |
167 | struct v4l2_mbus_framefmt *sink_fmt; | 154 | struct v4l2_mbus_framefmt *sink_fmt; |
168 | 155 | ||
156 | if (!vimc_mbus_code_supported(fmt->format.code)) | ||
157 | fmt->format.code = sink_fmt_default.code; | ||
158 | |||
169 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 159 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
170 | /* Do not change the format while stream is on */ | 160 | /* Do not change the format while stream is on */ |
171 | if (vsca->src_frame) | 161 | if (vsca->src_frame) |
@@ -208,7 +198,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, | |||
208 | 198 | ||
209 | static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { | 199 | static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { |
210 | .init_cfg = vimc_sca_init_cfg, | 200 | .init_cfg = vimc_sca_init_cfg, |
211 | .enum_mbus_code = vimc_sca_enum_mbus_code, | 201 | .enum_mbus_code = vimc_enum_mbus_code, |
212 | .enum_frame_size = vimc_sca_enum_frame_size, | 202 | .enum_frame_size = vimc_sca_enum_frame_size, |
213 | .get_fmt = vimc_sca_get_fmt, | 203 | .get_fmt = vimc_sca_get_fmt, |
214 | .set_fmt = vimc_sca_set_fmt, | 204 | .set_fmt = vimc_sca_set_fmt, |
@@ -219,15 +209,22 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) | |||
219 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); | 209 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); |
220 | 210 | ||
221 | if (enable) { | 211 | if (enable) { |
222 | const struct vimc_pix_map *vpix; | 212 | u32 pixelformat = vsca->ved.stream->producer_pixfmt; |
213 | const struct v4l2_format_info *pix_info; | ||
223 | unsigned int frame_size; | 214 | unsigned int frame_size; |
224 | 215 | ||
225 | if (vsca->src_frame) | 216 | if (vsca->src_frame) |
226 | return 0; | 217 | return 0; |
227 | 218 | ||
219 | if (!vimc_sca_is_pixfmt_supported(pixelformat)) { | ||
220 | dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n", | ||
221 | pixelformat); | ||
222 | return -EINVAL; | ||
223 | } | ||
224 | |||
228 | /* Save the bytes per pixel of the sink */ | 225 | /* Save the bytes per pixel of the sink */ |
229 | vpix = vimc_pix_map_by_code(vsca->sink_fmt.code); | 226 | pix_info = v4l2_format_info(pixelformat); |
230 | vsca->bpp = vpix->bpp; | 227 | vsca->bpp = pix_info->bpp[0]; |
231 | 228 | ||
232 | /* Calculate the width in bytes of the src frame */ | 229 | /* Calculate the width in bytes of the src frame */ |
233 | vsca->src_line_size = vsca->sink_fmt.width * | 230 | vsca->src_line_size = vsca->sink_fmt.width * |