static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_pad_config *cfg, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { struct v4l2_mbus_framefmt *format; switch (pad) { case BRU_PAD_SINK(0): /* Default to YUV if the requested format is not supported. */ if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 && fmt->code != MEDIA_BUS_FMT_AYUV8_1X32) fmt->code = MEDIA_BUS_FMT_AYUV8_1X32; break; default: /* The BRU can't perform format conversion. */ format = vsp1_entity_get_pad_format(&bru->entity, cfg, BRU_PAD_SINK(0), which); fmt->code = format->code; break; } fmt->width = clamp(fmt->width, BRU_MIN_SIZE, BRU_MAX_SIZE); fmt->height = clamp(fmt->height, BRU_MIN_SIZE, BRU_MAX_SIZE); fmt->field = V4L2_FIELD_NONE; fmt->colorspace = V4L2_COLORSPACE_SRGB; }
static int bru_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { MEDIA_BUS_FMT_ARGB8888_1X32, MEDIA_BUS_FMT_AYUV8_1X32, }; struct vsp1_bru *bru = to_bru(subdev); struct v4l2_mbus_framefmt *format; if (code->pad == BRU_PAD_SINK(0)) { if (code->index >= ARRAY_SIZE(codes)) return -EINVAL; code->code = codes[code->index]; } else { if (code->index) return -EINVAL; format = vsp1_entity_get_pad_format(&bru->entity, cfg, BRU_PAD_SINK(0), code->which); code->code = format->code; } return 0; }
static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct vsp1_bru *bru = to_bru(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&bru->entity.lock); config = vsp1_entity_get_pad_config(&bru->entity, cfg, fmt->which); if (!config) { ret = -EINVAL; goto done; } bru_try_format(bru, config, fmt->pad, &fmt->format); format = vsp1_entity_get_pad_format(&bru->entity, config, fmt->pad); *format = fmt->format; /* Reset the compose rectangle */ if (fmt->pad != bru->entity.source_pad) { struct v4l2_rect *compose; compose = bru_get_compose(bru, config, fmt->pad); compose->left = 0; compose->top = 0; compose->width = format->width; compose->height = format->height; } /* Propagate the format code to all pads */ if (fmt->pad == BRU_PAD_SINK(0)) { unsigned int i; for (i = 0; i <= bru->entity.source_pad; ++i) { format = vsp1_entity_get_pad_format(&bru->entity, config, i); format->code = fmt->format.code; } } done: mutex_unlock(&bru->entity.lock); return ret; }
static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct vsp1_bru *bru = to_bru(subdev); struct v4l2_mbus_framefmt *format; bru_try_format(bru, cfg, fmt->pad, &fmt->format, fmt->which); format = vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad, fmt->which); *format = fmt->format; /* Reset the compose rectangle */ if (fmt->pad != BRU_PAD_SOURCE) { struct v4l2_rect *compose; compose = bru_get_compose(bru, cfg, fmt->pad, fmt->which); compose->left = 0; compose->top = 0; compose->width = format->width; compose->height = format->height; } /* Propagate the format code to all pads */ if (fmt->pad == BRU_PAD_SINK(0)) { unsigned int i; for (i = 0; i <= BRU_PAD_SOURCE; ++i) { format = vsp1_entity_get_pad_format(&bru->entity, cfg, i, fmt->which); format->code = fmt->format.code; } } return 0; }