// vi:ft=cpp /* * (c) 2011 Adam Lackorzynski * economic rights: Technische Universität Dresden (Germany) * * This file is part of TUD:OS and distributed under the terms of the * GNU General Public License 2. * Please see the COPYING-GPL-2 file for details. */ #pragma once #include #include #include /** * \ingroup l4vbus_module * \{ */ namespace L4vbus { class Vbus; /** * \ingroup l4vbus_module * \brief Power-management API mixin. */ template class Pm { private: DEC const *self() const { return static_cast(this); } DEC *self() { return static_cast(this); } public: /** * \brief Suspend the module. */ int pm_suspend() const { return l4vbus_pm_suspend(self()->bus_cap().cap(), self()->dev_handle()); } /** * \brief Resume the module. */ int pm_resume() const { return l4vbus_pm_resume(self()->bus_cap().cap(), self()->dev_handle()); } }; /** * \ingroup l4vbus_module * \brief Device on a virtual bus (V-BUS) */ class Device : public Pm { public: Device() : _dev(L4VBUS_NULL) {} Device(L4::Cap bus, l4vbus_device_handle_t dev) : _bus(bus), _dev(dev) {} /** * \brief access the V-BUS capability of the underlying virtual bus. * \return the capability to the underlying V-BUS. */ L4::Cap bus_cap() const { return _bus; } /** * \brief access the device handle of this device. * \return the device handle for this device. * * The device handle is used to directly address the device on its virtual * bus. */ l4vbus_device_handle_t dev_handle() const { return _dev; } /** * \copydoc l4vbus_get_device_by_hid() * \note \a vbus and \a parent are Device#_bus and Device#_dev respectively. */ int device_by_hid(Device *child, char const *hid, int depth = L4VBUS_MAX_DEPTH, l4vbus_device_t *devinfo = 0) const { child->_bus = _bus; return l4vbus_get_device_by_hid(_bus.cap(), _dev, &child->_dev, hid, depth, devinfo); } /** * \copydoc l4vbus_get_next_device() * \note \a vbus and \a parent are Device#_bus and Device#_dev respectively. */ int next_device(Device *child, int depth = L4VBUS_MAX_DEPTH, l4vbus_device_t *devinfo = 0) const { child->_bus = _bus; return l4vbus_get_next_device(_bus.cap(), _dev, &child->_dev, depth, devinfo); } /** * \copydoc l4vbus_get_resource() * \note \a vbus and \a dev are Device#_bus and Device#_dev respectively. */ int get_resource(int res_idx, l4vbus_resource_t *res) const { return l4vbus_get_resource(_bus.cap(), _dev, res_idx, res); } /** * \copydoc l4vbus_is_compatible() * \note \a vbus and \a dev are Device#_bus and Device#_dev respectively. */ int is_compatible(char const *cid) const { return l4vbus_is_compatible(_bus.cap(), _dev, cid); } /** * \brief Test if two devices are the same V-BUS device. * \return true if the two devices are the same, false else. */ bool operator == (Device const &o) const { return _bus == o._bus && _dev == o._dev; } /** * \brief Test if two devices are not the same. * \return true if the two devices are different, false else. */ bool operator != (Device const &o) const { return _bus != o._bus || _dev != o._dev; } protected: L4::Cap _bus; /*!< The V-BUS capability (where this device is located on). */ l4vbus_device_handle_t _dev; ///< The device handle for this device. }; /** * \ingroup l4vbus_module * \brief V-BUS Interrupt controller API (ICU) * * Allows to access the underlying L4Re::Icu capability managing IRQs for * the V-BUS. */ class Icu : public Device { public: /** * \brief Request the L4Re::Icu capability for this V-BUS ICU. */ int vicu(L4::Cap icu) const { return l4vbus_vicu_get_cap(_bus.cap(), _dev, icu.cap()); } }; /** * \ingroup l4vbus_module * \brief The virtual BUS. */ class Vbus : public L4::Kobject_t { L4_KOBJECT_DISABLE_COPY(Vbus) public: /** * \brief Request the given resource from the bus. * \param res The resource that shall be requested from the bus. * \param flags The flags for the request. * \return >=0 on success, <0 on error. */ int request_resource(l4vbus_resource_t *res, int flags = 0) const { return l4vbus_request_resource(cap(), res, flags); } /** * \brief Release the given resource from the bus. * \param res The resource that shall be requested from the bus. * \return >=0 on success, <0 on error. */ int release_resource(l4vbus_resource_t *res) const { return l4vbus_release_resource(cap(), res); } /** * \brief Get the root of device of the device tree of this bus. * \return A V-BUS device representing the root of the device tree. */ Device root() const { return Device(L4::Cap(cap()), L4VBUS_ROOT_BUS); } }; } /** \} */