All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
To: Hans Verkuil <hverkuil@xs4all.nl>
Cc: linux-media <linux-media@vger.kernel.org>,
	Mauro Carvalho Chehab <m.chehab@samsung.com>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	Sylwester Nawrocki <s.nawrocki@samsung.com>,
	Ismael Luceno <ismael.luceno@corp.bluecherry.net>,
	pete@sensoray.com, Hans Verkuil <hans.verkuil@cisco.com>
Subject: Re: [REVIEWv2 PATCH 08/34] v4l2-ctrls: create type_ops.
Date: Wed, 12 Feb 2014 13:03:06 +0100	[thread overview]
Message-ID: <CAPybu_1U5vGdB9nDeEO71nfE3TrYrWnpngof9ook40dYg9zh9Q@mail.gmail.com> (raw)
In-Reply-To: <52FB5CBB.1040400@xs4all.nl>

Hello Hans

My usercase is different gain and offset per pixel (non uniformity
correction). My sensor is now 4 Mpx, and probably 12 Mpx soon :)

Right now it is implemented as a video output... but I think that I am
exploiting an API :)

Regards!

On Wed, Feb 12, 2014 at 12:36 PM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
> On 02/12/14 11:55, Ricardo Ribalda Delgado wrote:
>> Hello Hans
>>
>> If we have a matrix control with a huge number of elements (ie, the
>> number of pixels), a control validation will imply over ahuge number
>> of function calls.
>>
>> In the case of the matrix you are always validating/init all the
>> values of of the array. Why dont we modify the type_ops so they
>> operate on the whole matrix (remove the idx from the function).
>
> I actually considered that, but rejected it (for now) because I want
> to see a realistic use-case first. If you get such large matrices, then
> you have to ask yourself whether the control framework is the right
> approach anyway, and if it is, whether you want to do these validations
> in the first place.
>
> Also note that validations typically will still have to be done on a
> per-element basis (so pushing down the loop over all elements into the
> validation function will have little effect) and ditto for the more
> complex comparisons. Only if you are able to do something like memcmp
> to compare two matrices will it become beneficial to optimize this.
>
> I see this as a possible future performance enhancement and before doing
> that I need to see a good use-case and also see some performence measurements.
>
>> Anyway we should modify
>>
>> for (idx = 0; idx < ctrl->rows * ctrl->cols; idx++)
>>                ctrl_changed |= !ctrl->type_ops->equal(ctrl, idx,
>> ctrl->stores[0], ctrl->new);
>>
>> to
>>
>> for (idx = 0; idx < ctrl->rows * ctrl->cols; idx++)
>>                if (!ctrl->type_ops->equal(ctrl, idx, ctrl->stores[0],
>> ctrl->new))
>>                                 break
>>
>> if (idx==ctrl->rows * ctrl->col)
>>  ctrol_changed=true;
>>
>> Saving us some calls when we already know that the control has changed.
>
> Oops! Absolutely, thanks for pointing this out.  That's a left-over from
> older code.
>
> I'll post a patch for this.
>
> Regards,
>
>         Hans
>
>>
>>
>> Thanks!
>>
>>
>> ps: consider all my code pseudocode :P
>>
>>
>> On Mon, Feb 10, 2014 at 9:46 AM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
>>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>>
>>> Since complex controls can have non-standard types we need to be able to do
>>> type-specific checks etc. In order to make that easy type operations are added.
>>> There are four operations:
>>>
>>> - equal: check if two values are equal
>>> - init: initialize a value
>>> - log: log the value
>>> - validate: validate a new value
>>>
>>> This patch uses the v4l2_ctrl_ptr union for the first time.
>>>
>>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>>> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>>> ---
>>>  drivers/media/v4l2-core/v4l2-ctrls.c | 267 ++++++++++++++++++++++-------------
>>>  include/media/v4l2-ctrls.h           |  21 +++
>>>  2 files changed, 190 insertions(+), 98 deletions(-)
>>>
>>> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
>>> index 67e5d1e..988a2bd8 100644
>>> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
>>> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
>>> @@ -1132,6 +1132,149 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
>>>                         v4l2_event_queue_fh(sev->fh, &ev);
>>>  }
>>>
>>> +static bool std_equal(const struct v4l2_ctrl *ctrl,
>>> +                     union v4l2_ctrl_ptr ptr1,
>>> +                     union v4l2_ctrl_ptr ptr2)
>>> +{
>>> +       switch (ctrl->type) {
>>> +       case V4L2_CTRL_TYPE_BUTTON:
>>> +               return false;
>>> +       case V4L2_CTRL_TYPE_STRING:
>>> +               /* strings are always 0-terminated */
>>> +               return !strcmp(ptr1.p_char, ptr2.p_char);
>>> +       case V4L2_CTRL_TYPE_INTEGER64:
>>> +               return *ptr1.p_s64 == *ptr2.p_s64;
>>> +       default:
>>> +               if (ctrl->is_ptr)
>>> +                       return !memcmp(ptr1.p, ptr2.p, ctrl->elem_size);
>>> +               return *ptr1.p_s32 == *ptr2.p_s32;
>>> +       }
>>> +}
>>> +
>>> +static void std_init(const struct v4l2_ctrl *ctrl,
>>> +                    union v4l2_ctrl_ptr ptr)
>>> +{
>>> +       switch (ctrl->type) {
>>> +       case V4L2_CTRL_TYPE_STRING:
>>> +               memset(ptr.p_char, ' ', ctrl->minimum);
>>> +               ptr.p_char[ctrl->minimum] = '\0';
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_INTEGER64:
>>> +               *ptr.p_s64 = ctrl->default_value;
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_INTEGER:
>>> +       case V4L2_CTRL_TYPE_INTEGER_MENU:
>>> +       case V4L2_CTRL_TYPE_MENU:
>>> +       case V4L2_CTRL_TYPE_BITMASK:
>>> +       case V4L2_CTRL_TYPE_BOOLEAN:
>>> +               *ptr.p_s32 = ctrl->default_value;
>>> +               break;
>>> +       default:
>>> +               break;
>>> +       }
>>> +}
>>> +
>>> +static void std_log(const struct v4l2_ctrl *ctrl)
>>> +{
>>> +       union v4l2_ctrl_ptr ptr = ctrl->stores[0];
>>> +
>>> +       switch (ctrl->type) {
>>> +       case V4L2_CTRL_TYPE_INTEGER:
>>> +               pr_cont("%d", *ptr.p_s32);
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_BOOLEAN:
>>> +               pr_cont("%s", *ptr.p_s32 ? "true" : "false");
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_MENU:
>>> +               pr_cont("%s", ctrl->qmenu[*ptr.p_s32]);
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_INTEGER_MENU:
>>> +               pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]);
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_BITMASK:
>>> +               pr_cont("0x%08x", *ptr.p_s32);
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_INTEGER64:
>>> +               pr_cont("%lld", *ptr.p_s64);
>>> +               break;
>>> +       case V4L2_CTRL_TYPE_STRING:
>>> +               pr_cont("%s", ptr.p_char);
>>> +               break;
>>> +       default:
>>> +               pr_cont("unknown type %d", ctrl->type);
>>> +               break;
>>> +       }
>>> +}
>>> +
>>> +/* Round towards the closest legal value */
>>> +#define ROUND_TO_RANGE(val, offset_type, ctrl)                 \
>>> +({                                                             \
>>> +       offset_type offset;                                     \
>>> +       val += (ctrl)->step / 2;                                \
>>> +       val = clamp_t(typeof(val), val,                         \
>>> +                     (ctrl)->minimum, (ctrl)->maximum);        \
>>> +       offset = (val) - (ctrl)->minimum;                       \
>>> +       offset = (ctrl)->step * (offset / (ctrl)->step);        \
>>> +       val = (ctrl)->minimum + offset;                         \
>>> +       0;                                                      \
>>> +})
>>> +
>>> +/* Validate a new control */
>>> +static int std_validate(const struct v4l2_ctrl *ctrl,
>>> +                       union v4l2_ctrl_ptr ptr)
>>> +{
>>> +       size_t len;
>>> +
>>> +       switch (ctrl->type) {
>>> +       case V4L2_CTRL_TYPE_INTEGER:
>>> +               return ROUND_TO_RANGE(*ptr.p_s32, u32, ctrl);
>>> +       case V4L2_CTRL_TYPE_INTEGER64:
>>> +               return ROUND_TO_RANGE(*ptr.p_s64, u64, ctrl);
>>> +
>>> +       case V4L2_CTRL_TYPE_BOOLEAN:
>>> +               *ptr.p_s32 = !!*ptr.p_s32;
>>> +               return 0;
>>> +
>>> +       case V4L2_CTRL_TYPE_MENU:
>>> +       case V4L2_CTRL_TYPE_INTEGER_MENU:
>>> +               if (*ptr.p_s32 < ctrl->minimum || *ptr.p_s32 > ctrl->maximum)
>>> +                       return -ERANGE;
>>> +               if (ctrl->menu_skip_mask & (1 << *ptr.p_s32))
>>> +                       return -EINVAL;
>>> +               if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
>>> +                   ctrl->qmenu[*ptr.p_s32][0] == '\0')
>>> +                       return -EINVAL;
>>> +               return 0;
>>> +
>>> +       case V4L2_CTRL_TYPE_BITMASK:
>>> +               *ptr.p_s32 &= ctrl->maximum;
>>> +               return 0;
>>> +
>>> +       case V4L2_CTRL_TYPE_BUTTON:
>>> +       case V4L2_CTRL_TYPE_CTRL_CLASS:
>>> +               *ptr.p_s32 = 0;
>>> +               return 0;
>>> +
>>> +       case V4L2_CTRL_TYPE_STRING:
>>> +               len = strlen(ptr.p_char);
>>> +               if (len < ctrl->minimum)
>>> +                       return -ERANGE;
>>> +               if ((len - ctrl->minimum) % ctrl->step)
>>> +                       return -ERANGE;
>>> +               return 0;
>>> +
>>> +       default:
>>> +               return -EINVAL;
>>> +       }
>>> +}
>>> +
>>> +static const struct v4l2_ctrl_type_ops std_type_ops = {
>>> +       .equal = std_equal,
>>> +       .init = std_init,
>>> +       .log = std_log,
>>> +       .validate = std_validate,
>>> +};
>>> +
>>>  /* Helper function: copy the current control value back to the caller */
>>>  static int cur_to_user(struct v4l2_ext_control *c,
>>>                        struct v4l2_ctrl *ctrl)
>>> @@ -1315,21 +1458,7 @@ static int cluster_changed(struct v4l2_ctrl *master)
>>>
>>>                 if (ctrl == NULL)
>>>                         continue;
>>> -               switch (ctrl->type) {
>>> -               case V4L2_CTRL_TYPE_BUTTON:
>>> -                       /* Button controls are always 'different' */
>>> -                       return 1;
>>> -               case V4L2_CTRL_TYPE_STRING:
>>> -                       /* strings are always 0-terminated */
>>> -                       diff = strcmp(ctrl->string, ctrl->cur.string);
>>> -                       break;
>>> -               case V4L2_CTRL_TYPE_INTEGER64:
>>> -                       diff = ctrl->val64 != ctrl->cur.val64;
>>> -                       break;
>>> -               default:
>>> -                       diff = ctrl->val != ctrl->cur.val;
>>> -                       break;
>>> -               }
>>> +               diff = !ctrl->type_ops->equal(ctrl, ctrl->stores[0], ctrl->new);
>>>         }
>>>         return diff;
>>>  }
>>> @@ -1370,65 +1499,30 @@ static int check_range(enum v4l2_ctrl_type type,
>>>         }
>>>  }
>>>
>>> -/* Round towards the closest legal value */
>>> -#define ROUND_TO_RANGE(val, offset_type, ctrl)                 \
>>> -({                                                             \
>>> -       offset_type offset;                                     \
>>> -       val += (ctrl)->step / 2;                                \
>>> -       val = clamp_t(typeof(val), val,                         \
>>> -                     (ctrl)->minimum, (ctrl)->maximum);        \
>>> -       offset = (val) - (ctrl)->minimum;                       \
>>> -       offset = (ctrl)->step * (offset / (ctrl)->step);        \
>>> -       val = (ctrl)->minimum + offset;                         \
>>> -       0;                                                      \
>>> -})
>>> -
>>>  /* Validate a new control */
>>>  static int validate_new(const struct v4l2_ctrl *ctrl,
>>>                         struct v4l2_ext_control *c)
>>>  {
>>> -       size_t len;
>>> +       union v4l2_ctrl_ptr ptr;
>>>
>>>         switch (ctrl->type) {
>>>         case V4L2_CTRL_TYPE_INTEGER:
>>> -               return ROUND_TO_RANGE(*(s32 *)&c->value, u32, ctrl);
>>> -       case V4L2_CTRL_TYPE_INTEGER64:
>>> -               return ROUND_TO_RANGE(*(s64 *)&c->value64, u64, ctrl);
>>> -
>>> -       case V4L2_CTRL_TYPE_BOOLEAN:
>>> -               c->value = !!c->value;
>>> -               return 0;
>>> -
>>> -       case V4L2_CTRL_TYPE_MENU:
>>>         case V4L2_CTRL_TYPE_INTEGER_MENU:
>>> -               if (c->value < ctrl->minimum || c->value > ctrl->maximum)
>>> -                       return -ERANGE;
>>> -               if (ctrl->menu_skip_mask & (1 << c->value))
>>> -                       return -EINVAL;
>>> -               if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
>>> -                   ctrl->qmenu[c->value][0] == '\0')
>>> -                       return -EINVAL;
>>> -               return 0;
>>> -
>>> +       case V4L2_CTRL_TYPE_MENU:
>>>         case V4L2_CTRL_TYPE_BITMASK:
>>> -               c->value &= ctrl->maximum;
>>> -               return 0;
>>> -
>>> +       case V4L2_CTRL_TYPE_BOOLEAN:
>>>         case V4L2_CTRL_TYPE_BUTTON:
>>>         case V4L2_CTRL_TYPE_CTRL_CLASS:
>>> -               c->value = 0;
>>> -               return 0;
>>> +               ptr.p_s32 = &c->value;
>>> +               return ctrl->type_ops->validate(ctrl, ptr);
>>>
>>> -       case V4L2_CTRL_TYPE_STRING:
>>> -               len = strlen(c->string);
>>> -               if (len < ctrl->minimum)
>>> -                       return -ERANGE;
>>> -               if ((len - ctrl->minimum) % ctrl->step)
>>> -                       return -ERANGE;
>>> -               return 0;
>>> +       case V4L2_CTRL_TYPE_INTEGER64:
>>> +               ptr.p_s64 = &c->value64;
>>> +               return ctrl->type_ops->validate(ctrl, ptr);
>>>
>>>         default:
>>> -               return -EINVAL;
>>> +               ptr.p = c->p;
>>> +               return ctrl->type_ops->validate(ctrl, ptr);
>>>         }
>>>  }
>>>
>>> @@ -1645,6 +1739,7 @@ unlock:
>>>  /* Add a new control */
>>>  static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
>>>                         const struct v4l2_ctrl_ops *ops,
>>> +                       const struct v4l2_ctrl_type_ops *type_ops,
>>>                         u32 id, const char *name, const char *unit,
>>>                         enum v4l2_ctrl_type type,
>>>                         s64 min, s64 max, u64 step, s64 def,
>>> @@ -1656,6 +1751,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
>>>         unsigned sz_extra;
>>>         void *data;
>>>         int err;
>>> +       int s;
>>>
>>>         if (hdl->error)
>>>                 return NULL;
>>> @@ -1715,6 +1811,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
>>>         INIT_LIST_HEAD(&ctrl->ev_subs);
>>>         ctrl->handler = hdl;
>>>         ctrl->ops = ops;
>>> +       ctrl->type_ops = type_ops ? type_ops : &std_type_ops;
>>>         ctrl->id = id;
>>>         ctrl->name = name;
>>>         ctrl->unit = unit;
>>> @@ -1736,19 +1833,16 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
>>>         ctrl->cur.val = ctrl->val = def;
>>>         data = &ctrl->stores[1];
>>>
>>> -       if (ctrl->is_string) {
>>> -               ctrl->string = ctrl->new.p_char = data;
>>> -               ctrl->stores[0].p_char = data + elem_size;
>>> -
>>> -               if (ctrl->minimum)
>>> -                       memset(ctrl->cur.string, ' ', ctrl->minimum);
>>> -       } else if (ctrl->is_ptr) {
>>> +       if (ctrl->is_ptr) {
>>>                 ctrl->p = ctrl->new.p = data;
>>>                 ctrl->stores[0].p = data + elem_size;
>>>         } else {
>>>                 ctrl->new.p = &ctrl->val;
>>>                 ctrl->stores[0].p = &ctrl->cur.val;
>>>         }
>>> +       for (s = -1; s <= 0; s++)
>>> +               ctrl->type_ops->init(ctrl, ctrl->stores[s]);
>>> +
>>>         if (handler_new_ref(hdl, ctrl)) {
>>>                 kfree(ctrl);
>>>                 return NULL;
>>> @@ -1793,7 +1887,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
>>>                 return NULL;
>>>         }
>>>
>>> -       ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->id, name, unit,
>>> +       ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name, unit,
>>>                         type, min, max,
>>>                         is_menu ? cfg->menu_skip_mask : step,
>>>                         def, cfg->elem_size,
>>> @@ -1821,7 +1915,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
>>>                 handler_set_err(hdl, -EINVAL);
>>>                 return NULL;
>>>         }
>>> -       return v4l2_ctrl_new(hdl, ops, id, name, unit, type,
>>> +       return v4l2_ctrl_new(hdl, ops, NULL, id, name, unit, type,
>>>                              min, max, step, def, 0,
>>>                              flags, NULL, NULL, NULL);
>>>  }
>>> @@ -1855,7 +1949,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
>>>                 handler_set_err(hdl, -EINVAL);
>>>                 return NULL;
>>>         }
>>> -       return v4l2_ctrl_new(hdl, ops, id, name, unit, type,
>>> +       return v4l2_ctrl_new(hdl, ops, NULL, id, name, unit, type,
>>>                              0, max, mask, def, 0,
>>>                              flags, qmenu, qmenu_int, NULL);
>>>  }
>>> @@ -1888,7 +1982,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
>>>                 handler_set_err(hdl, -EINVAL);
>>>                 return NULL;
>>>         }
>>> -       return v4l2_ctrl_new(hdl, ops, id, name, unit, type, 0, max, mask, def,
>>> +       return v4l2_ctrl_new(hdl, ops, NULL, id, name, unit, type,
>>> +                            0, max, mask, def,
>>>                              0, flags, qmenu, NULL, NULL);
>>>
>>>  }
>>> @@ -1913,7 +2008,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
>>>                 handler_set_err(hdl, -EINVAL);
>>>                 return NULL;
>>>         }
>>> -       return v4l2_ctrl_new(hdl, ops, id, name, unit, type,
>>> +       return v4l2_ctrl_new(hdl, ops, NULL, id, name, unit, type,
>>>                              0, max, 0, def, 0,
>>>                              flags, NULL, qmenu_int, NULL);
>>>  }
>>> @@ -2096,32 +2191,8 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl,
>>>
>>>         pr_info("%s%s%s: ", prefix, colon, ctrl->name);
>>>
>>> -       switch (ctrl->type) {
>>> -       case V4L2_CTRL_TYPE_INTEGER:
>>> -               pr_cont("%d", ctrl->cur.val);
>>> -               break;
>>> -       case V4L2_CTRL_TYPE_BOOLEAN:
>>> -               pr_cont("%s", ctrl->cur.val ? "true" : "false");
>>> -               break;
>>> -       case V4L2_CTRL_TYPE_MENU:
>>> -               pr_cont("%s", ctrl->qmenu[ctrl->cur.val]);
>>> -               break;
>>> -       case V4L2_CTRL_TYPE_INTEGER_MENU:
>>> -               pr_cont("%lld", ctrl->qmenu_int[ctrl->cur.val]);
>>> -               break;
>>> -       case V4L2_CTRL_TYPE_BITMASK:
>>> -               pr_cont("0x%08x", ctrl->cur.val);
>>> -               break;
>>> -       case V4L2_CTRL_TYPE_INTEGER64:
>>> -               pr_cont("%lld", ctrl->cur.val64);
>>> -               break;
>>> -       case V4L2_CTRL_TYPE_STRING:
>>> -               pr_cont("%s", ctrl->cur.string);
>>> -               break;
>>> -       default:
>>> -               pr_cont("unknown type %d", ctrl->type);
>>> -               break;
>>> -       }
>>> +       ctrl->type_ops->log(ctrl);
>>> +
>>>         if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
>>>                            V4L2_CTRL_FLAG_GRABBED |
>>>                            V4L2_CTRL_FLAG_VOLATILE)) {
>>> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
>>> index 515c1ba..aaf7333 100644
>>> --- a/include/media/v4l2-ctrls.h
>>> +++ b/include/media/v4l2-ctrls.h
>>> @@ -67,6 +67,23 @@ struct v4l2_ctrl_ops {
>>>         int (*s_ctrl)(struct v4l2_ctrl *ctrl);
>>>  };
>>>
>>> +/** struct v4l2_ctrl_type_ops - The control type operations that the driver has to provide.
>>> +  * @equal: return true if both values are equal.
>>> +  * @init: initialize the value.
>>> +  * @log: log the value.
>>> +  * @validate: validate the value. Return 0 on success and a negative value otherwise.
>>> +  */
>>> +struct v4l2_ctrl_type_ops {
>>> +       bool (*equal)(const struct v4l2_ctrl *ctrl,
>>> +                     union v4l2_ctrl_ptr ptr1,
>>> +                     union v4l2_ctrl_ptr ptr2);
>>> +       void (*init)(const struct v4l2_ctrl *ctrl,
>>> +                    union v4l2_ctrl_ptr ptr);
>>> +       void (*log)(const struct v4l2_ctrl *ctrl);
>>> +       int (*validate)(const struct v4l2_ctrl *ctrl,
>>> +                       union v4l2_ctrl_ptr ptr);
>>> +};
>>> +
>>>  typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
>>>
>>>  /** struct v4l2_ctrl - The control structure.
>>> @@ -102,6 +119,7 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
>>>    *            value, then the whole cluster is in manual mode. Drivers should
>>>    *            never set this flag directly.
>>>    * @ops:      The control ops.
>>> +  * @type_ops: The control type ops.
>>>    * @id:       The control ID.
>>>    * @name:     The control name.
>>>    * @unit:     The control's unit. May be NULL.
>>> @@ -151,6 +169,7 @@ struct v4l2_ctrl {
>>>         unsigned int manual_mode_value:8;
>>>
>>>         const struct v4l2_ctrl_ops *ops;
>>> +       const struct v4l2_ctrl_type_ops *type_ops;
>>>         u32 id;
>>>         const char *name;
>>>         const char *unit;
>>> @@ -234,6 +253,7 @@ struct v4l2_ctrl_handler {
>>>
>>>  /** struct v4l2_ctrl_config - Control configuration structure.
>>>    * @ops:      The control ops.
>>> +  * @type_ops: The control type ops. Only needed for complex controls.
>>>    * @id:       The control ID.
>>>    * @name:     The control name.
>>>    * @unit:     The control's unit.
>>> @@ -259,6 +279,7 @@ struct v4l2_ctrl_handler {
>>>    */
>>>  struct v4l2_ctrl_config {
>>>         const struct v4l2_ctrl_ops *ops;
>>> +       const struct v4l2_ctrl_type_ops *type_ops;
>>>         u32 id;
>>>         const char *name;
>>>         const char *unit;
>>> --
>>> 1.8.5.2
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-media" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>
>>
>



-- 
Ricardo Ribalda

  reply	other threads:[~2014-02-12 12:03 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-10  8:46 [REVIEWv2 PATCH 00/34] Add support for complex controls, use in solo/go7007 Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 01/34] v4l2-ctrls: increase internal min/max/step/def to 64 bit Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 02/34] v4l2-ctrls: add unit string Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 03/34] v4l2-ctrls: use pr_info/cont instead of printk Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 04/34] videodev2.h: add initial support for complex controls Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 05/34] videodev2.h: add struct v4l2_query_ext_ctrl and VIDIOC_QUERY_EXT_CTRL Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 06/34] v4l2-ctrls: add support for complex types Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 07/34] v4l2: integrate support for VIDIOC_QUERY_EXT_CTRL Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 08/34] v4l2-ctrls: create type_ops Hans Verkuil
