From patchwork Wed Feb 6 06:08:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 539 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4C84A6102E for ; Wed, 6 Feb 2019 07:08:29 +0100 (CET) Received: from pendragon.ideasonboard.com (d51A4137F.access.telenet.be [81.164.19.127]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EA75D2D8 for ; Wed, 6 Feb 2019 07:08:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1549433309; bh=MDucwjuFwsuJIjZgyjkqHrLzRxfhWJSMRbAeJMD74Pw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oiv0D6Z0feX72kirK/N23RIFNUJaxLztgZ1c3qC+RbRnuvLZct0TYW/a7n4XeLSpQ Ounr+jBMcec/A1GPO4duXstrLQmNSVQQdKXvF5uI80G0M+7IjIoWUHHVukVFIGifvR 6k+fq0KPop98a8z6ZUWDnzKVgs7kgBW4aac2YZQU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Wed, 6 Feb 2019 08:08:15 +0200 Message-Id: <20190206060818.13907-25-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190206060818.13907-1-laurent.pinchart@ideasonboard.com> References: <20190206060818.13907-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 24/27] libcamera: pipeline: ipu3: Implement capture support 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: Wed, 06 Feb 2019 06:08:30 -0000 From: Jacopo Mondi Replace the buffer allocation, capture start/stop and request queue stubs with real implementations. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 123 +++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 9 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 9629057a1b2f..34b03995ae31 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include "device_enumerator.h" @@ -97,12 +98,23 @@ PipelineHandlerIPU3::streamConfiguration(Camera *camera, std::vector &streams) { IPU3CameraData *data = cameraData(camera); - std::map configs; + V4L2SubdeviceFormat format = {}; - StreamConfiguration config{}; + /* + * FIXME: As of now, return the image format reported by the sensor. + * In future good defaults should be provided for each stream. + */ + if (data->sensor_->getFormat(0, &format)) { + LOG(IPU3, Error) << "Failed to create stream configurations"; + return configs; + } - LOG(IPU3, Info) << "TODO: Return a good default format"; + StreamConfiguration config = {}; + config.width = format.width; + config.height = format.height; + config.pixelFormat = V4L2_PIX_FMT_IPU3_SGRBG10; + config.bufferCount = 4; configs[&data->stream_] = config; @@ -113,38 +125,131 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera, std::map &config) { IPU3CameraData *data = cameraData(camera); - StreamConfiguration *cfg = &config[&data->stream_]; + V4L2Subdevice *sensor = data->sensor_; + V4L2Subdevice *csi2 = data->csi2_; + V4L2Device *cio2 = data->cio2_; + V4L2SubdeviceFormat subdevFormat = {}; + V4L2DeviceFormat devFormat = {}; + int ret; - LOG(IPU3, Info) << "TODO: Configure the camera for resolution " - << cfg->width << "x" << cfg->height; + /* + * FIXME: as of now, the format gets applied to the sensor and is + * propagated along the pipeline. It should instead be applied on the + * capture device and the sensor format calculated accordingly. + */ + + ret = sensor->getFormat(0, &subdevFormat); + if (ret) + return ret; + + subdevFormat.width = cfg->width; + subdevFormat.height = cfg->height; + ret = sensor->setFormat(0, &subdevFormat); + if (ret) + return ret; + + /* Return error if the requested format cannot be applied to sensor. */ + if (subdevFormat.width != cfg->width || + subdevFormat.height != cfg->height) { + LOG(IPU3, Error) + << "Failed to apply image format " + << subdevFormat.width << "x" << subdevFormat.height + << " - got: " << cfg->width << "x" << cfg->height; + return -EINVAL; + } + + ret = csi2->setFormat(0, &subdevFormat); + if (ret) + return ret; + + ret = cio2->getFormat(&devFormat); + if (ret) + return ret; + + devFormat.width = subdevFormat.width; + devFormat.height = subdevFormat.height; + devFormat.fourcc = cfg->pixelFormat; + + ret = cio2->setFormat(&devFormat); + if (ret) + return ret; + + LOG(IPU3, Info) << cio2->driverName() << ": " + << devFormat.width << "x" << devFormat.height + << "- 0x" << std::hex << devFormat.fourcc << " planes: " + << devFormat.planes; return 0; } int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) { - return -ENOTRECOVERABLE; + IPU3CameraData *data = cameraData(camera); + const StreamConfiguration &cfg = stream->configuration(); + + if (!cfg.bufferCount) + return -EINVAL; + + int ret = data->cio2_->exportBuffers(cfg.bufferCount, + &stream->bufferPool()); + if (ret) { + LOG(IPU3, Error) << "Failed to request memory"; + return ret; + } + + return 0; } int PipelineHandlerIPU3::freeBuffers(Camera *camera, Stream *stream) { + IPU3CameraData *data = cameraData(camera); + + int ret = data->cio2_->releaseBuffers(); + if (ret) { + LOG(IPU3, Error) << "Failed to release memory"; + return ret; + } + return 0; } int PipelineHandlerIPU3::start(const Camera *camera) { - LOG(IPU3, Error) << "TODO: start camera"; + IPU3CameraData *data = cameraData(camera); + int ret; + + ret = data->cio2_->streamOn(); + if (ret) { + LOG(IPU3, Info) << "Failed to start camera " << camera->name(); + return ret; + } + return 0; } void PipelineHandlerIPU3::stop(const Camera *camera) { - LOG(IPU3, Error) << "TODO: stop camera"; + IPU3CameraData *data = cameraData(camera); + + if (data->cio2_->streamOff()) + LOG(IPU3, Info) << "Failed to stop camera " << camera->name(); } int PipelineHandlerIPU3::queueRequest(const Camera *camera, Request *request) { + IPU3CameraData *data = cameraData(camera); + Stream *stream = &data->stream_; + + Buffer *buffer = request->findBuffer(stream); + if (!buffer) { + LOG(IPU3, Error) + << "Attempt to queue request with invalid stream"; + return -ENOENT; + } + + data->cio2_->queueBuffer(buffer); + return 0; }