aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/platform/vimc/vimc-capture.c76
-rw-r--r--drivers/media/platform/vimc/vimc-common.c309
-rw-r--r--drivers/media/platform/vimc/vimc-common.h58
-rw-r--r--drivers/media/platform/vimc/vimc-debayer.c83
-rw-r--r--drivers/media/platform/vimc/vimc-scaler.c63
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c51
-rw-r--r--drivers/media/platform/vimc/vimc-streamer.c2
-rw-r--r--drivers/media/platform/vimc/vimc-streamer.h8
8 files changed, 342 insertions, 308 deletions
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
index 664855708fdf..1d56b91830ba 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -18,32 +18,6 @@
18 18
19#define VIMC_CAP_DRV_NAME "vimc-capture" 19#define VIMC_CAP_DRV_NAME "vimc-capture"
20 20
21static const u32 vimc_cap_supported_pixfmt[] = {
22 V4L2_PIX_FMT_BGR24,
23 V4L2_PIX_FMT_RGB24,
24 V4L2_PIX_FMT_ARGB32,
25 V4L2_PIX_FMT_SBGGR8,
26 V4L2_PIX_FMT_SGBRG8,
27 V4L2_PIX_FMT_SGRBG8,
28 V4L2_PIX_FMT_SRGGB8,
29 V4L2_PIX_FMT_SBGGR10,
30 V4L2_PIX_FMT_SGBRG10,
31 V4L2_PIX_FMT_SGRBG10,
32 V4L2_PIX_FMT_SRGGB10,
33 V4L2_PIX_FMT_SBGGR10ALAW8,
34 V4L2_PIX_FMT_SGBRG10ALAW8,
35 V4L2_PIX_FMT_SGRBG10ALAW8,
36 V4L2_PIX_FMT_SRGGB10ALAW8,
37 V4L2_PIX_FMT_SBGGR10DPCM8,
38 V4L2_PIX_FMT_SGBRG10DPCM8,
39 V4L2_PIX_FMT_SGRBG10DPCM8,
40 V4L2_PIX_FMT_SRGGB10DPCM8,
41 V4L2_PIX_FMT_SBGGR12,
42 V4L2_PIX_FMT_SGBRG12,
43 V4L2_PIX_FMT_SGRBG12,
44 V4L2_PIX_FMT_SRGGB12,
45};
46
47struct vimc_cap_device { 21struct vimc_cap_device {
48 struct vimc_ent_device ved; 22 struct vimc_ent_device ved;
49 struct video_device vdev; 23 struct video_device vdev;
@@ -117,25 +91,29 @@ static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv,
117 struct v4l2_format *f) 91 struct v4l2_format *f)
118{ 92{
119 struct v4l2_pix_format *format = &f->fmt.pix; 93 struct v4l2_pix_format *format = &f->fmt.pix;
94 const struct vimc_pix_map *vpix;
120 95
121 format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH, 96 format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
122 VIMC_FRAME_MAX_WIDTH) & ~1; 97 VIMC_FRAME_MAX_WIDTH) & ~1;
123 format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT, 98 format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
124 VIMC_FRAME_MAX_HEIGHT) & ~1; 99 VIMC_FRAME_MAX_HEIGHT) & ~1;
125 100
126 vimc_colorimetry_clamp(format); 101 /* Don't accept a pixelformat that is not on the table */
102 vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
103 if (!vpix) {
104 format->pixelformat = fmt_default.pixelformat;
105 vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
106 }
107 /* TODO: Add support for custom bytesperline values */
108 format->bytesperline = format->width * vpix->bpp;
109 format->sizeimage = format->bytesperline * format->height;
127 110
128 if (format->field == V4L2_FIELD_ANY) 111 if (format->field == V4L2_FIELD_ANY)
129 format->field = fmt_default.field; 112 format->field = fmt_default.field;
130 113
131 /* TODO: Add support for custom bytesperline values */ 114 vimc_colorimetry_clamp(format);
132
133 /* Don't accept a pixelformat that is not on the table */
134 if (!v4l2_format_info(format->pixelformat))
135 format->pixelformat = fmt_default.pixelformat;
136 115
137 return v4l2_fill_pixfmt(format, format->pixelformat, 116 return 0;
138 format->width, format->height);
139} 117}
140 118
141static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv, 119static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
@@ -174,31 +152,27 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
174static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv, 152static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
175 struct v4l2_fmtdesc *f) 153 struct v4l2_fmtdesc *f)
176{ 154{
177 if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt)) 155 const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index);
156
157 if (!vpix)
178 return -EINVAL; 158 return -EINVAL;
179 159
180 f->pixelformat = vimc_cap_supported_pixfmt[f->index]; 160 f->pixelformat = vpix->pixelformat;
181 161
182 return 0; 162 return 0;
183} 163}
184 164
185static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
186{
187 unsigned int i;
188
189 for (i = 0; i < ARRAY_SIZE(vimc_cap_supported_pixfmt); i++)
190 if (vimc_cap_supported_pixfmt[i] == pixelformat)
191 return true;
192 return false;
193}
194
195static int vimc_cap_enum_framesizes(struct file *file, void *fh, 165static int vimc_cap_enum_framesizes(struct file *file, void *fh,
196 struct v4l2_frmsizeenum *fsize) 166 struct v4l2_frmsizeenum *fsize)
197{ 167{
168 const struct vimc_pix_map *vpix;
169
198 if (fsize->index) 170 if (fsize->index)
199 return -EINVAL; 171 return -EINVAL;
200 172
201 if (!vimc_cap_is_pixfmt_supported(fsize->pixel_format)) 173 /* Only accept code in the pix map table */
174 vpix = vimc_pix_map_by_code(fsize->pixel_format);
175 if (!vpix)
202 return -EINVAL; 176 return -EINVAL;
203 177
204 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; 178 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
@@ -272,7 +246,6 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
272 return ret; 246 return ret;
273 } 247 }
274 248
275 vcap->stream.producer_pixfmt = vcap->format.pixelformat;
276 ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1); 249 ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
277 if (ret) { 250 if (ret) {
278 media_pipeline_stop(entity); 251 media_pipeline_stop(entity);
@@ -423,6 +396,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
423{ 396{
424 struct v4l2_device *v4l2_dev = master_data; 397 struct v4l2_device *v4l2_dev = master_data;
425 struct vimc_platform_data *pdata = comp->platform_data; 398 struct vimc_platform_data *pdata = comp->platform_data;
399 const struct vimc_pix_map *vpix;
426 struct vimc_cap_device *vcap; 400 struct vimc_cap_device *vcap;
427 struct video_device *vdev; 401 struct video_device *vdev;
428 struct vb2_queue *q; 402 struct vb2_queue *q;
@@ -477,8 +451,10 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
477 451
478 /* Set default frame format */ 452 /* Set default frame format */
479 vcap->format = fmt_default; 453 vcap->format = fmt_default;
480 v4l2_fill_pixfmt(&vcap->format, vcap->format.pixelformat, 454 vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat);
481 vcap->format.width, vcap->format.height); 455 vcap->format.bytesperline = vcap->format.width * vpix->bpp;
456 vcap->format.sizeimage = vcap->format.bytesperline *
457 vcap->format.height;
482 458
483 /* Fill the vimc_ent_device struct */ 459 /* Fill the vimc_ent_device struct */
484 vcap->ved.ent = &vcap->vdev.entity; 460 vcap->ved.ent = &vcap->vdev.entity;
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
index 03016f204d05..7e1ae0b12f1e 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -10,139 +10,192 @@
10 10
11#include "vimc-common.h" 11#include "vimc-common.h"
12 12
13static const __u32 vimc_mbus_list[] = { 13/*
14 MEDIA_BUS_FMT_FIXED, 14 * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
15 MEDIA_BUS_FMT_RGB444_1X12, 15 * in the scaler)
16 MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, 16 */
17 MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, 17static const struct vimc_pix_map vimc_pix_map_list[] = {
18 MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, 18 /* TODO: add all missing formats */
19 MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, 19
20 MEDIA_BUS_FMT_RGB565_1X16, 20 /* RGB formats */
21 MEDIA_BUS_FMT_BGR565_2X8_BE, 21 {
22 MEDIA_BUS_FMT_BGR565_2X8_LE, 22 .code = MEDIA_BUS_FMT_BGR888_1X24,
23 MEDIA_BUS_FMT_RGB565_2X8_BE, 23 .pixelformat = V4L2_PIX_FMT_BGR24,
24 MEDIA_BUS_FMT_RGB565_2X8_LE, 24 .bpp = 3,
25 MEDIA_BUS_FMT_RGB666_1X18, 25 .bayer = false,
26 MEDIA_BUS_FMT_RBG888_1X24, 26 },
27 MEDIA_BUS_FMT_RGB666_1X24_CPADHI, 27 {
28 MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 28 .code = MEDIA_BUS_FMT_RGB888_1X24,
29 MEDIA_BUS_FMT_BGR888_1X24, 29 .pixelformat = V4L2_PIX_FMT_RGB24,
30 MEDIA_BUS_FMT_GBR888_1X24, 30 .bpp = 3,
31 MEDIA_BUS_FMT_RGB888_1X24, 31 .bayer = false,
32 MEDIA_BUS_FMT_RGB888_2X12_BE, 32 },
33 MEDIA_BUS_FMT_RGB888_2X12_LE, 33 {
34 MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 34 .code = MEDIA_BUS_FMT_ARGB8888_1X32,
35 MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 35 .pixelformat = V4L2_PIX_FMT_ARGB32,
36 MEDIA_BUS_FMT_ARGB8888_1X32, 36 .bpp = 4,
37 MEDIA_BUS_FMT_RGB888_1X32_PADHI, 37 .bayer = false,
38 MEDIA_BUS_FMT_RGB101010_1X30, 38 },
39 MEDIA_BUS_FMT_RGB121212_1X36, 39
40 MEDIA_BUS_FMT_RGB161616_1X48, 40 /* Bayer formats */
41 MEDIA_BUS_FMT_Y8_1X8, 41 {
42 MEDIA_BUS_FMT_UV8_1X8, 42 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
43 MEDIA_BUS_FMT_UYVY8_1_5X8, 43 .pixelformat = V4L2_PIX_FMT_SBGGR8,
44 MEDIA_BUS_FMT_VYUY8_1_5X8, 44 .bpp = 1,
45 MEDIA_BUS_FMT_YUYV8_1_5X8, 45 .bayer = true,
46 MEDIA_BUS_FMT_YVYU8_1_5X8, 46 },
47 MEDIA_BUS_FMT_UYVY8_2X8, 47 {
48 MEDIA_BUS_FMT_VYUY8_2X8, 48 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
49 MEDIA_BUS_FMT_YUYV8_2X8, 49 .pixelformat = V4L2_PIX_FMT_SGBRG8,
50 MEDIA_BUS_FMT_YVYU8_2X8, 50 .bpp = 1,
51 MEDIA_BUS_FMT_Y10_1X10, 51 .bayer = true,
52 MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 52 },
53 MEDIA_BUS_FMT_UYVY10_2X10, 53 {
54 MEDIA_BUS_FMT_VYUY10_2X10, 54 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
55 MEDIA_BUS_FMT_YUYV10_2X10, 55 .pixelformat = V4L2_PIX_FMT_SGRBG8,
56 MEDIA_BUS_FMT_YVYU10_2X10, 56 .bpp = 1,
57 MEDIA_BUS_FMT_Y12_1X12, 57 .bayer = true,
58 MEDIA_BUS_FMT_UYVY12_2X12, 58 },
59 MEDIA_BUS_FMT_VYUY12_2X12, 59 {
60 MEDIA_BUS_FMT_YUYV12_2X12, 60 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
61 MEDIA_BUS_FMT_YVYU12_2X12, 61 .pixelformat = V4L2_PIX_FMT_SRGGB8,
62 MEDIA_BUS_FMT_UYVY8_1X16, 62 .bpp = 1,
63 MEDIA_BUS_FMT_VYUY8_1X16, 63 .bayer = true,
64 MEDIA_BUS_FMT_YUYV8_1X16, 64 },
65 MEDIA_BUS_FMT_YVYU8_1X16, 65 {
66 MEDIA_BUS_FMT_YDYUYDYV8_1X16, 66 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
67 MEDIA_BUS_FMT_UYVY10_1X20, 67 .pixelformat = V4L2_PIX_FMT_SBGGR10,
68 MEDIA_BUS_FMT_VYUY10_1X20, 68 .bpp = 2,
69 MEDIA_BUS_FMT_YUYV10_1X20, 69 .bayer = true,
70 MEDIA_BUS_FMT_YVYU10_1X20, 70 },
71 MEDIA_BUS_FMT_VUY8_1X24, 71 {
72 MEDIA_BUS_FMT_YUV8_1X24, 72 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
73 MEDIA_BUS_FMT_UYYVYY8_0_5X24, 73 .pixelformat = V4L2_PIX_FMT_SGBRG10,
74 MEDIA_BUS_FMT_UYVY12_1X24, 74 .bpp = 2,
75 MEDIA_BUS_FMT_VYUY12_1X24, 75 .bayer = true,
76 MEDIA_BUS_FMT_YUYV12_1X24, 76 },
77 MEDIA_BUS_FMT_YVYU12_1X24, 77 {
78 MEDIA_BUS_FMT_YUV10_1X30, 78 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
79 MEDIA_BUS_FMT_UYYVYY10_0_5X30, 79 .pixelformat = V4L2_PIX_FMT_SGRBG10,
80 MEDIA_BUS_FMT_AYUV8_1X32, 80 .bpp = 2,
81 MEDIA_BUS_FMT_UYYVYY12_0_5X36, 81 .bayer = true,
82 MEDIA_BUS_FMT_YUV12_1X36, 82 },
83 MEDIA_BUS_FMT_YUV16_1X48, 83 {
84 MEDIA_BUS_FMT_UYYVYY16_0_5X48, 84 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
85 MEDIA_BUS_FMT_SBGGR8_1X8, 85 .pixelformat = V4L2_PIX_FMT_SRGGB10,
86 MEDIA_BUS_FMT_SGBRG8_1X8, 86 .bpp = 2,
87 MEDIA_BUS_FMT_SGRBG8_1X8, 87 .bayer = true,
88 MEDIA_BUS_FMT_SRGGB8_1X8, 88 },
89 MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, 89
90 MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, 90 /* 10bit raw bayer a-law compressed to 8 bits */
91 MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, 91 {
92 MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, 92 .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
93 MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, 93 .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
94 MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, 94 .bpp = 1,
95 MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, 95 .bayer = true,
96 MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, 96 },
97 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, 97 {
98 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 98 .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
99 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, 99 .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
100 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, 100 .bpp = 1,
101 MEDIA_BUS_FMT_SBGGR10_1X10, 101 .bayer = true,
102 MEDIA_BUS_FMT_SGBRG10_1X10, 102 },
103 MEDIA_BUS_FMT_SGRBG10_1X10, 103 {
104 MEDIA_BUS_FMT_SRGGB10_1X10, 104 .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
105 MEDIA_BUS_FMT_SBGGR12_1X12, 105 .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
106 MEDIA_BUS_FMT_SGBRG12_1X12, 106 .bpp = 1,
107 MEDIA_BUS_FMT_SGRBG12_1X12, 107 .bayer = true,
108 MEDIA_BUS_FMT_SRGGB12_1X12, 108 },
109 MEDIA_BUS_FMT_SBGGR14_1X14, 109 {
110 MEDIA_BUS_FMT_SGBRG14_1X14, 110 .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
111 MEDIA_BUS_FMT_SGRBG14_1X14, 111 .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
112 MEDIA_BUS_FMT_SRGGB14_1X14, 112 .bpp = 1,
113 MEDIA_BUS_FMT_SBGGR16_1X16, 113 .bayer = true,
114 MEDIA_BUS_FMT_SGBRG16_1X16, 114 },
115 MEDIA_BUS_FMT_SGRBG16_1X16, 115
116 MEDIA_BUS_FMT_SRGGB16_1X16, 116 /* 10bit raw bayer DPCM compressed to 8 bits */
117 MEDIA_BUS_FMT_JPEG_1X8, 117 {
118 MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, 118 .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
119 MEDIA_BUS_FMT_AHSV8888_1X32, 119 .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
120 .bpp = 1,
121 .bayer = true,
122 },
123 {
124 .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
125 .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
126 .bpp = 1,
127 .bayer = true,
128 },
129 {
130 .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
131 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
132 .bpp = 1,
133 .bayer = true,
134 },
135 {
136 .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
137 .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
138 .bpp = 1,
139 .bayer = true,
140 },
141 {
142 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
143 .pixelformat = V4L2_PIX_FMT_SBGGR12,
144 .bpp = 2,
145 .bayer = true,
146 },
147 {
148 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
149 .pixelformat = V4L2_PIX_FMT_SGBRG12,
150 .bpp = 2,
151 .bayer = true,
152 },
153 {
154 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
155 .pixelformat = V4L2_PIX_FMT_SGRBG12,
156 .bpp = 2,
157 .bayer = true,
158 },
159 {
160 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
161 .pixelformat = V4L2_PIX_FMT_SRGGB12,
162 .bpp = 2,
163 .bayer = true,
164 },
120}; 165};
121 166
122/* Helper function to check mbus codes */ 167const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
123bool vimc_mbus_code_supported(__u32 code) 168{
169 if (i >= ARRAY_SIZE(vimc_pix_map_list))
170 return NULL;
171
172 return &vimc_pix_map_list[i];
173}
174EXPORT_SYMBOL_GPL(vimc_pix_map_by_index);
175
176const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
124{ 177{
125 unsigned int i; 178 unsigned int i;
126 179
127 for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++) 180 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
128 if (code == vimc_mbus_list[i]) 181 if (vimc_pix_map_list[i].code == code)
129 return true; 182 return &vimc_pix_map_list[i];
130 return false; 183 }
184 return NULL;
131} 185}
132EXPORT_SYMBOL_GPL(vimc_mbus_code_supported); 186EXPORT_SYMBOL_GPL(vimc_pix_map_by_code);
133 187
134/* Helper function to enumerate mbus codes */ 188const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
135int vimc_enum_mbus_code(struct v4l2_subdev *sd,
136 struct v4l2_subdev_pad_config *cfg,
137 struct v4l2_subdev_mbus_code_enum *code)
138{ 189{
139 if (code->index >= ARRAY_SIZE(vimc_mbus_list)) 190 unsigned int i;
140 return -EINVAL;
141 191
142 code->code = vimc_mbus_list[code->index]; 192 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
143 return 0; 193 if (vimc_pix_map_list[i].pixelformat == pixelformat)
194 return &vimc_pix_map_list[i];
195 }
196 return NULL;
144} 197}
145EXPORT_SYMBOL_GPL(vimc_enum_mbus_code); 198EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat);
146 199
147/* Helper function to allocate and initialize pads */ 200/* Helper function to allocate and initialize pads */
148struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) 201struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
@@ -214,13 +267,15 @@ static int vimc_get_mbus_format(struct media_pad *pad,
214 struct video_device, 267 struct video_device,
215 entity); 268 entity);
216 struct vimc_ent_device *ved = video_get_drvdata(vdev); 269 struct vimc_ent_device *ved = video_get_drvdata(vdev);
270 const struct vimc_pix_map *vpix;
217 struct v4l2_pix_format vdev_fmt; 271 struct v4l2_pix_format vdev_fmt;
218 272
219 if (!ved->vdev_get_format) 273 if (!ved->vdev_get_format)
220 return -ENOIOCTLCMD; 274 return -ENOIOCTLCMD;
221 275
222 ved->vdev_get_format(ved, &vdev_fmt); 276 ved->vdev_get_format(ved, &vdev_fmt);
223 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0); 277 vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat);
278 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code);
224 } else { 279 } else {
225 return -EINVAL; 280 return -EINVAL;
226 } 281 }
@@ -260,12 +315,8 @@ int vimc_link_validate(struct media_link *link)
260 /* The width, height and code must match. */ 315 /* The width, height and code must match. */
261 if (source_fmt.format.width != sink_fmt.format.width 316 if (source_fmt.format.width != sink_fmt.format.width
262 || source_fmt.format.height != sink_fmt.format.height 317 || source_fmt.format.height != sink_fmt.format.height
263 || (source_fmt.format.code && sink_fmt.format.code && 318 || source_fmt.format.code != sink_fmt.format.code)
264 source_fmt.format.code != sink_fmt.format.code)) {
265 pr_err("vimc: format doesn't match in link %s->%s\n",
266 link->source->entity->name, link->sink->entity->name);
267 return -EPIPE; 319 return -EPIPE;
268 }
269 320
270 /* 321 /*
271 * The field order must match, or the sink field order must be NONE 322 * The field order must match, or the sink field order must be NONE
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
index 7b4d988b208b..9c2e0e216c6b 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -12,8 +12,6 @@
12#include <media/media-device.h> 12#include <media/media-device.h>
13#include <media/v4l2-device.h> 13#include <media/v4l2-device.h>
14 14
15#include "vimc-streamer.h"
16
17#define VIMC_PDEV_NAME "vimc" 15#define VIMC_PDEV_NAME "vimc"
18 16
19/* VIMC-specific controls */ 17/* VIMC-specific controls */
@@ -70,6 +68,23 @@ struct vimc_platform_data {
70}; 68};
71 69
72/** 70/**
71 * struct vimc_pix_map - maps media bus code with v4l2 pixel format
72 *
73 * @code: media bus format code defined by MEDIA_BUS_FMT_* macros
74 * @bbp: number of bytes each pixel occupies
75 * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros
76 *
77 * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding
78 * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp)
79 */
80struct vimc_pix_map {
81 unsigned int code;
82 unsigned int bpp;
83 u32 pixelformat;
84 bool bayer;
85};
86
87/**
73 * struct vimc_ent_device - core struct that represents a node in the topology 88 * struct vimc_ent_device - core struct that represents a node in the topology
74 * 89 *
75 * @ent: the pointer to struct media_entity for the node 90 * @ent: the pointer to struct media_entity for the node
@@ -90,7 +105,6 @@ struct vimc_platform_data {
90struct vimc_ent_device { 105struct vimc_ent_device {
91 struct media_entity *ent; 106 struct media_entity *ent;
92 struct media_pad *pads; 107 struct media_pad *pads;
93 struct vimc_stream *stream;
94 void * (*process_frame)(struct vimc_ent_device *ved, 108 void * (*process_frame)(struct vimc_ent_device *ved,
95 const void *frame); 109 const void *frame);
96 void (*vdev_get_format)(struct vimc_ent_device *ved, 110 void (*vdev_get_format)(struct vimc_ent_device *ved,
@@ -98,23 +112,6 @@ struct vimc_ent_device {
98}; 112};
99 113
100/** 114/**
101 * vimc_mbus_code_supported - helper to check supported mbus codes
102 *
103 * Helper function to check if mbus code is enumerated by vimc_enum_mbus_code()
104 */
105bool vimc_mbus_code_supported(__u32 code);
106
107/**
108 * vimc_enum_mbus_code - enumerate mbus codes
109 *
110 * Helper function to be pluged in .enum_mbus_code from
111 * struct v4l2_subdev_pad_ops.
112 */
113int vimc_enum_mbus_code(struct v4l2_subdev *sd,
114 struct v4l2_subdev_pad_config *cfg,
115 struct v4l2_subdev_mbus_code_enum *code);
116
117/**
118 * vimc_pads_init - initialize pads 115 * vimc_pads_init - initialize pads
119 * 116 *
120 * @num_pads: number of pads to initialize 117 * @num_pads: number of pads to initialize
@@ -149,6 +146,27 @@ static inline void vimc_pads_cleanup(struct media_pad *pads)
149int vimc_pipeline_s_stream(struct media_entity *ent, int enable); 146int vimc_pipeline_s_stream(struct media_entity *ent, int enable);
150 147
151/** 148/**
149 * vimc_pix_map_by_index - get vimc_pix_map struct by its index
150 *
151 * @i: index of the vimc_pix_map struct in vimc_pix_map_list
152 */
153const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i);
154
155/**
156 * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code
157 *
158 * @code: media bus format code defined by MEDIA_BUS_FMT_* macros
159 */
160const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
161
162/**
163 * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format
164 *
165 * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros
166 */
167const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
168
169/**
152 * vimc_ent_sd_register - initialize and register a subdev node 170 * vimc_ent_sd_register - initialize and register a subdev node
153 * 171 *
154 * @ved: the vimc_ent_device struct to be initialize 172 * @ved: the vimc_ent_device struct to be initialize
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
index 72adba6cf892..b72b8385067b 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -16,11 +16,6 @@
16#include "vimc-common.h" 16#include "vimc-common.h"
17 17
18#define VIMC_DEB_DRV_NAME "vimc-debayer" 18#define VIMC_DEB_DRV_NAME "vimc-debayer"
19/* This module only supports transforming a bayer format
20 * to V4L2_PIX_FMT_RGB24
21 */
22#define VIMC_DEB_SRC_PIXFMT V4L2_PIX_FMT_RGB24
23#define VIMC_DEB_SRC_MBUS_FMT_DEFAULT MEDIA_BUS_FMT_RGB888_1X24
24 19
25static unsigned int deb_mean_win_size = 3; 20static unsigned int deb_mean_win_size = 3;
26module_param(deb_mean_win_size, uint, 0000); 21module_param(deb_mean_win_size, uint, 0000);
@@ -39,7 +34,6 @@ enum vimc_deb_rgb_colors {
39}; 34};
40 35
41struct vimc_deb_pix_map { 36struct vimc_deb_pix_map {
42 u32 pixelformat;
43 u32 code; 37 u32 code;
44 enum vimc_deb_rgb_colors order[2][2]; 38 enum vimc_deb_rgb_colors order[2][2];
45}; 39};
@@ -69,73 +63,61 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = {
69 63
70static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = { 64static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = {
71 { 65 {
72 .pixelformat = V4L2_PIX_FMT_SBGGR8,
73 .code = MEDIA_BUS_FMT_SBGGR8_1X8, 66 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
74 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, 67 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
75 { VIMC_DEB_GREEN, VIMC_DEB_RED } } 68 { VIMC_DEB_GREEN, VIMC_DEB_RED } }
76 }, 69 },
77 { 70 {
78 .pixelformat = V4L2_PIX_FMT_SGBRG8,
79 .code = MEDIA_BUS_FMT_SGBRG8_1X8, 71 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
80 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, 72 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
81 { VIMC_DEB_RED, VIMC_DEB_GREEN } } 73 { VIMC_DEB_RED, VIMC_DEB_GREEN } }
82 }, 74 },
83 { 75 {
84 .pixelformat = V4L2_PIX_FMT_SGRBG8,
85 .code = MEDIA_BUS_FMT_SGRBG8_1X8, 76 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
86 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, 77 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
87 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } 78 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
88 }, 79 },
89 { 80 {
90 .pixelformat = V4L2_PIX_FMT_SRGGB8,
91 .code = MEDIA_BUS_FMT_SRGGB8_1X8, 81 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
92 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, 82 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
93 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } 83 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
94 }, 84 },
95 { 85 {
96 .pixelformat = V4L2_PIX_FMT_SBGGR10,
97 .code = MEDIA_BUS_FMT_SBGGR10_1X10, 86 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
98 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, 87 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
99 { VIMC_DEB_GREEN, VIMC_DEB_RED } } 88 { VIMC_DEB_GREEN, VIMC_DEB_RED } }
100 }, 89 },
101 { 90 {
102 .pixelformat = V4L2_PIX_FMT_SGBRG10,
103 .code = MEDIA_BUS_FMT_SGBRG10_1X10, 91 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
104 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, 92 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
105 { VIMC_DEB_RED, VIMC_DEB_GREEN } } 93 { VIMC_DEB_RED, VIMC_DEB_GREEN } }
106 }, 94 },
107 { 95 {
108 .pixelformat = V4L2_PIX_FMT_SGRBG10,
109 .code = MEDIA_BUS_FMT_SGRBG10_1X10, 96 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
110 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, 97 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
111 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } 98 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
112 }, 99 },
113 { 100 {
114 .pixelformat = V4L2_PIX_FMT_SRGGB10,
115 .code = MEDIA_BUS_FMT_SRGGB10_1X10, 101 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
116 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, 102 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
117 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } 103 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
118 }, 104 },
119 { 105 {
120 .pixelformat = V4L2_PIX_FMT_SBGGR12,
121 .code = MEDIA_BUS_FMT_SBGGR12_1X12, 106 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
122 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, 107 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
123 { VIMC_DEB_GREEN, VIMC_DEB_RED } } 108 { VIMC_DEB_GREEN, VIMC_DEB_RED } }
124 }, 109 },
125 { 110 {
126 .pixelformat = V4L2_PIX_FMT_SGBRG12,
127 .code = MEDIA_BUS_FMT_SGBRG12_1X12, 111 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
128 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, 112 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
129 { VIMC_DEB_RED, VIMC_DEB_GREEN } } 113 { VIMC_DEB_RED, VIMC_DEB_GREEN } }
130 }, 114 },
131 { 115 {
132 .pixelformat = V4L2_PIX_FMT_SGRBG12,
133 .code = MEDIA_BUS_FMT_SGRBG12_1X12, 116 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
134 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, 117 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
135 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } 118 { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
136 }, 119 },
137 { 120 {
138 .pixelformat = V4L2_PIX_FMT_SRGGB12,
139 .code = MEDIA_BUS_FMT_SRGGB12_1X12, 121 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
140 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, 122 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
141 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } 123 { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
@@ -176,32 +158,41 @@ static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd,
176 struct v4l2_subdev_pad_config *cfg, 158 struct v4l2_subdev_pad_config *cfg,
177 struct v4l2_subdev_mbus_code_enum *code) 159 struct v4l2_subdev_mbus_code_enum *code)
178{ 160{
179 /* For the sink pad we only support codes in the map_list */ 161 /* We only support one format for source pads */
180 if (IS_SINK(code->pad)) { 162 if (IS_SRC(code->pad)) {
163 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
164
165 if (code->index)
166 return -EINVAL;
167
168 code->code = vdeb->src_code;
169 } else {
181 if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list)) 170 if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list))
182 return -EINVAL; 171 return -EINVAL;
183 172
184 code->code = vimc_deb_pix_map_list[code->index].code; 173 code->code = vimc_deb_pix_map_list[code->index].code;
185 return 0;
186 } 174 }
187 175
188 return vimc_enum_mbus_code(sd, cfg, code); 176 return 0;
189} 177}
190 178
191static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd, 179static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd,
192 struct v4l2_subdev_pad_config *cfg, 180 struct v4l2_subdev_pad_config *cfg,
193 struct v4l2_subdev_frame_size_enum *fse) 181 struct v4l2_subdev_frame_size_enum *fse)
194{ 182{
183 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
184
195 if (fse->index) 185 if (fse->index)
196 return -EINVAL; 186 return -EINVAL;
197 187
198 /* For the sink pad we only support codes in the map_list */
199 if (IS_SINK(fse->pad)) { 188 if (IS_SINK(fse->pad)) {
200 const struct vimc_deb_pix_map *vpix = 189 const struct vimc_deb_pix_map *vpix =
201 vimc_deb_pix_map_by_code(fse->code); 190 vimc_deb_pix_map_by_code(fse->code);
202 191
203 if (!vpix) 192 if (!vpix)
204 return -EINVAL; 193 return -EINVAL;
194 } else if (fse->code != vdeb->src_code) {
195 return -EINVAL;
205 } 196 }
206 197
207 fse->min_width = VIMC_FRAME_MIN_WIDTH; 198 fse->min_width = VIMC_FRAME_MIN_WIDTH;
@@ -257,9 +248,6 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
257 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); 248 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
258 struct v4l2_mbus_framefmt *sink_fmt; 249 struct v4l2_mbus_framefmt *sink_fmt;
259 250
260 if (!vimc_mbus_code_supported(fmt->format.code))
261 fmt->format.code = sink_fmt_default.code;
262
263 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 251 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
264 /* Do not change the format while stream is on */ 252 /* Do not change the format while stream is on */
265 if (vdeb->src_frame) 253 if (vdeb->src_frame)
@@ -272,11 +260,11 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
272 260
273 /* 261 /*
274 * Do not change the format of the source pad, 262 * Do not change the format of the source pad,
275 * it is propagated from the sink (except for the code) 263 * it is propagated from the sink
276 */ 264 */
277 if (IS_SRC(fmt->pad)) { 265 if (IS_SRC(fmt->pad)) {
278 vdeb->src_code = fmt->format.code;
279 fmt->format = *sink_fmt; 266 fmt->format = *sink_fmt;
267 /* TODO: Add support for other formats */
280 fmt->format.code = vdeb->src_code; 268 fmt->format.code = vdeb->src_code;
281 } else { 269 } else {
282 /* Set the new format in the sink pad */ 270 /* Set the new format in the sink pad */
@@ -308,7 +296,7 @@ static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = {
308 .set_fmt = vimc_deb_set_fmt, 296 .set_fmt = vimc_deb_set_fmt,
309}; 297};
310 298
311static void vimc_deb_set_rgb_pix_rgb24(struct vimc_deb_device *vdeb, 299static void vimc_deb_set_rgb_mbus_fmt_rgb888_1x24(struct vimc_deb_device *vdeb,
312 unsigned int lin, 300 unsigned int lin,
313 unsigned int col, 301 unsigned int col,
314 unsigned int rgb[3]) 302 unsigned int rgb[3])
@@ -325,38 +313,25 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
325 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); 313 struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
326 314
327 if (enable) { 315 if (enable) {
328 u32 src_pixelformat = vdeb->ved.stream->producer_pixfmt; 316 const struct vimc_pix_map *vpix;
329 const struct v4l2_format_info *pix_info;
330 unsigned int frame_size; 317 unsigned int frame_size;
331 318
332 if (vdeb->src_frame) 319 if (vdeb->src_frame)
333 return 0; 320 return 0;
334 321
335 /* We only support translating bayer to RGB24 */ 322 /* Calculate the frame size of the source pad */
336 if (src_pixelformat != V4L2_PIX_FMT_RGB24) { 323 vpix = vimc_pix_map_by_code(vdeb->src_code);
337 dev_err(vdeb->dev, 324 frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
338 "translating to pixfmt (0x%08x) is not supported\n", 325 vpix->bpp;
339 src_pixelformat); 326
340 return -EINVAL; 327 /* Save the bytes per pixel of the sink */
341 } 328 vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code);
329 vdeb->sink_bpp = vpix->bpp;
342 330
343 /* Get the corresponding pixel map from the table */ 331 /* Get the corresponding pixel map from the table */
344 vdeb->sink_pix_map = 332 vdeb->sink_pix_map =
345 vimc_deb_pix_map_by_code(vdeb->sink_fmt.code); 333 vimc_deb_pix_map_by_code(vdeb->sink_fmt.code);
346 334
347 /* Request bayer format from the pipeline for the sink pad */
348 vdeb->ved.stream->producer_pixfmt =
349 vdeb->sink_pix_map->pixelformat;
350
351 /* Calculate frame_size of the source */
352 pix_info = v4l2_format_info(src_pixelformat);
353 frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
354 pix_info->bpp[0];
355
356 /* Get bpp from the sink */
357 pix_info = v4l2_format_info(vdeb->sink_pix_map->pixelformat);
358 vdeb->sink_bpp = pix_info->bpp[0];
359
360 /* 335 /*
361 * Allocate the frame buffer. Use vmalloc to be able to 336 * Allocate the frame buffer. Use vmalloc to be able to
362 * allocate a large amount of memory 337 * allocate a large amount of memory
@@ -557,14 +532,14 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master,
557 532
558 /* Initialize the frame format */ 533 /* Initialize the frame format */
559 vdeb->sink_fmt = sink_fmt_default; 534 vdeb->sink_fmt = sink_fmt_default;
560 vdeb->src_code = VIMC_DEB_SRC_MBUS_FMT_DEFAULT;
561 /* 535 /*
562 * TODO: Add support for more output formats, we only support 536 * TODO: Add support for more output formats, we only support
563 * RGB24 for now. 537 * RGB888 for now
564 * NOTE: the src format is always the same as the sink, except 538 * NOTE: the src format is always the same as the sink, except
565 * for the code 539 * for the code
566 */ 540 */
567 vdeb->set_rgb_src = vimc_deb_set_rgb_pix_rgb24; 541 vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
542 vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
568 543
569 return 0; 544 return 0;
570} 545}
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 *
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index c47454cc7f70..6c53b9fc1617 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -55,13 +55,34 @@ static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
55 return 0; 55 return 0;
56} 56}
57 57
58static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
59 struct v4l2_subdev_pad_config *cfg,
60 struct v4l2_subdev_mbus_code_enum *code)
61{
62 const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
63
64 if (!vpix)
65 return -EINVAL;
66
67 code->code = vpix->code;
68
69 return 0;
70}
71
58static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, 72static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
59 struct v4l2_subdev_pad_config *cfg, 73 struct v4l2_subdev_pad_config *cfg,
60 struct v4l2_subdev_frame_size_enum *fse) 74 struct v4l2_subdev_frame_size_enum *fse)
61{ 75{
76 const struct vimc_pix_map *vpix;
77
62 if (fse->index) 78 if (fse->index)
63 return -EINVAL; 79 return -EINVAL;
64 80
81 /* Only accept code in the pix map table */
82 vpix = vimc_pix_map_by_code(fse->code);
83 if (!vpix)
84 return -EINVAL;
85
65 fse->min_width = VIMC_FRAME_MIN_WIDTH; 86 fse->min_width = VIMC_FRAME_MIN_WIDTH;
66 fse->max_width = VIMC_FRAME_MAX_WIDTH; 87 fse->max_width = VIMC_FRAME_MAX_WIDTH;
67 fse->min_height = VIMC_FRAME_MIN_HEIGHT; 88 fse->min_height = VIMC_FRAME_MIN_HEIGHT;
@@ -86,17 +107,14 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
86 107
87static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) 108static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
88{ 109{
89 u32 pixelformat = vsen->ved.stream->producer_pixfmt; 110 const struct vimc_pix_map *vpix =
90 const struct v4l2_format_info *pix_info; 111 vimc_pix_map_by_code(vsen->mbus_format.code);
91
92 pix_info = v4l2_format_info(pixelformat);
93 112
94 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width, 113 tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
95 vsen->mbus_format.height, vsen->mbus_format.field); 114 vsen->mbus_format.height, vsen->mbus_format.field);
96 tpg_s_bytesperline(&vsen->tpg, 0, 115 tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
97 vsen->mbus_format.width * pix_info->bpp[0]);
98 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height); 116 tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
99 tpg_s_fourcc(&vsen->tpg, pixelformat); 117 tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
100 /* TODO: add support for V4L2_FIELD_ALTERNATE */ 118 /* TODO: add support for V4L2_FIELD_ALTERNATE */
101 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false); 119 tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
102 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace); 120 tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
@@ -107,6 +125,13 @@ static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
107 125
108static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) 126static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
109{ 127{
128 const struct vimc_pix_map *vpix;
129
130 /* Only accept code in the pix map table */
131 vpix = vimc_pix_map_by_code(fmt->code);
132 if (!vpix)
133 fmt->code = fmt_default.code;
134
110 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, 135 fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
111 VIMC_FRAME_MAX_WIDTH) & ~1; 136 VIMC_FRAME_MAX_WIDTH) & ~1;
112 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, 137 fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
@@ -126,9 +151,6 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
126 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); 151 struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
127 struct v4l2_mbus_framefmt *mf; 152 struct v4l2_mbus_framefmt *mf;
128 153
129 if (!vimc_mbus_code_supported(fmt->format.code))
130 fmt->format.code = fmt_default.code;
131
132 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { 154 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
133 /* Do not change the format while stream is on */ 155 /* Do not change the format while stream is on */
134 if (vsen->frame) 156 if (vsen->frame)
@@ -161,7 +183,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
161 183
162static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { 184static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
163 .init_cfg = vimc_sen_init_cfg, 185 .init_cfg = vimc_sen_init_cfg,
164 .enum_mbus_code = vimc_enum_mbus_code, 186 .enum_mbus_code = vimc_sen_enum_mbus_code,
165 .enum_frame_size = vimc_sen_enum_frame_size, 187 .enum_frame_size = vimc_sen_enum_frame_size,
166 .get_fmt = vimc_sen_get_fmt, 188 .get_fmt = vimc_sen_get_fmt,
167 .set_fmt = vimc_sen_set_fmt, 189 .set_fmt = vimc_sen_set_fmt,
@@ -183,8 +205,7 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
183 container_of(sd, struct vimc_sen_device, sd); 205 container_of(sd, struct vimc_sen_device, sd);
184 206
185 if (enable) { 207 if (enable) {
186 u32 pixelformat = vsen->ved.stream->producer_pixfmt; 208 const struct vimc_pix_map *vpix;
187 const struct v4l2_format_info *pix_info;
188 unsigned int frame_size; 209 unsigned int frame_size;
189 210
190 if (vsen->kthread_sen) 211 if (vsen->kthread_sen)
@@ -192,8 +213,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
192 return 0; 213 return 0;
193 214
194 /* Calculate the frame size */ 215 /* Calculate the frame size */
195 pix_info = v4l2_format_info(pixelformat); 216 vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
196 frame_size = vsen->mbus_format.width * pix_info->bpp[0] * 217 frame_size = vsen->mbus_format.width * vpix->bpp *
197 vsen->mbus_format.height; 218 vsen->mbus_format.height;
198 219
199 /* 220 /*
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
index 62dde7d74c24..048d770e498b 100644
--- a/drivers/media/platform/vimc/vimc-streamer.c
+++ b/drivers/media/platform/vimc/vimc-streamer.c
@@ -54,7 +54,6 @@ static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream)
54 while (stream->pipe_size) { 54 while (stream->pipe_size) {
55 stream->pipe_size--; 55 stream->pipe_size--;
56 ved = stream->ved_pipeline[stream->pipe_size]; 56 ved = stream->ved_pipeline[stream->pipe_size];
57 ved->stream = NULL;
58 stream->ved_pipeline[stream->pipe_size] = NULL; 57 stream->ved_pipeline[stream->pipe_size] = NULL;
59 58
60 if (!is_media_entity_v4l2_subdev(ved->ent)) 59 if (!is_media_entity_v4l2_subdev(ved->ent))
@@ -93,7 +92,6 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
93 return -EINVAL; 92 return -EINVAL;
94 } 93 }
95 stream->ved_pipeline[stream->pipe_size++] = ved; 94 stream->ved_pipeline[stream->pipe_size++] = ved;
96 ved->stream = stream;
97 95
98 if (is_media_entity_v4l2_subdev(ved->ent)) { 96 if (is_media_entity_v4l2_subdev(ved->ent)) {
99 sd = media_entity_to_v4l2_subdev(ved->ent); 97 sd = media_entity_to_v4l2_subdev(ved->ent);
diff --git a/drivers/media/platform/vimc/vimc-streamer.h b/drivers/media/platform/vimc/vimc-streamer.h
index d744a787e0e7..fe3c51f15fad 100644
--- a/drivers/media/platform/vimc/vimc-streamer.h
+++ b/drivers/media/platform/vimc/vimc-streamer.h
@@ -25,13 +25,6 @@
25 * processed in the pipeline. 25 * processed in the pipeline.
26 * @pipe_size: size of @ved_pipeline 26 * @pipe_size: size of @ved_pipeline
27 * @kthread: thread that generates the frames of the stream. 27 * @kthread: thread that generates the frames of the stream.
28 * @producer_pixfmt: the pixel format requested from the pipeline. This must
29 * be set just before calling
30 * vimc_streamer_s_stream(ent, 1). This value is propagated
31 * up to the source of the base image (usually a sensor
32 * node) and can be modified by entities during s_stream
33 * callback to request a differentformat from rest of
34 * the pipeline.
35 * 28 *
36 * When the user call stream_on in a video device, struct vimc_stream is 29 * When the user call stream_on in a video device, struct vimc_stream is
37 * used to keep track of all entities and subdevices that generates and 30 * used to keep track of all entities and subdevices that generates and
@@ -42,7 +35,6 @@ struct vimc_stream {
42 struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE]; 35 struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
43 unsigned int pipe_size; 36 unsigned int pipe_size;
44 struct task_struct *kthread; 37 struct task_struct *kthread;
45 u32 producer_pixfmt;
46}; 38};
47 39
48int vimc_streamer_s_stream(struct vimc_stream *stream, 40int vimc_streamer_s_stream(struct vimc_stream *stream,