From patchwork Thu Jan 3 17:38:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 147 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AE50960B2D for ; Thu, 3 Jan 2019 18:39:03 +0100 (CET) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 4B39FFF804; Thu, 3 Jan 2019 17:39:03 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 3 Jan 2019 18:38:57 +0100 Message-Id: <20190103173859.22624-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190103173859.22624-1-jacopo@jmondi.org> References: <20190103173859.22624-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/5] libcamera: Add MediaLink link setup function X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Jan 2019 17:39:04 -0000 Add a function to the MediaLink class to set the state of a link to enabled or disabled. The function makes use of an internal MediaDevice method, which is defined private and only accessible by the MediaLink setup() function itself. Signed-off-by: Jacopo Mondi --- src/libcamera/include/media_device.h | 8 ++++++ src/libcamera/include/media_object.h | 1 + src/libcamera/media_device.cpp | 30 +++++++++++++++++++++ src/libcamera/media_object.cpp | 40 ++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/src/libcamera/include/media_device.h b/src/libcamera/include/media_device.h index 3228ad5..d019639 100644 --- a/src/libcamera/include/media_device.h +++ b/src/libcamera/include/media_device.h @@ -65,6 +65,14 @@ private: bool populateEntities(const struct media_v2_topology &topology); bool populatePads(const struct media_v2_topology &topology); bool populateLinks(const struct media_v2_topology &topology); + + /* + * The MediaLink enable method needs to access the private + * setLink() function. + */ + friend int MediaLink::enable(bool enable); + int setLink(const MediaPad *source, const MediaPad *sink, + unsigned int flags); }; } /* namespace libcamera */ diff --git a/src/libcamera/include/media_object.h b/src/libcamera/include/media_object.h index 0f0bb29..e00c639 100644 --- a/src/libcamera/include/media_object.h +++ b/src/libcamera/include/media_object.h @@ -40,6 +40,7 @@ public: MediaPad *source() const { return source_; } MediaPad *sink() const { return sink_; } unsigned int flags() const { return flags_; } + int enable(bool enable); private: friend class MediaDevice; diff --git a/src/libcamera/media_device.cpp b/src/libcamera/media_device.cpp index 6892300..b86d0c4 100644 --- a/src/libcamera/media_device.cpp +++ b/src/libcamera/media_device.cpp @@ -641,4 +641,34 @@ bool MediaDevice::populateLinks(const struct media_v2_topology &topology) return true; } +int MediaDevice::setLink(const MediaPad *source, const MediaPad *sink, + unsigned int flags) +{ + struct media_link_desc linkDesc = { }; + + linkDesc.source.entity = source->entity()->id(); + linkDesc.source.index = source->index(); + linkDesc.source.flags = MEDIA_PAD_FL_SOURCE; + + linkDesc.sink.entity = sink->entity()->id(); + linkDesc.sink.index = sink->index(); + linkDesc.sink.flags = MEDIA_PAD_FL_SINK; + + linkDesc.flags = flags; + + int ret = ioctl(fd_, MEDIA_IOC_SETUP_LINK, &linkDesc); + if (ret) { + ret = -errno; + LOG(Error) << "Failed to setup link: " << strerror(-ret) << "\n"; + return ret; + } + + LOG(Debug) << source->entity()->name() << "[" + << source->index() << "] -> " + << sink->entity()->name() << "[" + << sink->index() << "]: " << flags; + + return 0; +} + } /* namespace libcamera */ diff --git a/src/libcamera/media_object.cpp b/src/libcamera/media_object.cpp index f1535e6..1ee8823 100644 --- a/src/libcamera/media_object.cpp +++ b/src/libcamera/media_object.cpp @@ -16,6 +16,7 @@ #include "log.h" #include "media_object.h" +#include "media_device.h" /** * \file media_object.h @@ -87,6 +88,45 @@ namespace libcamera { * Each link is referenced in the link array of both of the pads it connect. */ +/** + * \brief Set a link state to enabled or disabled + * \param enable The enable flag, true enables the link, false disables it + * + * Set the status of a link, according to the value of \a enable. + * Links between two pads can be set to the enabled or disabled state freely, + * unless they're immutable links, whose status cannot be changed. + * Enabling an immutable link is not considered an error, while trying to + * disable it is. Caller should inspect the link flags before trying to + * disable an immutable link. + * + * Enabling a link establishes a data connection between two pads, while + * disabling it interrupts such a connections. + * + * \return 0 for success, negative error code otherwise + */ +int MediaLink::enable(bool enable) +{ + unsigned int flags = enable ? MEDIA_LNK_FL_ENABLED : 0; + + if ((flags_ & MEDIA_LNK_FL_IMMUTABLE) && !enable) { + LOG(Error) << "Immutable links cannot be disabled"; + return -EINVAL; + } + + /* Do not try to enable an already enabled link. */ + if ((flags_ & MEDIA_LNK_FL_ENABLED) && enable) + return 0; + + int ret = media_->setLink(source_, sink_, flags); + if (ret) + return ret; + + /* Only update flags if 'setLink()' didn't fail. */ + flags_ = flags; + + return 0; +} + /** * \brief Construct a MediaLink * \param media The media device this entity belongs to