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