]> Git Repo - J-linux.git/blob - drivers/media/test-drivers/vimc/vimc-debayer.c
Merge remote-tracking branch 'asoc/for-5.8' into asoc-linus
[J-linux.git] / drivers / media / test-drivers / vimc / vimc-debayer.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * vimc-debayer.c Virtual Media Controller Driver
4  *
5  * Copyright (C) 2015-2017 Helen Koike <[email protected]>
6  */
7
8 #include <linux/moduleparam.h>
9 #include <linux/platform_device.h>
10 #include <linux/vmalloc.h>
11 #include <linux/v4l2-mediabus.h>
12 #include <media/v4l2-ctrls.h>
13 #include <media/v4l2-event.h>
14 #include <media/v4l2-subdev.h>
15
16 #include "vimc-common.h"
17
18 enum vimc_deb_rgb_colors {
19         VIMC_DEB_RED = 0,
20         VIMC_DEB_GREEN = 1,
21         VIMC_DEB_BLUE = 2,
22 };
23
24 struct vimc_deb_pix_map {
25         u32 code;
26         enum vimc_deb_rgb_colors order[2][2];
27 };
28
29 struct vimc_deb_device {
30         struct vimc_ent_device ved;
31         struct v4l2_subdev sd;
32         /* The active format */
33         struct v4l2_mbus_framefmt sink_fmt;
34         u32 src_code;
35         void (*set_rgb_src)(struct vimc_deb_device *vdeb, unsigned int lin,
36                             unsigned int col, unsigned int rgb[3]);
37         /* Values calculated when the stream starts */
38         u8 *src_frame;
39         const struct vimc_deb_pix_map *sink_pix_map;
40         unsigned int sink_bpp;
41         unsigned int mean_win_size;
42         struct v4l2_ctrl_handler hdl;
43         struct media_pad pads[2];
44 };
45
46 static const struct v4l2_mbus_framefmt sink_fmt_default = {
47         .width = 640,
48         .height = 480,
49         .code = MEDIA_BUS_FMT_SRGGB8_1X8,
50         .field = V4L2_FIELD_NONE,
51         .colorspace = V4L2_COLORSPACE_SRGB,
52 };
53
54 static const u32 vimc_deb_src_mbus_codes[] = {
55         MEDIA_BUS_FMT_GBR888_1X24,
56         MEDIA_BUS_FMT_BGR888_1X24,
57         MEDIA_BUS_FMT_BGR888_3X8,
58         MEDIA_BUS_FMT_RGB888_1X24,
59         MEDIA_BUS_FMT_RGB888_2X12_BE,
60         MEDIA_BUS_FMT_RGB888_2X12_LE,
61         MEDIA_BUS_FMT_RGB888_3X8,
62         MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
63         MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
64         MEDIA_BUS_FMT_RGB888_1X32_PADHI,
65 };
66
67 static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = {
68         {
69                 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
70                 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
71                            { VIMC_DEB_GREEN, VIMC_DEB_RED } }
72         },
73         {
74                 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
75                 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
76                            { VIMC_DEB_RED, VIMC_DEB_GREEN } }
77         },
78         {
79                 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
80                 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
81                            { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
82         },
83         {
84                 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
85                 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
86                            { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
87         },
88         {
89                 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
90                 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
91                            { VIMC_DEB_GREEN, VIMC_DEB_RED } }
92         },
93         {
94                 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
95                 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
96                            { VIMC_DEB_RED, VIMC_DEB_GREEN } }
97         },
98         {
99                 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
100                 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
101                            { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
102         },
103         {
104                 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
105                 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
106                            { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
107         },
108         {
109                 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
110                 .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
111                            { VIMC_DEB_GREEN, VIMC_DEB_RED } }
112         },
113         {
114                 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
115                 .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
116                            { VIMC_DEB_RED, VIMC_DEB_GREEN } }
117         },
118         {
119                 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
120                 .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
121                            { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
122         },
123         {
124                 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
125                 .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
126                            { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
127         },
128 };
129
130 static const struct vimc_deb_pix_map *vimc_deb_pix_map_by_code(u32 code)
131 {
132         unsigned int i;
133
134         for (i = 0; i < ARRAY_SIZE(vimc_deb_pix_map_list); i++)
135                 if (vimc_deb_pix_map_list[i].code == code)
136                         return &vimc_deb_pix_map_list[i];
137
138         return NULL;
139 }
140
141 static bool vimc_deb_src_code_is_valid(u32 code)
142 {
143         unsigned int i;
144
145         for (i = 0; i < ARRAY_SIZE(vimc_deb_src_mbus_codes); i++)
146                 if (vimc_deb_src_mbus_codes[i] == code)
147                         return true;
148
149         return false;
150 }
151
152 static int vimc_deb_init_cfg(struct v4l2_subdev *sd,
153                              struct v4l2_subdev_pad_config *cfg)
154 {
155         struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
156         struct v4l2_mbus_framefmt *mf;
157         unsigned int i;
158
159         mf = v4l2_subdev_get_try_format(sd, cfg, 0);
160         *mf = sink_fmt_default;
161
162         for (i = 1; i < sd->entity.num_pads; i++) {
163                 mf = v4l2_subdev_get_try_format(sd, cfg, i);
164                 *mf = sink_fmt_default;
165                 mf->code = vdeb->src_code;
166         }
167
168         return 0;
169 }
170
171 static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd,
172                                    struct v4l2_subdev_pad_config *cfg,
173                                    struct v4l2_subdev_mbus_code_enum *code)
174 {
175         if (VIMC_IS_SRC(code->pad)) {
176                 if (code->index >= ARRAY_SIZE(vimc_deb_src_mbus_codes))
177                         return -EINVAL;
178
179                 code->code = vimc_deb_src_mbus_codes[code->index];
180         } else {
181                 if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list))
182                         return -EINVAL;
183
184                 code->code = vimc_deb_pix_map_list[code->index].code;
185         }
186
187         return 0;
188 }
189
190 static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd,
191                                     struct v4l2_subdev_pad_config *cfg,
192                                     struct v4l2_subdev_frame_size_enum *fse)
193 {
194         if (fse->index)
195                 return -EINVAL;
196
197         if (VIMC_IS_SINK(fse->pad)) {
198                 const struct vimc_deb_pix_map *vpix =
199                         vimc_deb_pix_map_by_code(fse->code);
200
201                 if (!vpix)
202                         return -EINVAL;
203         } else if (!vimc_deb_src_code_is_valid(fse->code)) {
204                 return -EINVAL;
205         }
206
207         fse->min_width = VIMC_FRAME_MIN_WIDTH;
208         fse->max_width = VIMC_FRAME_MAX_WIDTH;
209         fse->min_height = VIMC_FRAME_MIN_HEIGHT;
210         fse->max_height = VIMC_FRAME_MAX_HEIGHT;
211
212         return 0;
213 }
214
215 static int vimc_deb_get_fmt(struct v4l2_subdev *sd,
216                             struct v4l2_subdev_pad_config *cfg,
217                             struct v4l2_subdev_format *fmt)
218 {
219         struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
220
221         /* Get the current sink format */
222         fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
223                       *v4l2_subdev_get_try_format(sd, cfg, 0) :
224                       vdeb->sink_fmt;
225
226         /* Set the right code for the source pad */
227         if (VIMC_IS_SRC(fmt->pad))
228                 fmt->format.code = vdeb->src_code;
229
230         return 0;
231 }
232
233 static void vimc_deb_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
234 {
235         const struct vimc_deb_pix_map *vpix;
236
237         /* Don't accept a code that is not on the debayer table */
238         vpix = vimc_deb_pix_map_by_code(fmt->code);
239         if (!vpix)
240                 fmt->code = sink_fmt_default.code;
241
242         fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
243                              VIMC_FRAME_MAX_WIDTH) & ~1;
244         fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
245                               VIMC_FRAME_MAX_HEIGHT) & ~1;
246
247         if (fmt->field == V4L2_FIELD_ANY)
248                 fmt->field = sink_fmt_default.field;
249
250         vimc_colorimetry_clamp(fmt);
251 }
252
253 static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
254                             struct v4l2_subdev_pad_config *cfg,
255                             struct v4l2_subdev_format *fmt)
256 {
257         struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
258         struct v4l2_mbus_framefmt *sink_fmt;
259         u32 *src_code;
260
261         if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
262                 /* Do not change the format while stream is on */
263                 if (vdeb->src_frame)
264                         return -EBUSY;
265
266                 sink_fmt = &vdeb->sink_fmt;
267                 src_code = &vdeb->src_code;
268         } else {
269                 sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
270                 src_code = &v4l2_subdev_get_try_format(sd, cfg, 1)->code;
271         }
272
273         /*
274          * Do not change the format of the source pad,
275          * it is propagated from the sink
276          */
277         if (VIMC_IS_SRC(fmt->pad)) {
278                 u32 code = fmt->format.code;
279
280                 fmt->format = *sink_fmt;
281
282                 if (vimc_deb_src_code_is_valid(code))
283                         *src_code = code;
284
285                 fmt->format.code = *src_code;
286         } else {
287                 /* Set the new format in the sink pad */
288                 vimc_deb_adjust_sink_fmt(&fmt->format);
289
290                 dev_dbg(vdeb->ved.dev, "%s: sink format update: "
291                         "old:%dx%d (0x%x, %d, %d, %d, %d) "
292                         "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vdeb->sd.name,
293                         /* old */
294                         sink_fmt->width, sink_fmt->height, sink_fmt->code,
295                         sink_fmt->colorspace, sink_fmt->quantization,
296                         sink_fmt->xfer_func, sink_fmt->ycbcr_enc,
297                         /* new */
298                         fmt->format.width, fmt->format.height, fmt->format.code,
299                         fmt->format.colorspace, fmt->format.quantization,
300                         fmt->format.xfer_func, fmt->format.ycbcr_enc);
301
302                 *sink_fmt = fmt->format;
303         }
304
305         return 0;
306 }
307
308 static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = {
309         .init_cfg               = vimc_deb_init_cfg,
310         .enum_mbus_code         = vimc_deb_enum_mbus_code,
311         .enum_frame_size        = vimc_deb_enum_frame_size,
312         .get_fmt                = vimc_deb_get_fmt,
313         .set_fmt                = vimc_deb_set_fmt,
314 };
315
316 static void vimc_deb_process_rgb_frame(struct vimc_deb_device *vdeb,
317                                        unsigned int lin,
318                                        unsigned int col,
319                                        unsigned int rgb[3])
320 {
321         const struct vimc_pix_map *vpix;
322         unsigned int i, index;
323
324         vpix = vimc_pix_map_by_code(vdeb->src_code);
325         index = VIMC_FRAME_INDEX(lin, col, vdeb->sink_fmt.width, 3);
326         for (i = 0; i < 3; i++) {
327                 switch (vpix->pixelformat) {
328                 case V4L2_PIX_FMT_RGB24:
329                         vdeb->src_frame[index + i] = rgb[i];
330                         break;
331                 case V4L2_PIX_FMT_BGR24:
332                         vdeb->src_frame[index + i] = rgb[2 - i];
333                         break;
334                 }
335         }
336 }
337
338 static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
339 {
340         struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
341
342         if (enable) {
343                 const struct vimc_pix_map *vpix;
344                 unsigned int frame_size;
345
346                 if (vdeb->src_frame)
347                         return 0;
348
349                 /* Calculate the frame size of the source pad */
350                 vpix = vimc_pix_map_by_code(vdeb->src_code);
351                 frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
352                                 vpix->bpp;
353
354                 /* Save the bytes per pixel of the sink */
355                 vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code);
356                 vdeb->sink_bpp = vpix->bpp;
357
358                 /* Get the corresponding pixel map from the table */
359                 vdeb->sink_pix_map =
360                         vimc_deb_pix_map_by_code(vdeb->sink_fmt.code);
361
362                 /*
363                  * Allocate the frame buffer. Use vmalloc to be able to
364                  * allocate a large amount of memory
365                  */
366                 vdeb->src_frame = vmalloc(frame_size);
367                 if (!vdeb->src_frame)
368                         return -ENOMEM;
369
370         } else {
371                 if (!vdeb->src_frame)
372                         return 0;
373
374                 vfree(vdeb->src_frame);
375                 vdeb->src_frame = NULL;
376         }
377
378         return 0;
379 }
380
381 static const struct v4l2_subdev_core_ops vimc_deb_core_ops = {
382         .log_status = v4l2_ctrl_subdev_log_status,
383         .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
384         .unsubscribe_event = v4l2_event_subdev_unsubscribe,
385 };
386
387 static const struct v4l2_subdev_video_ops vimc_deb_video_ops = {
388         .s_stream = vimc_deb_s_stream,
389 };
390
391 static const struct v4l2_subdev_ops vimc_deb_ops = {
392         .core = &vimc_deb_core_ops,
393         .pad = &vimc_deb_pad_ops,
394         .video = &vimc_deb_video_ops,
395 };
396
397 static unsigned int vimc_deb_get_val(const u8 *bytes,
398                                      const unsigned int n_bytes)
399 {
400         unsigned int i;
401         unsigned int acc = 0;
402
403         for (i = 0; i < n_bytes; i++)
404                 acc = acc + (bytes[i] << (8 * i));
405
406         return acc;
407 }
408
409 static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
410                                    const u8 *frame,
411                                    const unsigned int lin,
412                                    const unsigned int col,
413                                    unsigned int rgb[3])
414 {
415         unsigned int i, seek, wlin, wcol;
416         unsigned int n_rgb[3] = {0, 0, 0};
417
418         for (i = 0; i < 3; i++)
419                 rgb[i] = 0;
420
421         /*
422          * Calculate how many we need to subtract to get to the pixel in
423          * the top left corner of the mean window (considering the current
424          * pixel as the center)
425          */
426         seek = vdeb->mean_win_size / 2;
427
428         /* Sum the values of the colors in the mean window */
429
430         dev_dbg(vdeb->ved.dev,
431                 "deb: %s: --- Calc pixel %dx%d, window mean %d, seek %d ---\n",
432                 vdeb->sd.name, lin, col, vdeb->sink_fmt.height, seek);
433
434         /*
435          * Iterate through all the lines in the mean window, start
436          * with zero if the pixel is outside the frame and don't pass
437          * the height when the pixel is in the bottom border of the
438          * frame
439          */
440         for (wlin = seek > lin ? 0 : lin - seek;
441              wlin < lin + seek + 1 && wlin < vdeb->sink_fmt.height;
442              wlin++) {
443
444                 /*
445                  * Iterate through all the columns in the mean window, start
446                  * with zero if the pixel is outside the frame and don't pass
447                  * the width when the pixel is in the right border of the
448                  * frame
449                  */
450                 for (wcol = seek > col ? 0 : col - seek;
451                      wcol < col + seek + 1 && wcol < vdeb->sink_fmt.width;
452                      wcol++) {
453                         enum vimc_deb_rgb_colors color;
454                         unsigned int index;
455
456                         /* Check which color this pixel is */
457                         color = vdeb->sink_pix_map->order[wlin % 2][wcol % 2];
458
459                         index = VIMC_FRAME_INDEX(wlin, wcol,
460                                                  vdeb->sink_fmt.width,
461                                                  vdeb->sink_bpp);
462
463                         dev_dbg(vdeb->ved.dev,
464                                 "deb: %s: RGB CALC: frame index %d, win pos %dx%d, color %d\n",
465                                 vdeb->sd.name, index, wlin, wcol, color);
466
467                         /* Get its value */
468                         rgb[color] = rgb[color] +
469                                 vimc_deb_get_val(&frame[index], vdeb->sink_bpp);
470
471                         /* Save how many values we already added */
472                         n_rgb[color]++;
473
474                         dev_dbg(vdeb->ved.dev, "deb: %s: RGB CALC: val %d, n %d\n",
475                                 vdeb->sd.name, rgb[color], n_rgb[color]);
476                 }
477         }
478
479         /* Calculate the mean */
480         for (i = 0; i < 3; i++) {
481                 dev_dbg(vdeb->ved.dev,
482                         "deb: %s: PRE CALC: %dx%d Color %d, val %d, n %d\n",
483                         vdeb->sd.name, lin, col, i, rgb[i], n_rgb[i]);
484
485                 if (n_rgb[i])
486                         rgb[i] = rgb[i] / n_rgb[i];
487
488                 dev_dbg(vdeb->ved.dev,
489                         "deb: %s: FINAL CALC: %dx%d Color %d, val %d\n",
490                         vdeb->sd.name, lin, col, i, rgb[i]);
491         }
492 }
493
494 static void *vimc_deb_process_frame(struct vimc_ent_device *ved,
495                                     const void *sink_frame)
496 {
497         struct vimc_deb_device *vdeb = container_of(ved, struct vimc_deb_device,
498                                                     ved);
499         unsigned int rgb[3];
500         unsigned int i, j;
501
502         /* If the stream in this node is not active, just return */
503         if (!vdeb->src_frame)
504                 return ERR_PTR(-EINVAL);
505
506         for (i = 0; i < vdeb->sink_fmt.height; i++)
507                 for (j = 0; j < vdeb->sink_fmt.width; j++) {
508                         vimc_deb_calc_rgb_sink(vdeb, sink_frame, i, j, rgb);
509                         vdeb->set_rgb_src(vdeb, i, j, rgb);
510                 }
511
512         return vdeb->src_frame;
513 }
514
515 static int vimc_deb_s_ctrl(struct v4l2_ctrl *ctrl)
516 {
517         struct vimc_deb_device *vdeb =
518                 container_of(ctrl->handler, struct vimc_deb_device, hdl);
519
520         switch (ctrl->id) {
521         case VIMC_CID_MEAN_WIN_SIZE:
522                 vdeb->mean_win_size = ctrl->val;
523                 break;
524         default:
525                 return -EINVAL;
526         }
527         return 0;
528 }
529
530 static const struct v4l2_ctrl_ops vimc_deb_ctrl_ops = {
531         .s_ctrl = vimc_deb_s_ctrl,
532 };
533
534 static void vimc_deb_release(struct vimc_ent_device *ved)
535 {
536         struct vimc_deb_device *vdeb =
537                 container_of(ved, struct vimc_deb_device, ved);
538
539         v4l2_ctrl_handler_free(&vdeb->hdl);
540         media_entity_cleanup(vdeb->ved.ent);
541         kfree(vdeb);
542 }
543
544 static const struct v4l2_ctrl_config vimc_deb_ctrl_class = {
545         .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
546         .id = VIMC_CID_VIMC_CLASS,
547         .name = "VIMC Controls",
548         .type = V4L2_CTRL_TYPE_CTRL_CLASS,
549 };
550
551 static const struct v4l2_ctrl_config vimc_deb_ctrl_mean_win_size = {
552         .ops = &vimc_deb_ctrl_ops,
553         .id = VIMC_CID_MEAN_WIN_SIZE,
554         .name = "Debayer Mean Window Size",
555         .type = V4L2_CTRL_TYPE_INTEGER,
556         .min = 1,
557         .max = 25,
558         .step = 2,
559         .def = 3,
560 };
561
562 static struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
563                                             const char *vcfg_name)
564 {
565         struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
566         struct vimc_deb_device *vdeb;
567         int ret;
568
569         /* Allocate the vdeb struct */
570         vdeb = kzalloc(sizeof(*vdeb), GFP_KERNEL);
571         if (!vdeb)
572                 return ERR_PTR(-ENOMEM);
573
574         /* Create controls: */
575         v4l2_ctrl_handler_init(&vdeb->hdl, 2);
576         v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_class, NULL);
577         v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_mean_win_size, NULL);
578         vdeb->sd.ctrl_handler = &vdeb->hdl;
579         if (vdeb->hdl.error) {
580                 ret = vdeb->hdl.error;
581                 goto err_free_vdeb;
582         }
583
584         /* Initialize ved and sd */
585         vdeb->pads[0].flags = MEDIA_PAD_FL_SINK;
586         vdeb->pads[1].flags = MEDIA_PAD_FL_SOURCE;
587
588         ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
589                                    vcfg_name,
590                                    MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
591                                    vdeb->pads, &vimc_deb_ops);
592         if (ret)
593                 goto err_free_hdl;
594
595         vdeb->ved.process_frame = vimc_deb_process_frame;
596         vdeb->ved.dev = vimc->mdev.dev;
597         vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def;
598
599         /* Initialize the frame format */
600         vdeb->sink_fmt = sink_fmt_default;
601         /*
602          * TODO: Add support for more output formats, we only support
603          * RGB888 for now
604          * NOTE: the src format is always the same as the sink, except
605          * for the code
606          */
607         vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
608         vdeb->set_rgb_src = vimc_deb_process_rgb_frame;
609
610         return &vdeb->ved;
611
612 err_free_hdl:
613         v4l2_ctrl_handler_free(&vdeb->hdl);
614 err_free_vdeb:
615         kfree(vdeb);
616
617         return ERR_PTR(ret);
618 }
619
620 struct vimc_ent_type vimc_deb_type = {
621         .add = vimc_deb_add,
622         .release = vimc_deb_release
623 };
This page took 0.066643 seconds and 4 git commands to generate.