return "Unknown Control";
 }
 
+static u32 uvc_get_ctrl_bitmap(struct uvc_control *ctrl,
+                              struct uvc_control_mapping *mapping)
+{
+       /*
+        * Some controls, like CT_AE_MODE_CONTROL, use GET_RES to represent
+        * the number of bits supported. Those controls do not list GET_MAX
+        * as supported.
+        */
+       if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
+               return mapping->get(mapping, UVC_GET_RES,
+                                   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+
+       if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
+               return mapping->get(mapping, UVC_GET_MAX,
+                                   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+
+       return ~0;
+}
+
 static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
        struct uvc_control *ctrl,
        struct uvc_control_mapping *mapping,
                v4l2_ctrl->step = 0;
                return 0;
 
+       case V4L2_CTRL_TYPE_BITMASK:
+               v4l2_ctrl->minimum = 0;
+               v4l2_ctrl->maximum = uvc_get_ctrl_bitmap(ctrl, mapping);
+               v4l2_ctrl->step = 0;
+               return 0;
+
        default:
                break;
        }
 
        menu_info = &mapping->menu_info[query_menu->index];
 
-       if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
-           (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
-               s32 bitmap;
-
+       if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) {
                if (!ctrl->cached) {
                        ret = uvc_ctrl_populate_cache(chain, ctrl);
                        if (ret < 0)
                                goto done;
                }
 
-               bitmap = mapping->get(mapping, UVC_GET_RES,
-                                     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
-               if (!(bitmap & menu_info->value)) {
+               if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & menu_info->value)) {
                        ret = -EINVAL;
                        goto done;
                }
                value = xctrl->value;
                break;
 
+       case V4L2_CTRL_TYPE_BITMASK:
+               if (!ctrl->cached) {
+                       ret = uvc_ctrl_populate_cache(chain, ctrl);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               xctrl->value &= uvc_get_ctrl_bitmap(ctrl, mapping);
+               value = xctrl->value;
+               break;
+
        case V4L2_CTRL_TYPE_BOOLEAN:
                xctrl->value = clamp(xctrl->value, 0, 1);
                value = xctrl->value;
                 * Valid menu indices are reported by the GET_RES request for
                 * UVC controls that support it.
                 */
-               if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK &&
-                   (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) {
+               if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) {
                        if (!ctrl->cached) {
                                ret = uvc_ctrl_populate_cache(chain, ctrl);
                                if (ret < 0)
                                        return ret;
                        }
 
-                       step = mapping->get(mapping, UVC_GET_RES,
-                                       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
-                       if (!(step & value))
+                       if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & value))
                                return -EINVAL;
                }