/* * The HGO is a special case, its routing is configured on the * sink pad.
*/
source = entity->sources[0];
smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
| (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
/* * The HGT is a special case, its routing is configured on the * sink pad.
*/
source = entity->sources[0];
smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
| (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
source = entity; if (source->route->reg == 0) return;
route = source->sink->route->inputs[source->sink_pad]; /* * The ILV and BRS share the same data path route. The extra BRSSEL bit * selects between the ILV and BRS. * * The BRU and IIF share the same data path route. The extra IIFSEL bit * selects between the IIF and BRU.
*/ if (source->type == VSP1_ENTITY_BRS)
route |= VI6_DPR_ROUTE_BRSSEL; elseif (source->type == VSP1_ENTITY_IIF)
route |= VI6_DPR_ROUTE_IIFSEL;
vsp1_dl_body_write(dlb, source->route->reg, route);
}
/** * vsp1_entity_get_state - Get the subdev state for an entity * @entity: the entity * @sd_state: the TRY state * @which: state selector (ACTIVE or TRY) * * When called with which set to V4L2_SUBDEV_FORMAT_ACTIVE the caller must hold * the entity lock to access the returned configuration. * * Return the subdev state requested by the which argument. The TRY state is * passed explicitly to the function through the sd_state argument and simply * returned when requested. The ACTIVE state comes from the entity structure.
*/ struct v4l2_subdev_state *
vsp1_entity_get_state(struct vsp1_entity *entity, struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which)
{ switch (which) { case V4L2_SUBDEV_FORMAT_ACTIVE: return entity->state; case V4L2_SUBDEV_FORMAT_TRY: default: return sd_state;
}
}
/* * vsp1_subdev_get_pad_format - Subdev pad get_fmt handler * @subdev: V4L2 subdevice * @sd_state: V4L2 subdev state * @fmt: V4L2 subdev format * * This function implements the subdev get_fmt pad operation. It can be used as * a direct drop-in for the operation handler.
*/ int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt)
{ struct vsp1_entity *entity = to_vsp1_entity(subdev); struct v4l2_subdev_state *state;
state = vsp1_entity_get_state(entity, sd_state, fmt->which); if (!state) return -EINVAL;
/* * vsp1_subdev_enum_mbus_code - Subdev pad enum_mbus_code handler * @subdev: V4L2 subdevice * @sd_state: V4L2 subdev state * @code: Media bus code enumeration * @codes: Array of supported media bus codes * @ncodes: Number of supported media bus codes * * This function implements the subdev enum_mbus_code pad operation for entities * that do not support format conversion. It enumerates the given supported * media bus codes on the sink pad and reports a source pad format identical to * the sink pad.
*/ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code, constunsignedint *codes, unsignedint ncodes)
{ struct vsp1_entity *entity = to_vsp1_entity(subdev);
if (code->pad == 0) { if (code->index >= ncodes) return -EINVAL;
/* * The entity can't perform format conversion, the sink format * is always identical to the source format.
*/ if (code->index) return -EINVAL;
state = vsp1_entity_get_state(entity, sd_state, code->which); if (!state) return -EINVAL;
mutex_lock(&entity->lock);
format = v4l2_subdev_state_get_format(state, 0);
code->code = format->code;
mutex_unlock(&entity->lock);
}
return 0;
}
/* * vsp1_subdev_enum_frame_size - Subdev pad enum_frame_size handler * @subdev: V4L2 subdevice * @sd_state: V4L2 subdev state * @fse: Frame size enumeration * @min_width: Minimum image width * @min_height: Minimum image height * @max_width: Maximum image width * @max_height: Maximum image height * * This function implements the subdev enum_frame_size pad operation for * entities that do not support scaling or cropping. It reports the given * minimum and maximum frame width and height on the sink pad, and a fixed * source pad size identical to the sink pad.
*/ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse, unsignedint min_width, unsignedint min_height, unsignedint max_width, unsignedint max_height)
{ struct vsp1_entity *entity = to_vsp1_entity(subdev); struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; int ret = 0;
state = vsp1_entity_get_state(entity, sd_state, fse->which); if (!state) return -EINVAL;
format = v4l2_subdev_state_get_format(state, fse->pad);
mutex_lock(&entity->lock);
if (fse->index || fse->code != format->code) {
ret = -EINVAL; goto done;
}
if (fse->pad == 0) {
fse->min_width = min_width;
fse->max_width = max_width;
fse->min_height = min_height;
fse->max_height = max_height;
} else { /* * The size on the source pad are fixed and always identical to * the size on the sink pad.
*/
fse->min_width = format->width;
fse->max_width = format->width;
fse->min_height = format->height;
fse->max_height = format->height;
}
done:
mutex_unlock(&entity->lock); return ret;
}
/* * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler * @subdev: V4L2 subdevice * @sd_state: V4L2 subdev state * @fmt: V4L2 subdev format * @codes: Array of supported media bus codes * @ncodes: Number of supported media bus codes * @min_width: Minimum image width * @min_height: Minimum image height * @max_width: Maximum image width * @max_height: Maximum image height * * This function implements the subdev set_fmt pad operation for entities that * do not support scaling or cropping. It defaults to the first supplied media * bus code if the requested code isn't supported, clamps the size to the * supplied minimum and maximum, and propagates the sink pad format to the * source pad.
*/ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt, constunsignedint *codes, unsignedint ncodes, unsignedint min_width, unsignedint min_height, unsignedint max_width, unsignedint max_height)
{ struct vsp1_entity *entity = to_vsp1_entity(subdev); struct v4l2_subdev_state *state; struct v4l2_mbus_framefmt *format; struct v4l2_rect *selection; unsignedint i; int ret = 0;
mutex_lock(&entity->lock);
state = vsp1_entity_get_state(entity, sd_state, fmt->which); if (!state) {
ret = -EINVAL; goto done;
}
format = v4l2_subdev_state_get_format(state, fmt->pad);
if (fmt->pad == entity->source_pad) { /* The output format can't be modified. */
fmt->format = *format; goto done;
}
/* * Default to the first media bus code if the requested format is not * supported.
*/ for (i = 0; i < ncodes; ++i) { if (fmt->format.code == codes[i]) break;
}
if (flags & MEDIA_LNK_FL_ENABLED) { struct vsp1_entity *sink
= media_entity_to_vsp1_entity(sink_pad->entity);
/* * Fan-out is limited to one for the normal data path plus * optional HGO and HGT. We ignore the HGO and HGT here.
*/ if (sink->type != VSP1_ENTITY_HGO &&
sink->type != VSP1_ENTITY_HGT) { if (source->sink) return -EBUSY;
source->sink = sink;
source->sink_pad = sink_pad->index;
}
} else {
source->sink = NULL;
source->sink_pad = 0;
}
/** * vsp1_entity_remote_pad - Find the pad at the remote end of a link * @pad: Pad at the local end of the link * * Search for a remote pad connected to the given pad by iterating over all * links originating or terminating at that pad until an enabled link is found. * * Our link setup implementation guarantees that the output fan-out will not be * higher than one for the data pipelines, except for the links to the HGO and * HGT that can be enabled in addition to a regular data link. When traversing * outgoing links this function ignores HGO and HGT entities and should thus be * used in place of the generic media_pad_remote_pad_first() function to * traverse data pipelines. * * Return a pointer to the pad at the remote end of the first found enabled * link, or NULL if no enabled link has been found.
*/ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
{ struct media_link *link;
/* * Allocate the subdev state to store formats and selection * rectangles.
*/ /* * FIXME: Drop this call, drivers are not supposed to use * __v4l2_subdev_state_alloc().
*/
entity->state = __v4l2_subdev_state_alloc(&entity->subdev, "vsp1:state->lock", &key); if (IS_ERR(entity->state)) {
media_entity_cleanup(&entity->subdev.entity); return PTR_ERR(entity->state);
}
return 0;
}
void vsp1_entity_destroy(struct vsp1_entity *entity)
{ if (entity->ops && entity->ops->destroy)
entity->ops->destroy(entity); if (entity->subdev.ctrl_handler)
v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
__v4l2_subdev_state_free(entity->state);
media_entity_cleanup(&entity->subdev.entity);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.3 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.