media: stm32: dcmipp: replace s_stream with enable/disable_streams

Replace s_stream ops with enable_streams and disable_streams.
At the same time, use v4l2_subdev_enable_streams and
v4l2_subdev_disable_streams functions instead of
direct s_stream calls.

Signed-off-by: Alain Volmat <alain.volmat@foss.st.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
This commit is contained in:
Alain Volmat 2024-12-12 10:17:29 +01:00 committed by Hans Verkuil
parent 255e0cc62b
commit b0f3cc7089
3 changed files with 135 additions and 111 deletions

View File

@ -112,6 +112,7 @@ struct dcmipp_bytecap_device {
u32 sequence;
struct media_pipeline pipe;
struct v4l2_subdev *s_subdev;
u32 s_subdev_pad_nb;
enum dcmipp_state state;
@ -337,33 +338,6 @@ static const struct v4l2_ioctl_ops dcmipp_bytecap_ioctl_ops = {
.vidioc_streamoff = vb2_ioctl_streamoff,
};
static int dcmipp_pipeline_s_stream(struct dcmipp_bytecap_device *vcap,
int state)
{
struct media_pad *pad;
int ret;
/*
* Get source subdev - since link is IMMUTABLE, pointer is cached
* within the dcmipp_bytecap_device structure
*/
if (!vcap->s_subdev) {
pad = media_pad_remote_pad_first(&vcap->vdev.entity.pads[0]);
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
return -EINVAL;
vcap->s_subdev = media_entity_to_v4l2_subdev(pad->entity);
}
ret = v4l2_subdev_call(vcap->s_subdev, video, s_stream, state);
if (ret < 0) {
dev_err(vcap->dev, "failed to %s streaming (%d)\n",
state ? "start" : "stop", ret);
return ret;
}
return 0;
}
static void dcmipp_start_capture(struct dcmipp_bytecap_device *vcap,
struct dcmipp_buf *buf)
{
@ -395,11 +369,24 @@ static int dcmipp_bytecap_start_streaming(struct vb2_queue *vq,
struct dcmipp_bytecap_device *vcap = vb2_get_drv_priv(vq);
struct media_entity *entity = &vcap->vdev.entity;
struct dcmipp_buf *buf;
struct media_pad *pad;
int ret;
vcap->sequence = 0;
memset(&vcap->count, 0, sizeof(vcap->count));
/*
* Get source subdev - since link is IMMUTABLE, pointer is cached
* within the dcmipp_bytecap_device structure
*/
if (!vcap->s_subdev) {
pad = media_pad_remote_pad_first(&vcap->vdev.entity.pads[0]);
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
return -EINVAL;
vcap->s_subdev = media_entity_to_v4l2_subdev(pad->entity);
vcap->s_subdev_pad_nb = pad->index;
}
ret = pm_runtime_resume_and_get(vcap->dev);
if (ret < 0) {
dev_err(vcap->dev, "%s: Failed to start streaming, cannot get sync (%d)\n",
@ -414,7 +401,8 @@ static int dcmipp_bytecap_start_streaming(struct vb2_queue *vq,
goto err_pm_put;
}
ret = dcmipp_pipeline_s_stream(vcap, 1);
ret = v4l2_subdev_enable_streams(vcap->s_subdev,
vcap->s_subdev_pad_nb, BIT_ULL(0));
if (ret)
goto err_media_pipeline_stop;
@ -482,7 +470,10 @@ static void dcmipp_bytecap_stop_streaming(struct vb2_queue *vq)
int ret;
u32 status;
dcmipp_pipeline_s_stream(vcap, 0);
ret = v4l2_subdev_disable_streams(vcap->s_subdev,
vcap->s_subdev_pad_nb, BIT_ULL(0));
if (ret)
dev_warn(vcap->dev, "Failed to disable stream\n");
/* Stop the media pipeline */
media_pipeline_stop(vcap->vdev.entity.pads);

View File

@ -380,30 +380,19 @@ static int dcmipp_byteproc_set_selection(struct v4l2_subdev *sd,
return 0;
}
static const struct v4l2_subdev_pad_ops dcmipp_byteproc_pad_ops = {
.enum_mbus_code = dcmipp_byteproc_enum_mbus_code,
.enum_frame_size = dcmipp_byteproc_enum_frame_size,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = dcmipp_byteproc_set_fmt,
.get_selection = dcmipp_byteproc_get_selection,
.set_selection = dcmipp_byteproc_set_selection,
};
static int dcmipp_byteproc_configure_scale_crop
(struct dcmipp_byteproc_device *byteproc)
(struct dcmipp_byteproc_device *byteproc,
struct v4l2_subdev_state *state)
{
const struct dcmipp_byteproc_pix_map *vpix;
struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *sink_fmt;
u32 hprediv, vprediv;
struct v4l2_rect *compose, *crop;
u32 val = 0;
state = v4l2_subdev_lock_and_get_active_state(&byteproc->sd);
sink_fmt = v4l2_subdev_state_get_format(state, 0);
compose = v4l2_subdev_state_get_compose(state, 0);
crop = v4l2_subdev_state_get_crop(state, 1);
v4l2_subdev_unlock_state(state);
/* find output format bpp */
vpix = dcmipp_byteproc_pix_map_by_code(sink_fmt->code);
@ -458,46 +447,73 @@ static int dcmipp_byteproc_configure_scale_crop
return 0;
}
static int dcmipp_byteproc_s_stream(struct v4l2_subdev *sd, int enable)
static int dcmipp_byteproc_enable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd);
struct v4l2_subdev *s_subdev;
struct media_pad *pad;
int ret = 0;
struct media_pad *s_pad;
int ret;
/* Get source subdev */
pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
return -EINVAL;
s_subdev = media_entity_to_v4l2_subdev(pad->entity);
s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
if (enable) {
ret = dcmipp_byteproc_configure_scale_crop(byteproc);
if (ret)
return ret;
ret = dcmipp_byteproc_configure_scale_crop(byteproc, state);
if (ret)
return ret;
ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
if (ret < 0) {
dev_err(byteproc->dev,
"failed to start source subdev streaming (%d)\n",
ret);
return ret;
}
} else {
ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
if (ret < 0) {
dev_err(byteproc->dev,
"failed to stop source subdev streaming (%d)\n",
ret);
return ret;
}
ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0));
if (ret < 0) {
dev_err(byteproc->dev,
"failed to start source subdev streaming (%d)\n", ret);
return ret;
}
return 0;
}
static int dcmipp_byteproc_disable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd);
struct v4l2_subdev *s_subdev;
struct media_pad *s_pad;
int ret;
/* Get source subdev */
s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
return -EINVAL;
s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
ret = v4l2_subdev_disable_streams(s_subdev, s_pad->index, BIT_ULL(0));
if (ret < 0) {
dev_err(byteproc->dev,
"failed to start source subdev streaming (%d)\n", ret);
return ret;
}
return 0;
}
static const struct v4l2_subdev_pad_ops dcmipp_byteproc_pad_ops = {
.enum_mbus_code = dcmipp_byteproc_enum_mbus_code,
.enum_frame_size = dcmipp_byteproc_enum_frame_size,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = dcmipp_byteproc_set_fmt,
.get_selection = dcmipp_byteproc_get_selection,
.set_selection = dcmipp_byteproc_set_selection,
.enable_streams = dcmipp_byteproc_enable_streams,
.disable_streams = dcmipp_byteproc_disable_streams,
};
static const struct v4l2_subdev_video_ops dcmipp_byteproc_video_ops = {
.s_stream = dcmipp_byteproc_s_stream,
.s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_ops dcmipp_byteproc_ops = {

View File

@ -260,18 +260,11 @@ static int dcmipp_par_set_fmt(struct v4l2_subdev *sd,
return 0;
}
static const struct v4l2_subdev_pad_ops dcmipp_par_pad_ops = {
.enum_mbus_code = dcmipp_par_enum_mbus_code,
.enum_frame_size = dcmipp_par_enum_frame_size,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = dcmipp_par_set_fmt,
};
static int dcmipp_par_configure(struct dcmipp_par_device *par)
static int dcmipp_par_configure(struct dcmipp_par_device *par,
struct v4l2_subdev_state *state)
{
u32 val = 0;
const struct dcmipp_par_pix_map *vpix;
struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *sink_fmt;
struct v4l2_mbus_framefmt *src_fmt;
@ -305,10 +298,8 @@ static int dcmipp_par_configure(struct dcmipp_par_device *par)
}
/* Set format */
state = v4l2_subdev_lock_and_get_active_state(&par->sd);
sink_fmt = v4l2_subdev_state_get_format(state, 0);
src_fmt = v4l2_subdev_state_get_format(state, 1);
v4l2_subdev_unlock_state(state);
vpix = dcmipp_par_pix_map_by_code(sink_fmt->code, src_fmt->code);
if (!vpix) {
@ -327,53 +318,79 @@ static int dcmipp_par_configure(struct dcmipp_par_device *par)
return 0;
}
static int dcmipp_par_s_stream(struct v4l2_subdev *sd, int enable)
static int dcmipp_par_enable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
struct dcmipp_par_device *par =
container_of(sd, struct dcmipp_par_device, sd);
struct v4l2_subdev *s_subdev;
struct media_pad *pad;
int ret = 0;
struct media_pad *s_pad;
int ret;
/* Get source subdev */
pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
return -EINVAL;
s_subdev = media_entity_to_v4l2_subdev(pad->entity);
s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
if (enable) {
ret = dcmipp_par_configure(par);
if (ret)
return ret;
ret = dcmipp_par_configure(par, state);
if (ret)
return ret;
/* Enable parallel interface */
reg_set(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
/* Enable parallel interface */
reg_set(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
if (ret < 0) {
dev_err(par->dev,
"failed to start source subdev streaming (%d)\n",
ret);
return ret;
}
} else {
ret = v4l2_subdev_call(s_subdev, video, s_stream, enable);
if (ret < 0) {
dev_err(par->dev,
"failed to stop source subdev streaming (%d)\n",
ret);
return ret;
}
/* Disable parallel interface */
reg_clear(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0));
if (ret < 0) {
dev_err(par->dev,
"failed to start source subdev streaming (%d)\n", ret);
return ret;
}
return ret;
return 0;
}
static int dcmipp_par_disable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
struct dcmipp_par_device *par =
container_of(sd, struct dcmipp_par_device, sd);
struct v4l2_subdev *s_subdev;
struct media_pad *s_pad;
int ret;
/* Get source subdev */
s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]);
if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity))
return -EINVAL;
s_subdev = media_entity_to_v4l2_subdev(s_pad->entity);
ret = v4l2_subdev_disable_streams(s_subdev, s_pad->index, BIT_ULL(0));
if (ret < 0) {
dev_err(par->dev,
"failed to stop source subdev streaming (%d)\n", ret);
return ret;
}
/* Disable parallel interface */
reg_clear(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE);
return 0;
}
static const struct v4l2_subdev_pad_ops dcmipp_par_pad_ops = {
.enum_mbus_code = dcmipp_par_enum_mbus_code,
.enum_frame_size = dcmipp_par_enum_frame_size,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = dcmipp_par_set_fmt,
.enable_streams = dcmipp_par_enable_streams,
.disable_streams = dcmipp_par_disable_streams,
};
static const struct v4l2_subdev_video_ops dcmipp_par_video_ops = {
.s_stream = dcmipp_par_s_stream,
.s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_ops dcmipp_par_ops = {