0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) "v4l2-ctrls: " fmt
0009
0010 #include <linux/export.h>
0011 #include <linux/mm.h>
0012 #include <linux/slab.h>
0013 #include <media/v4l2-ctrls.h>
0014 #include <media/v4l2-dev.h>
0015 #include <media/v4l2-device.h>
0016 #include <media/v4l2-event.h>
0017 #include <media/v4l2-ioctl.h>
0018
0019 #include "v4l2-ctrls-priv.h"
0020
0021
0022 struct v4l2_ctrl_helper {
0023
0024 struct v4l2_ctrl_ref *mref;
0025
0026 struct v4l2_ctrl_ref *ref;
0027
0028
0029
0030
0031 u32 next;
0032 };
0033
0034
0035
0036
0037
0038
0039
0040 static int ptr_to_user(struct v4l2_ext_control *c,
0041 struct v4l2_ctrl *ctrl,
0042 union v4l2_ctrl_ptr ptr)
0043 {
0044 u32 len;
0045
0046 if (ctrl->is_ptr && !ctrl->is_string)
0047 return copy_to_user(c->ptr, ptr.p_const, c->size) ?
0048 -EFAULT : 0;
0049
0050 switch (ctrl->type) {
0051 case V4L2_CTRL_TYPE_STRING:
0052 len = strlen(ptr.p_char);
0053 if (c->size < len + 1) {
0054 c->size = ctrl->elem_size;
0055 return -ENOSPC;
0056 }
0057 return copy_to_user(c->string, ptr.p_char, len + 1) ?
0058 -EFAULT : 0;
0059 case V4L2_CTRL_TYPE_INTEGER64:
0060 c->value64 = *ptr.p_s64;
0061 break;
0062 default:
0063 c->value = *ptr.p_s32;
0064 break;
0065 }
0066 return 0;
0067 }
0068
0069
0070 static int cur_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
0071 {
0072 return ptr_to_user(c, ctrl, ctrl->p_cur);
0073 }
0074
0075
0076 static int new_to_user(struct v4l2_ext_control *c,
0077 struct v4l2_ctrl *ctrl)
0078 {
0079 return ptr_to_user(c, ctrl, ctrl->p_new);
0080 }
0081
0082
0083 static int req_to_user(struct v4l2_ext_control *c,
0084 struct v4l2_ctrl_ref *ref)
0085 {
0086 return ptr_to_user(c, ref->ctrl, ref->p_req);
0087 }
0088
0089
0090 static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
0091 {
0092 int idx;
0093
0094 for (idx = 0; idx < ctrl->elems; idx++)
0095 ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
0096
0097 return ptr_to_user(c, ctrl, ctrl->p_new);
0098 }
0099
0100
0101 static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
0102 {
0103 int ret;
0104 u32 size;
0105
0106 ctrl->is_new = 0;
0107 if (ctrl->is_dyn_array &&
0108 c->size > ctrl->p_dyn_alloc_elems * ctrl->elem_size) {
0109 void *old = ctrl->p_dyn;
0110 void *tmp = kvzalloc(2 * c->size, GFP_KERNEL);
0111
0112 if (!tmp)
0113 return -ENOMEM;
0114 memcpy(tmp, ctrl->p_new.p, ctrl->elems * ctrl->elem_size);
0115 memcpy(tmp + c->size, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size);
0116 ctrl->p_new.p = tmp;
0117 ctrl->p_cur.p = tmp + c->size;
0118 ctrl->p_dyn = tmp;
0119 ctrl->p_dyn_alloc_elems = c->size / ctrl->elem_size;
0120 kvfree(old);
0121 }
0122
0123 if (ctrl->is_ptr && !ctrl->is_string) {
0124 unsigned int elems = c->size / ctrl->elem_size;
0125 unsigned int idx;
0126
0127 if (copy_from_user(ctrl->p_new.p, c->ptr, c->size))
0128 return -EFAULT;
0129 ctrl->is_new = 1;
0130 if (ctrl->is_dyn_array)
0131 ctrl->new_elems = elems;
0132 else if (ctrl->is_array)
0133 for (idx = elems; idx < ctrl->elems; idx++)
0134 ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
0135 return 0;
0136 }
0137
0138 switch (ctrl->type) {
0139 case V4L2_CTRL_TYPE_INTEGER64:
0140 *ctrl->p_new.p_s64 = c->value64;
0141 break;
0142 case V4L2_CTRL_TYPE_STRING:
0143 size = c->size;
0144 if (size == 0)
0145 return -ERANGE;
0146 if (size > ctrl->maximum + 1)
0147 size = ctrl->maximum + 1;
0148 ret = copy_from_user(ctrl->p_new.p_char, c->string, size) ? -EFAULT : 0;
0149 if (!ret) {
0150 char last = ctrl->p_new.p_char[size - 1];
0151
0152 ctrl->p_new.p_char[size - 1] = 0;
0153
0154
0155
0156
0157 if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last)
0158 return -ERANGE;
0159 }
0160 return ret;
0161 default:
0162 *ctrl->p_new.p_s32 = c->value;
0163 break;
0164 }
0165 ctrl->is_new = 1;
0166 return 0;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
0218 struct v4l2_ext_controls *cs,
0219 struct v4l2_ctrl_helper *helpers,
0220 struct video_device *vdev,
0221 bool get)
0222 {
0223 struct v4l2_ctrl_helper *h;
0224 bool have_clusters = false;
0225 u32 i;
0226
0227 for (i = 0, h = helpers; i < cs->count; i++, h++) {
0228 struct v4l2_ext_control *c = &cs->controls[i];
0229 struct v4l2_ctrl_ref *ref;
0230 struct v4l2_ctrl *ctrl;
0231 u32 id = c->id & V4L2_CTRL_ID_MASK;
0232
0233 cs->error_idx = i;
0234
0235 if (cs->which &&
0236 cs->which != V4L2_CTRL_WHICH_DEF_VAL &&
0237 cs->which != V4L2_CTRL_WHICH_REQUEST_VAL &&
0238 V4L2_CTRL_ID2WHICH(id) != cs->which) {
0239 dprintk(vdev,
0240 "invalid which 0x%x or control id 0x%x\n",
0241 cs->which, id);
0242 return -EINVAL;
0243 }
0244
0245
0246
0247
0248
0249 if (id >= V4L2_CID_PRIVATE_BASE) {
0250 dprintk(vdev,
0251 "old-style private controls not allowed\n");
0252 return -EINVAL;
0253 }
0254 ref = find_ref_lock(hdl, id);
0255 if (!ref) {
0256 dprintk(vdev, "cannot find control id 0x%x\n", id);
0257 return -EINVAL;
0258 }
0259 h->ref = ref;
0260 ctrl = ref->ctrl;
0261 if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) {
0262 dprintk(vdev, "control id 0x%x is disabled\n", id);
0263 return -EINVAL;
0264 }
0265
0266 if (ctrl->cluster[0]->ncontrols > 1)
0267 have_clusters = true;
0268 if (ctrl->cluster[0] != ctrl)
0269 ref = find_ref_lock(hdl, ctrl->cluster[0]->id);
0270 if (ctrl->is_dyn_array) {
0271 unsigned int max_size = ctrl->dims[0] * ctrl->elem_size;
0272 unsigned int tot_size = ctrl->elem_size;
0273
0274 if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL)
0275 tot_size *= ref->p_req_elems;
0276 else
0277 tot_size *= ctrl->elems;
0278
0279 c->size = ctrl->elem_size * (c->size / ctrl->elem_size);
0280 if (get) {
0281 if (c->size < tot_size) {
0282 c->size = tot_size;
0283 return -ENOSPC;
0284 }
0285 c->size = tot_size;
0286 } else {
0287 if (c->size > max_size) {
0288 c->size = max_size;
0289 return -ENOSPC;
0290 }
0291 if (!c->size)
0292 return -EFAULT;
0293 }
0294 } else if (ctrl->is_ptr && !ctrl->is_string) {
0295 unsigned int tot_size = ctrl->elems * ctrl->elem_size;
0296
0297 if (c->size < tot_size) {
0298
0299
0300
0301
0302 if (get) {
0303 c->size = tot_size;
0304 return -ENOSPC;
0305 }
0306 dprintk(vdev,
0307 "pointer control id 0x%x size too small, %d bytes but %d bytes needed\n",
0308 id, c->size, tot_size);
0309 return -EFAULT;
0310 }
0311 c->size = tot_size;
0312 }
0313
0314 h->mref = ref;
0315
0316
0317
0318
0319
0320 h->next = 0;
0321 }
0322
0323
0324
0325
0326
0327 if (!have_clusters)
0328 return 0;
0329
0330
0331
0332
0333
0334
0335
0336 mutex_lock(hdl->lock);
0337
0338
0339 for (i = 0; i < cs->count; i++)
0340 helpers[i].mref->helper = NULL;
0341 for (i = 0, h = helpers; i < cs->count; i++, h++) {
0342 struct v4l2_ctrl_ref *mref = h->mref;
0343
0344
0345
0346
0347
0348 if (mref->helper) {
0349
0350
0351
0352
0353
0354 mref->helper->next = i;
0355
0356
0357
0358
0359 h->mref = NULL;
0360 }
0361
0362 mref->helper = h;
0363 }
0364 mutex_unlock(hdl->lock);
0365 return 0;
0366 }
0367
0368
0369
0370
0371
0372
0373 static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
0374 {
0375 if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL ||
0376 which == V4L2_CTRL_WHICH_REQUEST_VAL)
0377 return 0;
0378 return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;
0379 }
0380
0381
0382
0383
0384
0385
0386
0387
0388 int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
0389 struct v4l2_ext_controls *cs,
0390 struct video_device *vdev)
0391 {
0392 struct v4l2_ctrl_helper helper[4];
0393 struct v4l2_ctrl_helper *helpers = helper;
0394 int ret;
0395 int i, j;
0396 bool is_default, is_request;
0397
0398 is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL);
0399 is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL);
0400
0401 cs->error_idx = cs->count;
0402 cs->which = V4L2_CTRL_ID2WHICH(cs->which);
0403
0404 if (!hdl)
0405 return -EINVAL;
0406
0407 if (cs->count == 0)
0408 return class_check(hdl, cs->which);
0409
0410 if (cs->count > ARRAY_SIZE(helper)) {
0411 helpers = kvmalloc_array(cs->count, sizeof(helper[0]),
0412 GFP_KERNEL);
0413 if (!helpers)
0414 return -ENOMEM;
0415 }
0416
0417 ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, true);
0418 cs->error_idx = cs->count;
0419
0420 for (i = 0; !ret && i < cs->count; i++)
0421 if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
0422 ret = -EACCES;
0423
0424 for (i = 0; !ret && i < cs->count; i++) {
0425 struct v4l2_ctrl *master;
0426 bool is_volatile = false;
0427 u32 idx = i;
0428
0429 if (!helpers[i].mref)
0430 continue;
0431
0432 master = helpers[i].mref->ctrl;
0433 cs->error_idx = i;
0434
0435 v4l2_ctrl_lock(master);
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445 if (!is_default && !is_request &&
0446 ((master->flags & V4L2_CTRL_FLAG_VOLATILE) ||
0447 (master->has_volatiles && !is_cur_manual(master)))) {
0448 for (j = 0; j < master->ncontrols; j++)
0449 cur_to_new(master->cluster[j]);
0450 ret = call_op(master, g_volatile_ctrl);
0451 is_volatile = true;
0452 }
0453
0454 if (ret) {
0455 v4l2_ctrl_unlock(master);
0456 break;
0457 }
0458
0459
0460
0461
0462
0463
0464
0465 do {
0466 struct v4l2_ctrl_ref *ref = helpers[idx].ref;
0467
0468 if (is_default)
0469 ret = def_to_user(cs->controls + idx, ref->ctrl);
0470 else if (is_request && ref->p_req_dyn_enomem)
0471 ret = -ENOMEM;
0472 else if (is_request && ref->p_req_valid)
0473 ret = req_to_user(cs->controls + idx, ref);
0474 else if (is_volatile)
0475 ret = new_to_user(cs->controls + idx, ref->ctrl);
0476 else
0477 ret = cur_to_user(cs->controls + idx, ref->ctrl);
0478 idx = helpers[idx].next;
0479 } while (!ret && idx);
0480
0481 v4l2_ctrl_unlock(master);
0482 }
0483
0484 if (cs->count > ARRAY_SIZE(helper))
0485 kvfree(helpers);
0486 return ret;
0487 }
0488
0489 int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev,
0490 struct media_device *mdev, struct v4l2_ext_controls *cs)
0491 {
0492 if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL)
0493 return v4l2_g_ext_ctrls_request(hdl, vdev, mdev, cs);
0494
0495 return v4l2_g_ext_ctrls_common(hdl, cs, vdev);
0496 }
0497 EXPORT_SYMBOL(v4l2_g_ext_ctrls);
0498
0499
0500 static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new)
0501 {
0502 unsigned int idx;
0503 int err = 0;
0504
0505 for (idx = 0; !err && idx < ctrl->new_elems; idx++)
0506 err = ctrl->type_ops->validate(ctrl, idx, p_new);
0507 return err;
0508 }
0509
0510
0511 static int validate_ctrls(struct v4l2_ext_controls *cs,
0512 struct v4l2_ctrl_helper *helpers,
0513 struct video_device *vdev,
0514 bool set)
0515 {
0516 unsigned int i;
0517 int ret = 0;
0518
0519 cs->error_idx = cs->count;
0520 for (i = 0; i < cs->count; i++) {
0521 struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl;
0522 union v4l2_ctrl_ptr p_new;
0523
0524 cs->error_idx = i;
0525
0526 if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) {
0527 dprintk(vdev,
0528 "control id 0x%x is read-only\n",
0529 ctrl->id);
0530 return -EACCES;
0531 }
0532
0533
0534
0535
0536
0537
0538
0539
0540 if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) {
0541 dprintk(vdev,
0542 "control id 0x%x is grabbed, cannot set\n",
0543 ctrl->id);
0544 return -EBUSY;
0545 }
0546
0547
0548
0549
0550 if (ctrl->is_ptr)
0551 continue;
0552 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
0553 p_new.p_s64 = &cs->controls[i].value64;
0554 else
0555 p_new.p_s32 = &cs->controls[i].value;
0556 ret = validate_new(ctrl, p_new);
0557 if (ret)
0558 return ret;
0559 }
0560 return 0;
0561 }
0562
0563
0564 int try_set_ext_ctrls_common(struct v4l2_fh *fh,
0565 struct v4l2_ctrl_handler *hdl,
0566 struct v4l2_ext_controls *cs,
0567 struct video_device *vdev, bool set)
0568 {
0569 struct v4l2_ctrl_helper helper[4];
0570 struct v4l2_ctrl_helper *helpers = helper;
0571 unsigned int i, j;
0572 int ret;
0573
0574 cs->error_idx = cs->count;
0575
0576
0577 if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) {
0578 dprintk(vdev, "%s: cannot change default value\n",
0579 video_device_node_name(vdev));
0580 return -EINVAL;
0581 }
0582
0583 cs->which = V4L2_CTRL_ID2WHICH(cs->which);
0584
0585 if (!hdl) {
0586 dprintk(vdev, "%s: invalid null control handler\n",
0587 video_device_node_name(vdev));
0588 return -EINVAL;
0589 }
0590
0591 if (cs->count == 0)
0592 return class_check(hdl, cs->which);
0593
0594 if (cs->count > ARRAY_SIZE(helper)) {
0595 helpers = kvmalloc_array(cs->count, sizeof(helper[0]),
0596 GFP_KERNEL);
0597 if (!helpers)
0598 return -ENOMEM;
0599 }
0600 ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, false);
0601 if (!ret)
0602 ret = validate_ctrls(cs, helpers, vdev, set);
0603 if (ret && set)
0604 cs->error_idx = cs->count;
0605 for (i = 0; !ret && i < cs->count; i++) {
0606 struct v4l2_ctrl *master;
0607 u32 idx = i;
0608
0609 if (!helpers[i].mref)
0610 continue;
0611
0612 cs->error_idx = i;
0613 master = helpers[i].mref->ctrl;
0614 v4l2_ctrl_lock(master);
0615
0616
0617 for (j = 0; j < master->ncontrols; j++)
0618 if (master->cluster[j])
0619 master->cluster[j]->is_new = 0;
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629 if (master->is_auto && master->has_volatiles &&
0630 !is_cur_manual(master)) {
0631
0632 s32 new_auto_val = master->manual_mode_value + 1;
0633 u32 tmp_idx = idx;
0634
0635 do {
0636
0637
0638
0639
0640 if (helpers[tmp_idx].ref->ctrl == master)
0641 new_auto_val = cs->controls[tmp_idx].value;
0642 tmp_idx = helpers[tmp_idx].next;
0643 } while (tmp_idx);
0644
0645
0646
0647
0648 if (new_auto_val == master->manual_mode_value)
0649 update_from_auto_cluster(master);
0650 }
0651
0652
0653
0654
0655
0656 do {
0657 struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl;
0658
0659 ret = user_to_new(cs->controls + idx, ctrl);
0660 if (!ret && ctrl->is_ptr) {
0661 ret = validate_new(ctrl, ctrl->p_new);
0662 if (ret)
0663 dprintk(vdev,
0664 "failed to validate control %s (%d)\n",
0665 v4l2_ctrl_get_name(ctrl->id), ret);
0666 }
0667 idx = helpers[idx].next;
0668 } while (!ret && idx);
0669
0670 if (!ret)
0671 ret = try_or_set_cluster(fh, master,
0672 !hdl->req_obj.req && set, 0);
0673 if (!ret && hdl->req_obj.req && set) {
0674 for (j = 0; j < master->ncontrols; j++) {
0675 struct v4l2_ctrl_ref *ref =
0676 find_ref(hdl, master->cluster[j]->id);
0677
0678 new_to_req(ref);
0679 }
0680 }
0681
0682
0683 if (!ret) {
0684 idx = i;
0685 do {
0686 ret = new_to_user(cs->controls + idx,
0687 helpers[idx].ref->ctrl);
0688 idx = helpers[idx].next;
0689 } while (!ret && idx);
0690 }
0691 v4l2_ctrl_unlock(master);
0692 }
0693
0694 if (cs->count > ARRAY_SIZE(helper))
0695 kvfree(helpers);
0696 return ret;
0697 }
0698
0699 static int try_set_ext_ctrls(struct v4l2_fh *fh,
0700 struct v4l2_ctrl_handler *hdl,
0701 struct video_device *vdev,
0702 struct media_device *mdev,
0703 struct v4l2_ext_controls *cs, bool set)
0704 {
0705 int ret;
0706
0707 if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL)
0708 return try_set_ext_ctrls_request(fh, hdl, vdev, mdev, cs, set);
0709
0710 ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set);
0711 if (ret)
0712 dprintk(vdev,
0713 "%s: try_set_ext_ctrls_common failed (%d)\n",
0714 video_device_node_name(vdev), ret);
0715
0716 return ret;
0717 }
0718
0719 int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,
0720 struct video_device *vdev,
0721 struct media_device *mdev,
0722 struct v4l2_ext_controls *cs)
0723 {
0724 return try_set_ext_ctrls(NULL, hdl, vdev, mdev, cs, false);
0725 }
0726 EXPORT_SYMBOL(v4l2_try_ext_ctrls);
0727
0728 int v4l2_s_ext_ctrls(struct v4l2_fh *fh,
0729 struct v4l2_ctrl_handler *hdl,
0730 struct video_device *vdev,
0731 struct media_device *mdev,
0732 struct v4l2_ext_controls *cs)
0733 {
0734 return try_set_ext_ctrls(fh, hdl, vdev, mdev, cs, true);
0735 }
0736 EXPORT_SYMBOL(v4l2_s_ext_ctrls);
0737
0738
0739
0740
0741
0742
0743 static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
0744 {
0745 struct v4l2_ctrl *master = ctrl->cluster[0];
0746 int ret = 0;
0747 int i;
0748
0749
0750
0751
0752
0753 if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64)
0754 return -EINVAL;
0755
0756 if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
0757 return -EACCES;
0758
0759 v4l2_ctrl_lock(master);
0760
0761 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
0762 for (i = 0; i < master->ncontrols; i++)
0763 cur_to_new(master->cluster[i]);
0764 ret = call_op(master, g_volatile_ctrl);
0765 new_to_user(c, ctrl);
0766 } else {
0767 cur_to_user(c, ctrl);
0768 }
0769 v4l2_ctrl_unlock(master);
0770 return ret;
0771 }
0772
0773 int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control)
0774 {
0775 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
0776 struct v4l2_ext_control c;
0777 int ret;
0778
0779 if (!ctrl || !ctrl->is_int)
0780 return -EINVAL;
0781 ret = get_ctrl(ctrl, &c);
0782 control->value = c.value;
0783 return ret;
0784 }
0785 EXPORT_SYMBOL(v4l2_g_ctrl);
0786
0787
0788 static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
0789 {
0790 struct v4l2_ctrl *master = ctrl->cluster[0];
0791 int ret;
0792 int i;
0793
0794
0795 for (i = 0; i < master->ncontrols; i++)
0796 if (master->cluster[i])
0797 master->cluster[i]->is_new = 0;
0798
0799 ret = validate_new(ctrl, ctrl->p_new);
0800 if (ret)
0801 return ret;
0802
0803
0804
0805
0806
0807
0808 if (master->is_auto && master->has_volatiles && ctrl == master &&
0809 !is_cur_manual(master) && ctrl->val == master->manual_mode_value)
0810 update_from_auto_cluster(master);
0811
0812 ctrl->is_new = 1;
0813 return try_or_set_cluster(fh, master, true, ch_flags);
0814 }
0815
0816
0817 static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
0818 struct v4l2_ext_control *c)
0819 {
0820 int ret;
0821
0822 v4l2_ctrl_lock(ctrl);
0823 user_to_new(c, ctrl);
0824 ret = set_ctrl(fh, ctrl, 0);
0825 if (!ret)
0826 cur_to_user(c, ctrl);
0827 v4l2_ctrl_unlock(ctrl);
0828 return ret;
0829 }
0830
0831 int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
0832 struct v4l2_control *control)
0833 {
0834 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
0835 struct v4l2_ext_control c = { control->id };
0836 int ret;
0837
0838 if (!ctrl || !ctrl->is_int)
0839 return -EINVAL;
0840
0841 if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
0842 return -EACCES;
0843
0844 c.value = control->value;
0845 ret = set_ctrl_lock(fh, ctrl, &c);
0846 control->value = c.value;
0847 return ret;
0848 }
0849 EXPORT_SYMBOL(v4l2_s_ctrl);
0850
0851
0852
0853
0854
0855 s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl)
0856 {
0857 struct v4l2_ext_control c;
0858
0859
0860 if (WARN_ON(!ctrl->is_int))
0861 return 0;
0862 c.value = 0;
0863 get_ctrl(ctrl, &c);
0864 return c.value;
0865 }
0866 EXPORT_SYMBOL(v4l2_ctrl_g_ctrl);
0867
0868 s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl)
0869 {
0870 struct v4l2_ext_control c;
0871
0872
0873 if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64))
0874 return 0;
0875 c.value64 = 0;
0876 get_ctrl(ctrl, &c);
0877 return c.value64;
0878 }
0879 EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64);
0880
0881 int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
0882 {
0883 lockdep_assert_held(ctrl->handler->lock);
0884
0885
0886 if (WARN_ON(!ctrl->is_int))
0887 return -EINVAL;
0888 ctrl->val = val;
0889 return set_ctrl(NULL, ctrl, 0);
0890 }
0891 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl);
0892
0893 int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
0894 {
0895 lockdep_assert_held(ctrl->handler->lock);
0896
0897
0898 if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64))
0899 return -EINVAL;
0900 *ctrl->p_new.p_s64 = val;
0901 return set_ctrl(NULL, ctrl, 0);
0902 }
0903 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64);
0904
0905 int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
0906 {
0907 lockdep_assert_held(ctrl->handler->lock);
0908
0909
0910 if (WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING))
0911 return -EINVAL;
0912 strscpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);
0913 return set_ctrl(NULL, ctrl, 0);
0914 }
0915 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
0916
0917 int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl,
0918 enum v4l2_ctrl_type type, const void *p)
0919 {
0920 lockdep_assert_held(ctrl->handler->lock);
0921
0922
0923 if (WARN_ON(ctrl->type != type))
0924 return -EINVAL;
0925
0926 if (WARN_ON(ctrl->is_dyn_array))
0927 return -EINVAL;
0928 memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size);
0929 return set_ctrl(NULL, ctrl, 0);
0930 }
0931 EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_compound);
0932
0933
0934
0935
0936 int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
0937 s64 min, s64 max, u64 step, s64 def)
0938 {
0939 bool value_changed;
0940 bool range_changed = false;
0941 int ret;
0942
0943 lockdep_assert_held(ctrl->handler->lock);
0944
0945 switch (ctrl->type) {
0946 case V4L2_CTRL_TYPE_INTEGER:
0947 case V4L2_CTRL_TYPE_INTEGER64:
0948 case V4L2_CTRL_TYPE_BOOLEAN:
0949 case V4L2_CTRL_TYPE_MENU:
0950 case V4L2_CTRL_TYPE_INTEGER_MENU:
0951 case V4L2_CTRL_TYPE_BITMASK:
0952 case V4L2_CTRL_TYPE_U8:
0953 case V4L2_CTRL_TYPE_U16:
0954 case V4L2_CTRL_TYPE_U32:
0955 if (ctrl->is_array)
0956 return -EINVAL;
0957 ret = check_range(ctrl->type, min, max, step, def);
0958 if (ret)
0959 return ret;
0960 break;
0961 default:
0962 return -EINVAL;
0963 }
0964 if (ctrl->minimum != min || ctrl->maximum != max ||
0965 ctrl->step != step || ctrl->default_value != def) {
0966 range_changed = true;
0967 ctrl->minimum = min;
0968 ctrl->maximum = max;
0969 ctrl->step = step;
0970 ctrl->default_value = def;
0971 }
0972 cur_to_new(ctrl);
0973 if (validate_new(ctrl, ctrl->p_new)) {
0974 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
0975 *ctrl->p_new.p_s64 = def;
0976 else
0977 *ctrl->p_new.p_s32 = def;
0978 }
0979
0980 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
0981 value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64;
0982 else
0983 value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32;
0984 if (value_changed)
0985 ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
0986 else if (range_changed)
0987 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
0988 return ret;
0989 }
0990 EXPORT_SYMBOL(__v4l2_ctrl_modify_range);
0991
0992
0993 int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)
0994 {
0995 const unsigned int next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
0996 u32 id = qc->id & V4L2_CTRL_ID_MASK;
0997 struct v4l2_ctrl_ref *ref;
0998 struct v4l2_ctrl *ctrl;
0999
1000 if (!hdl)
1001 return -EINVAL;
1002
1003 mutex_lock(hdl->lock);
1004
1005
1006 ref = find_ref(hdl, id);
1007
1008 if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) {
1009 bool is_compound;
1010
1011 unsigned int mask = 1;
1012 bool match = false;
1013
1014 if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) {
1015
1016 match = true;
1017 } else if ((qc->id & next_flags) == next_flags) {
1018
1019 mask = 0;
1020 }
1021
1022
1023
1024
1025 if (id >= node2id(hdl->ctrl_refs.prev)) {
1026 ref = NULL;
1027 } else if (ref) {
1028
1029
1030
1031
1032 list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) {
1033 is_compound = ref->ctrl->is_array ||
1034 ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
1035 if (id < ref->ctrl->id &&
1036 (is_compound & mask) == match)
1037 break;
1038 }
1039 if (&ref->node == &hdl->ctrl_refs)
1040 ref = NULL;
1041 } else {
1042
1043
1044
1045
1046
1047
1048 list_for_each_entry(ref, &hdl->ctrl_refs, node) {
1049 is_compound = ref->ctrl->is_array ||
1050 ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
1051 if (id < ref->ctrl->id &&
1052 (is_compound & mask) == match)
1053 break;
1054 }
1055 if (&ref->node == &hdl->ctrl_refs)
1056 ref = NULL;
1057 }
1058 }
1059 mutex_unlock(hdl->lock);
1060
1061 if (!ref)
1062 return -EINVAL;
1063
1064 ctrl = ref->ctrl;
1065 memset(qc, 0, sizeof(*qc));
1066 if (id >= V4L2_CID_PRIVATE_BASE)
1067 qc->id = id;
1068 else
1069 qc->id = ctrl->id;
1070 strscpy(qc->name, ctrl->name, sizeof(qc->name));
1071 qc->flags = user_flags(ctrl);
1072 qc->type = ctrl->type;
1073 qc->elem_size = ctrl->elem_size;
1074 qc->elems = ctrl->elems;
1075 qc->nr_of_dims = ctrl->nr_of_dims;
1076 memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0]));
1077 qc->minimum = ctrl->minimum;
1078 qc->maximum = ctrl->maximum;
1079 qc->default_value = ctrl->default_value;
1080 if (ctrl->type == V4L2_CTRL_TYPE_MENU ||
1081 ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
1082 qc->step = 1;
1083 else
1084 qc->step = ctrl->step;
1085 return 0;
1086 }
1087 EXPORT_SYMBOL(v4l2_query_ext_ctrl);
1088
1089
1090 int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
1091 {
1092 struct v4l2_query_ext_ctrl qec = { qc->id };
1093 int rc;
1094
1095 rc = v4l2_query_ext_ctrl(hdl, &qec);
1096 if (rc)
1097 return rc;
1098
1099 qc->id = qec.id;
1100 qc->type = qec.type;
1101 qc->flags = qec.flags;
1102 strscpy(qc->name, qec.name, sizeof(qc->name));
1103 switch (qc->type) {
1104 case V4L2_CTRL_TYPE_INTEGER:
1105 case V4L2_CTRL_TYPE_BOOLEAN:
1106 case V4L2_CTRL_TYPE_MENU:
1107 case V4L2_CTRL_TYPE_INTEGER_MENU:
1108 case V4L2_CTRL_TYPE_STRING:
1109 case V4L2_CTRL_TYPE_BITMASK:
1110 qc->minimum = qec.minimum;
1111 qc->maximum = qec.maximum;
1112 qc->step = qec.step;
1113 qc->default_value = qec.default_value;
1114 break;
1115 default:
1116 qc->minimum = 0;
1117 qc->maximum = 0;
1118 qc->step = 0;
1119 qc->default_value = 0;
1120 break;
1121 }
1122 return 0;
1123 }
1124 EXPORT_SYMBOL(v4l2_queryctrl);
1125
1126
1127 int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
1128 {
1129 struct v4l2_ctrl *ctrl;
1130 u32 i = qm->index;
1131
1132 ctrl = v4l2_ctrl_find(hdl, qm->id);
1133 if (!ctrl)
1134 return -EINVAL;
1135
1136 qm->reserved = 0;
1137
1138 switch (ctrl->type) {
1139 case V4L2_CTRL_TYPE_MENU:
1140 if (!ctrl->qmenu)
1141 return -EINVAL;
1142 break;
1143 case V4L2_CTRL_TYPE_INTEGER_MENU:
1144 if (!ctrl->qmenu_int)
1145 return -EINVAL;
1146 break;
1147 default:
1148 return -EINVAL;
1149 }
1150
1151 if (i < ctrl->minimum || i > ctrl->maximum)
1152 return -EINVAL;
1153
1154
1155 if (ctrl->menu_skip_mask & (1ULL << i))
1156 return -EINVAL;
1157
1158 if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
1159 if (!ctrl->qmenu[i] || ctrl->qmenu[i][0] == '\0')
1160 return -EINVAL;
1161 strscpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
1162 } else {
1163 qm->value = ctrl->qmenu_int[i];
1164 }
1165 return 0;
1166 }
1167 EXPORT_SYMBOL(v4l2_querymenu);
1168
1169
1170
1171
1172
1173 int v4l2_ctrl_log_status(struct file *file, void *fh)
1174 {
1175 struct video_device *vfd = video_devdata(file);
1176 struct v4l2_fh *vfh = file->private_data;
1177
1178 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)
1179 v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
1180 vfd->v4l2_dev->name);
1181 return 0;
1182 }
1183 EXPORT_SYMBOL(v4l2_ctrl_log_status);
1184
1185 int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd)
1186 {
1187 v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
1188 return 0;
1189 }
1190 EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status);
1191
1192
1193
1194
1195
1196 static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev,
1197 unsigned int elems)
1198 {
1199 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
1200
1201 if (!ctrl)
1202 return -EINVAL;
1203
1204 v4l2_ctrl_lock(ctrl);
1205 list_add_tail(&sev->node, &ctrl->ev_subs);
1206 if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&
1207 (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL))
1208 send_initial_event(sev->fh, ctrl);
1209 v4l2_ctrl_unlock(ctrl);
1210 return 0;
1211 }
1212
1213 static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
1214 {
1215 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
1216
1217 if (!ctrl)
1218 return;
1219
1220 v4l2_ctrl_lock(ctrl);
1221 list_del(&sev->node);
1222 v4l2_ctrl_unlock(ctrl);
1223 }
1224
1225 void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)
1226 {
1227 u32 old_changes = old->u.ctrl.changes;
1228
1229 old->u.ctrl = new->u.ctrl;
1230 old->u.ctrl.changes |= old_changes;
1231 }
1232 EXPORT_SYMBOL(v4l2_ctrl_replace);
1233
1234 void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)
1235 {
1236 new->u.ctrl.changes |= old->u.ctrl.changes;
1237 }
1238 EXPORT_SYMBOL(v4l2_ctrl_merge);
1239
1240 const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {
1241 .add = v4l2_ctrl_add_event,
1242 .del = v4l2_ctrl_del_event,
1243 .replace = v4l2_ctrl_replace,
1244 .merge = v4l2_ctrl_merge,
1245 };
1246 EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);
1247
1248 int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
1249 const struct v4l2_event_subscription *sub)
1250 {
1251 if (sub->type == V4L2_EVENT_CTRL)
1252 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
1253 return -EINVAL;
1254 }
1255 EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
1256
1257 int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1258 struct v4l2_event_subscription *sub)
1259 {
1260 if (!sd->ctrl_handler)
1261 return -EINVAL;
1262 return v4l2_ctrl_subscribe_event(fh, sub);
1263 }
1264 EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event);
1265
1266
1267
1268
1269 __poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)
1270 {
1271 struct v4l2_fh *fh = file->private_data;
1272
1273 poll_wait(file, &fh->wait, wait);
1274 if (v4l2_event_pending(fh))
1275 return EPOLLPRI;
1276 return 0;
1277 }
1278 EXPORT_SYMBOL(v4l2_ctrl_poll);