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, 33 insertions, 30 deletions
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index 5f31c1e351a3..49ab8d9dd9c9 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c | |||
@@ -25,12 +25,6 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier"); | |||
25 | #define IS_SRC(pad) (pad) | 25 | #define IS_SRC(pad) (pad) |
26 | #define MAX_ZOOM 8 | 26 | #define MAX_ZOOM 8 |
27 | 27 | ||
28 | static const u32 vimc_sca_supported_pixfmt[] = { | ||
29 | V4L2_PIX_FMT_BGR24, | ||
30 | V4L2_PIX_FMT_RGB24, | ||
31 | V4L2_PIX_FMT_ARGB32, | ||
32 | }; | ||
33 | |||
34 | struct vimc_sca_device { | 28 | struct vimc_sca_device { |
35 | struct vimc_ent_device ved; | 29 | struct vimc_ent_device ved; |
36 | struct v4l2_subdev sd; | 30 | struct v4l2_subdev sd; |
@@ -53,16 +47,6 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = { | |||
53 | .colorspace = V4L2_COLORSPACE_DEFAULT, | 47 | .colorspace = V4L2_COLORSPACE_DEFAULT, |
54 | }; | 48 | }; |
55 | 49 | ||
56 | static bool vimc_sca_is_pixfmt_supported(u32 pixelformat) | ||
57 | { | ||
58 | unsigned int i; | ||
59 | |||
60 | for (i = 0; i < ARRAY_SIZE(vimc_sca_supported_pixfmt); i++) | ||
61 | if (vimc_sca_supported_pixfmt[i] == pixelformat) | ||
62 | return true; | ||
63 | return false; | ||
64 | } | ||
65 | |||
66 | static int vimc_sca_init_cfg(struct v4l2_subdev *sd, | 50 | static int vimc_sca_init_cfg(struct v4l2_subdev *sd, |
67 | struct v4l2_subdev_pad_config *cfg) | 51 | struct v4l2_subdev_pad_config *cfg) |
68 | { | 52 | { |
@@ -82,13 +66,35 @@ static int vimc_sca_init_cfg(struct v4l2_subdev *sd, | |||
82 | return 0; | 66 | return 0; |
83 | } | 67 | } |
84 | 68 | ||
69 | static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd, | ||
70 | struct v4l2_subdev_pad_config *cfg, | ||
71 | struct v4l2_subdev_mbus_code_enum *code) | ||
72 | { | ||
73 | const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index); | ||
74 | |||
75 | /* We don't support bayer format */ | ||
76 | if (!vpix || vpix->bayer) | ||
77 | return -EINVAL; | ||
78 | |||
79 | code->code = vpix->code; | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
85 | static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, | 84 | static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, |
86 | struct v4l2_subdev_pad_config *cfg, | 85 | struct v4l2_subdev_pad_config *cfg, |
87 | struct v4l2_subdev_frame_size_enum *fse) | 86 | struct v4l2_subdev_frame_size_enum *fse) |
88 | { | 87 | { |
88 | const struct vimc_pix_map *vpix; | ||
89 | |||
89 | if (fse->index) | 90 | if (fse->index) |
90 | return -EINVAL; | 91 | return -EINVAL; |
91 | 92 | ||
93 | /* Only accept code in the pix map table in non bayer format */ | ||
94 | vpix = vimc_pix_map_by_code(fse->code); | ||
95 | if (!vpix || vpix->bayer) | ||
96 | return -EINVAL; | ||
97 | |||
92 | fse->min_width = VIMC_FRAME_MIN_WIDTH; | 98 | fse->min_width = VIMC_FRAME_MIN_WIDTH; |
93 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; | 99 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; |
94 | 100 | ||
@@ -125,6 +131,13 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd, | |||
125 | 131 | ||
126 | static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) | 132 | static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) |
127 | { | 133 | { |
134 | const struct vimc_pix_map *vpix; | ||
135 | |||
136 | /* Only accept code in the pix map table in non bayer format */ | ||
137 | vpix = vimc_pix_map_by_code(fmt->code); | ||
138 | if (!vpix || vpix->bayer) | ||
139 | fmt->code = sink_fmt_default.code; | ||
140 | |||
128 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, | 141 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, |
129 | VIMC_FRAME_MAX_WIDTH) & ~1; | 142 | VIMC_FRAME_MAX_WIDTH) & ~1; |
130 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, | 143 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, |
@@ -143,9 +156,6 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, | |||
143 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); | 156 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); |
144 | struct v4l2_mbus_framefmt *sink_fmt; | 157 | struct v4l2_mbus_framefmt *sink_fmt; |
145 | 158 | ||
146 | if (!vimc_mbus_code_supported(fmt->format.code)) | ||
147 | fmt->format.code = sink_fmt_default.code; | ||
148 | |||
149 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 159 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
150 | /* Do not change the format while stream is on */ | 160 | /* Do not change the format while stream is on */ |
151 | if (vsca->src_frame) | 161 | if (vsca->src_frame) |
@@ -188,7 +198,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, | |||
188 | 198 | ||
189 | static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { | 199 | static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { |
190 | .init_cfg = vimc_sca_init_cfg, | 200 | .init_cfg = vimc_sca_init_cfg, |
191 | .enum_mbus_code = vimc_enum_mbus_code, | 201 | .enum_mbus_code = vimc_sca_enum_mbus_code, |
192 | .enum_frame_size = vimc_sca_enum_frame_size, | 202 | .enum_frame_size = vimc_sca_enum_frame_size, |
193 | .get_fmt = vimc_sca_get_fmt, | 203 | .get_fmt = vimc_sca_get_fmt, |
194 | .set_fmt = vimc_sca_set_fmt, | 204 | .set_fmt = vimc_sca_set_fmt, |
@@ -199,22 +209,15 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) | |||
199 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); | 209 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); |
200 | 210 | ||
201 | if (enable) { | 211 | if (enable) { |
202 | u32 pixelformat = vsca->ved.stream->producer_pixfmt; | 212 | const struct vimc_pix_map *vpix; |
203 | const struct v4l2_format_info *pix_info; | ||
204 | unsigned int frame_size; | 213 | unsigned int frame_size; |
205 | 214 | ||
206 | if (vsca->src_frame) | 215 | if (vsca->src_frame) |
207 | return 0; | 216 | return 0; |
208 | 217 | ||
209 | if (!vimc_sca_is_pixfmt_supported(pixelformat)) { | ||
210 | dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n", | ||
211 | pixelformat); | ||
212 | return -EINVAL; | ||
213 | } | ||
214 | |||
215 | /* Save the bytes per pixel of the sink */ | 218 | /* Save the bytes per pixel of the sink */ |
216 | pix_info = v4l2_format_info(pixelformat); | 219 | vpix = vimc_pix_map_by_code(vsca->sink_fmt.code); |
217 | vsca->bpp = pix_info->bpp[0]; | 220 | vsca->bpp = vpix->bpp; |
218 | 221 | ||
219 | /* Calculate the width in bytes of the src frame */ | 222 | /* Calculate the width in bytes of the src frame */ |
220 | vsca->src_line_size = vsca->sink_fmt.width * | 223 | vsca->src_line_size = vsca->sink_fmt.width * |