[media] v4l2-ctrls: add a filter function to v4l2_ctrl_add_handler
With a filter function you can control more precisely which controls are added. This is useful in particular for radio device nodes for combined TV/Radio cards where you want to show just the radio-specific controls and not controls like brightness. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
a4f64407b9
commit
34a6b7d093
8 changed files with 50 additions and 9 deletions
|
@ -594,7 +594,11 @@ handler and finally add the first handler to the second. For example:
|
|||
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
|
||||
v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler);
|
||||
v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler, NULL);
|
||||
|
||||
The last argument to v4l2_ctrl_add_handler() is a filter function that allows
|
||||
you to filter which controls will be added. Set it to NULL if you want to add
|
||||
all controls.
|
||||
|
||||
Or you can add specific controls to a handler:
|
||||
|
||||
|
|
|
@ -1236,7 +1236,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
|
|||
err = cx2341x_handler_init(&dev->cxhdl, 36);
|
||||
if (err)
|
||||
goto fail_core;
|
||||
v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl);
|
||||
v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL);
|
||||
|
||||
/* blackbird stuff */
|
||||
printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
|
||||
|
|
|
@ -1795,7 +1795,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
|
|||
if (vc->id == V4L2_CID_CHROMA_AGC)
|
||||
core->chroma_agc = vc;
|
||||
}
|
||||
v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl);
|
||||
v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL);
|
||||
|
||||
/* load and configure helper modules */
|
||||
|
||||
|
|
|
@ -472,7 +472,7 @@ int fimc_capture_ctrls_create(struct fimc_dev *fimc)
|
|||
return ret;
|
||||
|
||||
return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
|
||||
fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler);
|
||||
fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler, NULL);
|
||||
}
|
||||
|
||||
static int fimc_capture_set_default_format(struct fimc_dev *fimc);
|
||||
|
|
|
@ -1184,7 +1184,7 @@ static int soc_camera_probe(struct soc_camera_device *icd)
|
|||
sd->grp_id = soc_camera_grp_id(icd);
|
||||
v4l2_set_subdev_hostdata(sd, icd);
|
||||
|
||||
if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
|
||||
if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL))
|
||||
goto ectrl;
|
||||
|
||||
/* At this point client .probe() should have run already */
|
||||
|
|
|
@ -1687,7 +1687,8 @@ EXPORT_SYMBOL(v4l2_ctrl_add_ctrl);
|
|||
|
||||
/* Add the controls from another handler to our own. */
|
||||
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
|
||||
struct v4l2_ctrl_handler *add)
|
||||
struct v4l2_ctrl_handler *add,
|
||||
bool (*filter)(const struct v4l2_ctrl *ctrl))
|
||||
{
|
||||
struct v4l2_ctrl_ref *ref;
|
||||
int ret = 0;
|
||||
|
@ -1707,6 +1708,9 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
|
|||
/* And control classes */
|
||||
if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
|
||||
continue;
|
||||
/* Filter any unwanted controls */
|
||||
if (filter && !filter(ctrl))
|
||||
continue;
|
||||
ret = handler_new_ref(hdl, ctrl);
|
||||
if (ret)
|
||||
break;
|
||||
|
@ -1716,6 +1720,25 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
|
|||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_add_handler);
|
||||
|
||||
bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_FM_TX)
|
||||
return true;
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
case V4L2_CID_AUDIO_VOLUME:
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
case V4L2_CID_AUDIO_BASS:
|
||||
case V4L2_CID_AUDIO_TREBLE:
|
||||
case V4L2_CID_AUDIO_LOUDNESS:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(v4l2_ctrl_radio_filter);
|
||||
|
||||
/* Cluster controls */
|
||||
void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
|
||||
{
|
||||
|
|
|
@ -166,7 +166,7 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
|
|||
}
|
||||
|
||||
/* This just returns 0 if either of the two args is NULL */
|
||||
err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
|
||||
err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL);
|
||||
if (err) {
|
||||
if (sd->internal_ops && sd->internal_ops->unregistered)
|
||||
sd->internal_ops->unregistered(sd);
|
||||
|
|
|
@ -384,14 +384,28 @@ struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl,
|
|||
* @hdl: The control handler.
|
||||
* @add: The control handler whose controls you want to add to
|
||||
* the @hdl control handler.
|
||||
* @filter: This function will filter which controls should be added.
|
||||
*
|
||||
* Does nothing if either of the two is a NULL pointer.
|
||||
* Does nothing if either of the two handlers is a NULL pointer.
|
||||
* If @filter is NULL, then all controls are added. Otherwise only those
|
||||
* controls for which @filter returns true will be added.
|
||||
* In case of an error @hdl->error will be set to the error code (if it
|
||||
* wasn't set already).
|
||||
*/
|
||||
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
|
||||
struct v4l2_ctrl_handler *add);
|
||||
struct v4l2_ctrl_handler *add,
|
||||
bool (*filter)(const struct v4l2_ctrl *ctrl));
|
||||
|
||||
/** v4l2_ctrl_radio_filter() - Standard filter for radio controls.
|
||||
* @ctrl: The control that is filtered.
|
||||
*
|
||||
* This will return true for any controls that are valid for radio device
|
||||
* nodes. Those are all of the V4L2_CID_AUDIO_* user controls and all FM
|
||||
* transmitter class controls.
|
||||
*
|
||||
* This function is to be used with v4l2_ctrl_add_handler().
|
||||
*/
|
||||
bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl);
|
||||
|
||||
/** v4l2_ctrl_cluster() - Mark all controls in the cluster as belonging to that cluster.
|
||||
* @ncontrols: The number of controls in this cluster.
|
||||
|
|
Loading…
Reference in a new issue