Show a patch.

GET /api/patches/22296/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 22296,
    "url": "https://patchwork.libcamera.org/api/patches/22296/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/22296/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20241212052438.1547410-3-paul.elder@ideasonboard.com>",
    "date": "2024-12-12T05:24:36",
    "name": "[v4,2/4] utils: codegen: controls.py: Parse direction information",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "6c36705e964d94db38c9d52175795fec01f6afda",
    "submitter": {
        "id": 17,
        "url": "https://patchwork.libcamera.org/api/people/17/?format=api",
        "name": "Paul Elder",
        "email": "paul.elder@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/22296/mbox/",
    "series": [
        {
            "id": 4876,
            "url": "https://patchwork.libcamera.org/api/series/4876/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4876",
            "date": "2024-12-12T05:24:34",
            "name": "Add direction field to ControlId",
            "version": 4,
            "mbox": "https://patchwork.libcamera.org/series/4876/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/22296/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/22296/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>",
        "X-Original-To": "parsemail@patchwork.libcamera.org",
        "Delivered-To": "parsemail@patchwork.libcamera.org",
        "Received": [
            "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id DA52DBD80A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 12 Dec 2024 05:25:14 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4C5A967EC5;\n\tThu, 12 Dec 2024 06:25:14 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 52EC86189C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 12 Dec 2024 06:25:11 +0100 (CET)",
            "from neptunite.flets-east.jp (unknown\n\t[IPv6:2404:7a81:160:2100:39eb:989c:b016:217b])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 10D2A316;\n\tThu, 12 Dec 2024 06:24:35 +0100 (CET)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"VP6zqVvV\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1733981077;\n\tbh=xnVIcCiAACAOLERCR3AbRwxwKTcjNddH1QuE+z0sb6U=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=VP6zqVvVbM5brogsUAcDwnTCIfNgchcZcKJ/exvF1spSNR7610XQBkfWiHqq757AZ\n\tbwGuLsD6OyqUiYTT1RIlbbiGpRi5aLoxajJ5J6TexQ4wEkLyD2WERuAYTq7Mth/Cbj\n\t3usuA5diIOdTRvM+3lLK6r1YPyitHpf+u149Az2o=",
        "From": "Paul Elder <paul.elder@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Paul Elder <paul.elder@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>",
        "Subject": "[PATCH v4 2/4] utils: codegen: controls.py: Parse direction\n\tinformation",
        "Date": "Thu, 12 Dec 2024 14:24:36 +0900",
        "Message-Id": "<20241212052438.1547410-3-paul.elder@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.39.2",
        "In-Reply-To": "<20241212052438.1547410-1-paul.elder@ideasonboard.com>",
        "References": "<20241212052438.1547410-1-paul.elder@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "In preparation for adding support for querying direction information\nfrom controls, parse the direction information from control ID\ndefinitions. This can later be plugged in directly to the IPA code\ngenerators simply by using ctrl.direction.\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n---\nNo change in v4\n\nChanges in v3:\n- minor reordering\n\nChanges in v2:\n- prevent errors in parsing properties, since the direction field is now\n  required yet properties can only be out\n  - do this by expanding the Control constructor to take the mode\n    argument, so that needs to be passed in by the users of Control\n---\n src/py/libcamera/gen-py-controls.py |  2 +-\n utils/codegen/controls.py           | 24 +++++++++++++++++++++++-\n utils/codegen/gen-controls.py       |  2 +-\n utils/codegen/gen-gst-controls.py   |  2 +-\n 4 files changed, 26 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py\nindex cf09c146084d..d43a7c1c7eab 100755\n--- a/src/py/libcamera/gen-py-controls.py\n+++ b/src/py/libcamera/gen-py-controls.py\n@@ -83,7 +83,7 @@ def main(argv):\n             vendors.append(vendor)\n \n         for ctrl in data['controls']:\n-            ctrl = Control(*ctrl.popitem(), vendor)\n+            ctrl = Control(*ctrl.popitem(), vendor, args.mode)\n             controls.append(extend_control(ctrl, args.mode))\n \n     data = {\ndiff --git a/utils/codegen/controls.py b/utils/codegen/controls.py\nindex 03c77cc64abe..602f15b25fb6 100644\n--- a/utils/codegen/controls.py\n+++ b/utils/codegen/controls.py\n@@ -28,7 +28,7 @@ class ControlEnum(object):\n \n \n class Control(object):\n-    def __init__(self, name, data, vendor):\n+    def __init__(self, name, data, vendor, mode):\n         self.__name = name\n         self.__data = data\n         self.__enum_values = None\n@@ -60,6 +60,16 @@ class Control(object):\n \n             self.__size = num_elems\n \n+        if mode == 'properties':\n+            self.__direction = 'out'\n+        else:\n+            direction = self.__data.get('direction')\n+            if direction is None:\n+                raise RuntimeError(f'Control `{self.__name}` missing required field `{direction}`')\n+            if direction not in ['in', 'out', 'inout']:\n+                raise RuntimeError(f'Control `{self.__name}` direction `{direction}` is invalid; must be one of `in`, `out`, or `inout`')\n+            self.__direction = direction\n+\n     @property\n     def description(self):\n         \"\"\"The control description\"\"\"\n@@ -111,6 +121,18 @@ class Control(object):\n         else:\n             return f\"Span<const {typ}>\"\n \n+    @property\n+    def direction(self):\n+        in_flag = 'ControlId::Direction::In'\n+        out_flag = 'ControlId::Direction::Out'\n+\n+        if self.__direction == 'inout':\n+            return f'{in_flag} | {out_flag}'\n+        if self.__direction == 'in':\n+            return in_flag\n+        if self.__direction == 'out':\n+            return out_flag\n+\n     @property\n     def element_type(self):\n         return self.__data.get('type')\ndiff --git a/utils/codegen/gen-controls.py b/utils/codegen/gen-controls.py\nindex 3034e9a54760..59b716c1c48c 100755\n--- a/utils/codegen/gen-controls.py\n+++ b/utils/codegen/gen-controls.py\n@@ -71,7 +71,7 @@ def main(argv):\n         ctrls = controls.setdefault(vendor, [])\n \n         for i, ctrl in enumerate(data['controls']):\n-            ctrl = Control(*ctrl.popitem(), vendor)\n+            ctrl = Control(*ctrl.popitem(), vendor, args.mode)\n             ctrls.append(extend_control(ctrl, i, ranges))\n \n     # Sort the vendors by range numerical value\ndiff --git a/utils/codegen/gen-gst-controls.py b/utils/codegen/gen-gst-controls.py\nindex 2601a67588a3..df0988266294 100755\n--- a/utils/codegen/gen-gst-controls.py\n+++ b/utils/codegen/gen-gst-controls.py\n@@ -154,7 +154,7 @@ def main(argv):\n         ctrls = controls.setdefault(vendor, [])\n \n         for ctrl in data['controls']:\n-            ctrl = Control(*ctrl.popitem(), vendor)\n+            ctrl = Control(*ctrl.popitem(), vendor, mode='controls')\n \n             if ctrl.name in exposed_controls:\n                 ctrls.append(extend_control(ctrl))\n",
    "prefixes": [
        "v4",
        "2/4"
    ]
}