Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e790c3cb authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[media] v4l: vsp1: Store active formats in a pad config structure



Add a pad config structure field to the vsp1_entity structure and use it
to store all active pad formats. This generalizes the code to operate on
pad config structures.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 0efdf0f5
Loading
Loading
Loading
Loading
+39 −20
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
	if (!enable)
		return 0;

	format = &bru->entity.formats[bru->entity.source_pad];
	format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config,
					    bru->entity.source_pad);

	/* The hardware is extremely flexible but we have no userspace API to
	 * expose all the parameters, nor is it clear whether we would have use
@@ -183,7 +184,6 @@ static int bru_enum_mbus_code(struct v4l2_subdev *subdev,
		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))
@@ -191,12 +191,19 @@ static int bru_enum_mbus_code(struct v4l2_subdev *subdev,

		code->code = codes[code->index];
	} else {
		struct v4l2_subdev_pad_config *config;
		struct v4l2_mbus_framefmt *format;

		if (code->index)
			return -EINVAL;

		format = vsp1_entity_get_pad_format(&bru->entity, cfg,
						    BRU_PAD_SINK(0),
		config = vsp1_entity_get_pad_config(&bru->entity, cfg,
						    code->which);
		if (!config)
			return -EINVAL;

		format = vsp1_entity_get_pad_format(&bru->entity, config,
						    BRU_PAD_SINK(0));
		code->code = format->code;
	}

@@ -242,17 +249,21 @@ static int bru_get_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_bru *bru = to_bru(subdev);
	struct v4l2_subdev_pad_config *config;

	config = vsp1_entity_get_pad_config(&bru->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	fmt->format = *vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
						  fmt->which);
	fmt->format = *vsp1_entity_get_pad_format(&bru->entity, config,
						  fmt->pad);

	return 0;
}

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_subdev_pad_config *config,
			   unsigned int pad, struct v4l2_mbus_framefmt *fmt)
{
	struct v4l2_mbus_framefmt *format;

@@ -266,8 +277,8 @@ static void bru_try_format(struct vsp1_bru *bru,

	default:
		/* The BRU can't perform format conversion. */
		format = vsp1_entity_get_pad_format(&bru->entity, cfg,
						    BRU_PAD_SINK(0), which);
		format = vsp1_entity_get_pad_format(&bru->entity, config,
						    BRU_PAD_SINK(0));
		fmt->code = format->code;
		break;
	}
@@ -283,12 +294,16 @@ static int bru_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_bru *bru = to_bru(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	bru_try_format(bru, cfg, fmt->pad, &fmt->format, fmt->which);
	config = vsp1_entity_get_pad_config(&bru->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	bru_try_format(bru, config, fmt->pad, &fmt->format);

	format = vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
					    fmt->which);
	format = vsp1_entity_get_pad_format(&bru->entity, config, fmt->pad);
	*format = fmt->format;

	/* Reset the compose rectangle */
@@ -307,8 +322,8 @@ static int bru_set_format(struct v4l2_subdev *subdev,
		unsigned int i;

		for (i = 0; i <= bru->entity.source_pad; ++i) {
			format = vsp1_entity_get_pad_format(&bru->entity, cfg,
							    i, fmt->which);
			format = vsp1_entity_get_pad_format(&bru->entity,
							    config, i);
			format->code = fmt->format.code;
		}
	}
@@ -347,6 +362,7 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
			     struct v4l2_subdev_selection *sel)
{
	struct vsp1_bru *bru = to_bru(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *compose;

@@ -356,19 +372,22 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
	if (sel->target != V4L2_SEL_TGT_COMPOSE)
		return -EINVAL;

	config = vsp1_entity_get_pad_config(&bru->entity, cfg, sel->which);
	if (!config)
		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);
	format = vsp1_entity_get_pad_format(&bru->entity, config,
					    bru->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(&bru->entity, cfg, sel->pad,
					    sel->which);
	format = vsp1_entity_get_pad_format(&bru->entity, config, sel->pad);
	sel->r.width = format->width;
	sel->r.height = format->height;

+45 −15
Original line number Diff line number Diff line
@@ -46,19 +46,46 @@ void vsp1_entity_route_setup(struct vsp1_entity *source)
 * V4L2 Subdevice Operations
 */

struct v4l2_mbus_framefmt *
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
/**
 * vsp1_entity_get_pad_config - Get the pad configuration for an entity
 * @entity: the entity
 * @cfg: the TRY pad configuration
 * @which: configuration selector (ACTIVE or TRY)
 *
 * Return the pad configuration requested by the which argument. The TRY
 * configuration is passed explicitly to the function through the cfg argument
 * and simply returned when requested. The ACTIVE configuration comes from the
 * entity structure.
 */
struct v4l2_subdev_pad_config *
vsp1_entity_get_pad_config(struct vsp1_entity *entity,
			   struct v4l2_subdev_pad_config *cfg,
			   unsigned int pad, u32 which)
			   enum v4l2_subdev_format_whence which)
{
	switch (which) {
	case V4L2_SUBDEV_FORMAT_TRY:
		return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad);
	case V4L2_SUBDEV_FORMAT_ACTIVE:
		return &entity->formats[pad];
		return entity->config;
	case V4L2_SUBDEV_FORMAT_TRY:
	default:
		return NULL;
		return cfg;
	}
}

