static int bru_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { struct vsp1_bru *bru = to_bru(subdev); struct v4l2_mbus_framefmt *format; struct v4l2_rect *compose; if (sel->pad == bru->entity.source_pad) return -EINVAL; if (sel->target != V4L2_SEL_TGT_COMPOSE) return -EINVAL; /* The compose rectangle top left corner must be inside the output * frame. */ format = vsp1_entity_get_pad_format(&bru->entity, cfg, bru->entity.source_pad, sel->which); sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); /* Scaling isn't supported, the compose rectangle size must be identical * to the sink format size. */ format = vsp1_entity_get_pad_format(&bru->entity, cfg, sel->pad, sel->which); sel->r.width = format->width; sel->r.height = format->height; compose = bru_get_compose(bru, cfg, sel->pad, sel->which); *compose = sel->r; return 0; }
static int bru_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { struct vsp1_bru *bru = to_bru(subdev); if (sel->pad == bru->entity.source_pad) return -EINVAL; switch (sel->target) { case V4L2_SEL_TGT_COMPOSE_BOUNDS: sel->r.left = 0; sel->r.top = 0; sel->r.width = BRU_MAX_SIZE; sel->r.height = BRU_MAX_SIZE; return 0; case V4L2_SEL_TGT_COMPOSE: sel->r = *bru_get_compose(bru, cfg, sel->pad, sel->which); return 0; default: return -EINVAL; } }
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; }