[{"id":32441,"web_url":"https://patchwork.libcamera.org/comment/32441/","msgid":"<2vyg3mrqae4akkzxnpe3wxhcjczhi2onucwsocwbptawerxb24@skekkttwznjn>","date":"2024-11-28T17:38:49","subject":"Re: [PATCH v5 1/2] libcamera: Extend u32 control type","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Harvey\n\nOn Tue, Oct 29, 2024 at 04:07:12PM +0000, Harvey Yang wrote:\n> From: Yudhistira Erlandinata <yerlandinata@chromium.org>\n>\n> V4L2 Controls support a wide variety of types not yet supported by the\n> ControlValue type system.\n>\n> Extend the libcamera ControlValue types to support an explicit 32 bit\n> unsigned integer type, and map that to the corresponding\n> V4L2_CTRL_TYPE_U32 type within the v4l2_device support class.\n>\n> Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>\n> Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>\n\nReviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n\nThanks\n  j\n\n> ---\n>  include/libcamera/controls.h    |  7 ++++++\n>  src/libcamera/controls.cpp      | 12 ++++++++--\n>  src/libcamera/v4l2_device.cpp   | 39 +++++++++++++++++++++++++++-----\n>  test/controls/control_value.cpp | 40 +++++++++++++++++++++++++++++++++\n>  4 files changed, 91 insertions(+), 7 deletions(-)\n>\n> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> index ca60bbaca..6da8ad2c3 100644\n> --- a/include/libcamera/controls.h\n> +++ b/include/libcamera/controls.h\n> @@ -29,6 +29,7 @@ enum ControlType {\n>  \tControlTypeNone,\n>  \tControlTypeBool,\n>  \tControlTypeByte,\n> +\tControlTypeUnsigned32,\n>  \tControlTypeInteger32,\n>  \tControlTypeInteger64,\n>  \tControlTypeFloat,\n> @@ -62,6 +63,12 @@ struct control_type<uint8_t> {\n>  \tstatic constexpr std::size_t size = 0;\n>  };\n>\n> +template<>\n> +struct control_type<uint32_t> {\n> +\tstatic constexpr ControlType value = ControlTypeUnsigned32;\n> +\tstatic constexpr std::size_t size = 0;\n> +};\n> +\n>  template<>\n>  struct control_type<int32_t> {\n>  \tstatic constexpr ControlType value = ControlTypeInteger32;\n> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\n> index 62185d643..8ae295191 100644\n> --- a/src/libcamera/controls.cpp\n> +++ b/src/libcamera/controls.cpp\n> @@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = {\n>  \t[ControlTypeNone]\t\t= 0,\n>  \t[ControlTypeBool]\t\t= sizeof(bool),\n>  \t[ControlTypeByte]\t\t= sizeof(uint8_t),\n> +\t[ControlTypeUnsigned32]\t\t= sizeof(uint32_t),\n>  \t[ControlTypeInteger32]\t\t= sizeof(int32_t),\n>  \t[ControlTypeInteger64]\t\t= sizeof(int64_t),\n>  \t[ControlTypeFloat]\t\t= sizeof(float),\n> @@ -74,10 +75,12 @@ static constexpr size_t ControlValueSize[] = {\n>   * The control stores a boolean value\n>   * \\var ControlTypeByte\n>   * The control stores a byte value as an unsigned 8-bit integer\n> + * \\var ControlTypeUnsigned32\n> + * The control stores an unsigned 32-bit integer value\n>   * \\var ControlTypeInteger32\n> - * The control stores a 32-bit integer value\n> + * The control stores a signed 32-bit integer value\n>   * \\var ControlTypeInteger64\n> - * The control stores a 64-bit integer value\n> + * The control stores a signed 64-bit integer value\n>   * \\var ControlTypeFloat\n>   * The control stores a 32-bit floating point value\n>   * \\var ControlTypeString\n> @@ -230,6 +233,11 @@ std::string ControlValue::toString() const\n>  \t\t\tstr += std::to_string(*value);\n>  \t\t\tbreak;\n>  \t\t}\n> +\t\tcase ControlTypeUnsigned32: {\n> +\t\t\tconst uint32_t *value = reinterpret_cast<const uint32_t *>(data);\n> +\t\t\tstr += std::to_string(*value);\n> +\t\t\tbreak;\n> +\t\t}\n>  \t\tcase ControlTypeInteger32: {\n>  \t\t\tconst int32_t *value = reinterpret_cast<const int32_t *>(data);\n>  \t\t\tstr += std::to_string(*value);\n> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> index 68add4f2e..90fa6b278 100644\n> --- a/src/libcamera/v4l2_device.cpp\n> +++ b/src/libcamera/v4l2_device.cpp\n> @@ -9,6 +9,7 @@\n>\n>  #include <fcntl.h>\n>  #include <map>\n> +#include <stdint.h>\n>  #include <stdlib.h>\n>  #include <string.h>\n>  #include <sys/ioctl.h>\n> @@ -204,10 +205,22 @@ ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n>\n>  \t\tif (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {\n>  \t\t\tControlType type;\n> +\t\t\tControlValue &value = ctrl.second;\n> +\t\t\tSpan<uint8_t> data;\n>\n>  \t\t\tswitch (info.type) {\n>  \t\t\tcase V4L2_CTRL_TYPE_U8:\n>  \t\t\t\ttype = ControlTypeByte;\n> +\t\t\t\tvalue.reserve(type, true, info.elems);\n> +\t\t\t\tdata = value.data();\n> +\t\t\t\tv4l2Ctrl.p_u8 = data.data();\n> +\t\t\t\tbreak;\n> +\n> +\t\t\tcase V4L2_CTRL_TYPE_U32:\n> +\t\t\t\ttype = ControlTypeUnsigned32;\n> +\t\t\t\tvalue.reserve(type, true, info.elems);\n> +\t\t\t\tdata = value.data();\n> +\t\t\t\tv4l2Ctrl.p_u32 = reinterpret_cast<uint32_t *>(data.data());\n>  \t\t\t\tbreak;\n>\n>  \t\t\tdefault:\n> @@ -217,11 +230,6 @@ ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n>  \t\t\t\treturn {};\n>  \t\t\t}\n>\n> -\t\t\tControlValue &value = ctrl.second;\n> -\t\t\tvalue.reserve(type, true, info.elems);\n> -\t\t\tSpan<uint8_t> data = value.data();\n> -\n> -\t\t\tv4l2Ctrl.p_u8 = data.data();\n>  \t\t\tv4l2Ctrl.size = data.size();\n>  \t\t}\n>  \t}\n> @@ -299,6 +307,18 @@ int V4L2Device::setControls(ControlList *ctrls)\n>  \t\t/* Set the v4l2_ext_control value for the write operation. */\n>  \t\tControlValue &value = ctrl->second;\n>  \t\tswitch (iter->first->type()) {\n> +\t\tcase ControlTypeUnsigned32: {\n> +\t\t\tif (value.isArray()) {\n> +\t\t\t\tSpan<uint8_t> data = value.data();\n> +\t\t\t\tv4l2Ctrl.p_u32 = reinterpret_cast<uint32_t *>(data.data());\n> +\t\t\t\tv4l2Ctrl.size = data.size();\n> +\t\t\t} else {\n> +\t\t\t\tv4l2Ctrl.value = value.get<uint32_t>();\n> +\t\t\t}\n> +\n> +\t\t\tbreak;\n> +\t\t}\n> +\n>  \t\tcase ControlTypeInteger32: {\n>  \t\t\tif (value.isArray()) {\n>  \t\t\t\tSpan<uint8_t> data = value.data();\n> @@ -488,6 +508,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType)\n>  \tcase V4L2_CTRL_TYPE_BOOLEAN:\n>  \t\treturn ControlTypeBool;\n>\n> +\tcase V4L2_CTRL_TYPE_U32:\n> +\t\treturn ControlTypeUnsigned32;\n> +\n>  \tcase V4L2_CTRL_TYPE_INTEGER:\n>  \t\treturn ControlTypeInteger32;\n>\n> @@ -536,6 +559,11 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl\n>  \t\t\t\t   static_cast<uint8_t>(ctrl.maximum),\n>  \t\t\t\t   static_cast<uint8_t>(ctrl.default_value));\n>\n> +\tcase V4L2_CTRL_TYPE_U32:\n> +\t\treturn ControlInfo(static_cast<uint32_t>(ctrl.minimum),\n> +\t\t\t\t   static_cast<uint32_t>(ctrl.maximum),\n> +\t\t\t\t   static_cast<uint32_t>(ctrl.default_value));\n> +\n>  \tcase V4L2_CTRL_TYPE_BOOLEAN:\n>  \t\treturn ControlInfo(static_cast<bool>(ctrl.minimum),\n>  \t\t\t\t   static_cast<bool>(ctrl.maximum),\n> @@ -622,6 +650,7 @@ void V4L2Device::listControls()\n>  \t\tcase V4L2_CTRL_TYPE_BITMASK:\n>  \t\tcase V4L2_CTRL_TYPE_INTEGER_MENU:\n>  \t\tcase V4L2_CTRL_TYPE_U8:\n> +\t\tcase V4L2_CTRL_TYPE_U32:\n>  \t\t\tbreak;\n>  \t\t/* \\todo Support other control types. */\n>  \t\tdefault:\n> diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\n> index 344107fae..6ca85b739 100644\n> --- a/test/controls/control_value.cpp\n> +++ b/test/controls/control_value.cpp\n> @@ -109,6 +109,46 @@ protected:\n>  \t\t\treturn TestFail;\n>  \t\t}\n>\n> +\t\t/*\n> +\t\t * Unsigned Integer32 type.\n> +\t\t */\n> +\t\tvalue.set(static_cast<uint32_t>(42));\n> +\t\tif (value.isNone() || value.isArray() ||\n> +\t\t    value.type() != ControlTypeUnsigned32) {\n> +\t\t\tcerr << \"Control type mismatch after setting to uint32_t\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (value.get<uint32_t>() != 42) {\n> +\t\t\tcerr << \"Control value mismatch after setting to uint32_t\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (value.toString() != \"42\") {\n> +\t\t\tcerr << \"Control string mismatch after setting to uint32_t\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tstd::array<uint32_t, 4> uint32s{ 3, 14, 15, 9 };\n> +\t\tvalue.set(Span<uint32_t>(uint32s));\n> +\t\tif (value.isNone() || !value.isArray() ||\n> +\t\t    value.type() != ControlTypeUnsigned32) {\n> +\t\t\tcerr << \"Control type mismatch after setting to uint32_t array\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tSpan<const uint32_t> uint32sResult = value.get<Span<const uint32_t>>();\n> +\t\tif (uint32s.size() != uint32sResult.size() ||\n> +\t\t    !std::equal(uint32s.begin(), uint32s.end(), uint32sResult.begin())) {\n> +\t\t\tcerr << \"Control value mismatch after setting to uint32_t array\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (value.toString() != \"[ 3, 14, 15, 9 ]\") {\n> +\t\t\tcerr << \"Control string mismatch after setting to uint32_t array\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n>  \t\t/*\n>  \t\t * Integer32 type.\n>  \t\t */\n> --\n> 2.47.0.163.g1226f6d8fa-goog\n>","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 A0192BD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 28 Nov 2024 17:38:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5E8F465FC0;\n\tThu, 28 Nov 2024 18:38:54 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C629E65898\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 28 Nov 2024 18:38:52 +0100 (CET)","from ideasonboard.com (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B4A5B526;\n\tThu, 28 Nov 2024 18:38:28 +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=\"n99zqqEy\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1732815508;\n\tbh=f5yjbyc3ZaTfU23bfC5PlGRvSM/UZR1NJ3XZ9BpzOfs=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=n99zqqEyZyn4Eo9FDI1KQRjzaWkXepun0FzXOjgXZHWaZkI+PNyEL3RK4uzvRKz3U\n\t87BXu6QuL41uGoDiBXeOkZrG+/lFXGk21F0nr/qrMlacdOY6fMBtmwiKriRMjldJLo\n\t/x37DfoDPUQOI1DIz68qe5uGOI3Qoq/zvR1zLFNU=","Date":"Thu, 28 Nov 2024 18:38:49 +0100","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Harvey Yang <chenghaoyang@chromium.org>","Cc":"libcamera-devel@lists.libcamera.org, \n\tYudhistira Erlandinata <yerlandinata@chromium.org>","Subject":"Re: [PATCH v5 1/2] libcamera: Extend u32 control type","Message-ID":"<2vyg3mrqae4akkzxnpe3wxhcjczhi2onucwsocwbptawerxb24@skekkttwznjn>","References":"<20241029161117.1197603-1-chenghaoyang@chromium.org>\n\t<20241029161117.1197603-2-chenghaoyang@chromium.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20241029161117.1197603-2-chenghaoyang@chromium.org>","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>"}},{"id":32443,"web_url":"https://patchwork.libcamera.org/comment/32443/","msgid":"<173281593580.1605529.17791561497177721220@ping.linuxembedded.co.uk>","date":"2024-11-28T17:45:35","subject":"Re: [PATCH v5 1/2] libcamera: Extend u32 control type","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Jacopo Mondi (2024-11-28 17:38:49)\n> Hi Harvey\n> \n> On Tue, Oct 29, 2024 at 04:07:12PM +0000, Harvey Yang wrote:\n> > From: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> >\n> > V4L2 Controls support a wide variety of types not yet supported by the\n> > ControlValue type system.\n> >\n> > Extend the libcamera ControlValue types to support an explicit 32 bit\n> > unsigned integer type, and map that to the corresponding\n> > V4L2_CTRL_TYPE_U32 type within the v4l2_device support class.\n> >\n> > Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> > Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>\n> > Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>\n> \n> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n\nThanks,\n\nI'm happy too - will merge if the CI succeeds ;-)\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> \n> Thanks\n>   j\n> \n> > ---\n> >  include/libcamera/controls.h    |  7 ++++++\n> >  src/libcamera/controls.cpp      | 12 ++++++++--\n> >  src/libcamera/v4l2_device.cpp   | 39 +++++++++++++++++++++++++++-----\n> >  test/controls/control_value.cpp | 40 +++++++++++++++++++++++++++++++++\n> >  4 files changed, 91 insertions(+), 7 deletions(-)\n> >\n> > diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> > index ca60bbaca..6da8ad2c3 100644\n> > --- a/include/libcamera/controls.h\n> > +++ b/include/libcamera/controls.h\n> > @@ -29,6 +29,7 @@ enum ControlType {\n> >       ControlTypeNone,\n> >       ControlTypeBool,\n> >       ControlTypeByte,\n> > +     ControlTypeUnsigned32,\n> >       ControlTypeInteger32,\n> >       ControlTypeInteger64,\n> >       ControlTypeFloat,\n> > @@ -62,6 +63,12 @@ struct control_type<uint8_t> {\n> >       static constexpr std::size_t size = 0;\n> >  };\n> >\n> > +template<>\n> > +struct control_type<uint32_t> {\n> > +     static constexpr ControlType value = ControlTypeUnsigned32;\n> > +     static constexpr std::size_t size = 0;\n> > +};\n> > +\n> >  template<>\n> >  struct control_type<int32_t> {\n> >       static constexpr ControlType value = ControlTypeInteger32;\n> > diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\n> > index 62185d643..8ae295191 100644\n> > --- a/src/libcamera/controls.cpp\n> > +++ b/src/libcamera/controls.cpp\n> > @@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = {\n> >       [ControlTypeNone]               = 0,\n> >       [ControlTypeBool]               = sizeof(bool),\n> >       [ControlTypeByte]               = sizeof(uint8_t),\n> > +     [ControlTypeUnsigned32]         = sizeof(uint32_t),\n> >       [ControlTypeInteger32]          = sizeof(int32_t),\n> >       [ControlTypeInteger64]          = sizeof(int64_t),\n> >       [ControlTypeFloat]              = sizeof(float),\n> > @@ -74,10 +75,12 @@ static constexpr size_t ControlValueSize[] = {\n> >   * The control stores a boolean value\n> >   * \\var ControlTypeByte\n> >   * The control stores a byte value as an unsigned 8-bit integer\n> > + * \\var ControlTypeUnsigned32\n> > + * The control stores an unsigned 32-bit integer value\n> >   * \\var ControlTypeInteger32\n> > - * The control stores a 32-bit integer value\n> > + * The control stores a signed 32-bit integer value\n> >   * \\var ControlTypeInteger64\n> > - * The control stores a 64-bit integer value\n> > + * The control stores a signed 64-bit integer value\n> >   * \\var ControlTypeFloat\n> >   * The control stores a 32-bit floating point value\n> >   * \\var ControlTypeString\n> > @@ -230,6 +233,11 @@ std::string ControlValue::toString() const\n> >                       str += std::to_string(*value);\n> >                       break;\n> >               }\n> > +             case ControlTypeUnsigned32: {\n> > +                     const uint32_t *value = reinterpret_cast<const uint32_t *>(data);\n> > +                     str += std::to_string(*value);\n> > +                     break;\n> > +             }\n> >               case ControlTypeInteger32: {\n> >                       const int32_t *value = reinterpret_cast<const int32_t *>(data);\n> >                       str += std::to_string(*value);\n> > diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> > index 68add4f2e..90fa6b278 100644\n> > --- a/src/libcamera/v4l2_device.cpp\n> > +++ b/src/libcamera/v4l2_device.cpp\n> > @@ -9,6 +9,7 @@\n> >\n> >  #include <fcntl.h>\n> >  #include <map>\n> > +#include <stdint.h>\n> >  #include <stdlib.h>\n> >  #include <string.h>\n> >  #include <sys/ioctl.h>\n> > @@ -204,10 +205,22 @@ ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n> >\n> >               if (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {\n> >                       ControlType type;\n> > +                     ControlValue &value = ctrl.second;\n> > +                     Span<uint8_t> data;\n> >\n> >                       switch (info.type) {\n> >                       case V4L2_CTRL_TYPE_U8:\n> >                               type = ControlTypeByte;\n> > +                             value.reserve(type, true, info.elems);\n> > +                             data = value.data();\n> > +                             v4l2Ctrl.p_u8 = data.data();\n> > +                             break;\n> > +\n> > +                     case V4L2_CTRL_TYPE_U32:\n> > +                             type = ControlTypeUnsigned32;\n> > +                             value.reserve(type, true, info.elems);\n> > +                             data = value.data();\n> > +                             v4l2Ctrl.p_u32 = reinterpret_cast<uint32_t *>(data.data());\n> >                               break;\n> >\n> >                       default:\n> > @@ -217,11 +230,6 @@ ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n> >                               return {};\n> >                       }\n> >\n> > -                     ControlValue &value = ctrl.second;\n> > -                     value.reserve(type, true, info.elems);\n> > -                     Span<uint8_t> data = value.data();\n> > -\n> > -                     v4l2Ctrl.p_u8 = data.data();\n> >                       v4l2Ctrl.size = data.size();\n> >               }\n> >       }\n> > @@ -299,6 +307,18 @@ int V4L2Device::setControls(ControlList *ctrls)\n> >               /* Set the v4l2_ext_control value for the write operation. */\n> >               ControlValue &value = ctrl->second;\n> >               switch (iter->first->type()) {\n> > +             case ControlTypeUnsigned32: {\n> > +                     if (value.isArray()) {\n> > +                             Span<uint8_t> data = value.data();\n> > +                             v4l2Ctrl.p_u32 = reinterpret_cast<uint32_t *>(data.data());\n> > +                             v4l2Ctrl.size = data.size();\n> > +                     } else {\n> > +                             v4l2Ctrl.value = value.get<uint32_t>();\n> > +                     }\n> > +\n> > +                     break;\n> > +             }\n> > +\n> >               case ControlTypeInteger32: {\n> >                       if (value.isArray()) {\n> >                               Span<uint8_t> data = value.data();\n> > @@ -488,6 +508,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType)\n> >       case V4L2_CTRL_TYPE_BOOLEAN:\n> >               return ControlTypeBool;\n> >\n> > +     case V4L2_CTRL_TYPE_U32:\n> > +             return ControlTypeUnsigned32;\n> > +\n> >       case V4L2_CTRL_TYPE_INTEGER:\n> >               return ControlTypeInteger32;\n> >\n> > @@ -536,6 +559,11 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl\n> >                                  static_cast<uint8_t>(ctrl.maximum),\n> >                                  static_cast<uint8_t>(ctrl.default_value));\n> >\n> > +     case V4L2_CTRL_TYPE_U32:\n> > +             return ControlInfo(static_cast<uint32_t>(ctrl.minimum),\n> > +                                static_cast<uint32_t>(ctrl.maximum),\n> > +                                static_cast<uint32_t>(ctrl.default_value));\n> > +\n> >       case V4L2_CTRL_TYPE_BOOLEAN:\n> >               return ControlInfo(static_cast<bool>(ctrl.minimum),\n> >                                  static_cast<bool>(ctrl.maximum),\n> > @@ -622,6 +650,7 @@ void V4L2Device::listControls()\n> >               case V4L2_CTRL_TYPE_BITMASK:\n> >               case V4L2_CTRL_TYPE_INTEGER_MENU:\n> >               case V4L2_CTRL_TYPE_U8:\n> > +             case V4L2_CTRL_TYPE_U32:\n> >                       break;\n> >               /* \\todo Support other control types. */\n> >               default:\n> > diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\n> > index 344107fae..6ca85b739 100644\n> > --- a/test/controls/control_value.cpp\n> > +++ b/test/controls/control_value.cpp\n> > @@ -109,6 +109,46 @@ protected:\n> >                       return TestFail;\n> >               }\n> >\n> > +             /*\n> > +              * Unsigned Integer32 type.\n> > +              */\n> > +             value.set(static_cast<uint32_t>(42));\n> > +             if (value.isNone() || value.isArray() ||\n> > +                 value.type() != ControlTypeUnsigned32) {\n> > +                     cerr << \"Control type mismatch after setting to uint32_t\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             if (value.get<uint32_t>() != 42) {\n> > +                     cerr << \"Control value mismatch after setting to uint32_t\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             if (value.toString() != \"42\") {\n> > +                     cerr << \"Control string mismatch after setting to uint32_t\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             std::array<uint32_t, 4> uint32s{ 3, 14, 15, 9 };\n> > +             value.set(Span<uint32_t>(uint32s));\n> > +             if (value.isNone() || !value.isArray() ||\n> > +                 value.type() != ControlTypeUnsigned32) {\n> > +                     cerr << \"Control type mismatch after setting to uint32_t array\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             Span<const uint32_t> uint32sResult = value.get<Span<const uint32_t>>();\n> > +             if (uint32s.size() != uint32sResult.size() ||\n> > +                 !std::equal(uint32s.begin(), uint32s.end(), uint32sResult.begin())) {\n> > +                     cerr << \"Control value mismatch after setting to uint32_t array\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             if (value.toString() != \"[ 3, 14, 15, 9 ]\") {\n> > +                     cerr << \"Control string mismatch after setting to uint32_t array\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> >               /*\n> >                * Integer32 type.\n> >                */\n> > --\n> > 2.47.0.163.g1226f6d8fa-goog\n> >","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 926D7BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 28 Nov 2024 17:45:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C903265FDD;\n\tThu, 28 Nov 2024 18:45:39 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9112065898\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 28 Nov 2024 18:45:38 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8E5A8526;\n\tThu, 28 Nov 2024 18:45:14 +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=\"pABujRyk\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1732815914;\n\tbh=0oEg+uJxG0xBH1ACDUNeKGkNTs03eOdLHeBPN5wAVsc=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=pABujRykrczi4TFMouRMbx4V6GvB4phCoTSHB129hYWNWJAcw5rBXsKXwzZbO1aGo\n\t2YEA7RWimJGmzwi9YruGXyKWl+2do1F6vSUJzRkL7Y/2hrpXA0SuBsWnNXRiZjI9ni\n\tvaDdPzGTdmP001qZloFPF5xaq0gwHQQTBts1RBs8=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<2vyg3mrqae4akkzxnpe3wxhcjczhi2onucwsocwbptawerxb24@skekkttwznjn>","References":"<20241029161117.1197603-1-chenghaoyang@chromium.org>\n\t<20241029161117.1197603-2-chenghaoyang@chromium.org>\n\t<2vyg3mrqae4akkzxnpe3wxhcjczhi2onucwsocwbptawerxb24@skekkttwznjn>","Subject":"Re: [PATCH v5 1/2] libcamera: Extend u32 control type","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tYudhistira Erlandinata <yerlandinata@chromium.org>","To":"Harvey Yang <chenghaoyang@chromium.org>,\n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>","Date":"Thu, 28 Nov 2024 17:45:35 +0000","Message-ID":"<173281593580.1605529.17791561497177721220@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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>"}}]