#pragma once
#include <l4/vbus/vbus.h>
+#include <l4/vbus/vbus_pm.h>
#include <l4/sys/icu>
+/**
+ * \ingroup l4vbus_module
+ * \{ */
namespace L4vbus {
class Vbus;
-class Device
+/**
+ * \ingroup l4vbus_module
+ * \brief Power-management API mixin.
+ */
+template<typename DEC>
+class Pm
+{
+private:
+ DEC const *self() const { return static_cast<DEC const *>(this); }
+ DEC *self() { return static_cast<DEC *>(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<Device>
{
public:
Device() : _dev(L4VBUS_NULL) {}
Device(L4::Cap<Vbus> 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<Vbus> 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);
+ 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);
+ 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<Vbus> _bus;
- l4vbus_device_handle_t _dev;
+ L4::Cap<Vbus> _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<L4::Icu> 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<Vbus, L4::Kobject>
{
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<Vbus>(cap()), L4VBUS_ROOT_BUS); }
-
+ return Device(L4::Cap<Vbus>(cap()), L4VBUS_ROOT_BUS);
+ }
};
}
-
+/** \} */