diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-04-08 11:59:49 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-07 15:31:25 -0400 |
commit | 35f16741263fb50c82d5ade53ef9880a6b05f08a (patch) | |
tree | fdfd870b2d688fd2160f1656f98c1b1dd492dd08 /drivers/media/video/uvc/uvc_ctrl.c | |
parent | 57fb4a4831793de9e8dbdfc8dc5eb8796026d47e (diff) |
[media] uvcvideo: Refactor uvc_ctrl_get and query
This is a preparation patch for adding ctrl event support.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc/uvc_ctrl.c')
-rw-r--r-- | drivers/media/video/uvc/uvc_ctrl.c | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 0efd3b10b353..d20d0de707d1 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -899,24 +899,13 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, | |||
899 | return 0; | 899 | return 0; |
900 | } | 900 | } |
901 | 901 | ||
902 | int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 902 | static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
903 | struct uvc_control *ctrl, | ||
904 | struct uvc_control_mapping *mapping, | ||
903 | struct v4l2_queryctrl *v4l2_ctrl) | 905 | struct v4l2_queryctrl *v4l2_ctrl) |
904 | { | 906 | { |
905 | struct uvc_control *ctrl; | ||
906 | struct uvc_control_mapping *mapping; | ||
907 | struct uvc_menu_info *menu; | 907 | struct uvc_menu_info *menu; |
908 | unsigned int i; | 908 | unsigned int i; |
909 | int ret; | ||
910 | |||
911 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | ||
912 | if (ret < 0) | ||
913 | return -ERESTARTSYS; | ||
914 | |||
915 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); | ||
916 | if (ctrl == NULL) { | ||
917 | ret = -EINVAL; | ||
918 | goto done; | ||
919 | } | ||
920 | 909 | ||
921 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); | 910 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); |
922 | v4l2_ctrl->id = mapping->id; | 911 | v4l2_ctrl->id = mapping->id; |
@@ -930,9 +919,9 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
930 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | 919 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
931 | 920 | ||
932 | if (!ctrl->cached) { | 921 | if (!ctrl->cached) { |
933 | ret = uvc_ctrl_populate_cache(chain, ctrl); | 922 | int ret = uvc_ctrl_populate_cache(chain, ctrl); |
934 | if (ret < 0) | 923 | if (ret < 0) |
935 | goto done; | 924 | return ret; |
936 | } | 925 | } |
937 | 926 | ||
938 | if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) { | 927 | if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) { |
@@ -954,19 +943,19 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
954 | } | 943 | } |
955 | } | 944 | } |
956 | 945 | ||
957 | goto done; | 946 | return 0; |
958 | 947 | ||
959 | case V4L2_CTRL_TYPE_BOOLEAN: | 948 | case V4L2_CTRL_TYPE_BOOLEAN: |
960 | v4l2_ctrl->minimum = 0; | 949 | v4l2_ctrl->minimum = 0; |
961 | v4l2_ctrl->maximum = 1; | 950 | v4l2_ctrl->maximum = 1; |
962 | v4l2_ctrl->step = 1; | 951 | v4l2_ctrl->step = 1; |
963 | goto done; | 952 | return 0; |
964 | 953 | ||
965 | case V4L2_CTRL_TYPE_BUTTON: | 954 | case V4L2_CTRL_TYPE_BUTTON: |
966 | v4l2_ctrl->minimum = 0; | 955 | v4l2_ctrl->minimum = 0; |
967 | v4l2_ctrl->maximum = 0; | 956 | v4l2_ctrl->maximum = 0; |
968 | v4l2_ctrl->step = 0; | 957 | v4l2_ctrl->step = 0; |
969 | goto done; | 958 | return 0; |
970 | 959 | ||
971 | default: | 960 | default: |
972 | break; | 961 | break; |
@@ -984,6 +973,27 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
984 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, | 973 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, |
985 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); | 974 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); |
986 | 975 | ||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | ||
980 | struct v4l2_queryctrl *v4l2_ctrl) | ||
981 | { | ||
982 | struct uvc_control *ctrl; | ||
983 | struct uvc_control_mapping *mapping; | ||
984 | int ret; | ||
985 | |||
986 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | ||
987 | if (ret < 0) | ||
988 | return -ERESTARTSYS; | ||
989 | |||
990 | ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); | ||
991 | if (ctrl == NULL) { | ||
992 | ret = -EINVAL; | ||
993 | goto done; | ||
994 | } | ||
995 | |||
996 | ret = __uvc_query_v4l2_ctrl(chain, ctrl, mapping, v4l2_ctrl); | ||
987 | done: | 997 | done: |
988 | mutex_unlock(&chain->ctrl_mutex); | 998 | mutex_unlock(&chain->ctrl_mutex); |
989 | return ret; | 999 | return ret; |
@@ -1148,17 +1158,15 @@ done: | |||
1148 | return ret; | 1158 | return ret; |
1149 | } | 1159 | } |
1150 | 1160 | ||
1151 | int uvc_ctrl_get(struct uvc_video_chain *chain, | 1161 | static int __uvc_ctrl_get(struct uvc_video_chain *chain, |
1152 | struct v4l2_ext_control *xctrl) | 1162 | struct uvc_control *ctrl, struct uvc_control_mapping *mapping, |
1163 | s32 *value) | ||
1153 | { | 1164 | { |
1154 | struct uvc_control *ctrl; | ||
1155 | struct uvc_control_mapping *mapping; | ||
1156 | struct uvc_menu_info *menu; | 1165 | struct uvc_menu_info *menu; |
1157 | unsigned int i; | 1166 | unsigned int i; |
1158 | int ret; | 1167 | int ret; |
1159 | 1168 | ||
1160 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1169 | if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) |
1161 | if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) | ||
1162 | return -EINVAL; | 1170 | return -EINVAL; |
1163 | 1171 | ||
1164 | if (!ctrl->loaded) { | 1172 | if (!ctrl->loaded) { |
@@ -1172,14 +1180,14 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, | |||
1172 | ctrl->loaded = 1; | 1180 | ctrl->loaded = 1; |
1173 | } | 1181 | } |
1174 | 1182 | ||
1175 | xctrl->value = mapping->get(mapping, UVC_GET_CUR, | 1183 | *value = mapping->get(mapping, UVC_GET_CUR, |
1176 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); | 1184 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); |
1177 | 1185 | ||
1178 | if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { | 1186 | if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { |
1179 | menu = mapping->menu_info; | 1187 | menu = mapping->menu_info; |
1180 | for (i = 0; i < mapping->menu_count; ++i, ++menu) { | 1188 | for (i = 0; i < mapping->menu_count; ++i, ++menu) { |
1181 | if (menu->value == xctrl->value) { | 1189 | if (menu->value == *value) { |
1182 | xctrl->value = i; | 1190 | *value = i; |
1183 | break; | 1191 | break; |
1184 | } | 1192 | } |
1185 | } | 1193 | } |
@@ -1188,6 +1196,19 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, | |||
1188 | return 0; | 1196 | return 0; |
1189 | } | 1197 | } |
1190 | 1198 | ||
1199 | int uvc_ctrl_get(struct uvc_video_chain *chain, | ||
1200 | struct v4l2_ext_control *xctrl) | ||
1201 | { | ||
1202 | struct uvc_control *ctrl; | ||
1203 | struct uvc_control_mapping *mapping; | ||
1204 | |||
1205 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | ||
1206 | if (ctrl == NULL) | ||
1207 | return -EINVAL; | ||
1208 | |||
1209 | return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); | ||
1210 | } | ||
1211 | |||
1191 | int uvc_ctrl_set(struct uvc_video_chain *chain, | 1212 | int uvc_ctrl_set(struct uvc_video_chain *chain, |
1192 | struct v4l2_ext_control *xctrl) | 1213 | struct v4l2_ext_control *xctrl) |
1193 | { | 1214 | { |