static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
 {
        struct vpfe_device *vpfe_dev = video_drvdata(file);
+       struct v4l2_subdev *sd;
        struct vpfe_subdev_info *sdinfo;
        int subdev_index, inp_index;
        struct vpfe_route *route;
        }
 
        sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
+       sd = vpfe_dev->sd[subdev_index];
        route = &sdinfo->routes[inp_index];
        if (route && sdinfo->can_route) {
                input = route->input;
                output = route->output;
        }
 
-       ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                        video, s_routing, input, output, 0);
+       if (sd)
+               ret = v4l2_subdev_call(sd, video, s_routing, input, output, 0);
 
        if (ret) {
                v4l2_err(&vpfe_dev->v4l2_dev,
                goto unlock_out;
        }
        vpfe_dev->current_subdev = sdinfo;
+       if (sd)
+               vpfe_dev->v4l2_dev.ctrl_handler = sd->ctrl_handler;
        vpfe_dev->current_input = index;
        vpfe_dev->std_index = 0;
 
                                      buf, file->f_flags & O_NONBLOCK);
 }
 
-static int vpfe_queryctrl(struct file *file, void *priv,
-               struct v4l2_queryctrl *qctrl)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_subdev_info *sdinfo;
-
-       sdinfo = vpfe_dev->current_subdev;
-
-       return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                        core, queryctrl, qctrl);
-
-}
-
-static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_subdev_info *sdinfo;
-
-       sdinfo = vpfe_dev->current_subdev;
-
-       return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                        core, g_ctrl, ctrl);
-}
-
-static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
-{
-       struct vpfe_device *vpfe_dev = video_drvdata(file);
-       struct vpfe_subdev_info *sdinfo;
-
-       sdinfo = vpfe_dev->current_subdev;
-
-       return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-                                        core, s_ctrl, ctrl);
-}
-
 /*
  * vpfe_calculate_offsets : This function calculates buffers offset
  * for top and bottom field
        .vidioc_querystd         = vpfe_querystd,
        .vidioc_s_std            = vpfe_s_std,
        .vidioc_g_std            = vpfe_g_std,
-       .vidioc_queryctrl        = vpfe_queryctrl,
-       .vidioc_g_ctrl           = vpfe_g_ctrl,
-       .vidioc_s_ctrl           = vpfe_s_ctrl,
        .vidioc_reqbufs          = vpfe_reqbufs,
        .vidioc_querybuf         = vpfe_querybuf,
        .vidioc_qbuf             = vpfe_qbuf,
 
        /* set first sub device as current one */
        vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
+       vpfe_dev->v4l2_dev.ctrl_handler = vpfe_dev->sd[0]->ctrl_handler;
 
        /* We have at least one sub device to work with */
        mutex_unlock(&ccdc_lock);