21
21
#include <linux/vmalloc.h>
22
22
#include <linux/wait.h>
23
23
#include <linux/atomic.h>
24
+ #include <media/v4l2-ctrls.h>
24
25
25
26
#include "uvcvideo.h"
26
27
@@ -1102,6 +1103,117 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
1102
1103
return ret ;
1103
1104
}
1104
1105
1106
+ /* --------------------------------------------------------------------------
1107
+ * Ctrl event handling
1108
+ */
1109
+
1110
+ static void uvc_ctrl_fill_event (struct uvc_video_chain * chain ,
1111
+ struct v4l2_event * ev ,
1112
+ struct uvc_control * ctrl ,
1113
+ struct uvc_control_mapping * mapping ,
1114
+ s32 value , u32 changes )
1115
+ {
1116
+ struct v4l2_queryctrl v4l2_ctrl ;
1117
+
1118
+ __uvc_query_v4l2_ctrl (chain , ctrl , mapping , & v4l2_ctrl );
1119
+
1120
+ memset (ev -> reserved , 0 , sizeof (ev -> reserved ));
1121
+ ev -> type = V4L2_EVENT_CTRL ;
1122
+ ev -> id = v4l2_ctrl .id ;
1123
+ ev -> u .ctrl .value = value ;
1124
+ ev -> u .ctrl .changes = changes ;
1125
+ ev -> u .ctrl .type = v4l2_ctrl .type ;
1126
+ ev -> u .ctrl .flags = v4l2_ctrl .flags ;
1127
+ ev -> u .ctrl .minimum = v4l2_ctrl .minimum ;
1128
+ ev -> u .ctrl .maximum = v4l2_ctrl .maximum ;
1129
+ ev -> u .ctrl .step = v4l2_ctrl .step ;
1130
+ ev -> u .ctrl .default_value = v4l2_ctrl .default_value ;
1131
+ }
1132
+
1133
+ static void uvc_ctrl_send_event (struct uvc_fh * handle ,
1134
+ struct uvc_control * ctrl , struct uvc_control_mapping * mapping ,
1135
+ s32 value , u32 changes )
1136
+ {
1137
+ struct v4l2_subscribed_event * sev ;
1138
+ struct v4l2_event ev ;
1139
+
1140
+ if (list_empty (& mapping -> ev_subs ))
1141
+ return ;
1142
+
1143
+ uvc_ctrl_fill_event (handle -> chain , & ev , ctrl , mapping , value , changes );
1144
+
1145
+ list_for_each_entry (sev , & mapping -> ev_subs , node ) {
1146
+ if (sev -> fh && (sev -> fh != & handle -> vfh ||
1147
+ (sev -> flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK )))
1148
+ v4l2_event_queue_fh (sev -> fh , & ev );
1149
+ }
1150
+ }
1151
+
1152
+ static void uvc_ctrl_send_events (struct uvc_fh * handle ,
1153
+ const struct v4l2_ext_control * xctrls , unsigned int xctrls_count )
1154
+ {
1155
+ struct uvc_control_mapping * mapping ;
1156
+ struct uvc_control * ctrl ;
1157
+ unsigned int i ;
1158
+
1159
+ for (i = 0 ; i < xctrls_count ; ++ i ) {
1160
+ ctrl = uvc_find_control (handle -> chain , xctrls [i ].id , & mapping );
1161
+ uvc_ctrl_send_event (handle , ctrl , mapping , xctrls [i ].value ,
1162
+ V4L2_EVENT_CTRL_CH_VALUE );
1163
+ }
1164
+ }
1165
+
1166
+ static int uvc_ctrl_add_event (struct v4l2_subscribed_event * sev )
1167
+ {
1168
+ struct uvc_fh * handle = container_of (sev -> fh , struct uvc_fh , vfh );
1169
+ struct uvc_control_mapping * mapping ;
1170
+ struct uvc_control * ctrl ;
1171
+ int ret ;
1172
+
1173
+ ret = mutex_lock_interruptible (& handle -> chain -> ctrl_mutex );
1174
+ if (ret < 0 )
1175
+ return - ERESTARTSYS ;
1176
+
1177
+ ctrl = uvc_find_control (handle -> chain , sev -> id , & mapping );
1178
+ if (ctrl == NULL ) {
1179
+ ret = - EINVAL ;
1180
+ goto done ;
1181
+ }
1182
+
1183
+ list_add_tail (& sev -> node , & mapping -> ev_subs );
1184
+ if (sev -> flags & V4L2_EVENT_SUB_FL_SEND_INITIAL ) {
1185
+ struct v4l2_event ev ;
1186
+ u32 changes = V4L2_EVENT_CTRL_CH_FLAGS ;
1187
+ s32 val = 0 ;
1188
+
1189
+ if (__uvc_ctrl_get (handle -> chain , ctrl , mapping , & val ) == 0 )
1190
+ changes |= V4L2_EVENT_CTRL_CH_VALUE ;
1191
+
1192
+ uvc_ctrl_fill_event (handle -> chain , & ev , ctrl , mapping , val ,
1193
+ changes );
1194
+ v4l2_event_queue_fh (sev -> fh , & ev );
1195
+ }
1196
+
1197
+ done :
1198
+ mutex_unlock (& handle -> chain -> ctrl_mutex );
1199
+ return ret ;
1200
+ }
1201
+
1202
+ static void uvc_ctrl_del_event (struct v4l2_subscribed_event * sev )
1203
+ {
1204
+ struct uvc_fh * handle = container_of (sev -> fh , struct uvc_fh , vfh );
1205
+
1206
+ mutex_lock (& handle -> chain -> ctrl_mutex );
1207
+ list_del (& sev -> node );
1208
+ mutex_unlock (& handle -> chain -> ctrl_mutex );
1209
+ }
1210
+
1211
+ const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops = {
1212
+ .add = uvc_ctrl_add_event ,
1213
+ .del = uvc_ctrl_del_event ,
1214
+ .replace = v4l2_ctrl_replace ,
1215
+ .merge = v4l2_ctrl_merge ,
1216
+ };
1105
1217
1106
1218
/* --------------------------------------------------------------------------
1107
1219
* Control transactions
@@ -1179,8 +1291,11 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1179
1291
return 0 ;
1180
1292
}
1181
1293
1182
- int __uvc_ctrl_commit (struct uvc_video_chain * chain , int rollback )
1294
+ int __uvc_ctrl_commit (struct uvc_fh * handle , int rollback ,
1295
+ const struct v4l2_ext_control * xctrls ,
1296
+ unsigned int xctrls_count )
1183
1297
{
1298
+ struct uvc_video_chain * chain = handle -> chain ;
1184
1299
struct uvc_entity * entity ;
1185
1300
int ret = 0 ;
1186
1301
@@ -1191,6 +1306,8 @@ int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
1191
1306
goto done ;
1192
1307
}
1193
1308
1309
+ if (!rollback )
1310
+ uvc_ctrl_send_events (handle , xctrls , xctrls_count );
1194
1311
done :
1195
1312
mutex_unlock (& chain -> ctrl_mutex );
1196
1313
return ret ;
@@ -1662,6 +1779,8 @@ static int __uvc_ctrl_add_mapping(struct uvc_device *dev,
1662
1779
if (map == NULL )
1663
1780
return - ENOMEM ;
1664
1781
1782
+ INIT_LIST_HEAD (& map -> ev_subs );
1783
+
1665
1784
size = sizeof (* mapping -> menu_info ) * mapping -> menu_count ;
1666
1785
map -> menu_info = kmemdup (mapping -> menu_info , size , GFP_KERNEL );
1667
1786
if (map -> menu_info == NULL ) {
0 commit comments