/**
 * vsp1_entity_get_pad_format - Get a pad format from storage for an entity
 * @entity: the entity
 * @cfg: the configuration storage
 * @pad: the pad number
 *
 * Return the format stored in the given configuration for an entity's pad. The
 * configuration can be an ACTIVE or TRY configuration.
 */
struct v4l2_mbus_framefmt *
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
			   struct v4l2_subdev_pad_config *cfg,
			   unsigned int pad)
{
	return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad);
}

/*
@@ -169,19 +196,12 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
	entity->vsp1 = vsp1;
	entity->source_pad = num_pads - 1;

	/* Allocate formats and pads. */
	entity->formats = devm_kzalloc(vsp1->dev,
				       num_pads * sizeof(*entity->formats),
				       GFP_KERNEL);
	if (entity->formats == NULL)
		return -ENOMEM;

	/* Allocate and initialize pads. */
	entity->pads = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->pads),
				    GFP_KERNEL);
	if (entity->pads == NULL)
		return -ENOMEM;

	/* Initialize pads. */
	for (i = 0; i < num_pads - 1; ++i)
		entity->pads[i].flags = MEDIA_PAD_FL_SINK;

@@ -205,6 +225,15 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,

	vsp1_entity_init_cfg(subdev, NULL);

	/* Allocate the pad configuration to store formats and selection
	 * rectangles.
	 */
	entity->config = v4l2_subdev_alloc_pad_config(&entity->subdev);
	if (entity->config == NULL) {
		media_entity_cleanup(&entity->subdev.entity);
		return -ENOMEM;
	}

	return 0;
}

@@ -214,5 +243,6 @@ void vsp1_entity_destroy(struct vsp1_entity *entity)
		entity->ops->destroy(entity);
	if (entity->subdev.ctrl_handler)
		v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
	v4l2_subdev_free_pad_config(entity->config);
	media_entity_cleanup(&entity->subdev.entity);
}
+6 −2
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ struct vsp1_entity {
	unsigned int sink_pad;

	struct v4l2_subdev subdev;
	struct v4l2_mbus_framefmt *formats;
	struct v4l2_subdev_pad_config *config;
};

static inline struct vsp1_entity *to_vsp1_entity(struct v4l2_subdev *subdev)
@@ -103,10 +103,14 @@ int vsp1_entity_link_setup(struct media_entity *entity,
			   const struct media_pad *local,
			   const struct media_pad *remote, u32 flags);

struct v4l2_subdev_pad_config *
vsp1_entity_get_pad_config(struct vsp1_entity *entity,
			   struct v4l2_subdev_pad_config *cfg,
			   enum v4l2_subdev_format_whence which);
