From patchwork Wed Sep 27 06:18:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 726945 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C610CE80A93 for ; Wed, 27 Sep 2023 06:18:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229884AbjI0GS4 (ORCPT ); Wed, 27 Sep 2023 02:18:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33534 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229584AbjI0GSk (ORCPT ); Wed, 27 Sep 2023 02:18:40 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9541812A for ; Tue, 26 Sep 2023 23:18:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695795519; x=1727331519; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KkACzm6rCRlzxaVRUFccKHvp1nDFcGBzYlanlUmyCVE=; b=QUhZiaTsY+seeyu6iWnMc+PyTyfoQLkOE9z8oZx5pa1ANRWHDGfXmRl+ LatMURU/ZxMfkhdiWiAmkwB5CPQeXRETKZB0Z+ll9jtGFMLMAN770ZZH/ CaUp95W5NltHCRzNeyJ3fQWtUsdLWwwUZkMLlSWxPVOqqmZoSuCk+lZ+d R/JRJR2a555I8YUkz6bYhC9blE93PbczxZ0IY2cBEJb1rAwplzxlWJxpb Rlh3zIxVyX89Ex5wkKW29HKyhvzJvwbZc9sGTdEwsb77NBf1wy/u+4irR 9LyYuNn5FjL0VjbT6VfxDTC0dvnwz1jE2N7DNlWG9NKckyiGqOI+6KK6G Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="381641102" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="381641102" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="742598578" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="742598578" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:36 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id D34E912061E; Wed, 27 Sep 2023 09:18:32 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Tianshu Qiu , Bingbu Cao , Tomi Valkeinen , Jacopo Mondi , Rui Miguel Silva , Martin Kepplinger Subject: [PATCH v5 01/13] media: Documentation: Align numbered list, make it a proper ReST Date: Wed, 27 Sep 2023 09:18:17 +0300 Message-Id: <20230927061829.366107-2-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230927061829.366107-1-sakari.ailus@linux.intel.com> References: <20230927061829.366107-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Align lines for numbered list so that Sphinx produces an uniform output for all list entries. Also indent paragraphs of such list entries for consistency. Also use ReST numbered list syntax for the entries. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart --- .../userspace-api/media/v4l/dev-subdev.rst | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/dev-subdev.rst b/Documentation/userspace-api/media/v4l/dev-subdev.rst index a4f1df7093e8..43988516acdd 100644 --- a/Documentation/userspace-api/media/v4l/dev-subdev.rst +++ b/Documentation/userspace-api/media/v4l/dev-subdev.rst @@ -579,20 +579,19 @@ is started. There are three steps in configuring the streams: -1) Set up links. Connect the pads between sub-devices using the :ref:`Media -Controller API ` +1. Set up links. Connect the pads between sub-devices using the + :ref:`Media Controller API ` -2) Streams. Streams are declared and their routing is configured by -setting the routing table for the sub-device using -:ref:`VIDIOC_SUBDEV_S_ROUTING ` ioctl. Note that -setting the routing table will reset formats and selections in the -sub-device to default values. +2. Streams. Streams are declared and their routing is configured by setting the + routing table for the sub-device using :ref:`VIDIOC_SUBDEV_S_ROUTING + ` ioctl. Note that setting the routing table will + reset formats and selections in the sub-device to default values. -3) Configure formats and selections. Formats and selections of each stream -are configured separately as documented for plain sub-devices in -:ref:`format-propagation`. The stream ID is set to the same stream ID -associated with either sink or source pads of routes configured using the -:ref:`VIDIOC_SUBDEV_S_ROUTING ` ioctl. +3. Configure formats and selections. Formats and selections of each stream are + configured separately as documented for plain sub-devices in + :ref:`format-propagation`. The stream ID is set to the same stream ID + associated with either sink or source pads of routes configured using the + :ref:`VIDIOC_SUBDEV_S_ROUTING ` ioctl. Multiplexed streams setup example ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -618,11 +617,11 @@ modeled as V4L2 devices, exposed to userspace via /dev/videoX nodes. To configure this pipeline, the userspace must take the following steps: -1) Set up media links between entities: connect the sensors to the bridge, -bridge to the receiver, and the receiver to the DMA engines. This step does -not differ from normal non-multiplexed media controller setup. +1. Set up media links between entities: connect the sensors to the bridge, + bridge to the receiver, and the receiver to the DMA engines. This step does + not differ from normal non-multiplexed media controller setup. -2) Configure routing +2. Configure routing .. flat-table:: Bridge routing table :header-rows: 1 @@ -656,14 +655,14 @@ not differ from normal non-multiplexed media controller setup. - V4L2_SUBDEV_ROUTE_FL_ACTIVE - Pixel data stream from Sensor B -3) Configure formats and selections +3. Configure formats and selections -After configuring routing, the next step is configuring the formats and -selections for the streams. This is similar to performing this step without -streams, with just one exception: the ``stream`` field needs to be assigned -to the value of the stream ID. + After configuring routing, the next step is configuring the formats and + selections for the streams. This is similar to performing this step without + streams, with just one exception: the ``stream`` field needs to be assigned + to the value of the stream ID. -A common way to accomplish this is to start from the sensors and propagate the -configurations along the stream towards the receiver, -using :ref:`VIDIOC_SUBDEV_S_FMT ` ioctls to configure each -stream endpoint in each sub-device. + A common way to accomplish this is to start from the sensors and propagate + the configurations along the stream towards the receiver, using + :ref:`VIDIOC_SUBDEV_S_FMT ` ioctls to configure each + stream endpoint in each sub-device. From patchwork Wed Sep 27 06:18:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 726944 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B9DDE80A92 for ; Wed, 27 Sep 2023 06:19:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229765AbjI0GS7 (ORCPT ); Wed, 27 Sep 2023 02:18:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37248 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229791AbjI0GSn (ORCPT ); Wed, 27 Sep 2023 02:18:43 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE8AD97 for ; Tue, 26 Sep 2023 23:18:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695795522; x=1727331522; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2rV5oZR1lD0N8kdUt1c+r+AazqaPEEAyA6KQ9dKEmOI=; b=RcuZ3og41nRCUNbiHnyGqGjIrN5HJAKyaFpxy7tvHIu2u/jovYquFNN1 QGA8ku41OnSHn5KkC31Jjq8drrFkX9sQjppHZCbK+HIY+EnBIvEVSJXNx g+6BnBWaLcFMX5k+lRJ3Mp+Xj1o+K1slXfECT11XzSdU2Lky7rxWV19+1 Eejbspfmi9ToIfP4Fvv0jWSBKGl1vj6xboUfM5mXuYBnrm7pZdhbuJw8Q v8uZBfQV/lOOyQ2XWa5aoh5cuWQfXC9nVeTSR36ANgR2Ur53QkLcw+fNJ ZWzo2GMQP3t7COpO8km5plzNYR7VppDIg+BHTB+ZEAPbAywcr0ZRNc7ZH w==; X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="381641129" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="381641129" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="742598588" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="742598588" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:39 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 34D2A120A68; Wed, 27 Sep 2023 09:18:36 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Tianshu Qiu , Bingbu Cao , Tomi Valkeinen , Jacopo Mondi , Rui Miguel Silva , Martin Kepplinger Subject: [PATCH v5 04/13] media: ccs: Correct error handling in ccs_register_subdev Date: Wed, 27 Sep 2023 09:18:20 +0300 Message-Id: <20230927061829.366107-5-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230927061829.366107-1-sakari.ailus@linux.intel.com> References: <20230927061829.366107-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org ccs_register_subdev() did not clean up the media entity in error case, do that now. Also switch to goto based error handling. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ccs/ccs-core.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 022e8712d48e..fb823c5c3dd3 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -2968,7 +2968,7 @@ static int ccs_register_subdev(struct ccs_sensor *sensor, rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, &ssd->sd); if (rval) { dev_err(&client->dev, "v4l2_device_register_subdev failed\n"); - return rval; + goto out_media_entity_cleanup; } rval = media_create_pad_link(&ssd->sd.entity, source_pad, @@ -2976,11 +2976,18 @@ static int ccs_register_subdev(struct ccs_sensor *sensor, link_flags); if (rval) { dev_err(&client->dev, "media_create_pad_link failed\n"); - v4l2_device_unregister_subdev(&ssd->sd); - return rval; + goto out_v4l2_device_unregister_subdev; } return 0; + +out_v4l2_device_unregister_subdev: + v4l2_device_unregister_subdev(&ssd->sd); + +out_media_entity_cleanup: + media_entity_cleanup(&ssd->sd.entity); + + return rval; } static void ccs_unregistered(struct v4l2_subdev *subdev) From patchwork Wed Sep 27 06:18:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 726943 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CAC99E80A95 for ; Wed, 27 Sep 2023 06:19:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229985AbjI0GT0 (ORCPT ); Wed, 27 Sep 2023 02:19:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52716 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229853AbjI0GTH (ORCPT ); Wed, 27 Sep 2023 02:19:07 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E36CC1B5 for ; Tue, 26 Sep 2023 23:19:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695795544; x=1727331544; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZzNdFvlIhtV+fG33ITPR6l3ZZYaIHdODNxyW0eJmz7s=; b=GFmktezv4lsoKZbFJCbwZEH+hmCoHjor25lhcugtQ9/VoDBERhYvpH+L EmsTXpYbU3Vi+sh1X+7qaH57gP+J8mq2RzvbLNNLI4/jyyCLmBKiK0OZ4 Pb1bzGPPrW2DX4biDngkKm3+5uUhqkJgBrMcAbcnH5yV0aH6dROi9sFC1 uijiiKoiKmt2KxuyTkb3R9rpnOaQ+l9L3WypHh5lIM84H3I7AfXlrZ6Gb mIq6/wR6++V8H1pi706lKBg/bopwQRJxAbtmDoK4378ulRcFbfbK/7BHW rfkGSc1+zA26LJPr9L1ROTQ4fl+W1QuLvbypBL2EtFkh+/JVljFma1feV g==; X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="381641143" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="381641143" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="742598594" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="742598594" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:42 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id DFDA01202BB; Wed, 27 Sep 2023 09:18:38 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Tianshu Qiu , Bingbu Cao , Tomi Valkeinen , Jacopo Mondi , Rui Miguel Silva , Martin Kepplinger Subject: [PATCH v5 06/13] media: ccs: Use sub-device active state Date: Wed, 27 Sep 2023 09:18:22 +0300 Message-Id: <20230927061829.366107-7-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230927061829.366107-1-sakari.ailus@linux.intel.com> References: <20230927061829.366107-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Make use of sub-device active state. In most cases the effect on need for acquiring the mutex is non-existent as access to the driver's core data structure still needs to be serialised. This still removes a lot of code as the code paths for active and try state are the same in many cases. Signed-off-by: Sakari Ailus --- drivers/media/i2c/ccs/ccs-core.c | 278 ++++++++++++------------------- drivers/media/i2c/ccs/ccs.h | 4 +- 2 files changed, 103 insertions(+), 179 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 9e8769603704..08cb5ad3a737 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -508,9 +508,8 @@ static void __ccs_update_exposure_limits(struct ccs_sensor *sensor) struct v4l2_ctrl *ctrl = sensor->exposure; int max; - max = sensor->pixel_array->crop[CCS_PA_PAD_SRC].height - + sensor->vblank->val - - CCS_LIM(sensor, COARSE_INTEGRATION_TIME_MAX_MARGIN); + max = sensor->pa_src.height + sensor->vblank->val - + CCS_LIM(sensor, COARSE_INTEGRATION_TIME_MAX_MARGIN); __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max); } @@ -728,15 +727,12 @@ static int ccs_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: rval = ccs_write(sensor, FRAME_LENGTH_LINES, - sensor->pixel_array->crop[ - CCS_PA_PAD_SRC].height - + ctrl->val); + sensor->pa_src.height + ctrl->val); break; case V4L2_CID_HBLANK: rval = ccs_write(sensor, LINE_LENGTH_PCK, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width - + ctrl->val); + sensor->pa_src.width + ctrl->val); break; case V4L2_CID_TEST_PATTERN: @@ -1214,15 +1210,13 @@ static void ccs_update_blanking(struct ccs_sensor *sensor) min = max_t(int, CCS_LIM(sensor, MIN_FRAME_BLANKING_LINES), - min_fll - sensor->pixel_array->crop[CCS_PA_PAD_SRC].height); - max = max_fll - sensor->pixel_array->crop[CCS_PA_PAD_SRC].height; + min_fll - sensor->pa_src.height); + max = max_fll - sensor->pa_src.height; __v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min); - min = max_t(int, - min_llp - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width, - min_lbp); - max = max_llp - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width; + min = max_t(int, min_llp - sensor->pa_src.width, min_lbp); + max = max_llp - sensor->pa_src.width; __v4l2_ctrl_modify_range(hblank, min, max, hblank->step, min); @@ -1246,10 +1240,8 @@ static int ccs_pll_blanking_update(struct ccs_sensor *sensor) dev_dbg(&client->dev, "real timeperframe\t100/%d\n", sensor->pll.pixel_rate_pixel_array / - ((sensor->pixel_array->crop[CCS_PA_PAD_SRC].width - + sensor->hblank->val) * - (sensor->pixel_array->crop[CCS_PA_PAD_SRC].height - + sensor->vblank->val) / 100)); + ((sensor->pa_src.width + sensor->hblank->val) * + (sensor->pa_src.height + sensor->vblank->val) / 100)); return 0; } @@ -1756,28 +1748,22 @@ static int ccs_start_streaming(struct ccs_sensor *sensor) goto out; /* Analog crop start coordinates */ - rval = ccs_write(sensor, X_ADDR_START, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].left); + rval = ccs_write(sensor, X_ADDR_START, sensor->pa_src.left); if (rval < 0) goto out; - rval = ccs_write(sensor, Y_ADDR_START, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].top); + rval = ccs_write(sensor, Y_ADDR_START, sensor->pa_src.top); if (rval < 0) goto out; /* Analog crop end coordinates */ - rval = ccs_write( - sensor, X_ADDR_END, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].left - + sensor->pixel_array->crop[CCS_PA_PAD_SRC].width - 1); + rval = ccs_write(sensor, X_ADDR_END, + sensor->pa_src.left + sensor->pa_src.width - 1); if (rval < 0) goto out; - rval = ccs_write( - sensor, Y_ADDR_END, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].top - + sensor->pixel_array->crop[CCS_PA_PAD_SRC].height - 1); + rval = ccs_write(sensor, Y_ADDR_END, + sensor->pa_src.top + sensor->pa_src.height - 1); if (rval < 0) goto out; @@ -1789,27 +1775,23 @@ static int ccs_start_streaming(struct ccs_sensor *sensor) /* Digital crop */ if (CCS_LIM(sensor, DIGITAL_CROP_CAPABILITY) == CCS_DIGITAL_CROP_CAPABILITY_INPUT_CROP) { - rval = ccs_write( - sensor, DIGITAL_CROP_X_OFFSET, - sensor->scaler->crop[CCS_PAD_SINK].left); + rval = ccs_write(sensor, DIGITAL_CROP_X_OFFSET, + sensor->scaler_sink.left); if (rval < 0) goto out; - rval = ccs_write( - sensor, DIGITAL_CROP_Y_OFFSET, - sensor->scaler->crop[CCS_PAD_SINK].top); + rval = ccs_write(sensor, DIGITAL_CROP_Y_OFFSET, + sensor->scaler_sink.top); if (rval < 0) goto out; - rval = ccs_write( - sensor, DIGITAL_CROP_IMAGE_WIDTH, - sensor->scaler->crop[CCS_PAD_SINK].width); + rval = ccs_write(sensor, DIGITAL_CROP_IMAGE_WIDTH, + sensor->scaler_sink.width); if (rval < 0) goto out; - rval = ccs_write( - sensor, DIGITAL_CROP_IMAGE_HEIGHT, - sensor->scaler->crop[CCS_PAD_SINK].height); + rval = ccs_write(sensor, DIGITAL_CROP_IMAGE_HEIGHT, + sensor->scaler_sink.height); if (rval < 0) goto out; } @@ -1827,12 +1809,10 @@ static int ccs_start_streaming(struct ccs_sensor *sensor) } /* Output size from sensor */ - rval = ccs_write(sensor, X_OUTPUT_SIZE, - sensor->src->crop[CCS_PAD_SRC].width); + rval = ccs_write(sensor, X_OUTPUT_SIZE, sensor->src_src.width); if (rval < 0) goto out; - rval = ccs_write(sensor, Y_OUTPUT_SIZE, - sensor->src->crop[CCS_PAD_SRC].height); + rval = ccs_write(sensor, Y_OUTPUT_SIZE, sensor->src_src.height); if (rval < 0) goto out; @@ -2053,24 +2033,8 @@ static int __ccs_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - struct ccs_subdev *ssd = to_ccs_subdev(subdev); - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(subdev, sd_state, - fmt->pad); - } else { - struct v4l2_rect *r; - - if (fmt->pad == ssd->source_pad) - r = &ssd->crop[ssd->source_pad]; - else - r = &ssd->sink_fmt; - - fmt->format.code = __ccs_get_mbus_code(subdev, fmt->pad); - fmt->format.width = r->width; - fmt->format.height = r->height; - fmt->format.field = V4L2_FIELD_NONE; - } + fmt->format = *v4l2_subdev_get_pad_format(subdev, sd_state, fmt->pad); + fmt->format.code = __ccs_get_mbus_code(subdev, fmt->pad); return 0; } @@ -2092,28 +2056,18 @@ static int ccs_get_format(struct v4l2_subdev *subdev, static void ccs_get_crop_compose(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_rect **crops, - struct v4l2_rect **comps, int which) + struct v4l2_rect **comps) { struct ccs_subdev *ssd = to_ccs_subdev(subdev); unsigned int i; - if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { - if (crops) - for (i = 0; i < subdev->entity.num_pads; i++) - crops[i] = &ssd->crop[i]; - if (comps) - *comps = &ssd->compose; - } else { - if (crops) { - for (i = 0; i < subdev->entity.num_pads; i++) - crops[i] = v4l2_subdev_get_try_crop(subdev, - sd_state, - i); - } - if (comps) - *comps = v4l2_subdev_get_try_compose(subdev, sd_state, - CCS_PAD_SINK); - } + if (crops) + for (i = 0; i < subdev->entity.num_pads; i++) + crops[i] = + v4l2_subdev_get_pad_crop(subdev, sd_state, i); + if (comps) + *comps = v4l2_subdev_get_pad_compose(subdev, sd_state, + ssd->sink_pad); } /* Changes require propagation only on sink pad. */ @@ -2125,7 +2079,7 @@ static void ccs_propagate(struct v4l2_subdev *subdev, struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - ccs_get_crop_compose(subdev, sd_state, crops, &comp, which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp); switch (target) { case V4L2_SEL_TGT_CROP: @@ -2136,6 +2090,7 @@ static void ccs_propagate(struct v4l2_subdev *subdev, sensor->scale_m = CCS_LIM(sensor, SCALER_N_MIN); sensor->scaling_mode = CCS_SCALING_MODE_NO_SCALING; + sensor->scaler_sink = *comp; } else if (ssd == sensor->binner) { sensor->binning_horizontal = 1; sensor->binning_vertical = 1; @@ -2144,6 +2099,8 @@ static void ccs_propagate(struct v4l2_subdev *subdev, fallthrough; case V4L2_SEL_TGT_COMPOSE: *crops[CCS_PAD_SRC] = *comp; + if (which == V4L2_SUBDEV_FORMAT_ACTIVE && ssd == sensor->src) + sensor->src_src = *crops[CCS_PAD_SRC]; break; default: WARN_ON_ONCE(1); @@ -2252,14 +2209,12 @@ static int ccs_set_format(struct v4l2_subdev *subdev, CCS_LIM(sensor, MIN_Y_OUTPUT_SIZE), CCS_LIM(sensor, MAX_Y_OUTPUT_SIZE)); - ccs_get_crop_compose(subdev, sd_state, crops, NULL, fmt->which); + ccs_get_crop_compose(subdev, sd_state, crops, NULL); crops[ssd->sink_pad]->left = 0; crops[ssd->sink_pad]->top = 0; crops[ssd->sink_pad]->width = fmt->format.width; crops[ssd->sink_pad]->height = fmt->format.height; - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) - ssd->sink_fmt = *crops[ssd->sink_pad]; ccs_propagate(subdev, sd_state, fmt->which, V4L2_SEL_TGT_CROP); mutex_unlock(&sensor->mutex); @@ -2482,7 +2437,7 @@ static int ccs_set_compose(struct v4l2_subdev *subdev, struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp); sel->r.top = 0; sel->r.left = 0; @@ -2501,8 +2456,8 @@ static int ccs_set_compose(struct v4l2_subdev *subdev, return 0; } -static int __ccs_sel_supported(struct v4l2_subdev *subdev, - struct v4l2_subdev_selection *sel) +static int ccs_sel_supported(struct v4l2_subdev *subdev, + struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); @@ -2545,33 +2500,18 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); - struct v4l2_rect *src_size, *crops[CCS_PADS]; - struct v4l2_rect _r; + struct v4l2_rect src_size = { 0 }, *crops[CCS_PADS], *comp; - ccs_get_crop_compose(subdev, sd_state, crops, NULL, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp); - if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - if (sel->pad == ssd->sink_pad) - src_size = &ssd->sink_fmt; - else - src_size = &ssd->compose; + if (sel->pad == ssd->sink_pad) { + struct v4l2_mbus_framefmt *mfmt = + v4l2_subdev_get_pad_format(subdev, sd_state, sel->pad); + + src_size.width = mfmt->width; + src_size.height = mfmt->height; } else { - if (sel->pad == ssd->sink_pad) { - _r.left = 0; - _r.top = 0; - _r.width = v4l2_subdev_get_try_format(subdev, - sd_state, - sel->pad) - ->width; - _r.height = v4l2_subdev_get_try_format(subdev, - sd_state, - sel->pad) - ->height; - src_size = &_r; - } else { - src_size = v4l2_subdev_get_try_compose( - subdev, sd_state, ssd->sink_pad); - } + src_size = *comp; } if (ssd == sensor->src && sel->pad == CCS_PAD_SRC) { @@ -2579,16 +2519,19 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, sel->r.top = 0; } - sel->r.width = min(sel->r.width, src_size->width); - sel->r.height = min(sel->r.height, src_size->height); + sel->r.width = min(sel->r.width, src_size.width); + sel->r.height = min(sel->r.height, src_size.height); - sel->r.left = min_t(int, sel->r.left, src_size->width - sel->r.width); - sel->r.top = min_t(int, sel->r.top, src_size->height - sel->r.height); + sel->r.left = min_t(int, sel->r.left, src_size.width - sel->r.width); + sel->r.top = min_t(int, sel->r.top, src_size.height - sel->r.height); *crops[sel->pad] = sel->r; if (ssd != sensor->pixel_array && sel->pad == CCS_PAD_SINK) ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_CROP); + else if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE && + ssd == sensor->pixel_array) + sensor->pa_src = sel->r; return 0; } @@ -2601,44 +2544,36 @@ static void ccs_get_native_size(struct ccs_subdev *ssd, struct v4l2_rect *r) r->height = CCS_LIM(ssd->sensor, Y_ADDR_MAX) + 1; } -static int __ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) +static int ccs_get_selection(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - struct v4l2_rect sink_fmt; int ret; - ret = __ccs_sel_supported(subdev, sel); + ret = ccs_sel_supported(subdev, sel); if (ret) return ret; - ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); - - if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - sink_fmt = ssd->sink_fmt; - } else { - struct v4l2_mbus_framefmt *fmt = - v4l2_subdev_get_try_format(subdev, sd_state, - ssd->sink_pad); - - sink_fmt.left = 0; - sink_fmt.top = 0; - sink_fmt.width = fmt->width; - sink_fmt.height = fmt->height; - } + ccs_get_crop_compose(subdev, sd_state, crops, &comp); switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_NATIVE_SIZE: - if (ssd == sensor->pixel_array) + if (ssd == sensor->pixel_array) { ccs_get_native_size(ssd, &sel->r); - else if (sel->pad == ssd->sink_pad) - sel->r = sink_fmt; - else + } else if (sel->pad == ssd->sink_pad) { + struct v4l2_mbus_framefmt *sink_fmt = + v4l2_subdev_get_pad_format(subdev, sd_state, + ssd->sink_pad); + sel->r.top = sel->r.left = 0; + sel->r.width = sink_fmt->width; + sel->r.height = sink_fmt->height; + } else { sel->r = *comp; + } break; case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_COMPOSE_BOUNDS: @@ -2652,20 +2587,6 @@ static int __ccs_get_selection(struct v4l2_subdev *subdev, return 0; } -static int ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) -{ - struct ccs_sensor *sensor = to_ccs_sensor(subdev); - int rval; - - mutex_lock(&sensor->mutex); - rval = __ccs_get_selection(subdev, sd_state, sel); - mutex_unlock(&sensor->mutex); - - return rval; -} - static int ccs_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) @@ -2673,7 +2594,7 @@ static int ccs_set_selection(struct v4l2_subdev *subdev, struct ccs_sensor *sensor = to_ccs_sensor(subdev); int ret; - ret = __ccs_sel_supported(subdev, sel); + ret = ccs_sel_supported(subdev, sel); if (ret) return ret; @@ -2964,10 +2885,14 @@ static int ccs_register_subdev(struct ccs_sensor *sensor, return rval; } + rval = v4l2_subdev_init_finalize(&ssd->sd); + if (rval) + goto out_media_entity_cleanup; + rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, &ssd->sd); if (rval) { dev_err(&client->dev, "v4l2_device_register_subdev failed\n"); - goto out_media_entity_cleanup; + goto out_v4l2_subdev_cleanup; } rval = media_create_pad_link(&ssd->sd.entity, source_pad, @@ -2983,6 +2908,9 @@ static int ccs_register_subdev(struct ccs_sensor *sensor, out_v4l2_device_unregister_subdev: v4l2_device_unregister_subdev(&ssd->sd); +out_v4l2_subdev_cleanup: + v4l2_subdev_cleanup(&ssd->sd); + out_media_entity_cleanup: media_entity_cleanup(&ssd->sd.entity); @@ -3059,16 +2987,9 @@ static void ccs_create_subdev(struct ccs_sensor *sensor, v4l2_i2c_subdev_set_name(&ssd->sd, client, sensor->minfo.name, name); - ccs_get_native_size(ssd, &ssd->sink_fmt); - - ssd->compose.width = ssd->sink_fmt.width; - ssd->compose.height = ssd->sink_fmt.height; - ssd->crop[ssd->source_pad] = ssd->compose; ssd->pads[ssd->source_pad].flags = MEDIA_PAD_FL_SOURCE; - if (ssd != sensor->pixel_array) { - ssd->crop[ssd->sink_pad] = ssd->compose; + if (ssd != sensor->pixel_array) ssd->pads[ssd->sink_pad].flags = MEDIA_PAD_FL_SINK; - } ssd->sd.entity.ops = &ccs_entity_ops; @@ -3090,24 +3011,24 @@ static int ccs_init_cfg(struct v4l2_subdev *sd, mutex_lock(&sensor->mutex); for (i = 0; i < ssd->npads; i++) { - struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, sd_state, i); - struct v4l2_rect *try_crop = - v4l2_subdev_get_try_crop(sd, sd_state, i); - struct v4l2_rect *try_comp; + struct v4l2_mbus_framefmt *fmt = + v4l2_subdev_get_pad_format(sd, sd_state, i); + struct v4l2_rect *crop = + v4l2_subdev_get_pad_crop(sd, sd_state, i); + struct v4l2_rect *comp; - ccs_get_native_size(ssd, try_crop); + ccs_get_native_size(ssd, crop); - try_fmt->width = try_crop->width; - try_fmt->height = try_crop->height; - try_fmt->code = sensor->internal_csi_format->code; - try_fmt->field = V4L2_FIELD_NONE; + fmt->width = crop->width; + fmt->height = crop->height; + fmt->code = sensor->internal_csi_format->code; + fmt->field = V4L2_FIELD_NONE; if (ssd == sensor->pixel_array) continue; - try_comp = v4l2_subdev_get_try_compose(sd, sd_state, i); - *try_comp = *try_crop; + comp = v4l2_subdev_get_pad_compose(sd, sd_state, i); + *comp = *crop; } mutex_unlock(&sensor->mutex); @@ -3596,6 +3517,10 @@ static int ccs_probe(struct i2c_client *client) if (rval < 0) goto out_media_entity_cleanup; + rval = v4l2_subdev_init_finalize(&sensor->src->sd); + if (rval) + goto out_media_entity_cleanup; + rval = ccs_write_msr_regs(sensor); if (rval) goto out_media_entity_cleanup; @@ -3655,6 +3580,7 @@ static void ccs_remove(struct i2c_client *client) for (i = 0; i < sensor->ssds_used; i++) { v4l2_device_unregister_subdev(&sensor->ssds[i].sd); + v4l2_subdev_cleanup(subdev); media_entity_cleanup(&sensor->ssds[i].sd.entity); } ccs_cleanup(sensor); diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index a94c796cea48..9c3587b2fbe7 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -182,9 +182,6 @@ struct ccs_binning_subtype { struct ccs_subdev { struct v4l2_subdev sd; struct media_pad pads[CCS_PADS]; - struct v4l2_rect sink_fmt; - struct v4l2_rect crop[CCS_PADS]; - struct v4l2_rect compose; /* compose on sink */ unsigned short sink_pad; unsigned short source_pad; int npads; @@ -220,6 +217,7 @@ struct ccs_sensor { u32 mbus_frame_fmts; const struct ccs_csi_data_format *csi_format; const struct ccs_csi_data_format *internal_csi_format; + struct v4l2_rect pa_src, scaler_sink, src_src; u32 default_mbus_frame_fmts; int default_pixel_order; struct ccs_data_container sdata, mdata; From patchwork Wed Sep 27 06:18:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 726941 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60FBDE80A96 for ; Wed, 27 Sep 2023 06:19:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230033AbjI0GTd (ORCPT ); Wed, 27 Sep 2023 02:19:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229890AbjI0GTI (ORCPT ); Wed, 27 Sep 2023 02:19:08 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9F2BF196 for ; Tue, 26 Sep 2023 23:19:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695795546; x=1727331546; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6cYVqCUeLnXfrYUAyPAGPd3J/a2k76+Fz1Dpl3VHKps=; b=SLXNEvpLc8DQZtB/pi8ge/Sr56h6WaGQ6L1st/OtAqIlPZY3Whepkfb5 W9q62TGRYVrcNoWf4WyGRdDrJp6y1x87Zyd54LwmYP8ITvfxFCsYZSkiz ydnR1AhFfWKV3RBrl5mkPubbre9juIx0sS9dghR74xWcgZnf7D1/SSWqQ cq3KfuZpPQye4KzlXTwq3AwoTnkeIz9y8/7weXqM32R7lc9T9NY8NNlds R8uL7COwwhAtiYmf0p+tiimLYjzMnzgy93p0NO79m1j5ZNgb2H/aISeKu 3CuvfwsEwugIjWXWux8t3wR8301gVBCLSlNVK7ms6Zf9JT+eaE2W2rIAk Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="381641157" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="381641157" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="742598601" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="742598601" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:44 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 66F521209F6; Wed, 27 Sep 2023 09:18:41 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Tianshu Qiu , Bingbu Cao , Tomi Valkeinen , Jacopo Mondi , Rui Miguel Silva , Martin Kepplinger Subject: [PATCH v5 08/13] media: ov2740: Use sub-device active state Date: Wed, 27 Sep 2023 09:18:24 +0300 Message-Id: <20230927061829.366107-9-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230927061829.366107-1-sakari.ailus@linux.intel.com> References: <20230927061829.366107-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Use sub-device active state. Rely on control handler lock to serialise access to the active state. Also clean up locking on s_stream handler. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov2740.c | 109 ++++++++++++++----------------------- 1 file changed, 42 insertions(+), 67 deletions(-) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 6d5fb2789dc6..d83ac31efd9c 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -336,9 +336,6 @@ struct ov2740 { /* Current mode */ const struct ov2740_mode *cur_mode; - /* To serialize asynchronus callbacks */ - struct mutex mutex; - /* NVM data inforamtion */ struct nvm_data *nvm; @@ -579,7 +576,6 @@ static int ov2740_init_controls(struct ov2740 *ov2740) if (ret) return ret; - ctrl_hdlr->lock = &ov2740->mutex; cur_mode = ov2740->cur_mode; size = ARRAY_SIZE(link_freq_menu_items); @@ -789,15 +785,15 @@ static int ov2740_set_stream(struct v4l2_subdev *sd, int enable) { struct ov2740 *ov2740 = to_ov2740(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); + struct v4l2_subdev_state *sd_state; int ret = 0; - mutex_lock(&ov2740->mutex); + sd_state = v4l2_subdev_lock_and_get_active_state(&ov2740->sd); + if (enable) { ret = pm_runtime_resume_and_get(&client->dev); - if (ret < 0) { - mutex_unlock(&ov2740->mutex); - return ret; - } + if (ret < 0) + goto out_unlock; ret = ov2740_start_streaming(ov2740); if (ret) { @@ -810,7 +806,8 @@ static int ov2740_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - mutex_unlock(&ov2740->mutex); +out_unlock: + v4l2_subdev_unlock_state(sd_state); return ret; } @@ -828,48 +825,26 @@ static int ov2740_set_format(struct v4l2_subdev *sd, height, fmt->format.width, fmt->format.height); - mutex_lock(&ov2740->mutex); ov2740_update_pad_format(mode, &fmt->format); - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; - } else { - ov2740->cur_mode = mode; - __v4l2_ctrl_s_ctrl(ov2740->link_freq, mode->link_freq_index); - __v4l2_ctrl_s_ctrl_int64(ov2740->pixel_rate, - to_pixel_rate(mode->link_freq_index)); - - /* Update limits and set FPS to default */ - vblank_def = mode->vts_def - mode->height; - __v4l2_ctrl_modify_range(ov2740->vblank, - mode->vts_min - mode->height, - OV2740_VTS_MAX - mode->height, 1, - vblank_def); - __v4l2_ctrl_s_ctrl(ov2740->vblank, vblank_def); - h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) - - mode->width; - __v4l2_ctrl_modify_range(ov2740->hblank, h_blank, h_blank, 1, - h_blank); - } - mutex_unlock(&ov2740->mutex); + *v4l2_subdev_get_pad_format(sd, sd_state, fmt->pad) = fmt->format; - return 0; -} - -static int ov2740_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) -{ - struct ov2740 *ov2740 = to_ov2740(sd); - - mutex_lock(&ov2740->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&ov2740->sd, - sd_state, - fmt->pad); - else - ov2740_update_pad_format(ov2740->cur_mode, &fmt->format); + return 0; - mutex_unlock(&ov2740->mutex); + ov2740->cur_mode = mode; + __v4l2_ctrl_s_ctrl(ov2740->link_freq, mode->link_freq_index); + __v4l2_ctrl_s_ctrl_int64(ov2740->pixel_rate, + to_pixel_rate(mode->link_freq_index)); + + /* Update limits and set FPS to default */ + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(ov2740->vblank, + mode->vts_min - mode->height, + OV2740_VTS_MAX - mode->height, 1, vblank_def); + __v4l2_ctrl_s_ctrl(ov2740->vblank, vblank_def); + h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) - + mode->width; + __v4l2_ctrl_modify_range(ov2740->hblank, h_blank, h_blank, 1, h_blank); return 0; } @@ -904,14 +879,11 @@ static int ov2740_enum_frame_size(struct v4l2_subdev *sd, return 0; } -static int ov2740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +static int ov2740_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) { - struct ov2740 *ov2740 = to_ov2740(sd); - - mutex_lock(&ov2740->mutex); ov2740_update_pad_format(&supported_modes[0], - v4l2_subdev_get_try_format(sd, fh->state, 0)); - mutex_unlock(&ov2740->mutex); + v4l2_subdev_get_pad_format(sd, sd_state, 0)); return 0; } @@ -921,10 +893,11 @@ static const struct v4l2_subdev_video_ops ov2740_video_ops = { }; static const struct v4l2_subdev_pad_ops ov2740_pad_ops = { + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = ov2740_set_format, - .get_fmt = ov2740_get_format, .enum_mbus_code = ov2740_enum_mbus_code, .enum_frame_size = ov2740_enum_frame_size, + .init_cfg = ov2740_init_cfg, }; static const struct v4l2_subdev_ops ov2740_subdev_ops = { @@ -936,10 +909,6 @@ static const struct media_entity_operations ov2740_subdev_entity_ops = { .link_validate = v4l2_subdev_link_validate, }; -static const struct v4l2_subdev_internal_ops ov2740_internal_ops = { - .open = ov2740_open, -}; - static int ov2740_check_hwcfg(struct device *dev) { struct fwnode_handle *ep; @@ -1005,13 +974,12 @@ static int ov2740_check_hwcfg(struct device *dev) static void ov2740_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov2740 *ov2740 = to_ov2740(sd); v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); + v4l2_subdev_cleanup(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); pm_runtime_disable(&client->dev); - mutex_destroy(&ov2740->mutex); } static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, @@ -1020,9 +988,11 @@ static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, struct nvm_data *nvm = priv; struct device *dev = regmap_get_device(nvm->regmap); struct ov2740 *ov2740 = to_ov2740(dev_get_drvdata(dev)); + struct v4l2_subdev_state *sd_state; int ret = 0; - mutex_lock(&ov2740->mutex); + /* Serialise sensor access */ + sd_state = v4l2_subdev_lock_and_get_active_state(&ov2740->sd); if (nvm->nvm_buffer) { memcpy(val, nvm->nvm_buffer + off, count); @@ -1040,7 +1010,7 @@ static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, pm_runtime_put(dev); exit: - mutex_unlock(&ov2740->mutex); + v4l2_subdev_unlock_state(sd_state); return ret; } @@ -1111,7 +1081,6 @@ static int ov2740_probe(struct i2c_client *client) return dev_err_probe(dev, ret, "failed to find sensor\n"); } - mutex_init(&ov2740->mutex); ov2740->cur_mode = &supported_modes[0]; ret = ov2740_init_controls(ov2740); if (ret) { @@ -1119,7 +1088,7 @@ static int ov2740_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } - ov2740->sd.internal_ops = &ov2740_internal_ops; + ov2740->sd.state_lock = ov2740->ctrl_handler.lock; ov2740->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ov2740->sd.entity.ops = &ov2740_subdev_entity_ops; ov2740->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; @@ -1130,6 +1099,10 @@ static int ov2740_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } + ret = v4l2_subdev_init_finalize(&ov2740->sd); + if (ret) + goto probe_error_media_entity_cleanup; + /* Set the device's state to active if it's in D0 state. */ if (full_power) pm_runtime_set_active(&client->dev); @@ -1139,7 +1112,7 @@ static int ov2740_probe(struct i2c_client *client) ret = v4l2_async_register_subdev_sensor(&ov2740->sd); if (ret < 0) { dev_err_probe(dev, ret, "failed to register V4L2 subdev\n"); - goto probe_error_media_entity_cleanup; + goto probe_error_v4l2_subdev_cleanup; } ret = ov2740_register_nvmem(client, ov2740); @@ -1148,6 +1121,9 @@ static int ov2740_probe(struct i2c_client *client) return 0; +probe_error_v4l2_subdev_cleanup: + v4l2_subdev_cleanup(&ov2740->sd); + probe_error_media_entity_cleanup: media_entity_cleanup(&ov2740->sd.entity); pm_runtime_disable(&client->dev); @@ -1155,7 +1131,6 @@ static int ov2740_probe(struct i2c_client *client) probe_error_v4l2_ctrl_handler_free: v4l2_ctrl_handler_free(ov2740->sd.ctrl_handler); - mutex_destroy(&ov2740->mutex); return ret; } From patchwork Wed Sep 27 06:18:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 726942 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4AD69E80A95 for ; Wed, 27 Sep 2023 06:19:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230016AbjI0GTb (ORCPT ); Wed, 27 Sep 2023 02:19:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52752 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229882AbjI0GTI (ORCPT ); Wed, 27 Sep 2023 02:19:08 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA0C7194 for ; Tue, 26 Sep 2023 23:19:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695795547; x=1727331547; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=84btf6YxV+F5wtOY+4HXZDNLyU7cW9nmlQhBFlQlCnA=; b=LlbYlZz88Q3aciKHc42AkLOt/xuoJ1ub/LjyJspNpLJhmzh2BmDSglJF g2OGlKJ+K6b5rkKba8fifGZ/ZIlOyGPLjRhRW19tFGunWlk+lvdmfGFJz WyPNw7SnVD5OTCGaDepRyPNy1RgdDykI90l4nyuVHCnJdEFx1EAD/xTUW pViNU5C+9zVe2m/QpYr3PRCPXVKgl3V08Lk6/eYqB59AV0T2JHNz+IgsK WxCZ0J0WDmJOV/JvYpFuWKHCsnRRQSc5DwfgzpwPi6YB6icrcp2ny9uZ8 i0y7jZo+JlOT/KQyltbd5/qRZyQFJ0OlM4QV6rjB4OVs84/prYdjTG2m9 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="381641164" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="381641164" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="742598605" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="742598605" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:46 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id EC7611209F7; Wed, 27 Sep 2023 09:18:42 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Tianshu Qiu , Bingbu Cao , Tomi Valkeinen , Jacopo Mondi , Rui Miguel Silva , Martin Kepplinger Subject: [PATCH v5 09/13] media: ov2740: Return -EPROBE_DEFER if no endpoint is found Date: Wed, 27 Sep 2023 09:18:25 +0300 Message-Id: <20230927061829.366107-10-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230927061829.366107-1-sakari.ailus@linux.intel.com> References: <20230927061829.366107-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org With ipu bridge, endpoints may only be created when ipu bridge has initialised. This may happen after the sensor driver has first probed. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov2740.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index d83ac31efd9c..24e468485fbf 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -931,7 +931,7 @@ static int ov2740_check_hwcfg(struct device *dev) ep = fwnode_graph_get_next_endpoint(fwnode, NULL); if (!ep) - return -ENXIO; + return -EPROBE_DEFER; ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); fwnode_handle_put(ep); From patchwork Wed Sep 27 06:18:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 726940 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0A3FDE80A93 for ; Wed, 27 Sep 2023 06:19:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229478AbjI0GTh (ORCPT ); Wed, 27 Sep 2023 02:19:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229906AbjI0GTJ (ORCPT ); Wed, 27 Sep 2023 02:19:09 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A56C719A for ; Tue, 26 Sep 2023 23:19:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695795548; x=1727331548; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/5qfMiNZKaKzPMA2ot2UgTS9i5w3pBhS0BNps/Obmak=; b=kJkfXiYXyvDon7PSowEpmQzrRTdvbW6d5mqqlJTa1U/ZTpklfYzNDU4Z PzR1mkPA/kaYVyZqfYMGMDiGqsGh1KMoUAW3HcAY0A10cDiHd+wYxp8DC JUTr2o3EmsxBFdZ3oNn2rzh9tRRhU5rvidF1nWhXsvYRjrgIwj6RQEMSg kttrXgfPWPs7OAk2iPnxdF13J8mkrtC2xXwE4fbo0pvwyOLAhgRpc2IHr GuQ4n34GlgH63wVJoPVse0uc0fdUTYt8KgJ1xj7StzEU/1SuVfrXc024j suGKL3+Rqm+IVB0exbAFDYNCPEa7UM/EbSQiwww6Ga0anyX3OW5+rgR/U A==; X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="381641176" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="381641176" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="742598616" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208";a="742598616" Received: from turnipsi.fi.intel.com (HELO kekkonen.fi.intel.com) ([10.237.72.44]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 23:18:48 -0700 Received: from svinhufvud.ger.corp.intel.com (localhost [IPv6:::1]) by kekkonen.fi.intel.com (Postfix) with ESMTP id 984AB1202BB; Wed, 27 Sep 2023 09:18:45 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, Tianshu Qiu , Bingbu Cao , Tomi Valkeinen , Jacopo Mondi , Rui Miguel Silva , Martin Kepplinger Subject: [PATCH v5 11/13] media: v4l: subdev: Print debug information on frame descriptor Date: Wed, 27 Sep 2023 09:18:27 +0300 Message-Id: <20230927061829.366107-12-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230927061829.366107-1-sakari.ailus@linux.intel.com> References: <20230927061829.366107-1-sakari.ailus@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Print debug level information on returned frame descriptors. Signed-off-by: Sakari Ailus --- drivers/media/v4l2-core/v4l2-subdev.c | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 9cb04ace86ae..d295a4e87b66 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -309,9 +310,37 @@ static int call_set_selection(struct v4l2_subdev *sd, static int call_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_frame_desc *fd) { + unsigned int i; + int ret; + memset(fd, 0, sizeof(*fd)); - return sd->ops->pad->get_frame_desc(sd, pad, fd); + ret = sd->ops->pad->get_frame_desc(sd, pad, fd); + if (ret) + return ret; + + dev_dbg(sd->dev, "Frame descriptor on pad %u, type %s\n", pad, + fd->type == V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL ? "parallel" : + fd->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2 ? "CSI-2" : + "unknown"); + + for (i = 0; i < fd->num_entries; i++) { + struct v4l2_mbus_frame_desc_entry *entry = &fd->entry[i]; + char buf[20] = ""; + + if (fd->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2) + WARN_ON(snprintf(buf, sizeof(buf), + ", vc %u, dt 0x%02x", + entry->bus.csi2.vc, + entry->bus.csi2.dt) >= sizeof(buf)); + + dev_dbg(sd->dev, + "\tstream %u, code 0x%04x, length %u, flags 0x%04x%s\n", + entry->stream, entry->pixelcode, entry->length, + entry->flags, buf); + } + + return 0; } static inline int check_edid(struct v4l2_subdev *sd,