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, 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
38static const u32 vimc_sca_supported_pixfmt[] = {
39 V4L2_PIX_FMT_BGR24,
40 V4L2_PIX_FMT_RGB24,
41 V4L2_PIX_FMT_ARGB32,
42};
43
38struct vimc_sca_device { 44struct 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
66static 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
60static int vimc_sca_init_cfg(struct v4l2_subdev *sd, 76static 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
79static 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
94static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, 95static 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
142static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) 136static 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
209static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { 199static 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 *