aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-scaler.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/vimc/vimc-scaler.c')
-rw-r--r--drivers/media/platform/vimc/vimc-scaler.c63
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
28static const u32 vimc_sca_supported_pixfmt[] = {
29 V4L2_PIX_FMT_BGR24,
30 V4L2_PIX_FMT_RGB24,
31 V4L2_PIX_FMT_ARGB32,
32};
33
34struct vimc_sca_device { 28struct 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
56static 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
66static int vimc_sca_init_cfg(struct v4l2_subdev *sd, 50static 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
69static 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
85static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, 84static 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
126static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) 132static 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
189static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { 199static 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 *