static int brx_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { struct vsp1_brx *brx = to_brx(subdev); struct v4l2_subdev_pad_config *config; if (sel->pad == brx->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 = BRX_MAX_SIZE; sel->r.height = BRX_MAX_SIZE; return 0; case V4L2_SEL_TGT_COMPOSE: config = vsp1_entity_get_pad_config(&brx->entity, cfg, sel->which); if (!config) return -EINVAL; mutex_lock(&brx->entity.lock); sel->r = *brx_get_compose(brx, config, sel->pad); mutex_unlock(&brx->entity.lock); return 0; default: return -EINVAL; } }
static int histo_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); struct v4l2_subdev_pad_config *config; int ret; if (sel->pad != HISTO_PAD_SINK) return -EINVAL; mutex_lock(&histo->entity.lock); config = vsp1_entity_get_pad_config(&histo->entity, cfg, sel->which); if (!config) { ret = -EINVAL; goto done; } if (sel->target == V4L2_SEL_TGT_CROP) ret = histo_set_crop(subdev, config, sel); else if (sel->target == V4L2_SEL_TGT_COMPOSE) ret = histo_set_compose(subdev, config, sel); else ret = -EINVAL; done: mutex_unlock(&histo->entity.lock); return ret; }
static int histo_get_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; int ret = 0; if (sel->pad != HISTO_PAD_SINK) return -EINVAL; mutex_lock(&histo->entity.lock); config = vsp1_entity_get_pad_config(&histo->entity, cfg, sel->which); if (!config) { ret = -EINVAL; goto done; } switch (sel->target) { case V4L2_SEL_TGT_COMPOSE_BOUNDS: case V4L2_SEL_TGT_COMPOSE_DEFAULT: crop = vsp1_entity_get_pad_selection(&histo->entity, config, HISTO_PAD_SINK, V4L2_SEL_TGT_CROP); sel->r.left = 0; sel->r.top = 0; sel->r.width = crop->width; sel->r.height = crop->height; break; case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_CROP_DEFAULT: format = vsp1_entity_get_pad_format(&histo->entity, config, HISTO_PAD_SINK); sel->r.left = 0; sel->r.top = 0; sel->r.width = format->width; sel->r.height = format->height; break; case V4L2_SEL_TGT_COMPOSE: case V4L2_SEL_TGT_CROP: sel->r = *vsp1_entity_get_pad_selection(&histo->entity, config, sel->pad, sel->target); break; default: ret = -EINVAL; break; } done: mutex_unlock(&histo->entity.lock); return ret; }
static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct vsp1_lut *lut = to_lut(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&lut->entity.lock); config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which); if (!config) { ret = -EINVAL; goto done; } /* Default to YUV if the requested format is not supported. */ if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 && fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad); if (fmt->pad == LUT_PAD_SOURCE) { /* The LUT output format can't be modified. */ fmt->format = *format; goto done; } format->code = fmt->format.code; format->width = clamp_t(unsigned int, fmt->format.width, LUT_MIN_SIZE, LUT_MAX_SIZE); format->height = clamp_t(unsigned int, fmt->format.height, LUT_MIN_SIZE, LUT_MAX_SIZE); format->field = V4L2_FIELD_NONE; format->colorspace = V4L2_COLORSPACE_SRGB; fmt->format = *format; /* Propagate the format to the source pad. */ format = vsp1_entity_get_pad_format(&lut->entity, config, LUT_PAD_SOURCE); *format = fmt->format; done: mutex_unlock(&lut->entity.lock); return ret; }
static int brx_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { struct vsp1_brx *brx = to_brx(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; struct v4l2_rect *compose; int ret = 0; if (sel->pad == brx->entity.source_pad) return -EINVAL; if (sel->target != V4L2_SEL_TGT_COMPOSE) return -EINVAL; mutex_lock(&brx->entity.lock); config = vsp1_entity_get_pad_config(&brx->entity, cfg, sel->which); if (!config) { ret = -EINVAL; goto done; } /* * The compose rectangle top left corner must be inside the output * frame. */ format = vsp1_entity_get_pad_format(&brx->entity, config, brx->entity.source_pad); 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(&brx->entity, config, sel->pad); sel->r.width = format->width; sel->r.height = format->height; compose = brx_get_compose(brx, config, sel->pad); *compose = sel->r; done: mutex_unlock(&brx->entity.lock); return ret; }
static int brx_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct vsp1_brx *brx = to_brx(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&brx->entity.lock); config = vsp1_entity_get_pad_config(&brx->entity, cfg, fmt->which); if (!config) { ret = -EINVAL; goto done; } brx_try_format(brx, config, fmt->pad, &fmt->format); format = vsp1_entity_get_pad_format(&brx->entity, config, fmt->pad); *format = fmt->format; /* Reset the compose rectangle */ if (fmt->pad != brx->entity.source_pad) { struct v4l2_rect *compose; compose = brx_get_compose(brx, 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 == BRX_PAD_SINK(0)) { unsigned int i; for (i = 0; i <= brx->entity.source_pad; ++i) { format = vsp1_entity_get_pad_format(&brx->entity, config, i); format->code = fmt->format.code; } } done: mutex_unlock(&brx->entity.lock); return ret; }
static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct vsp1_lif *lif = to_lif(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which); if (!config) return -EINVAL; /* Default to YUV if the requested format is not supported. */ if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad); if (fmt->pad == LIF_PAD_SOURCE) { /* The LIF source format is always identical to its sink * format. */ fmt->format = *format; return 0; } format->code = fmt->format.code; format->width = clamp_t(unsigned int, fmt->format.width, LIF_MIN_SIZE, LIF_MAX_SIZE); format->height = clamp_t(unsigned int, fmt->format.height, LIF_MIN_SIZE, LIF_MAX_SIZE); format->field = V4L2_FIELD_NONE; format->colorspace = V4L2_COLORSPACE_SRGB; fmt->format = *format; /* Propagate the format to the source pad. */ format = vsp1_entity_get_pad_format(&lif->entity, config, LIF_PAD_SOURCE); *format = fmt->format; return 0; }
static int clu_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct vsp1_clu *clu = to_clu(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which); if (!config) return -EINVAL; /* Default to YUV if the requested format is not supported. */ if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 && fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 && fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad); if (fmt->pad == CLU_PAD_SOURCE) { /* The CLU output format can't be modified. */ fmt->format = *format; return 0; } format->code = fmt->format.code; format->width = clamp_t(unsigned int, fmt->format.width, CLU_MIN_SIZE, CLU_MAX_SIZE); format->height = clamp_t(unsigned int, fmt->format.height, CLU_MIN_SIZE, CLU_MAX_SIZE); format->field = V4L2_FIELD_NONE; format->colorspace = V4L2_COLORSPACE_SRGB; fmt->format = *format; /* Propagate the format to the source pad. */ format = vsp1_entity_get_pad_format(&clu->entity, config, CLU_PAD_SOURCE); *format = fmt->format; return 0; }
static int hsit_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct vsp1_hsit *hsit = to_hsit(subdev); struct v4l2_subdev_pad_config *config; struct v4l2_mbus_framefmt *format; config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fmt->which); if (!config) return -EINVAL; format = vsp1_entity_get_pad_format(&hsit->entity, config, fmt->pad); if (fmt->pad == HSIT_PAD_SOURCE) { /* The HST and HSI output format code and resolution can't be * modified. */ fmt->format = *format; return 0; } format->code = hsit->inverse ? MEDIA_BUS_FMT_AHSV8888_1X32 : MEDIA_BUS_FMT_ARGB8888_1X32; format->width = clamp_t(unsigned int, fmt->format.width, HSIT_MIN_SIZE, HSIT_MAX_SIZE); format->height = clamp_t(unsigned int, fmt->format.height, HSIT_MIN_SIZE, HSIT_MAX_SIZE); format->field = V4L2_FIELD_NONE; format->colorspace = V4L2_COLORSPACE_SRGB; fmt->format = *format; /* Propagate the format to the source pad. */ format = vsp1_entity_get_pad_format(&hsit->entity, config, HSIT_PAD_SOURCE); *format = fmt->format; format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32 : MEDIA_BUS_FMT_AHSV8888_1X32; return 0; }