[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: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
0efdf0f5ea
commit
e790c3cb8d
|
@ -70,7 +70,8 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
if (!enable)
|
if (!enable)
|
||||||
return 0;
|
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
|
/* 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
|
* 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,
|
MEDIA_BUS_FMT_AYUV8_1X32,
|
||||||
};
|
};
|
||||||
struct vsp1_bru *bru = to_bru(subdev);
|
struct vsp1_bru *bru = to_bru(subdev);
|
||||||
struct v4l2_mbus_framefmt *format;
|
|
||||||
|
|
||||||
if (code->pad == BRU_PAD_SINK(0)) {
|
if (code->pad == BRU_PAD_SINK(0)) {
|
||||||
if (code->index >= ARRAY_SIZE(codes))
|
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];
|
code->code = codes[code->index];
|
||||||
} else {
|
} else {
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
if (code->index)
|
if (code->index)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&bru->entity, cfg,
|
config = vsp1_entity_get_pad_config(&bru->entity, cfg,
|
||||||
BRU_PAD_SINK(0),
|
|
||||||
code->which);
|
code->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&bru->entity, config,
|
||||||
|
BRU_PAD_SINK(0));
|
||||||
code->code = format->code;
|
code->code = format->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,17 +249,21 @@ static int bru_get_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_bru *bru = to_bru(subdev);
|
struct vsp1_bru *bru = to_bru(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
|
||||||
fmt->format = *vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
|
config = vsp1_entity_get_pad_config(&bru->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fmt->format = *vsp1_entity_get_pad_format(&bru->entity, config,
|
||||||
|
fmt->pad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bru_try_format(struct vsp1_bru *bru,
|
static void bru_try_format(struct vsp1_bru *bru,
|
||||||
struct v4l2_subdev_pad_config *cfg,
|
struct v4l2_subdev_pad_config *config,
|
||||||
unsigned int pad, struct v4l2_mbus_framefmt *fmt,
|
unsigned int pad, struct v4l2_mbus_framefmt *fmt)
|
||||||
enum v4l2_subdev_format_whence which)
|
|
||||||
{
|
{
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
|
@ -266,8 +277,8 @@ static void bru_try_format(struct vsp1_bru *bru,
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* The BRU can't perform format conversion. */
|
/* The BRU can't perform format conversion. */
|
||||||
format = vsp1_entity_get_pad_format(&bru->entity, cfg,
|
format = vsp1_entity_get_pad_format(&bru->entity, config,
|
||||||
BRU_PAD_SINK(0), which);
|
BRU_PAD_SINK(0));
|
||||||
fmt->code = format->code;
|
fmt->code = format->code;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -283,12 +294,16 @@ static int bru_set_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_bru *bru = to_bru(subdev);
|
struct vsp1_bru *bru = to_bru(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
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;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
|
bru_try_format(bru, config, fmt->pad, &fmt->format);
|
||||||
fmt->which);
|
|
||||||
|
format = vsp1_entity_get_pad_format(&bru->entity, config, fmt->pad);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
/* Reset the compose rectangle */
|
/* Reset the compose rectangle */
|
||||||
|
@ -307,8 +322,8 @@ static int bru_set_format(struct v4l2_subdev *subdev,
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i <= bru->entity.source_pad; ++i) {
|
for (i = 0; i <= bru->entity.source_pad; ++i) {
|
||||||
format = vsp1_entity_get_pad_format(&bru->entity, cfg,
|
format = vsp1_entity_get_pad_format(&bru->entity,
|
||||||
i, fmt->which);
|
config, i);
|
||||||
format->code = fmt->format.code;
|
format->code = fmt->format.code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,6 +362,7 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_selection *sel)
|
struct v4l2_subdev_selection *sel)
|
||||||
{
|
{
|
||||||
struct vsp1_bru *bru = to_bru(subdev);
|
struct vsp1_bru *bru = to_bru(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
struct v4l2_rect *compose;
|
struct v4l2_rect *compose;
|
||||||
|
|
||||||
|
@ -356,19 +372,22 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
|
||||||
if (sel->target != V4L2_SEL_TGT_COMPOSE)
|
if (sel->target != V4L2_SEL_TGT_COMPOSE)
|
||||||
return -EINVAL;
|
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
|
/* The compose rectangle top left corner must be inside the output
|
||||||
* frame.
|
* frame.
|
||||||
*/
|
*/
|
||||||
format = vsp1_entity_get_pad_format(&bru->entity, cfg,
|
format = vsp1_entity_get_pad_format(&bru->entity, config,
|
||||||
bru->entity.source_pad, sel->which);
|
bru->entity.source_pad);
|
||||||
sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
|
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);
|
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
|
/* Scaling isn't supported, the compose rectangle size must be identical
|
||||||
* to the sink format size.
|
* to the sink format size.
|
||||||
*/
|
*/
|
||||||
format = vsp1_entity_get_pad_format(&bru->entity, cfg, sel->pad,
|
format = vsp1_entity_get_pad_format(&bru->entity, config, sel->pad);
|
||||||
sel->which);
|
|
||||||
sel->r.width = format->width;
|
sel->r.width = format->width;
|
||||||
sel->r.height = format->height;
|
sel->r.height = format->height;
|
||||||
|
|
||||||
|
|
|
@ -46,19 +46,46 @@ void vsp1_entity_route_setup(struct vsp1_entity *source)
|
||||||
* V4L2 Subdevice Operations
|
* V4L2 Subdevice Operations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
enum v4l2_subdev_format_whence which)
|
||||||
|
{
|
||||||
|
switch (which) {
|
||||||
|
case V4L2_SUBDEV_FORMAT_ACTIVE:
|
||||||
|
return entity->config;
|
||||||
|
case V4L2_SUBDEV_FORMAT_TRY:
|
||||||
|
default:
|
||||||
|
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 *
|
struct v4l2_mbus_framefmt *
|
||||||
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
|
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
|
||||||
struct v4l2_subdev_pad_config *cfg,
|
struct v4l2_subdev_pad_config *cfg,
|
||||||
unsigned int pad, u32 which)
|
unsigned int pad)
|
||||||
{
|
{
|
||||||
switch (which) {
|
return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad);
|
||||||
case V4L2_SUBDEV_FORMAT_TRY:
|
|
||||||
return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad);
|
|
||||||
case V4L2_SUBDEV_FORMAT_ACTIVE:
|
|
||||||
return &entity->formats[pad];
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -169,19 +196,12 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
|
||||||
entity->vsp1 = vsp1;
|
entity->vsp1 = vsp1;
|
||||||
entity->source_pad = num_pads - 1;
|
entity->source_pad = num_pads - 1;
|
||||||
|
|
||||||
/* Allocate formats and pads. */
|
/* Allocate and initialize pads. */
|
||||||
entity->formats = devm_kzalloc(vsp1->dev,
|
|
||||||
num_pads * sizeof(*entity->formats),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (entity->formats == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
entity->pads = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->pads),
|
entity->pads = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->pads),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (entity->pads == NULL)
|
if (entity->pads == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Initialize pads. */
|
|
||||||
for (i = 0; i < num_pads - 1; ++i)
|
for (i = 0; i < num_pads - 1; ++i)
|
||||||
entity->pads[i].flags = MEDIA_PAD_FL_SINK;
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,5 +243,6 @@ void vsp1_entity_destroy(struct vsp1_entity *entity)
|
||||||
entity->ops->destroy(entity);
|
entity->ops->destroy(entity);
|
||||||
if (entity->subdev.ctrl_handler)
|
if (entity->subdev.ctrl_handler)
|
||||||
v4l2_ctrl_handler_free(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);
|
media_entity_cleanup(&entity->subdev.entity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ struct vsp1_entity {
|
||||||
unsigned int sink_pad;
|
unsigned int sink_pad;
|
||||||
|
|
||||||
struct v4l2_subdev subdev;
|
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)
|
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 *local,
|
||||||
const struct media_pad *remote, u32 flags);
|
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 *
|
struct v4l2_mbus_framefmt *
|
||||||
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
|
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
|
||||||
struct v4l2_subdev_pad_config *cfg,
|
struct v4l2_subdev_pad_config *cfg,
|
||||||
unsigned int pad, u32 which);
|
unsigned int pad);
|
||||||
int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
|
int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_pad_config *cfg);
|
struct v4l2_subdev_pad_config *cfg);
|
||||||
|
|
||||||
|
|
|
@ -77,10 +77,14 @@ static int hsit_enum_frame_size(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_frame_size_enum *fse)
|
struct v4l2_subdev_frame_size_enum *fse)
|
||||||
{
|
{
|
||||||
struct vsp1_hsit *hsit = to_hsit(subdev);
|
struct vsp1_hsit *hsit = to_hsit(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fse->pad,
|
config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fse->which);
|
||||||
fse->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&hsit->entity, config, fse->pad);
|
||||||
|
|
||||||
if (fse->index || fse->code != format->code)
|
if (fse->index || fse->code != format->code)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -108,9 +112,14 @@ static int hsit_get_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_hsit *hsit = to_hsit(subdev);
|
struct vsp1_hsit *hsit = to_hsit(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
|
||||||
fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad,
|
config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, config,
|
||||||
|
fmt->pad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -120,10 +129,14 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_hsit *hsit = to_hsit(subdev);
|
struct vsp1_hsit *hsit = to_hsit(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad,
|
config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&hsit->entity, config, fmt->pad);
|
||||||
|
|
||||||
if (fmt->pad == HSIT_PAD_SOURCE) {
|
if (fmt->pad == HSIT_PAD_SOURCE) {
|
||||||
/* The HST and HSI output format code and resolution can't be
|
/* 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;
|
fmt->format = *format;
|
||||||
|
|
||||||
/* Propagate the format to the source pad. */
|
/* Propagate the format to the source pad. */
|
||||||
format = vsp1_entity_get_pad_format(&hsit->entity, cfg, HSIT_PAD_SOURCE,
|
format = vsp1_entity_get_pad_format(&hsit->entity, config,
|
||||||
fmt->which);
|
HSIT_PAD_SOURCE);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32
|
format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32
|
||||||
: MEDIA_BUS_FMT_AHSV8888_1X32;
|
: MEDIA_BUS_FMT_AHSV8888_1X32;
|
||||||
|
|
|
@ -48,7 +48,8 @@ static int lif_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
return 0;
|
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);
|
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];
|
code->code = codes[code->index];
|
||||||
} else {
|
} else {
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
/* The LIF can't perform format conversion, the sink format is
|
/* 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)
|
if (code->index)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&lif->entity, cfg,
|
config = vsp1_entity_get_pad_config(&lif->entity, cfg,
|
||||||
LIF_PAD_SINK, code->which);
|
code->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&lif->entity, config,
|
||||||
|
LIF_PAD_SINK);
|
||||||
code->code = format->code;
|
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 v4l2_subdev_frame_size_enum *fse)
|
||||||
{
|
{
|
||||||
struct vsp1_lif *lif = to_lif(subdev);
|
struct vsp1_lif *lif = to_lif(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SINK,
|
config = vsp1_entity_get_pad_config(&lif->entity, cfg, fse->which);
|
||||||
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)
|
if (fse->index || fse->code != format->code)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -133,9 +144,14 @@ static int lif_get_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_lif *lif = to_lif(subdev);
|
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,
|
config = vsp1_entity_get_pad_config(&lif->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fmt->format = *vsp1_entity_get_pad_format(&lif->entity, config,
|
||||||
|
fmt->pad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -145,15 +161,19 @@ static int lif_set_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_lif *lif = to_lif(subdev);
|
struct vsp1_lif *lif = to_lif(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
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. */
|
/* Default to YUV if the requested format is not supported. */
|
||||||
if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
|
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)
|
||||||
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,
|
format = vsp1_entity_get_pad_format(&lif->entity, config, fmt->pad);
|
||||||
fmt->which);
|
|
||||||
|
|
||||||
if (fmt->pad == LIF_PAD_SOURCE) {
|
if (fmt->pad == LIF_PAD_SOURCE) {
|
||||||
/* The LIF source format is always identical to its sink
|
/* 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;
|
fmt->format = *format;
|
||||||
|
|
||||||
/* Propagate the format to the source pad. */
|
/* Propagate the format to the source pad. */
|
||||||
format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SOURCE,
|
format = vsp1_entity_get_pad_format(&lif->entity, config,
|
||||||
fmt->which);
|
LIF_PAD_SOURCE);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -86,7 +86,6 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||||
MEDIA_BUS_FMT_AYUV8_1X32,
|
MEDIA_BUS_FMT_AYUV8_1X32,
|
||||||
};
|
};
|
||||||
struct vsp1_lut *lut = to_lut(subdev);
|
struct vsp1_lut *lut = to_lut(subdev);
|
||||||
struct v4l2_mbus_framefmt *format;
|
|
||||||
|
|
||||||
if (code->pad == LUT_PAD_SINK) {
|
if (code->pad == LUT_PAD_SINK) {
|
||||||
if (code->index >= ARRAY_SIZE(codes))
|
if (code->index >= ARRAY_SIZE(codes))
|
||||||
|
@ -94,14 +93,22 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||||
|
|
||||||
code->code = codes[code->index];
|
code->code = codes[code->index];
|
||||||
} else {
|
} else {
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
/* The LUT can't perform format conversion, the sink format is
|
/* The LUT can't perform format conversion, the sink format is
|
||||||
* always identical to the source format.
|
* always identical to the source format.
|
||||||
*/
|
*/
|
||||||
if (code->index)
|
if (code->index)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&lut->entity, cfg,
|
config = vsp1_entity_get_pad_config(&lut->entity, cfg,
|
||||||
LUT_PAD_SINK, code->which);
|
code->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&lut->entity, config,
|
||||||
|
LUT_PAD_SINK);
|
||||||
code->code = format->code;
|
code->code = format->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,10 +120,14 @@ static int lut_enum_frame_size(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_frame_size_enum *fse)
|
struct v4l2_subdev_frame_size_enum *fse)
|
||||||
{
|
{
|
||||||
struct vsp1_lut *lut = to_lut(subdev);
|
struct vsp1_lut *lut = to_lut(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&lut->entity, cfg,
|
config = vsp1_entity_get_pad_config(&lut->entity, cfg, fse->which);
|
||||||
fse->pad, fse->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&lut->entity, config, fse->pad);
|
||||||
|
|
||||||
if (fse->index || fse->code != format->code)
|
if (fse->index || fse->code != format->code)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -144,9 +155,14 @@ static int lut_get_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_lut *lut = to_lut(subdev);
|
struct vsp1_lut *lut = to_lut(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
|
||||||
fmt->format = *vsp1_entity_get_pad_format(&lut->entity, cfg, fmt->pad,
|
config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fmt->format = *vsp1_entity_get_pad_format(&lut->entity, config,
|
||||||
|
fmt->pad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -156,16 +172,20 @@ static int lut_set_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_lut *lut = to_lut(subdev);
|
struct vsp1_lut *lut = to_lut(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
|
config = vsp1_entity_get_pad_config(&lut->entity, cfg, fmt->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* Default to YUV if the requested format is not supported. */
|
/* Default to YUV if the requested format is not supported. */
|
||||||
if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
|
if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
|
||||||
fmt->format.code != MEDIA_BUS_FMT_AHSV8888_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)
|
||||||
fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
|
fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&lut->entity, cfg, fmt->pad,
|
format = vsp1_entity_get_pad_format(&lut->entity, config, fmt->pad);
|
||||||
fmt->which);
|
|
||||||
|
|
||||||
if (fmt->pad == LUT_PAD_SOURCE) {
|
if (fmt->pad == LUT_PAD_SOURCE) {
|
||||||
/* The LUT output format can't be modified. */
|
/* The LUT output format can't be modified. */
|
||||||
|
@ -183,8 +203,8 @@ static int lut_set_format(struct v4l2_subdev *subdev,
|
||||||
fmt->format = *format;
|
fmt->format = *format;
|
||||||
|
|
||||||
/* Propagate the format to the source pad. */
|
/* Propagate the format to the source pad. */
|
||||||
format = vsp1_entity_get_pad_format(&lut->entity, cfg, LUT_PAD_SOURCE,
|
format = vsp1_entity_get_pad_format(&lut->entity, config,
|
||||||
fmt->which);
|
LUT_PAD_SOURCE);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -42,6 +42,8 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
struct vsp1_rwpf *rpf = to_rwpf(subdev);
|
struct vsp1_rwpf *rpf = to_rwpf(subdev);
|
||||||
const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
|
const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
|
||||||
const struct v4l2_pix_format_mplane *format = &rpf->format;
|
const struct v4l2_pix_format_mplane *format = &rpf->format;
|
||||||
|
const struct v4l2_mbus_framefmt *source_format;
|
||||||
|
const struct v4l2_mbus_framefmt *sink_format;
|
||||||
const struct v4l2_rect *crop = &rpf->crop;
|
const struct v4l2_rect *crop = &rpf->crop;
|
||||||
u32 pstride;
|
u32 pstride;
|
||||||
u32 infmt;
|
u32 infmt;
|
||||||
|
@ -79,6 +81,13 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
vsp1_rpf_write(rpf, VI6_RPF_SRCM_PSTRIDE, pstride);
|
vsp1_rpf_write(rpf, VI6_RPF_SRCM_PSTRIDE, pstride);
|
||||||
|
|
||||||
/* Format */
|
/* Format */
|
||||||
|
sink_format = vsp1_entity_get_pad_format(&rpf->entity,
|
||||||
|
rpf->entity.config,
|
||||||
|
RWPF_PAD_SINK);
|
||||||
|
source_format = vsp1_entity_get_pad_format(&rpf->entity,
|
||||||
|
rpf->entity.config,
|
||||||
|
RWPF_PAD_SOURCE);
|
||||||
|
|
||||||
infmt = VI6_RPF_INFMT_CIPM
|
infmt = VI6_RPF_INFMT_CIPM
|
||||||
| (fmtinfo->hwfmt << VI6_RPF_INFMT_RDFMT_SHIFT);
|
| (fmtinfo->hwfmt << VI6_RPF_INFMT_RDFMT_SHIFT);
|
||||||
|
|
||||||
|
@ -87,8 +96,7 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
if (fmtinfo->swap_uv)
|
if (fmtinfo->swap_uv)
|
||||||
infmt |= VI6_RPF_INFMT_SPUVS;
|
infmt |= VI6_RPF_INFMT_SPUVS;
|
||||||
|
|
||||||
if (rpf->entity.formats[RWPF_PAD_SINK].code !=
|
if (sink_format->code != source_format->code)
|
||||||
rpf->entity.formats[RWPF_PAD_SOURCE].code)
|
|
||||||
infmt |= VI6_RPF_INFMT_CSC;
|
infmt |= VI6_RPF_INFMT_CSC;
|
||||||
|
|
||||||
vsp1_rpf_write(rpf, VI6_RPF_INFMT, infmt);
|
vsp1_rpf_write(rpf, VI6_RPF_INFMT, infmt);
|
||||||
|
|
|
@ -46,10 +46,14 @@ int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_frame_size_enum *fse)
|
struct v4l2_subdev_frame_size_enum *fse)
|
||||||
{
|
{
|
||||||
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fse->pad,
|
config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, fse->which);
|
||||||
fse->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&rwpf->entity, config, fse->pad);
|
||||||
|
|
||||||
if (fse->index || fse->code != format->code)
|
if (fse->index || fse->code != format->code)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -92,9 +96,14 @@ int vsp1_rwpf_get_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
|
||||||
fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad,
|
config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, config,
|
||||||
|
fmt->pad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -104,16 +113,20 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
struct v4l2_rect *crop;
|
struct v4l2_rect *crop;
|
||||||
|
|
||||||
|
config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, fmt->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* Default to YUV if the requested format is not supported. */
|
/* Default to YUV if the requested format is not supported. */
|
||||||
if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
|
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)
|
||||||
fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
|
fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad,
|
format = vsp1_entity_get_pad_format(&rwpf->entity, config, fmt->pad);
|
||||||
fmt->which);
|
|
||||||
|
|
||||||
if (fmt->pad == RWPF_PAD_SOURCE) {
|
if (fmt->pad == RWPF_PAD_SOURCE) {
|
||||||
/* The RWPF performs format conversion but can't scale, only the
|
/* The RWPF performs format conversion but can't scale, only the
|
||||||
|
@ -142,8 +155,8 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
|
||||||
crop->height = fmt->format.height;
|
crop->height = fmt->format.height;
|
||||||
|
|
||||||
/* Propagate the format to the source pad. */
|
/* Propagate the format to the source pad. */
|
||||||
format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SOURCE,
|
format = vsp1_entity_get_pad_format(&rwpf->entity, config,
|
||||||
fmt->which);
|
RWPF_PAD_SOURCE);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -154,20 +167,25 @@ int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_selection *sel)
|
struct v4l2_subdev_selection *sel)
|
||||||
{
|
{
|
||||||
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
/* Cropping is implemented on the sink pad. */
|
/* Cropping is implemented on the sink pad. */
|
||||||
if (sel->pad != RWPF_PAD_SINK)
|
if (sel->pad != RWPF_PAD_SINK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, sel->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
switch (sel->target) {
|
switch (sel->target) {
|
||||||
case V4L2_SEL_TGT_CROP:
|
case V4L2_SEL_TGT_CROP:
|
||||||
sel->r = *vsp1_rwpf_get_crop(rwpf, cfg, sel->which);
|
sel->r = *vsp1_rwpf_get_crop(rwpf, cfg, sel->which);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||||
format = vsp1_entity_get_pad_format(&rwpf->entity, cfg,
|
format = vsp1_entity_get_pad_format(&rwpf->entity, config,
|
||||||
RWPF_PAD_SINK, sel->which);
|
RWPF_PAD_SINK);
|
||||||
sel->r.left = 0;
|
sel->r.left = 0;
|
||||||
sel->r.top = 0;
|
sel->r.top = 0;
|
||||||
sel->r.width = format->width;
|
sel->r.width = format->width;
|
||||||
|
@ -186,6 +204,7 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_selection *sel)
|
struct v4l2_subdev_selection *sel)
|
||||||
{
|
{
|
||||||
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
struct v4l2_rect *crop;
|
struct v4l2_rect *crop;
|
||||||
|
|
||||||
|
@ -196,11 +215,15 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
|
||||||
if (sel->target != V4L2_SEL_TGT_CROP)
|
if (sel->target != V4L2_SEL_TGT_CROP)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, sel->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* Make sure the crop rectangle is entirely contained in the image. The
|
/* Make sure the crop rectangle is entirely contained in the image. The
|
||||||
* WPF top and left offsets are limited to 255.
|
* WPF top and left offsets are limited to 255.
|
||||||
*/
|
*/
|
||||||
format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SINK,
|
format = vsp1_entity_get_pad_format(&rwpf->entity, config,
|
||||||
sel->which);
|
RWPF_PAD_SINK);
|
||||||
|
|
||||||
/* Restrict the crop rectangle coordinates to multiples of 2 to avoid
|
/* Restrict the crop rectangle coordinates to multiples of 2 to avoid
|
||||||
* shifting the color plane.
|
* shifting the color plane.
|
||||||
|
@ -227,8 +250,8 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
|
||||||
*crop = sel->r;
|
*crop = sel->r;
|
||||||
|
|
||||||
/* Propagate the format to the source pad. */
|
/* Propagate the format to the source pad. */
|
||||||
format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SOURCE,
|
format = vsp1_entity_get_pad_format(&rwpf->entity, config,
|
||||||
sel->which);
|
RWPF_PAD_SOURCE);
|
||||||
format->width = crop->width;
|
format->width = crop->width;
|
||||||
format->height = crop->height;
|
format->height = crop->height;
|
||||||
|
|
||||||
|
|
|
@ -117,8 +117,10 @@ static int sru_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
if (!enable)
|
if (!enable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
input = &sru->entity.formats[SRU_PAD_SINK];
|
input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
|
||||||
output = &sru->entity.formats[SRU_PAD_SOURCE];
|
SRU_PAD_SINK);
|
||||||
|
output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
|
||||||
|
SRU_PAD_SOURCE);
|
||||||
|
|
||||||
if (input->code == MEDIA_BUS_FMT_ARGB8888_1X32)
|
if (input->code == MEDIA_BUS_FMT_ARGB8888_1X32)
|
||||||
ctrl0 = VI6_SRU_CTRL0_PARAM2 | VI6_SRU_CTRL0_PARAM3
|
ctrl0 = VI6_SRU_CTRL0_PARAM2 | VI6_SRU_CTRL0_PARAM3
|
||||||
|
@ -153,7 +155,6 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||||
MEDIA_BUS_FMT_AYUV8_1X32,
|
MEDIA_BUS_FMT_AYUV8_1X32,
|
||||||
};
|
};
|
||||||
struct vsp1_sru *sru = to_sru(subdev);
|
struct vsp1_sru *sru = to_sru(subdev);
|
||||||
struct v4l2_mbus_framefmt *format;
|
|
||||||
|
|
||||||
if (code->pad == SRU_PAD_SINK) {
|
if (code->pad == SRU_PAD_SINK) {
|
||||||
if (code->index >= ARRAY_SIZE(codes))
|
if (code->index >= ARRAY_SIZE(codes))
|
||||||
|
@ -161,14 +162,22 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||||
|
|
||||||
code->code = codes[code->index];
|
code->code = codes[code->index];
|
||||||
} else {
|
} else {
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
/* The SRU can't perform format conversion, the sink format is
|
/* The SRU can't perform format conversion, the sink format is
|
||||||
* always identical to the source format.
|
* always identical to the source format.
|
||||||
*/
|
*/
|
||||||
if (code->index)
|
if (code->index)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&sru->entity, cfg,
|
config = vsp1_entity_get_pad_config(&sru->entity, cfg,
|
||||||
SRU_PAD_SINK, code->which);
|
code->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&sru->entity, config,
|
||||||
|
SRU_PAD_SINK);
|
||||||
code->code = format->code;
|
code->code = format->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +189,14 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_frame_size_enum *fse)
|
struct v4l2_subdev_frame_size_enum *fse)
|
||||||
{
|
{
|
||||||
struct vsp1_sru *sru = to_sru(subdev);
|
struct vsp1_sru *sru = to_sru(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&sru->entity, cfg,
|
config = vsp1_entity_get_pad_config(&sru->entity, cfg, fse->which);
|
||||||
SRU_PAD_SINK, fse->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&sru->entity, config, SRU_PAD_SINK);
|
||||||
|
|
||||||
if (fse->index || fse->code != format->code)
|
if (fse->index || fse->code != format->code)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -214,17 +227,21 @@ static int sru_get_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_sru *sru = to_sru(subdev);
|
struct vsp1_sru *sru = to_sru(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
|
||||||
fmt->format = *vsp1_entity_get_pad_format(&sru->entity, cfg, fmt->pad,
|
config = vsp1_entity_get_pad_config(&sru->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fmt->format = *vsp1_entity_get_pad_format(&sru->entity, config,
|
||||||
|
fmt->pad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sru_try_format(struct vsp1_sru *sru,
|
static void sru_try_format(struct vsp1_sru *sru,
|
||||||
struct v4l2_subdev_pad_config *cfg,
|
struct v4l2_subdev_pad_config *config,
|
||||||
unsigned int pad, struct v4l2_mbus_framefmt *fmt,
|
unsigned int pad, struct v4l2_mbus_framefmt *fmt)
|
||||||
enum v4l2_subdev_format_whence which)
|
|
||||||
{
|
{
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
unsigned int input_area;
|
unsigned int input_area;
|
||||||
|
@ -243,8 +260,8 @@ static void sru_try_format(struct vsp1_sru *sru,
|
||||||
|
|
||||||
case SRU_PAD_SOURCE:
|
case SRU_PAD_SOURCE:
|
||||||
/* The SRU can't perform format conversion. */
|
/* The SRU can't perform format conversion. */
|
||||||
format = vsp1_entity_get_pad_format(&sru->entity, cfg,
|
format = vsp1_entity_get_pad_format(&sru->entity, config,
|
||||||
SRU_PAD_SINK, which);
|
SRU_PAD_SINK);
|
||||||
fmt->code = format->code;
|
fmt->code = format->code;
|
||||||
|
|
||||||
/* We can upscale by 2 in both direction, but not independently.
|
/* We can upscale by 2 in both direction, but not independently.
|
||||||
|
@ -278,21 +295,25 @@ static int sru_set_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_sru *sru = to_sru(subdev);
|
struct vsp1_sru *sru = to_sru(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
sru_try_format(sru, cfg, fmt->pad, &fmt->format, fmt->which);
|
config = vsp1_entity_get_pad_config(&sru->entity, cfg, fmt->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&sru->entity, cfg, fmt->pad,
|
sru_try_format(sru, config, fmt->pad, &fmt->format);
|
||||||
fmt->which);
|
|
||||||
|
format = vsp1_entity_get_pad_format(&sru->entity, config, fmt->pad);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
if (fmt->pad == SRU_PAD_SINK) {
|
if (fmt->pad == SRU_PAD_SINK) {
|
||||||
/* Propagate the format to the source pad. */
|
/* Propagate the format to the source pad. */
|
||||||
format = vsp1_entity_get_pad_format(&sru->entity, cfg,
|
format = vsp1_entity_get_pad_format(&sru->entity, config,
|
||||||
SRU_PAD_SOURCE, fmt->which);
|
SRU_PAD_SOURCE);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
sru_try_format(sru, cfg, SRU_PAD_SOURCE, format, fmt->which);
|
sru_try_format(sru, config, SRU_PAD_SOURCE, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -120,8 +120,10 @@ static int uds_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
if (!enable)
|
if (!enable)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
input = &uds->entity.formats[UDS_PAD_SINK];
|
input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
|
||||||
output = &uds->entity.formats[UDS_PAD_SOURCE];
|
UDS_PAD_SINK);
|
||||||
|
output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
|
||||||
|
UDS_PAD_SOURCE);
|
||||||
|
|
||||||
hscale = uds_compute_ratio(input->width, output->width);
|
hscale = uds_compute_ratio(input->width, output->width);
|
||||||
vscale = uds_compute_ratio(input->height, output->height);
|
vscale = uds_compute_ratio(input->height, output->height);
|
||||||
|
@ -178,16 +180,22 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||||
|
|
||||||
code->code = codes[code->index];
|
code->code = codes[code->index];
|
||||||
} else {
|
} else {
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
|
config = vsp1_entity_get_pad_config(&uds->entity, cfg,
|
||||||
|
code->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* The UDS can't perform format conversion, the sink format is
|
/* The UDS can't perform format conversion, the sink format is
|
||||||
* always identical to the source format.
|
* always identical to the source format.
|
||||||
*/
|
*/
|
||||||
if (code->index)
|
if (code->index)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&uds->entity, cfg,
|
format = vsp1_entity_get_pad_format(&uds->entity, config,
|
||||||
UDS_PAD_SINK, code->which);
|
UDS_PAD_SINK);
|
||||||
code->code = format->code;
|
code->code = format->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,10 +207,15 @@ static int uds_enum_frame_size(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_frame_size_enum *fse)
|
struct v4l2_subdev_frame_size_enum *fse)
|
||||||
{
|
{
|
||||||
struct vsp1_uds *uds = to_uds(subdev);
|
struct vsp1_uds *uds = to_uds(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&uds->entity, cfg,
|
config = vsp1_entity_get_pad_config(&uds->entity, cfg, fse->which);
|
||||||
UDS_PAD_SINK, fse->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
format = vsp1_entity_get_pad_format(&uds->entity, config,
|
||||||
|
UDS_PAD_SINK);
|
||||||
|
|
||||||
if (fse->index || fse->code != format->code)
|
if (fse->index || fse->code != format->code)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -227,17 +240,21 @@ static int uds_get_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_uds *uds = to_uds(subdev);
|
struct vsp1_uds *uds = to_uds(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
|
|
||||||
fmt->format = *vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad,
|
config = vsp1_entity_get_pad_config(&uds->entity, cfg, fmt->which);
|
||||||
fmt->which);
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fmt->format = *vsp1_entity_get_pad_format(&uds->entity, config,
|
||||||
|
fmt->pad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uds_try_format(struct vsp1_uds *uds,
|
static void uds_try_format(struct vsp1_uds *uds,
|
||||||
struct v4l2_subdev_pad_config *cfg,
|
struct v4l2_subdev_pad_config *config,
|
||||||
unsigned int pad, struct v4l2_mbus_framefmt *fmt,
|
unsigned int pad, struct v4l2_mbus_framefmt *fmt)
|
||||||
enum v4l2_subdev_format_whence which)
|
|
||||||
{
|
{
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
unsigned int minimum;
|
unsigned int minimum;
|
||||||
|
@ -256,8 +273,8 @@ static void uds_try_format(struct vsp1_uds *uds,
|
||||||
|
|
||||||
case UDS_PAD_SOURCE:
|
case UDS_PAD_SOURCE:
|
||||||
/* The UDS scales but can't perform format conversion. */
|
/* The UDS scales but can't perform format conversion. */
|
||||||
format = vsp1_entity_get_pad_format(&uds->entity, cfg,
|
format = vsp1_entity_get_pad_format(&uds->entity, config,
|
||||||
UDS_PAD_SINK, which);
|
UDS_PAD_SINK);
|
||||||
fmt->code = format->code;
|
fmt->code = format->code;
|
||||||
|
|
||||||
uds_output_limits(format->width, &minimum, &maximum);
|
uds_output_limits(format->width, &minimum, &maximum);
|
||||||
|
@ -276,21 +293,25 @@ static int uds_set_format(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct vsp1_uds *uds = to_uds(subdev);
|
struct vsp1_uds *uds = to_uds(subdev);
|
||||||
|
struct v4l2_subdev_pad_config *config;
|
||||||
struct v4l2_mbus_framefmt *format;
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
uds_try_format(uds, cfg, fmt->pad, &fmt->format, fmt->which);
|
config = vsp1_entity_get_pad_config(&uds->entity, cfg, fmt->which);
|
||||||
|
if (!config)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
format = vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad,
|
uds_try_format(uds, config, fmt->pad, &fmt->format);
|
||||||
fmt->which);
|
|
||||||
|
format = vsp1_entity_get_pad_format(&uds->entity, config, fmt->pad);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
if (fmt->pad == UDS_PAD_SINK) {
|
if (fmt->pad == UDS_PAD_SINK) {
|
||||||
/* Propagate the format to the source pad. */
|
/* Propagate the format to the source pad. */
|
||||||
format = vsp1_entity_get_pad_format(&uds->entity, cfg,
|
format = vsp1_entity_get_pad_format(&uds->entity, config,
|
||||||
UDS_PAD_SOURCE, fmt->which);
|
UDS_PAD_SOURCE);
|
||||||
*format = fmt->format;
|
*format = fmt->format;
|
||||||
|
|
||||||
uds_try_format(uds, cfg, UDS_PAD_SOURCE, format, fmt->which);
|
uds_try_format(uds, config, UDS_PAD_SOURCE, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -42,6 +42,8 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity);
|
struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity);
|
||||||
struct vsp1_rwpf *wpf = to_rwpf(subdev);
|
struct vsp1_rwpf *wpf = to_rwpf(subdev);
|
||||||
struct vsp1_device *vsp1 = wpf->entity.vsp1;
|
struct vsp1_device *vsp1 = wpf->entity.vsp1;
|
||||||
|
const struct v4l2_mbus_framefmt *source_format;
|
||||||
|
const struct v4l2_mbus_framefmt *sink_format;
|
||||||
const struct v4l2_rect *crop = &wpf->crop;
|
const struct v4l2_rect *crop = &wpf->crop;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u32 srcrpf = 0;
|
u32 srcrpf = 0;
|
||||||
|
@ -94,6 +96,13 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
(crop->height << VI6_WPF_SZCLIP_SIZE_SHIFT));
|
(crop->height << VI6_WPF_SZCLIP_SIZE_SHIFT));
|
||||||
|
|
||||||
/* Format */
|
/* Format */
|
||||||
|
sink_format = vsp1_entity_get_pad_format(&wpf->entity,
|
||||||
|
wpf->entity.config,
|
||||||
|
RWPF_PAD_SINK);
|
||||||
|
source_format = vsp1_entity_get_pad_format(&wpf->entity,
|
||||||
|
wpf->entity.config,
|
||||||
|
RWPF_PAD_SOURCE);
|
||||||
|
|
||||||
if (!pipe->lif) {
|
if (!pipe->lif) {
|
||||||
const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
|
const struct vsp1_format_info *fmtinfo = wpf->fmtinfo;
|
||||||
|
|
||||||
|
@ -109,8 +118,7 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
|
||||||
vsp1_wpf_write(wpf, VI6_WPF_DSWAP, fmtinfo->swap);
|
vsp1_wpf_write(wpf, VI6_WPF_DSWAP, fmtinfo->swap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wpf->entity.formats[RWPF_PAD_SINK].code !=
|
if (sink_format->code != source_format->code)
|
||||||
wpf->entity.formats[RWPF_PAD_SOURCE].code)
|
|
||||||
outfmt |= VI6_WPF_OUTFMT_CSC;
|
outfmt |= VI6_WPF_OUTFMT_CSC;
|
||||||
|
|
||||||
outfmt |= wpf->alpha << VI6_WPF_OUTFMT_PDV_SHIFT;
|
outfmt |= wpf->alpha << VI6_WPF_OUTFMT_PDV_SHIFT;
|
||||||
|
|
Loading…
Reference in New Issue