Lines Matching +full:no +full:- +full:sd

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * Copyright (C) 2016-2017 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
17 #include <media/v4l2-async.h>
18 #include <media/v4l2-device.h>
19 #include <media/v4l2-fwnode.h>
20 #include <media/v4l2-mc.h>
21 #include <media/v4l2-subdev.h>
46 static inline struct video_mux *v4l2_subdev_to_video_mux(struct v4l2_subdev *sd) in v4l2_subdev_to_video_mux() argument
48 return container_of(sd, struct video_mux, subdev); in v4l2_subdev_to_video_mux()
55 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); in video_mux_link_setup() local
56 struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); in video_mux_link_setup()
57 u16 source_pad = entity->num_pads - 1; in video_mux_link_setup()
62 * Enabling or disabling the source pad link has no effect. in video_mux_link_setup()
64 if (local->flags & MEDIA_PAD_FL_SOURCE) in video_mux_link_setup()
67 dev_dbg(sd->dev, "link setup '%s':%d->'%s':%d[%d]", in video_mux_link_setup()
68 remote->entity->name, remote->index, local->entity->name, in video_mux_link_setup()
69 local->index, flags & MEDIA_LNK_FL_ENABLED); in video_mux_link_setup()
71 mutex_lock(&vmux->lock); in video_mux_link_setup()
74 if (vmux->active == local->index) in video_mux_link_setup()
77 if (vmux->active >= 0) { in video_mux_link_setup()
78 ret = -EBUSY; in video_mux_link_setup()
82 dev_dbg(sd->dev, "setting %d active\n", local->index); in video_mux_link_setup()
83 ret = mux_control_try_select(vmux->mux, local->index); in video_mux_link_setup()
86 vmux->active = local->index; in video_mux_link_setup()
89 vmux->format_mbus[source_pad] = vmux->format_mbus[vmux->active]; in video_mux_link_setup()
91 if (vmux->active != local->index) in video_mux_link_setup()
94 dev_dbg(sd->dev, "going inactive\n"); in video_mux_link_setup()
95 mux_control_deselect(vmux->mux); in video_mux_link_setup()
96 vmux->active = -1; in video_mux_link_setup()
100 mutex_unlock(&vmux->lock); in video_mux_link_setup()
110 static int video_mux_s_stream(struct v4l2_subdev *sd, int enable) in video_mux_s_stream() argument
112 struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); in video_mux_s_stream()
116 if (vmux->active == -1) { in video_mux_s_stream()
117 dev_err(sd->dev, "Can not start streaming on inactive mux\n"); in video_mux_s_stream()
118 return -EINVAL; in video_mux_s_stream()
121 pad = media_entity_remote_pad(&sd->entity.pads[vmux->active]); in video_mux_s_stream()
123 dev_err(sd->dev, "Failed to find remote source pad\n"); in video_mux_s_stream()
124 return -ENOLINK; in video_mux_s_stream()
127 if (!is_media_entity_v4l2_subdev(pad->entity)) { in video_mux_s_stream()
128 dev_err(sd->dev, "Upstream entity is not a v4l2 subdev\n"); in video_mux_s_stream()
129 return -ENODEV; in video_mux_s_stream()
132 upstream_sd = media_entity_to_v4l2_subdev(pad->entity); in video_mux_s_stream()
142 __video_mux_get_pad_format(struct v4l2_subdev *sd, in __video_mux_get_pad_format() argument
146 struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); in __video_mux_get_pad_format()
150 return v4l2_subdev_get_try_format(sd, cfg, pad); in __video_mux_get_pad_format()
152 return &vmux->format_mbus[pad]; in __video_mux_get_pad_format()
158 static int video_mux_get_format(struct v4l2_subdev *sd, in video_mux_get_format() argument
162 struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); in video_mux_get_format()
164 mutex_lock(&vmux->lock); in video_mux_get_format()
166 sdformat->format = *__video_mux_get_pad_format(sd, cfg, sdformat->pad, in video_mux_get_format()
167 sdformat->which); in video_mux_get_format()
169 mutex_unlock(&vmux->lock); in video_mux_get_format()
174 static int video_mux_set_format(struct v4l2_subdev *sd, in video_mux_set_format() argument
178 struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); in video_mux_set_format()
180 struct media_pad *pad = &vmux->pads[sdformat->pad]; in video_mux_set_format()
181 u16 source_pad = sd->entity.num_pads - 1; in video_mux_set_format()
183 mbusformat = __video_mux_get_pad_format(sd, cfg, sdformat->pad, in video_mux_set_format()
184 sdformat->which); in video_mux_set_format()
186 return -EINVAL; in video_mux_set_format()
188 source_mbusformat = __video_mux_get_pad_format(sd, cfg, source_pad, in video_mux_set_format()
189 sdformat->which); in video_mux_set_format()
191 return -EINVAL; in video_mux_set_format()
193 /* No size limitations except V4L2 compliance requirements */ in video_mux_set_format()
194 v4l_bound_align_image(&sdformat->format.width, 1, 65536, 0, in video_mux_set_format()
195 &sdformat->format.height, 1, 65536, 0, 0); in video_mux_set_format()
198 switch (sdformat->format.code) { in video_mux_set_format()
289 sdformat->format.code = MEDIA_BUS_FMT_Y8_1X8; in video_mux_set_format()
292 if (sdformat->format.field == V4L2_FIELD_ANY) in video_mux_set_format()
293 sdformat->format.field = V4L2_FIELD_NONE; in video_mux_set_format()
295 mutex_lock(&vmux->lock); in video_mux_set_format()
297 /* Source pad mirrors active sink pad, no limitations on sink pads */ in video_mux_set_format()
298 if ((pad->flags & MEDIA_PAD_FL_SOURCE) && vmux->active >= 0) in video_mux_set_format()
299 sdformat->format = vmux->format_mbus[vmux->active]; in video_mux_set_format()
301 *mbusformat = sdformat->format; in video_mux_set_format()
304 if ((pad->flags & MEDIA_PAD_FL_SINK) && (pad->index == vmux->active)) in video_mux_set_format()
305 *source_mbusformat = sdformat->format; in video_mux_set_format()
307 mutex_unlock(&vmux->lock); in video_mux_set_format()
312 static int video_mux_init_cfg(struct v4l2_subdev *sd, in video_mux_init_cfg() argument
315 struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); in video_mux_init_cfg()
319 mutex_lock(&vmux->lock); in video_mux_init_cfg()
321 for (i = 0; i < sd->entity.num_pads; i++) { in video_mux_init_cfg()
322 mbusformat = v4l2_subdev_get_try_format(sd, cfg, i); in video_mux_init_cfg()
326 mutex_unlock(&vmux->lock); in video_mux_init_cfg()
343 struct v4l2_subdev *sd, in video_mux_notify_bound() argument
348 return v4l2_create_fwnode_links(sd, &vmux->subdev); in video_mux_notify_bound()
361 v4l2_async_notifier_init(&vmux->notifier); in video_mux_async_register()
368 dev_fwnode(vmux->subdev.dev), i, 0, in video_mux_async_register()
376 return -ENOMEM; in video_mux_async_register()
380 &vmux->notifier, ep, asd); in video_mux_async_register()
387 if (ret != -EEXIST) in video_mux_async_register()
392 vmux->notifier.ops = &video_mux_notify_ops; in video_mux_async_register()
394 ret = v4l2_async_subdev_notifier_register(&vmux->subdev, in video_mux_async_register()
395 &vmux->notifier); in video_mux_async_register()
399 return v4l2_async_register_subdev(&vmux->subdev); in video_mux_async_register()
404 struct device_node *np = pdev->dev.of_node; in video_mux_probe()
405 struct device *dev = &pdev->dev; in video_mux_probe()
414 return -ENOMEM; in video_mux_probe()
418 v4l2_subdev_init(&vmux->subdev, &video_mux_subdev_ops); in video_mux_probe()
419 snprintf(vmux->subdev.name, sizeof(vmux->subdev.name), "%pOFn", np); in video_mux_probe()
420 vmux->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in video_mux_probe()
421 vmux->subdev.dev = dev; in video_mux_probe()
436 return -EINVAL; in video_mux_probe()
439 vmux->mux = devm_mux_control_get(dev, NULL); in video_mux_probe()
440 if (IS_ERR(vmux->mux)) { in video_mux_probe()
441 ret = PTR_ERR(vmux->mux); in video_mux_probe()
442 if (ret != -EPROBE_DEFER) in video_mux_probe()
447 mutex_init(&vmux->lock); in video_mux_probe()
448 vmux->active = -1; in video_mux_probe()
449 vmux->pads = devm_kcalloc(dev, num_pads, sizeof(*vmux->pads), in video_mux_probe()
451 if (!vmux->pads) in video_mux_probe()
452 return -ENOMEM; in video_mux_probe()
454 vmux->format_mbus = devm_kcalloc(dev, num_pads, in video_mux_probe()
455 sizeof(*vmux->format_mbus), in video_mux_probe()
457 if (!vmux->format_mbus) in video_mux_probe()
458 return -ENOMEM; in video_mux_probe()
461 vmux->pads[i].flags = (i < num_pads - 1) ? MEDIA_PAD_FL_SINK in video_mux_probe()
463 vmux->format_mbus[i] = video_mux_format_mbus_default; in video_mux_probe()
466 vmux->subdev.entity.function = MEDIA_ENT_F_VID_MUX; in video_mux_probe()
467 ret = media_entity_pads_init(&vmux->subdev.entity, num_pads, in video_mux_probe()
468 vmux->pads); in video_mux_probe()
472 vmux->subdev.entity.ops = &video_mux_ops; in video_mux_probe()
474 ret = video_mux_async_register(vmux, num_pads - 1); in video_mux_probe()
476 v4l2_async_notifier_unregister(&vmux->notifier); in video_mux_probe()
477 v4l2_async_notifier_cleanup(&vmux->notifier); in video_mux_probe()
486 struct v4l2_subdev *sd = &vmux->subdev; in video_mux_remove() local
488 v4l2_async_notifier_unregister(&vmux->notifier); in video_mux_remove()
489 v4l2_async_notifier_cleanup(&vmux->notifier); in video_mux_remove()
490 v4l2_async_unregister_subdev(sd); in video_mux_remove()
491 media_entity_cleanup(&sd->entity); in video_mux_remove()
497 { .compatible = "video-mux", },
507 .name = "video-mux",