summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/video4linux/v4l2-controls.txt6
-rw-r--r--drivers/media/pci/cx88/cx88-blackbird.c2
-rw-r--r--drivers/media/pci/cx88/cx88-video.c2
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-capture.c2
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c25
-rw-r--r--drivers/media/v4l2-core/v4l2-device.c2
-rw-r--r--include/media/v4l2-ctrls.h18
8 files changed, 50 insertions, 9 deletions
diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt
index 43da22b89728..54270df99d5c 100644
--- a/Documentation/video4linux/v4l2-controls.txt
+++ b/Documentation/video4linux/v4l2-controls.txt
@@ -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:
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c
index 843ffd9e533b..def363fb71c0 100644
--- a/drivers/media/pci/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -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",
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index f6fcc7e763ab..a146d50d7795 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -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 */
diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c
index 40923885977a..ac2ca36039e4 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -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);
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index f6b1c1f87761..3be92944f8e7 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -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 */
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index f40003550b60..631cdc0e0bda 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -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)
{
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 1f203b85a637..513969fa695d 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -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);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 6890f5e11ad0..801adb466bd2 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -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.