Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: uvcvideo: Factor out clamping from uvc_ctrl_set

Move the logic to a separated function. Do not expect any change.
This is a preparation for supporting compound controls.

Reviewed-by: Yunke Cao <yunkec@google.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Yunke Cao <yunkec@google.com>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Link: https://lore.kernel.org/r/20250203-uvc-roi-v17-9-5900a9fed613@chromium.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>

authored by

Ricardo Ribalda and committed by
Hans Verkuil
813b0156 4e15c535

+46 -40
+46 -40
drivers/media/usb/uvc/uvc_ctrl.c
··· 2053 2053 return -EINVAL; 2054 2054 } 2055 2055 2056 - int uvc_ctrl_set(struct uvc_fh *handle, 2057 - struct v4l2_ext_control *xctrl) 2056 + static int uvc_ctrl_clamp(struct uvc_video_chain *chain, 2057 + struct uvc_control *ctrl, 2058 + struct uvc_control_mapping *mapping, 2059 + s32 *value_in_out) 2058 2060 { 2059 - struct uvc_video_chain *chain = handle->chain; 2060 - struct uvc_control *ctrl; 2061 - struct uvc_control_mapping *mapping; 2062 - s32 value; 2061 + s32 value = *value_in_out; 2063 2062 u32 step; 2064 2063 s32 min; 2065 2064 s32 max; 2066 2065 int ret; 2067 2066 2068 - lockdep_assert_held(&chain->ctrl_mutex); 2069 - 2070 - if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) 2071 - return -EACCES; 2072 - 2073 - ctrl = uvc_find_control(chain, xctrl->id, &mapping); 2074 - if (ctrl == NULL) 2075 - return -EINVAL; 2076 - if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) 2077 - return -EACCES; 2078 - 2079 - /* Clamp out of range values. */ 2080 2067 switch (mapping->v4l2_type) { 2081 2068 case V4L2_CTRL_TYPE_INTEGER: 2082 2069 if (!ctrl->cached) { ··· 2081 2094 if (step == 0) 2082 2095 step = 1; 2083 2096 2084 - xctrl->value = min + DIV_ROUND_CLOSEST((u32)(xctrl->value - min), 2085 - step) * step; 2097 + value = min + DIV_ROUND_CLOSEST((u32)(value - min), step) * step; 2086 2098 if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) 2087 - xctrl->value = clamp(xctrl->value, min, max); 2099 + value = clamp(value, min, max); 2088 2100 else 2089 - xctrl->value = clamp_t(u32, xctrl->value, min, max); 2090 - value = xctrl->value; 2091 - break; 2101 + value = clamp_t(u32, value, min, max); 2102 + *value_in_out = value; 2103 + return 0; 2092 2104 2093 2105 case V4L2_CTRL_TYPE_BITMASK: 2094 2106 if (!ctrl->cached) { ··· 2096 2110 return ret; 2097 2111 } 2098 2112 2099 - xctrl->value &= uvc_get_ctrl_bitmap(ctrl, mapping); 2100 - value = xctrl->value; 2101 - break; 2113 + value &= uvc_get_ctrl_bitmap(ctrl, mapping); 2114 + *value_in_out = value; 2115 + return 0; 2102 2116 2103 2117 case V4L2_CTRL_TYPE_BOOLEAN: 2104 - xctrl->value = clamp(xctrl->value, 0, 1); 2105 - value = xctrl->value; 2106 - break; 2118 + *value_in_out = clamp(value, 0, 1); 2119 + return 0; 2107 2120 2108 2121 case V4L2_CTRL_TYPE_MENU: 2109 - if (xctrl->value < (ffs(mapping->menu_mask) - 1) || 2110 - xctrl->value > (fls(mapping->menu_mask) - 1)) 2122 + if (value < (ffs(mapping->menu_mask) - 1) || 2123 + value > (fls(mapping->menu_mask) - 1)) 2111 2124 return -ERANGE; 2112 2125 2113 - if (!test_bit(xctrl->value, &mapping->menu_mask)) 2126 + if (!test_bit(value, &mapping->menu_mask)) 2114 2127 return -EINVAL; 2115 2128 2116 2129 /* ··· 2117 2132 * UVC controls that support it. 2118 2133 */ 2119 2134 if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) { 2120 - int val = uvc_mapping_get_menu_value(mapping, 2121 - xctrl->value); 2135 + int val = uvc_mapping_get_menu_value(mapping, value); 2122 2136 if (!ctrl->cached) { 2123 2137 ret = uvc_ctrl_populate_cache(chain, ctrl); 2124 2138 if (ret < 0) ··· 2127 2143 if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & val)) 2128 2144 return -EINVAL; 2129 2145 } 2130 - value = xctrl->value; 2131 - break; 2146 + return 0; 2132 2147 2133 2148 default: 2134 - value = xctrl->value; 2135 - break; 2149 + return 0; 2136 2150 } 2137 2151 2152 + return 0; 2153 + } 2154 + 2155 + int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl) 2156 + { 2157 + struct uvc_video_chain *chain = handle->chain; 2158 + struct uvc_control_mapping *mapping; 2159 + struct uvc_control *ctrl; 2160 + int ret; 2161 + 2162 + lockdep_assert_held(&chain->ctrl_mutex); 2163 + 2164 + if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) 2165 + return -EACCES; 2166 + 2167 + ctrl = uvc_find_control(chain, xctrl->id, &mapping); 2168 + if (!ctrl) 2169 + return -EINVAL; 2170 + if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) 2171 + return -EACCES; 2172 + 2173 + ret = uvc_ctrl_clamp(chain, ctrl, mapping, &xctrl->value); 2174 + if (ret) 2175 + return ret; 2138 2176 /* 2139 2177 * If the mapping doesn't span the whole UVC control, the current value 2140 2178 * needs to be loaded from the device to perform the read-modify-write ··· 2175 2169 ctrl->info.size); 2176 2170 } 2177 2171 2178 - uvc_mapping_set_s32(mapping, value, 2172 + uvc_mapping_set_s32(mapping, xctrl->value, 2179 2173 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); 2180 2174 2181 2175 ctrl->dirty = 1;