summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2019-02-27 15:26:40 +0100
committerJacopo Mondi <jacopo@jmondi.org>2019-04-03 10:11:17 +0200
commitd698ed27494a11b780ba786b148cb5060e40b2f1 (patch)
tree43761159a50093c7e1798af8753146dab2d3e393
parent2be53dc60565822008ebb7d877bc10e6c234ef8f (diff)
libcamera: ipu3: Create ImgUDevice class
Group ImgU components in a class associated with a camera at camera registration time and provide an intialization method to create and open all video devices and subdevices of the ImgU. Statically assign imgu0 to the first camera and imgu1 to the second one and limit support to two cameras. This will have to be revised in the future. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r--src/libcamera/pipeline/ipu3/ipu3.cpp154
1 files changed, 144 insertions, 10 deletions
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 02521f5f..c4b0c16e 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -26,6 +26,43 @@ namespace libcamera {
LOG_DEFINE_CATEGORY(IPU3)
+class ImgUDevice
+{
+public:
+ static constexpr unsigned int PAD_INPUT = 0;
+ static constexpr unsigned int PAD_OUTPUT = 2;
+ static constexpr unsigned int PAD_VF = 3;
+ static constexpr unsigned int PAD_STAT = 4;
+
+ ImgUDevice()
+ : imgu_(nullptr), input_(nullptr), output_(nullptr),
+ viewfinder_(nullptr), stat_(nullptr)
+ {
+ }
+
+ ~ImgUDevice()
+ {
+ delete imgu_;
+ delete input_;
+ delete output_;
+ delete viewfinder_;
+ delete stat_;
+ }
+
+ int init(MediaDevice *media, unsigned int index);
+
+ unsigned int index_;
+ std::string name_;
+ MediaDevice *media_;
+
+ V4L2Subdevice *imgu_;
+ V4L2Device *input_;
+ V4L2Device *output_;
+ V4L2Device *viewfinder_;
+ V4L2Device *stat_;
+ /* \todo Add param video device for 3A tuning */
+};
+
class CIO2Device
{
public:
@@ -88,6 +125,7 @@ private:
void bufferReady(Buffer *buffer);
CIO2Device cio2_;
+ ImgUDevice *imgu_;
Stream stream_;
};
@@ -98,8 +136,10 @@ private:
PipelineHandler::cameraData(camera));
}
- void registerCameras();
+ int registerCameras();
+ ImgUDevice imgu0_;
+ ImgUDevice imgu1_;
std::shared_ptr<MediaDevice> cio2MediaDev_;
std::shared_ptr<MediaDevice> imguMediaDev_;
};
@@ -290,6 +330,8 @@ int PipelineHandlerIPU3::queueRequest(Camera *camera, Request *request)
bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
{
+ int ret;
+
DeviceMatch cio2_dm("ipu3-cio2");
cio2_dm.add("ipu3-csi2 0");
cio2_dm.add("ipu3-cio2 0");
@@ -345,36 +387,68 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)
return false;
}
- registerCameras();
+ if (imguMediaDev_->open()) {
+ cio2MediaDev_->close();
+ return false;
+ }
+
+ if (imguMediaDev_->disableLinks())
+ goto error;
+ ret = registerCameras();
+
+error:
cio2MediaDev_->close();
+ imguMediaDev_->close();
- return true;
+ return ret == 0;
}
-/*
- * Cameras are created associating an image sensor (represented by a
- * media entity with function MEDIA_ENT_F_CAM_SENSOR) to one of the four
- * CIO2 CSI-2 receivers.
+/**
+ * \brief Initialise ImgU and CIO2 devices associated with cameras
+ *
+ * Initialise the two ImgU instances and create cameras with an associated
+ * CIO2 device instance.
+ *
+ * \return 0 on success or a negative error code for error or if no camera
+ * has been created
+ * \retval -ENODEV no camera has been created
*/
-void PipelineHandlerIPU3::registerCameras()
+int PipelineHandlerIPU3::registerCameras()
{
+ int ret;
+
+ ret = imgu0_.init(imguMediaDev_.get(), 0);
+ if (ret)
+ return ret;
+
+ ret = imgu1_.init(imguMediaDev_.get(), 1);
+ if (ret)
+ return ret;
+
/*
* For each CSI-2 receiver on the IPU3, create a Camera if an
* image sensor is connected to it and the sensor can produce images
* in a compatible format.
*/
unsigned int numCameras = 0;
- for (unsigned int id = 0; id < 4; ++id) {
+ for (unsigned int id = 0; id < 4 && numCameras < 2; ++id) {
std::unique_ptr<IPU3CameraData> data =
utils::make_unique<IPU3CameraData>(this);
std::set<Stream *> streams{ &data->stream_ };
CIO2Device *cio2 = &data->cio2_;
- int ret = cio2->init(cio2MediaDev_.get(), id);
+ ret = cio2->init(cio2MediaDev_.get(), id);
if (ret)
continue;
+ /**
+ * \todo Dynamically assign ImgU devices; as of now, limit
+ * support to two cameras only, and assign imgu0 to the first
+ * one and imgu1 to the second.
+ */
+ data->imgu_ = numCameras ? &imgu1_ : &imgu0_;
+
std::string cameraName = cio2->sensor_->entityName() + " "
+ std::to_string(id);
std::shared_ptr<Camera> camera = Camera::create(this,
@@ -393,6 +467,8 @@ void PipelineHandlerIPU3::registerCameras()
numCameras++;
}
+
+ return numCameras ? 0 : -ENODEV;
}
void PipelineHandlerIPU3::IPU3CameraData::bufferReady(Buffer *buffer)
@@ -403,6 +479,64 @@ void PipelineHandlerIPU3::IPU3CameraData::bufferReady(Buffer *buffer)
pipe_->completeRequest(camera_, request);
}
+/* -----------------------------------------------------------------------------
+ * ImgU Device
+ */
+
+/**
+ * \brief Initialize components of the ImgU instance
+ * \param[in] mediaDevice The ImgU instance media device
+ * \param[in] index The ImgU instance index
+ *
+ * Create and open the V4L2 devices and subdevices of the ImgU instance
+ * with \a index.
+ *
+ * In case of errors the created V4L2Device and V4L2Subdevice instances
+ * are destroyed at pipeline handler delete time.
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+int ImgUDevice::init(MediaDevice *media, unsigned int index)
+{
+ int ret;
+
+ index_ = index;
+ name_ = "ipu3-imgu " + std::to_string(index_);
+ media_ = media;
+
+ /*
+ * The media entities presence in the media device has been verified
+ * by the match() function: no need to check for newly created
+ * video devices and subdevice validity here.
+ */
+ imgu_ = V4L2Subdevice::fromEntityName(media, name_);
+ ret = imgu_->open();
+ if (ret)
+ return ret;
+
+ input_ = V4L2Device::fromEntityName(media, name_ + " input");
+ ret = input_->open();
+ if (ret)
+ return ret;
+
+ output_ = V4L2Device::fromEntityName(media, name_ + " output");
+ ret = output_->open();
+ if (ret)
+ return ret;
+
+ viewfinder_ = V4L2Device::fromEntityName(media, name_ + " viewfinder");
+ ret = viewfinder_->open();
+ if (ret)
+ return ret;
+
+ stat_ = V4L2Device::fromEntityName(media, name_ + " 3a stat");
+ ret = stat_->open();
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
/*------------------------------------------------------------------------------
* CIO2 Device
*/