Commit da1b1aea authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: v4l2-ctrls: v4l2_ctrl_add_handler: add from_other_dev

Add a 'bool from_other_dev' argument: set to true if the two
handlers refer to different devices (e.g. it is true when
inheriting controls from a subdev into a main v4l2 bridge
driver).

This will be used later when implementing support for the
request API since we need to skip such controls.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Reviewed-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent f23317ad
...@@ -1394,7 +1394,8 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) ...@@ -1394,7 +1394,8 @@ static int rtl2832_sdr_probe(struct platform_device *pdev)
case RTL2832_SDR_TUNER_E4000: case RTL2832_SDR_TUNER_E4000:
v4l2_ctrl_handler_init(&dev->hdl, 9); v4l2_ctrl_handler_init(&dev->hdl, 9);
if (subdev) if (subdev)
v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler, NULL); v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler,
NULL, true);
break; break;
case RTL2832_SDR_TUNER_R820T: case RTL2832_SDR_TUNER_R820T:
case RTL2832_SDR_TUNER_R828D: case RTL2832_SDR_TUNER_R828D:
...@@ -1423,7 +1424,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) ...@@ -1423,7 +1424,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev)
v4l2_ctrl_handler_init(&dev->hdl, 2); v4l2_ctrl_handler_init(&dev->hdl, 2);
if (subdev) if (subdev)
v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler, v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler,
NULL); NULL, true);
break; break;
default: default:
v4l2_ctrl_handler_init(&dev->hdl, 0); v4l2_ctrl_handler_init(&dev->hdl, 0);
......
...@@ -4211,7 +4211,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) ...@@ -4211,7 +4211,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
/* register video4linux + input */ /* register video4linux + input */
if (!bttv_tvcards[btv->c.type].no_video) { if (!bttv_tvcards[btv->c.type].no_video) {
v4l2_ctrl_add_handler(&btv->radio_ctrl_handler, hdl, v4l2_ctrl_add_handler(&btv->radio_ctrl_handler, hdl,
v4l2_ctrl_radio_filter); v4l2_ctrl_radio_filter, false);
if (btv->radio_ctrl_handler.error) { if (btv->radio_ctrl_handler.error) {
result = btv->radio_ctrl_handler.error; result = btv->radio_ctrl_handler.error;
goto fail2; goto fail2;
......
...@@ -1527,7 +1527,7 @@ int cx23885_417_register(struct cx23885_dev *dev) ...@@ -1527,7 +1527,7 @@ int cx23885_417_register(struct cx23885_dev *dev)
dev->cxhdl.priv = dev; dev->cxhdl.priv = dev;
dev->cxhdl.func = cx23885_api_func; dev->cxhdl.func = cx23885_api_func;
cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576); cx2341x_handler_set_50hz(&dev->cxhdl, tsport->height == 576);
v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL); v4l2_ctrl_add_handler(&dev->ctrl_handler, &dev->cxhdl.hdl, NULL, false);
/* Allocate and initialize V4L video device */ /* Allocate and initialize V4L video device */
dev->v4l_device = cx23885_video_dev_alloc(tsport, dev->v4l_device = cx23885_video_dev_alloc(tsport,
......
...@@ -1183,7 +1183,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) ...@@ -1183,7 +1183,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
err = cx2341x_handler_init(&dev->cxhdl, 36); err = cx2341x_handler_init(&dev->cxhdl, 36);
if (err) if (err)
goto fail_core; goto fail_core;
v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL); v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL, false);
/* blackbird stuff */ /* blackbird stuff */
pr_info("cx23416 based mpeg encoder (blackbird reference design)\n"); pr_info("cx23416 based mpeg encoder (blackbird reference design)\n");
......
...@@ -1378,7 +1378,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, ...@@ -1378,7 +1378,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev,
if (vc->id == V4L2_CID_CHROMA_AGC) if (vc->id == V4L2_CID_CHROMA_AGC)
core->chroma_agc = vc; core->chroma_agc = vc;
} }
v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL); v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL, false);
/* load and configure helper modules */ /* load and configure helper modules */
......
...@@ -265,9 +265,9 @@ static int empress_init(struct saa7134_dev *dev) ...@@ -265,9 +265,9 @@ static int empress_init(struct saa7134_dev *dev)
"%s empress (%s)", dev->name, "%s empress (%s)", dev->name,
saa7134_boards[dev->board].name); saa7134_boards[dev->board].name);
v4l2_ctrl_handler_init(hdl, 21); v4l2_ctrl_handler_init(hdl, 21);
v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter); v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter, false);
if (dev->empress_sd) if (dev->empress_sd)
v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL); v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL, true);
if (hdl->error) { if (hdl->error) {
video_device_release(dev->empress_dev); video_device_release(dev->empress_dev);
return hdl->error; return hdl->error;
......
...@@ -2136,7 +2136,7 @@ int saa7134_video_init1(struct saa7134_dev *dev) ...@@ -2136,7 +2136,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
hdl = &dev->radio_ctrl_handler; hdl = &dev->radio_ctrl_handler;
v4l2_ctrl_handler_init(hdl, 2); v4l2_ctrl_handler_init(hdl, 2);
v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler,
v4l2_ctrl_radio_filter); v4l2_ctrl_radio_filter, false);
if (hdl->error) if (hdl->error)
return hdl->error; return hdl->error;
} }
......
...@@ -1424,7 +1424,7 @@ static int fimc_link_setup(struct media_entity *entity, ...@@ -1424,7 +1424,7 @@ static int fimc_link_setup(struct media_entity *entity,
return 0; return 0;
return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler, return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler,
sensor->ctrl_handler, NULL); sensor->ctrl_handler, NULL, true);
} }
static const struct media_entity_operations fimc_sd_media_ops = { static const struct media_entity_operations fimc_sd_media_ops = {
......
...@@ -476,7 +476,7 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin, ...@@ -476,7 +476,7 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
return ret; return ret;
ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler, ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler,
NULL); NULL, true);
if (ret < 0) { if (ret < 0) {
v4l2_ctrl_handler_free(&vin->ctrl_handler); v4l2_ctrl_handler_free(&vin->ctrl_handler);
return ret; return ret;
......
...@@ -1164,7 +1164,7 @@ static int rcar_drif_notify_complete(struct v4l2_async_notifier *notifier) ...@@ -1164,7 +1164,7 @@ static int rcar_drif_notify_complete(struct v4l2_async_notifier *notifier)
} }
ret = v4l2_ctrl_add_handler(&sdr->ctrl_hdl, ret = v4l2_ctrl_add_handler(&sdr->ctrl_hdl,
sdr->ep.subdev->ctrl_handler, NULL); sdr->ep.subdev->ctrl_handler, NULL, true);
if (ret) { if (ret) {
rdrif_err(sdr, "failed: ctrl add hdlr ret %d\n", ret); rdrif_err(sdr, "failed: ctrl add hdlr ret %d\n", ret);
goto error; goto error;
......
...@@ -1181,7 +1181,8 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd) ...@@ -1181,7 +1181,8 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd)
v4l2_subdev_call(sd, video, g_tvnorms, &icd->vdev->tvnorms); v4l2_subdev_call(sd, video, g_tvnorms, &icd->vdev->tvnorms);
ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL); ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler,
NULL, true);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -1662,59 +1662,59 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, ...@@ -1662,59 +1662,59 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true); v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
if (dev->has_vid_cap) { if (dev->has_vid_cap) {
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL); v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false);
if (hdl_vid_cap->error) if (hdl_vid_cap->error)
return hdl_vid_cap->error; return hdl_vid_cap->error;
dev->vid_cap_dev.ctrl_handler = hdl_vid_cap; dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
} }
if (dev->has_vid_out) { if (dev->has_vid_out) {
v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL); v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL); v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false);
v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL); v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false);
if (hdl_vid_out->error) if (hdl_vid_out->error)
return hdl_vid_out->error; return hdl_vid_out->error;
dev->vid_out_dev.ctrl_handler = hdl_vid_out; dev->vid_out_dev.ctrl_handler = hdl_vid_out;
} }
if (dev->has_vbi_cap) { if (dev->has_vbi_cap) {
v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false);
v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL); v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false);
v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL); v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false);
v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL); v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false);
if (hdl_vbi_cap->error) if (hdl_vbi_cap->error)
return hdl_vbi_cap->error; return hdl_vbi_cap->error;
dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap; dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
} }
if (dev->has_vbi_out) { if (dev->has_vbi_out) {
v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false);
v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL); v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false);
if (hdl_vbi_out->error) if (hdl_vbi_out->error)
return hdl_vbi_out->error; return hdl_vbi_out->error;
dev->vbi_out_dev.ctrl_handler = hdl_vbi_out; dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
} }
if (dev->has_radio_rx) { if (dev->has_radio_rx) {
v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false);
v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL); v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false);
if (hdl_radio_rx->error) if (hdl_radio_rx->error)
return hdl_radio_rx->error; return hdl_radio_rx->error;
dev->radio_rx_dev.ctrl_handler = hdl_radio_rx; dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
} }
if (dev->has_radio_tx) { if (dev->has_radio_tx) {
v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false);
v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL); v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false);
if (hdl_radio_tx->error) if (hdl_radio_tx->error)
return hdl_radio_tx->error; return hdl_radio_tx->error;
dev->radio_tx_dev.ctrl_handler = hdl_radio_tx; dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
} }
if (dev->has_sdr_cap) { if (dev->has_sdr_cap) {
v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL); v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false);
v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL); v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false);
if (hdl_sdr_cap->error) if (hdl_sdr_cap->error)
return hdl_sdr_cap->error; return hdl_sdr_cap->error;
dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap; dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
......
...@@ -1992,7 +1992,7 @@ int cx231xx_417_register(struct cx231xx *dev) ...@@ -1992,7 +1992,7 @@ int cx231xx_417_register(struct cx231xx *dev)
dev->mpeg_ctrl_handler.ops = &cx231xx_ops; dev->mpeg_ctrl_handler.ops = &cx231xx_ops;
if (dev->sd_cx25840) if (dev->sd_cx25840)
v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl, v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl,
dev->sd_cx25840->ctrl_handler, NULL); dev->sd_cx25840->ctrl_handler, NULL, false);
if (dev->mpeg_ctrl_handler.hdl.error) { if (dev->mpeg_ctrl_handler.hdl.error) {
err = dev->mpeg_ctrl_handler.hdl.error; err = dev->mpeg_ctrl_handler.hdl.error;
dprintk(3, "%s: can't add cx25840 controls\n", dev->name); dprintk(3, "%s: can't add cx25840 controls\n", dev->name);
......
...@@ -2204,10 +2204,10 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ...@@ -2204,10 +2204,10 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
if (dev->sd_cx25840) { if (dev->sd_cx25840) {
v4l2_ctrl_add_handler(&dev->ctrl_handler, v4l2_ctrl_add_handler(&dev->ctrl_handler,
dev->sd_cx25840->ctrl_handler, NULL); dev->sd_cx25840->ctrl_handler, NULL, true);
v4l2_ctrl_add_handler(&dev->radio_ctrl_handler, v4l2_ctrl_add_handler(&dev->radio_ctrl_handler,
dev->sd_cx25840->ctrl_handler, dev->sd_cx25840->ctrl_handler,
v4l2_ctrl_radio_filter); v4l2_ctrl_radio_filter, true);
} }
if (dev->ctrl_handler.error) if (dev->ctrl_handler.error)
......
...@@ -1278,7 +1278,7 @@ static int msi2500_probe(struct usb_interface *intf, ...@@ -1278,7 +1278,7 @@ static int msi2500_probe(struct usb_interface *intf,
} }
/* currently all controls are from subdev */ /* currently all controls are from subdev */
v4l2_ctrl_add_handler(&dev->hdl, sd->ctrl_handler, NULL); v4l2_ctrl_add_handler(&dev->hdl, sd->ctrl_handler, NULL, true);
dev->v4l2_dev.ctrl_handler = &dev->hdl; dev->v4l2_dev.ctrl_handler = &dev->hdl;
dev->vdev.v4l2_dev = &dev->v4l2_dev; dev->vdev.v4l2_dev = &dev->v4l2_dev;
......
...@@ -1625,7 +1625,7 @@ int tm6000_v4l2_register(struct tm6000_core *dev) ...@@ -1625,7 +1625,7 @@ int tm6000_v4l2_register(struct tm6000_core *dev)
v4l2_ctrl_new_std(&dev->ctrl_handler, &tm6000_ctrl_ops, v4l2_ctrl_new_std(&dev->ctrl_handler, &tm6000_ctrl_ops,
V4L2_CID_HUE, -128, 127, 1, 0); V4L2_CID_HUE, -128, 127, 1, 0);
v4l2_ctrl_add_handler(&dev->ctrl_handler, v4l2_ctrl_add_handler(&dev->ctrl_handler,
&dev->radio_ctrl_handler, NULL); &dev->radio_ctrl_handler, NULL, false);
if (dev->radio_ctrl_handler.error) if (dev->radio_ctrl_handler.error)
ret = dev->radio_ctrl_handler.error; ret = dev->radio_ctrl_handler.error;
......
...@@ -2016,7 +2016,8 @@ EXPORT_SYMBOL(v4l2_ctrl_find); ...@@ -2016,7 +2016,8 @@ EXPORT_SYMBOL(v4l2_ctrl_find);
/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */ /* Allocate a new v4l2_ctrl_ref and hook it into the handler. */
static int handler_new_ref(struct v4l2_ctrl_handler *hdl, static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
struct v4l2_ctrl *ctrl) struct v4l2_ctrl *ctrl,
bool from_other_dev)
{ {
struct v4l2_ctrl_ref *ref; struct v4l2_ctrl_ref *ref;
struct v4l2_ctrl_ref *new_ref; struct v4l2_ctrl_ref *new_ref;
...@@ -2040,6 +2041,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl, ...@@ -2040,6 +2041,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
if (!new_ref) if (!new_ref)
return handler_set_err(hdl, -ENOMEM); return handler_set_err(hdl, -ENOMEM);
new_ref->ctrl = ctrl; new_ref->ctrl = ctrl;
new_ref->from_other_dev = from_other_dev;
if (ctrl->handler == hdl) { if (ctrl->handler == hdl) {
/* By default each control starts in a cluster of its own. /* By default each control starts in a cluster of its own.
new_ref->ctrl is basically a cluster array with one new_ref->ctrl is basically a cluster array with one
...@@ -2220,7 +2222,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, ...@@ -2220,7 +2222,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
ctrl->type_ops->init(ctrl, idx, ctrl->p_new); ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
} }
if (handler_new_ref(hdl, ctrl)) { if (handler_new_ref(hdl, ctrl, false)) {
kvfree(ctrl); kvfree(ctrl);
return NULL; return NULL;
} }
...@@ -2389,7 +2391,8 @@ EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); ...@@ -2389,7 +2391,8 @@ EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
/* Add the controls from another handler to our own. */ /* Add the controls from another handler to our own. */
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, 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)) bool (*filter)(const struct v4l2_ctrl *ctrl),
bool from_other_dev)
{ {
struct v4l2_ctrl_ref *ref; struct v4l2_ctrl_ref *ref;
int ret = 0; int ret = 0;
...@@ -2412,7 +2415,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, ...@@ -2412,7 +2415,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
/* Filter any unwanted controls */ /* Filter any unwanted controls */
if (filter && !filter(ctrl)) if (filter && !filter(ctrl))
continue; continue;
ret = handler_new_ref(hdl, ctrl); ret = handler_new_ref(hdl, ctrl, from_other_dev);
if (ret) if (ret)
break; break;
} }
......
...@@ -178,7 +178,8 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, ...@@ -178,7 +178,8 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
sd->v4l2_dev = v4l2_dev; sd->v4l2_dev = v4l2_dev;
/* This just returns 0 if either of the two args is NULL */ /* This just returns 0 if either of the two args is NULL */
err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL); err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler,
NULL, true);
if (err) if (err)
goto error_module; goto error_module;
......
...@@ -391,7 +391,7 @@ static int imx_media_inherit_controls(struct imx_media_dev *imxmd, ...@@ -391,7 +391,7 @@ static int imx_media_inherit_controls(struct imx_media_dev *imxmd,
ret = v4l2_ctrl_add_handler(vfd->ctrl_handler, ret = v4l2_ctrl_add_handler(vfd->ctrl_handler,
sd->ctrl_handler, sd->ctrl_handler,
NULL); NULL, true);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -463,7 +463,7 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim) ...@@ -463,7 +463,7 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim)
{ {
/* add the FIM controls to the calling subdev ctrl handler */ /* add the FIM controls to the calling subdev ctrl handler */
return v4l2_ctrl_add_handler(fim->sd->ctrl_handler, return v4l2_ctrl_add_handler(fim->sd->ctrl_handler,
&fim->ctrl_handler, NULL); &fim->ctrl_handler, NULL, false);
} }
EXPORT_SYMBOL_GPL(imx_media_fim_add_controls); EXPORT_SYMBOL_GPL(imx_media_fim_add_controls);
......
...@@ -247,6 +247,8 @@ struct v4l2_ctrl { ...@@ -247,6 +247,8 @@ struct v4l2_ctrl {
* @ctrl: The actual control information. * @ctrl: The actual control information.
* @helper: Pointer to helper struct. Used internally in * @helper: Pointer to helper struct. Used internally in
* ``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``. * ``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``.
* @from_other_dev: If true, then @ctrl was defined in another
* device than the &struct v4l2_ctrl_handler.
* *
* Each control handler has a list of these refs. The list_head is used to * Each control handler has a list of these refs. The list_head is used to
* keep a sorted-by-control-ID list of all controls, while the next pointer * keep a sorted-by-control-ID list of all controls, while the next pointer
...@@ -257,6 +259,7 @@ struct v4l2_ctrl_ref { ...@@ -257,6 +259,7 @@ struct v4l2_ctrl_ref {
struct v4l2_ctrl_ref *next; struct v4l2_ctrl_ref *next;
struct v4l2_ctrl *ctrl; struct v4l2_ctrl *ctrl;
struct v4l2_ctrl_helper *helper; struct v4l2_ctrl_helper *helper;
bool from_other_dev;
}; };
/** /**
...@@ -633,6 +636,8 @@ typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl); ...@@ -633,6 +636,8 @@ typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl);
* @add: The control handler whose controls you want to add to * @add: The control handler whose controls you want to add to
* the @hdl control handler. * the @hdl control handler.
* @filter: This function will filter which controls should be added. * @filter: This function will filter which controls should be added.
* @from_other_dev: If true, then the controls in @add were defined in another
* device than @hdl.
* *
* Does nothing if either of the two handlers 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 * If @filter is NULL, then all controls are added. Otherwise only those
...@@ -642,7 +647,8 @@ typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl); ...@@ -642,7 +647,8 @@ typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl);
*/ */
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
struct v4l2_ctrl_handler *add, struct v4l2_ctrl_handler *add,
v4l2_ctrl_filter filter); v4l2_ctrl_filter filter,
bool from_other_dev);
/** /**
* v4l2_ctrl_radio_filter() - Standard filter for radio controls. * v4l2_ctrl_radio_filter() - Standard filter for radio controls.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment