@@ -1277,6 +1277,37 @@ static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,
12771277 return 0 ;
12781278}
12791279
1280+ static bool uvc_ctrl_is_readable (u32 which , struct uvc_control * ctrl ,
1281+ struct uvc_control_mapping * mapping )
1282+ {
1283+ if (which == V4L2_CTRL_WHICH_CUR_VAL )
1284+ return !!(ctrl -> info .flags & UVC_CTRL_FLAG_GET_CUR );
1285+
1286+ if (which == V4L2_CTRL_WHICH_DEF_VAL )
1287+ return !!(ctrl -> info .flags & UVC_CTRL_FLAG_GET_DEF );
1288+
1289+ /* Types with implicit boundaries. */
1290+ switch (mapping -> v4l2_type ) {
1291+ case V4L2_CTRL_TYPE_MENU :
1292+ case V4L2_CTRL_TYPE_BOOLEAN :
1293+ case V4L2_CTRL_TYPE_BUTTON :
1294+ return true;
1295+ case V4L2_CTRL_TYPE_BITMASK :
1296+ return (ctrl -> info .flags & UVC_CTRL_FLAG_GET_RES ) ||
1297+ (ctrl -> info .flags & UVC_CTRL_FLAG_GET_MAX );
1298+ default :
1299+ break ;
1300+ }
1301+
1302+ if (which == V4L2_CTRL_WHICH_MIN_VAL )
1303+ return !!(ctrl -> info .flags & UVC_CTRL_FLAG_GET_MIN );
1304+
1305+ if (which == V4L2_CTRL_WHICH_MAX_VAL )
1306+ return !!(ctrl -> info .flags & UVC_CTRL_FLAG_GET_MAX );
1307+
1308+ return false;
1309+ }
1310+
12801311/*
12811312 * Check if control @v4l2_id can be accessed by the given control @ioctl
12821313 * (VIDIOC_G_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS or VIDIOC_S_EXT_CTRLS).
@@ -1295,7 +1326,6 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
12951326 struct uvc_control * master_ctrl = NULL ;
12961327 struct uvc_control_mapping * mapping ;
12971328 struct uvc_control * ctrl ;
1298- bool read = ioctl == VIDIOC_G_EXT_CTRLS ;
12991329 s32 val ;
13001330 int ret ;
13011331 int i ;
@@ -1307,10 +1337,10 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
13071337 if (!ctrl )
13081338 return - EINVAL ;
13091339
1310- if (!( ctrl -> info . flags & UVC_CTRL_FLAG_GET_CUR ) && read )
1311- return - EACCES ;
1340+ if (ioctl == VIDIOC_G_EXT_CTRLS )
1341+ return uvc_ctrl_is_readable ( ctrls -> which , ctrl , mapping ) ;
13121342
1313- if (!(ctrl -> info .flags & UVC_CTRL_FLAG_SET_CUR ) && ! read )
1343+ if (!(ctrl -> info .flags & UVC_CTRL_FLAG_SET_CUR ))
13141344 return - EACCES ;
13151345
13161346 if (ioctl != VIDIOC_S_EXT_CTRLS || !mapping -> master_id )
@@ -1459,6 +1489,9 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
14591489 v4l2_ctrl -> flags |= V4L2_CTRL_FLAG_WRITE_ONLY ;
14601490 if (!(ctrl -> info .flags & UVC_CTRL_FLAG_SET_CUR ))
14611491 v4l2_ctrl -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
1492+ if ((ctrl -> info .flags & UVC_CTRL_FLAG_GET_MAX ) &&
1493+ (ctrl -> info .flags & UVC_CTRL_FLAG_GET_MIN ))
1494+ v4l2_ctrl -> flags |= V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX ;
14621495
14631496 if (mapping -> master_id )
14641497 __uvc_find_control (ctrl -> entity , mapping -> master_id ,
@@ -2088,16 +2121,18 @@ static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain,
20882121
20892122 switch (which ) {
20902123 case V4L2_CTRL_WHICH_CUR_VAL :
2091- ret = __uvc_ctrl_load_cur (chain , ctrl );
2092- if (ret < 0 )
2093- return ret ;
20942124 id = UVC_CTRL_DATA_CURRENT ;
20952125 query = UVC_GET_CUR ;
20962126 break ;
2127+ case V4L2_CTRL_WHICH_MIN_VAL :
2128+ id = UVC_CTRL_DATA_MIN ;
2129+ query = UVC_GET_MIN ;
2130+ break ;
2131+ case V4L2_CTRL_WHICH_MAX_VAL :
2132+ id = UVC_CTRL_DATA_MAX ;
2133+ query = UVC_GET_MAX ;
2134+ break ;
20972135 case V4L2_CTRL_WHICH_DEF_VAL :
2098- ret = uvc_ctrl_populate_cache (chain , ctrl );
2099- if (ret < 0 )
2100- return ret ;
21012136 id = UVC_CTRL_DATA_DEF ;
21022137 query = UVC_GET_DEF ;
21032138 break ;
@@ -2115,6 +2150,14 @@ static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain,
21152150 if (!data )
21162151 return - ENOMEM ;
21172152
2153+ if (which == V4L2_CTRL_WHICH_CUR_VAL )
2154+ ret = __uvc_ctrl_load_cur (chain , ctrl );
2155+ else
2156+ ret = uvc_ctrl_populate_cache (chain , ctrl );
2157+
2158+ if (ret < 0 )
2159+ return ret ;
2160+
21182161 ret = mapping -> get (mapping , query , uvc_ctrl_data (ctrl , id ), size , data );
21192162 if (ret < 0 )
21202163 return ret ;
@@ -2132,22 +2175,37 @@ static int uvc_mapping_get_xctrl_std(struct uvc_video_chain *chain,
21322175 struct uvc_control_mapping * mapping ,
21332176 u32 which , struct v4l2_ext_control * xctrl )
21342177{
2178+ struct v4l2_queryctrl qc ;
2179+ int ret ;
2180+
21352181 switch (which ) {
21362182 case V4L2_CTRL_WHICH_CUR_VAL :
21372183 return __uvc_ctrl_get (chain , ctrl , mapping , & xctrl -> value );
21382184 case V4L2_CTRL_WHICH_DEF_VAL :
2139- if (!ctrl -> cached ) {
2140- int ret = uvc_ctrl_populate_cache (chain , ctrl );
2185+ case V4L2_CTRL_WHICH_MIN_VAL :
2186+ case V4L2_CTRL_WHICH_MAX_VAL :
2187+ break ;
2188+ default :
2189+ return - EINVAL ;
2190+ }
21412191
2142- if (ret < 0 )
2143- return ret ;
2144- }
2145- xctrl -> value = uvc_mapping_get_s32 (mapping , UVC_GET_DEF ,
2146- uvc_ctrl_data (ctrl , UVC_CTRL_DATA_DEF ));
2147- return 0 ;
2192+ ret = __uvc_queryctrl_boundaries (chain , ctrl , mapping , & qc );
2193+ if (ret < 0 )
2194+ return ret ;
2195+
2196+ switch (which ) {
2197+ case V4L2_CTRL_WHICH_DEF_VAL :
2198+ xctrl -> value = qc .default_value ;
2199+ break ;
2200+ case V4L2_CTRL_WHICH_MIN_VAL :
2201+ xctrl -> value = qc .minimum ;
2202+ break ;
2203+ case V4L2_CTRL_WHICH_MAX_VAL :
2204+ xctrl -> value = qc .maximum ;
2205+ break ;
21482206 }
21492207
2150- return - EINVAL ;
2208+ return 0 ;
21512209}
21522210
21532211static int uvc_mapping_get_xctrl (struct uvc_video_chain * chain ,
0 commit comments