diff options
Diffstat (limited to 'drivers/media/video/uvc/uvc_ctrl.c')
-rw-r--r-- | drivers/media/video/uvc/uvc_ctrl.c | 242 |
1 files changed, 149 insertions, 93 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index ec8ef8c5560a..3b2e7800d56f 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -23,9 +23,13 @@ | |||
23 | 23 | ||
24 | #include "uvcvideo.h" | 24 | #include "uvcvideo.h" |
25 | 25 | ||
26 | #define UVC_CTRL_NDATA 2 | ||
27 | #define UVC_CTRL_DATA_CURRENT 0 | 26 | #define UVC_CTRL_DATA_CURRENT 0 |
28 | #define UVC_CTRL_DATA_BACKUP 1 | 27 | #define UVC_CTRL_DATA_BACKUP 1 |
28 | #define UVC_CTRL_DATA_MIN 2 | ||
29 | #define UVC_CTRL_DATA_MAX 3 | ||
30 | #define UVC_CTRL_DATA_RES 4 | ||
31 | #define UVC_CTRL_DATA_DEF 5 | ||
32 | #define UVC_CTRL_DATA_LAST 6 | ||
29 | 33 | ||
30 | /* ------------------------------------------------------------------------ | 34 | /* ------------------------------------------------------------------------ |
31 | * Controls | 35 | * Controls |
@@ -755,6 +759,49 @@ struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | |||
755 | return ctrl; | 759 | return ctrl; |
756 | } | 760 | } |
757 | 761 | ||
762 | static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, | ||
763 | struct uvc_control *ctrl) | ||
764 | { | ||
765 | int ret; | ||
766 | |||
767 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | ||
768 | ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, | ||
769 | chain->dev->intfnum, ctrl->info->selector, | ||
770 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), | ||
771 | ctrl->info->size); | ||
772 | if (ret < 0) | ||
773 | return ret; | ||
774 | } | ||
775 | |||
776 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { | ||
777 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, | ||
778 | chain->dev->intfnum, ctrl->info->selector, | ||
779 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), | ||
780 | ctrl->info->size); | ||
781 | if (ret < 0) | ||
782 | return ret; | ||
783 | } | ||
784 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { | ||
785 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, | ||
786 | chain->dev->intfnum, ctrl->info->selector, | ||
787 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), | ||
788 | ctrl->info->size); | ||
789 | if (ret < 0) | ||
790 | return ret; | ||
791 | } | ||
792 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { | ||
793 | ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, | ||
794 | chain->dev->intfnum, ctrl->info->selector, | ||
795 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), | ||
796 | ctrl->info->size); | ||
797 | if (ret < 0) | ||
798 | return ret; | ||
799 | } | ||
800 | |||
801 | ctrl->cached = 1; | ||
802 | return 0; | ||
803 | } | ||
804 | |||
758 | int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 805 | int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
759 | struct v4l2_queryctrl *v4l2_ctrl) | 806 | struct v4l2_queryctrl *v4l2_ctrl) |
760 | { | 807 | { |
@@ -762,17 +809,12 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
762 | struct uvc_control_mapping *mapping; | 809 | struct uvc_control_mapping *mapping; |
763 | struct uvc_menu_info *menu; | 810 | struct uvc_menu_info *menu; |
764 | unsigned int i; | 811 | unsigned int i; |
765 | __u8 *data; | ||
766 | int ret; | 812 | int ret; |
767 | 813 | ||
768 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); | 814 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); |
769 | if (ctrl == NULL) | 815 | if (ctrl == NULL) |
770 | return -EINVAL; | 816 | return -EINVAL; |
771 | 817 | ||
772 | data = kmalloc(ctrl->info->size, GFP_KERNEL); | ||
773 | if (data == NULL) | ||
774 | return -ENOMEM; | ||
775 | |||
776 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); | 818 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); |
777 | v4l2_ctrl->id = mapping->id; | 819 | v4l2_ctrl->id = mapping->id; |
778 | v4l2_ctrl->type = mapping->v4l2_type; | 820 | v4l2_ctrl->type = mapping->v4l2_type; |
@@ -782,14 +824,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
782 | if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) | 824 | if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) |
783 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | 825 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
784 | 826 | ||
785 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | 827 | if (!ctrl->cached) { |
786 | ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, | 828 | ret = uvc_ctrl_populate_cache(chain, ctrl); |
787 | chain->dev->intfnum, ctrl->info->selector, | ||
788 | data, ctrl->info->size); | ||
789 | if (ret < 0) | 829 | if (ret < 0) |
790 | goto out; | 830 | return ret; |
791 | v4l2_ctrl->default_value = | 831 | } |
792 | mapping->get(mapping, UVC_GET_DEF, data); | 832 | |
833 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | ||
834 | v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, | ||
835 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); | ||
793 | } | 836 | } |
794 | 837 | ||
795 | switch (mapping->v4l2_type) { | 838 | switch (mapping->v4l2_type) { |
@@ -806,56 +849,37 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
806 | } | 849 | } |
807 | } | 850 | } |
808 | 851 | ||
809 | ret = 0; | 852 | return 0; |
810 | goto out; | ||
811 | 853 | ||
812 | case V4L2_CTRL_TYPE_BOOLEAN: | 854 | case V4L2_CTRL_TYPE_BOOLEAN: |
813 | v4l2_ctrl->minimum = 0; | 855 | v4l2_ctrl->minimum = 0; |
814 | v4l2_ctrl->maximum = 1; | 856 | v4l2_ctrl->maximum = 1; |
815 | v4l2_ctrl->step = 1; | 857 | v4l2_ctrl->step = 1; |
816 | ret = 0; | 858 | return 0; |
817 | goto out; | ||
818 | 859 | ||
819 | case V4L2_CTRL_TYPE_BUTTON: | 860 | case V4L2_CTRL_TYPE_BUTTON: |
820 | v4l2_ctrl->minimum = 0; | 861 | v4l2_ctrl->minimum = 0; |
821 | v4l2_ctrl->maximum = 0; | 862 | v4l2_ctrl->maximum = 0; |
822 | v4l2_ctrl->step = 0; | 863 | v4l2_ctrl->step = 0; |
823 | ret = 0; | 864 | return 0; |
824 | goto out; | ||
825 | 865 | ||
826 | default: | 866 | default: |
827 | break; | 867 | break; |
828 | } | 868 | } |
829 | 869 | ||
830 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { | 870 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) |
831 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, | 871 | v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, |
832 | chain->dev->intfnum, ctrl->info->selector, | 872 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); |
833 | data, ctrl->info->size); | ||
834 | if (ret < 0) | ||
835 | goto out; | ||
836 | v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data); | ||
837 | } | ||
838 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { | ||
839 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, | ||
840 | chain->dev->intfnum, ctrl->info->selector, | ||
841 | data, ctrl->info->size); | ||
842 | if (ret < 0) | ||
843 | goto out; | ||
844 | v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data); | ||
845 | } | ||
846 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { | ||
847 | ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, | ||
848 | chain->dev->intfnum, ctrl->info->selector, | ||
849 | data, ctrl->info->size); | ||
850 | if (ret < 0) | ||
851 | goto out; | ||
852 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data); | ||
853 | } | ||
854 | 873 | ||
855 | ret = 0; | 874 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) |
856 | out: | 875 | v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, |
857 | kfree(data); | 876 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); |
858 | return ret; | 877 | |
878 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) | ||
879 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, | ||
880 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); | ||
881 | |||
882 | return 0; | ||
859 | } | 883 | } |
860 | 884 | ||
861 | 885 | ||
@@ -997,19 +1021,57 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
997 | { | 1021 | { |
998 | struct uvc_control *ctrl; | 1022 | struct uvc_control *ctrl; |
999 | struct uvc_control_mapping *mapping; | 1023 | struct uvc_control_mapping *mapping; |
1000 | s32 value = xctrl->value; | 1024 | s32 value; |
1025 | u32 step; | ||
1026 | s32 min; | ||
1027 | s32 max; | ||
1001 | int ret; | 1028 | int ret; |
1002 | 1029 | ||
1003 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1030 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); |
1004 | if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) | 1031 | if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) |
1005 | return -EINVAL; | 1032 | return -EINVAL; |
1006 | 1033 | ||
1007 | if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { | 1034 | /* Clamp out of range values. */ |
1008 | if (value < 0 || value >= mapping->menu_count) | 1035 | switch (mapping->v4l2_type) { |
1009 | return -EINVAL; | 1036 | case V4L2_CTRL_TYPE_INTEGER: |
1010 | value = mapping->menu_info[value].value; | 1037 | if (!ctrl->cached) { |
1038 | ret = uvc_ctrl_populate_cache(chain, ctrl); | ||
1039 | if (ret < 0) | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | min = mapping->get(mapping, UVC_GET_MIN, | ||
1044 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); | ||
1045 | max = mapping->get(mapping, UVC_GET_MAX, | ||
1046 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); | ||
1047 | step = mapping->get(mapping, UVC_GET_RES, | ||
1048 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); | ||
1049 | |||
1050 | xctrl->value = min + (xctrl->value - min + step/2) / step * step; | ||
1051 | xctrl->value = clamp(xctrl->value, min, max); | ||
1052 | value = xctrl->value; | ||
1053 | break; | ||
1054 | |||
1055 | case V4L2_CTRL_TYPE_BOOLEAN: | ||
1056 | xctrl->value = clamp(xctrl->value, 0, 1); | ||
1057 | value = xctrl->value; | ||
1058 | break; | ||
1059 | |||
1060 | case V4L2_CTRL_TYPE_MENU: | ||
1061 | if (xctrl->value < 0 || xctrl->value >= mapping->menu_count) | ||
1062 | return -ERANGE; | ||
1063 | value = mapping->menu_info[xctrl->value].value; | ||
1064 | break; | ||
1065 | |||
1066 | default: | ||
1067 | value = xctrl->value; | ||
1068 | break; | ||
1011 | } | 1069 | } |
1012 | 1070 | ||
1071 | /* If the mapping doesn't span the whole UVC control, the current value | ||
1072 | * needs to be loaded from the device to perform the read-modify-write | ||
1073 | * operation. | ||
1074 | */ | ||
1013 | if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { | 1075 | if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { |
1014 | if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { | 1076 | if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { |
1015 | memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1077 | memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
@@ -1027,6 +1089,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1027 | ctrl->loaded = 1; | 1089 | ctrl->loaded = 1; |
1028 | } | 1090 | } |
1029 | 1091 | ||
1092 | /* Backup the current value in case we need to rollback later. */ | ||
1030 | if (!ctrl->dirty) { | 1093 | if (!ctrl->dirty) { |
1031 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), | 1094 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), |
1032 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1095 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
@@ -1080,10 +1143,8 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | |||
1080 | } | 1143 | } |
1081 | 1144 | ||
1082 | if (!found) { | 1145 | if (!found) { |
1083 | uvc_trace(UVC_TRACE_CONTROL, | 1146 | uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n", |
1084 | "Control " UVC_GUID_FORMAT "/%u not found.\n", | 1147 | entity->extension.guidExtensionCode, xctrl->selector); |
1085 | UVC_GUID_ARGS(entity->extension.guidExtensionCode), | ||
1086 | xctrl->selector); | ||
1087 | return -EINVAL; | 1148 | return -EINVAL; |
1088 | } | 1149 | } |
1089 | 1150 | ||
@@ -1159,9 +1220,9 @@ int uvc_ctrl_resume_device(struct uvc_device *dev) | |||
1159 | (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) | 1220 | (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) |
1160 | continue; | 1221 | continue; |
1161 | 1222 | ||
1162 | printk(KERN_INFO "restoring control " UVC_GUID_FORMAT | 1223 | printk(KERN_INFO "restoring control %pUl/%u/%u\n", |
1163 | "/%u/%u\n", UVC_GUID_ARGS(ctrl->info->entity), | 1224 | ctrl->info->entity, ctrl->info->index, |
1164 | ctrl->info->index, ctrl->info->selector); | 1225 | ctrl->info->selector); |
1165 | ctrl->dirty = 1; | 1226 | ctrl->dirty = 1; |
1166 | } | 1227 | } |
1167 | 1228 | ||
@@ -1215,47 +1276,43 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev, | |||
1215 | ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, | 1276 | ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, |
1216 | dev->intfnum, info->selector, (__u8 *)&size, 2); | 1277 | dev->intfnum, info->selector, (__u8 *)&size, 2); |
1217 | if (ret < 0) { | 1278 | if (ret < 0) { |
1218 | uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on " | 1279 | uvc_trace(UVC_TRACE_CONTROL, |
1219 | "control " UVC_GUID_FORMAT "/%u (%d).\n", | 1280 | "GET_LEN failed on control %pUl/%u (%d).\n", |
1220 | UVC_GUID_ARGS(info->entity), info->selector, | 1281 | info->entity, info->selector, ret); |
1221 | ret); | ||
1222 | return; | 1282 | return; |
1223 | } | 1283 | } |
1224 | 1284 | ||
1225 | if (info->size != le16_to_cpu(size)) { | 1285 | if (info->size != le16_to_cpu(size)) { |
1226 | uvc_trace(UVC_TRACE_CONTROL, "Control " UVC_GUID_FORMAT | 1286 | uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u size " |
1227 | "/%u size doesn't match user supplied " | 1287 | "doesn't match user supplied value.\n", |
1228 | "value.\n", UVC_GUID_ARGS(info->entity), | 1288 | info->entity, info->selector); |
1229 | info->selector); | ||
1230 | return; | 1289 | return; |
1231 | } | 1290 | } |
1232 | 1291 | ||
1233 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, | 1292 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, |
1234 | dev->intfnum, info->selector, &inf, 1); | 1293 | dev->intfnum, info->selector, &inf, 1); |
1235 | if (ret < 0) { | 1294 | if (ret < 0) { |
1236 | uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on " | 1295 | uvc_trace(UVC_TRACE_CONTROL, |
1237 | "control " UVC_GUID_FORMAT "/%u (%d).\n", | 1296 | "GET_INFO failed on control %pUl/%u (%d).\n", |
1238 | UVC_GUID_ARGS(info->entity), info->selector, | 1297 | info->entity, info->selector, ret); |
1239 | ret); | ||
1240 | return; | 1298 | return; |
1241 | } | 1299 | } |
1242 | 1300 | ||
1243 | flags = info->flags; | 1301 | flags = info->flags; |
1244 | if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) || | 1302 | if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) || |
1245 | ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) { | 1303 | ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) { |
1246 | uvc_trace(UVC_TRACE_CONTROL, "Control " | 1304 | uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u flags " |
1247 | UVC_GUID_FORMAT "/%u flags don't match " | 1305 | "don't match supported operations.\n", |
1248 | "supported operations.\n", | 1306 | info->entity, info->selector); |
1249 | UVC_GUID_ARGS(info->entity), info->selector); | ||
1250 | return; | 1307 | return; |
1251 | } | 1308 | } |
1252 | } | 1309 | } |
1253 | 1310 | ||
1254 | ctrl->info = info; | 1311 | ctrl->info = info; |
1255 | ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_NDATA, GFP_KERNEL); | 1312 | ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_DATA_LAST, GFP_KERNEL); |
1256 | uvc_trace(UVC_TRACE_CONTROL, "Added control " UVC_GUID_FORMAT "/%u " | 1313 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " |
1257 | "to device %s entity %u\n", UVC_GUID_ARGS(ctrl->info->entity), | 1314 | "entity %u\n", ctrl->info->entity, ctrl->info->selector, |
1258 | ctrl->info->selector, dev->udev->devpath, entity->id); | 1315 | dev->udev->devpath, entity->id); |
1259 | } | 1316 | } |
1260 | 1317 | ||
1261 | /* | 1318 | /* |
@@ -1281,17 +1338,16 @@ int uvc_ctrl_add_info(struct uvc_control_info *info) | |||
1281 | continue; | 1338 | continue; |
1282 | 1339 | ||
1283 | if (ctrl->selector == info->selector) { | 1340 | if (ctrl->selector == info->selector) { |
1284 | uvc_trace(UVC_TRACE_CONTROL, "Control " | 1341 | uvc_trace(UVC_TRACE_CONTROL, |
1285 | UVC_GUID_FORMAT "/%u is already defined.\n", | 1342 | "Control %pUl/%u is already defined.\n", |
1286 | UVC_GUID_ARGS(info->entity), info->selector); | 1343 | info->entity, info->selector); |
1287 | ret = -EEXIST; | 1344 | ret = -EEXIST; |
1288 | goto end; | 1345 | goto end; |
1289 | } | 1346 | } |
1290 | if (ctrl->index == info->index) { | 1347 | if (ctrl->index == info->index) { |
1291 | uvc_trace(UVC_TRACE_CONTROL, "Control " | 1348 | uvc_trace(UVC_TRACE_CONTROL, |
1292 | UVC_GUID_FORMAT "/%u would overwrite index " | 1349 | "Control %pUl/%u would overwrite index %d.\n", |
1293 | "%d.\n", UVC_GUID_ARGS(info->entity), | 1350 | info->entity, info->selector, info->index); |
1294 | info->selector, info->index); | ||
1295 | ret = -EEXIST; | 1351 | ret = -EEXIST; |
1296 | goto end; | 1352 | goto end; |
1297 | } | 1353 | } |
@@ -1332,10 +1388,9 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping) | |||
1332 | continue; | 1388 | continue; |
1333 | 1389 | ||
1334 | if (info->size * 8 < mapping->size + mapping->offset) { | 1390 | if (info->size * 8 < mapping->size + mapping->offset) { |
1335 | uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' would " | 1391 | uvc_trace(UVC_TRACE_CONTROL, |
1336 | "overflow control " UVC_GUID_FORMAT "/%u\n", | 1392 | "Mapping '%s' would overflow control %pUl/%u\n", |
1337 | mapping->name, UVC_GUID_ARGS(info->entity), | 1393 | mapping->name, info->entity, info->selector); |
1338 | info->selector); | ||
1339 | ret = -EOVERFLOW; | 1394 | ret = -EOVERFLOW; |
1340 | goto end; | 1395 | goto end; |
1341 | } | 1396 | } |
@@ -1354,9 +1409,9 @@ int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping) | |||
1354 | 1409 | ||
1355 | mapping->ctrl = info; | 1410 | mapping->ctrl = info; |
1356 | list_add_tail(&mapping->list, &info->mappings); | 1411 | list_add_tail(&mapping->list, &info->mappings); |
1357 | uvc_trace(UVC_TRACE_CONTROL, "Adding mapping %s to control " | 1412 | uvc_trace(UVC_TRACE_CONTROL, |
1358 | UVC_GUID_FORMAT "/%u.\n", mapping->name, | 1413 | "Adding mapping %s to control %pUl/%u.\n", |
1359 | UVC_GUID_ARGS(info->entity), info->selector); | 1414 | mapping->name, info->entity, info->selector); |
1360 | 1415 | ||
1361 | ret = 0; | 1416 | ret = 0; |
1362 | break; | 1417 | break; |
@@ -1378,6 +1433,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity) | |||
1378 | struct usb_device_id id; | 1433 | struct usb_device_id id; |
1379 | u8 index; | 1434 | u8 index; |
1380 | } blacklist[] = { | 1435 | } blacklist[] = { |
1436 | { { USB_DEVICE(0x13d3, 0x509b) }, 9 }, /* Gain */ | ||
1381 | { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ | 1437 | { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ |
1382 | { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ | 1438 | { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ |
1383 | }; | 1439 | }; |