2014-02-12 10:55   ` Ricardo Ribalda Delgado
2014-02-12 11:36     ` Hans Verkuil
2014-02-12 12:03       ` Ricardo Ribalda Delgado [this message]
2014-02-12 12:31         ` Hans Verkuil
2014-02-12 13:03           ` Ricardo Ribalda Delgado
2014-02-10  8:46 ` [REVIEWv2 PATCH 09/34] v4l2-ctrls: rewrite copy routines to operate on union v4l2_ctrl_ptr Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 10/34] v4l2-ctrls: compare values only once Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 11/34] v4l2-ctrls: prepare for matrix support: add cols & rows fields Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 12/34] v4l2-ctrls: replace cur by a union v4l2_ctrl_ptr Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 13/34] v4l2-ctrls: use 'new' to access pointer controls Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 14/34] v4l2-ctrls: prepare for matrix support Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 15/34] v4l2-ctrls: type_ops can handle matrix elements Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 16/34] v4l2-ctrls: add matrix support Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 17/34] v4l2-ctrls: return elem_size instead of strlen Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 18/34] v4l2-ctrl: fix error return of copy_to/from_user Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 19/34] DocBook media: document VIDIOC_QUERY_EXT_CTRL Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 20/34] DocBook media: update VIDIOC_G/S/TRY_EXT_CTRLS Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 21/34] DocBook media: fix coding style in the control example code Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 22/34] DocBook media: update control section Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 23/34] v4l2-controls.txt: update to the new way of accessing controls Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 24/34] v4l2-ctrls/videodev2.h: add u8 and u16 types Hans Verkuil
2014-02-12 10:44   ` Ricardo Ribalda Delgado
2014-02-12 11:20     ` Hans Verkuil
2014-02-12 12:11       ` Ricardo Ribalda Delgado
2014-02-12 12:40         ` Hans Verkuil
2014-02-12 13:13           ` Ricardo Ribalda Delgado
2014-02-12 13:26             ` Hans Verkuil
2014-02-12 13:40               ` Ricardo Ribalda Delgado
2014-02-12 14:05                 ` Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 25/34] DocBook media: document new u8 and u16 control types Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 26/34] v4l2-ctrls: fix comments Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 27/34] v4l2-ctrls/v4l2-controls.h: add MD controls Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 28/34] DocBook media: document new motion detection controls Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 29/34] v4l2: add a motion detection event Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 30/34] DocBook: document new v4l " Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 31/34] solo6x10: implement the new motion detection controls Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 32/34] solo6x10: implement the motion detection event Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 33/34] solo6x10: fix 'dma from stack' warning Hans Verkuil
2014-02-10  8:46 ` [REVIEWv2 PATCH 34/34] go7007: add motion detection support Hans Verkuil
2014-02-12  7:56   ` [REVIEWv2 PATCH 35/34] DocBook media: clarify how the matrix maps to the grid Hans Verkuil
2014-02-12 11:39 ` [REVIEWv2 PATCH 36/34] v4l2-ctrls: break off loop on first changed element Hans Verkuil
2014-02-16 20:14 ` [REVIEWv2 PATCH 00/34] Add support for complex controls, use in solo/go7007 Sakari Ailus
2014-02-17  9:45   ` Hans Verkuil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAPybu_1U5vGdB9nDeEO71nfE3TrYrWnpngof9ook40dYg9zh9Q@mail.gmail.com \
    --to=ricardo.ribalda@gmail.com \
    --cc=hans.verkuil@cisco.com \
    --cc=hverkuil@xs4all.nl \
    --cc=ismael.luceno@corp.bluecherry.net \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=m.chehab@samsung.com \
    --cc=pete@sensoray.com \
    --cc=s.nawrocki@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.