struct v4l2_mbus_framefmt *
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
			   struct v4l2_subdev_pad_config *cfg,
			   unsigned int pad, u32 which);
			   unsigned int pad);
int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
			 struct v4l2_subdev_pad_config *cfg);

+21 −8
Original line number Diff line number Diff line
@@ -77,10 +77,14 @@ static int hsit_enum_frame_size(struct v4l2_subdev *subdev,
				struct v4l2_subdev_frame_size_enum *fse)
{
	struct vsp1_hsit *hsit = to_hsit(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fse->pad,
					    fse->which);
	config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fse->which);
	if (!config)
		return -EINVAL;

	format = vsp1_entity_get_pad_format(&hsit->entity, config, fse->pad);

	if (fse->index || fse->code != format->code)
		return -EINVAL;
@@ -108,9 +112,14 @@ static int hsit_get_format(struct v4l2_subdev *subdev,
			   struct v4l2_subdev_format *fmt)
{
	struct vsp1_hsit *hsit = to_hsit(subdev);
	struct v4l2_subdev_pad_config *config;

	config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad,
						  fmt->which);
	fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, config,
						  fmt->pad);

	return 0;
}
@@ -120,10 +129,14 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
			   struct v4l2_subdev_format *fmt)
{
	struct vsp1_hsit *hsit = to_hsit(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad,
					    fmt->which);
	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
@@ -145,8 +158,8 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&hsit->entity, cfg, HSIT_PAD_SOURCE,
					    fmt->which);
	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;
+31 −11
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@ static int lif_s_stream(struct v4l2_subdev *subdev, int enable)
		return 0;
	}

	format = &lif->entity.formats[LIF_PAD_SOURCE];
	format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
					    LIF_PAD_SOURCE);

	obth = min(obth, (format->width + 1) / 2 * format->height - 4);

@@ -84,6 +85,7 @@ static int lif_enum_mbus_code(struct v4l2_subdev *subdev,

		code->code = codes[code->index];
	} else {
		struct v4l2_subdev_pad_config *config;
		struct v4l2_mbus_framefmt *format;

		/* The LIF can't perform format conversion, the sink format is
@@ -92,8 +94,13 @@ static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
		if (code->index)
			return -EINVAL;

		format = vsp1_entity_get_pad_format(&lif->entity, cfg,
						    LIF_PAD_SINK, code->which);
		config = vsp1_entity_get_pad_config(&lif->entity, cfg,
						    code->which);
		if (!config)
			return -EINVAL;

		format = vsp1_entity_get_pad_format(&lif->entity, config,
						    LIF_PAD_SINK);
		code->code = format->code;
	}

@@ -105,10 +112,14 @@ static int lif_enum_frame_size(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_frame_size_enum *fse)
{
	struct vsp1_lif *lif = to_lif(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SINK,
					    fse->which);
	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fse->which);
	if (!config)
		return -EINVAL;

	format = vsp1_entity_get_pad_format(&lif->entity, config, LIF_PAD_SINK);

	if (fse->index || fse->code != format->code)
		return -EINVAL;
@@ -133,9 +144,14 @@ static int lif_get_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_lif *lif = to_lif(subdev);
	struct v4l2_subdev_pad_config *config;

	fmt->format = *vsp1_entity_get_pad_format(&lif->entity, cfg, fmt->pad,
						  fmt->which);
	config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	fmt->format = *vsp1_entity_get_pad_format(&lif->entity, config,
						  fmt->pad);

	return 0;
}
@@ -145,15 +161,19 @@ static int lif_set_format(struct v4l2_subdev *subdev,
			  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, cfg, fmt->pad,
					    fmt->which);
	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
@@ -174,8 +194,8 @@ static int lif_set_format(struct v4l2_subdev *subdev,
	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SOURCE,
					    fmt->which);
	format = vsp1_entity_get_pad_format(&lif->entity, config,
					    LIF_PAD_SOURCE);
	*format = fmt->format;

	return 0;
Loading