aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-04-08 11:59:53 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-07 15:41:35 -0400
commit805e9b4a06bf874c56e0811e9cca5e25cf465e42 (patch)
tree4a45d1fbbe4aa3c66774a9fc441aa3536d395a14 /drivers/media/video/uvc
parent55afeb8a4d3ffdf8de546d5de37aca5b229ca9a4 (diff)
[media] uvcvideo: Send control change events for slave ctrls when the master changes
This allows v4l2 control UI-s to update the inactive state (ie grey-ing out of controls) for slave controls when the master control changes. [Use __uvc_find_control() to find slave controls, as they're always located in the same entity as the corresponding master control] 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')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index ae7371f3a39..03212c70333 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1177,22 +1177,76 @@ static void uvc_ctrl_send_event(struct uvc_fh *handle,
1177 1177
1178 list_for_each_entry(sev, &mapping->ev_subs, node) { 1178 list_for_each_entry(sev, &mapping->ev_subs, node) {
1179 if (sev->fh && (sev->fh != &handle->vfh || 1179 if (sev->fh && (sev->fh != &handle->vfh ||
1180 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))) 1180 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK) ||
1181 (changes & V4L2_EVENT_CTRL_CH_FLAGS)))
1181 v4l2_event_queue_fh(sev->fh, &ev); 1182 v4l2_event_queue_fh(sev->fh, &ev);
1182 } 1183 }
1183} 1184}
1184 1185
1186static void uvc_ctrl_send_slave_event(struct uvc_fh *handle,
1187 struct uvc_control *master, u32 slave_id,
1188 const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
1189{
1190 struct uvc_control_mapping *mapping = NULL;
1191 struct uvc_control *ctrl = NULL;
1192 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
1193 unsigned int i;
1194 s32 val = 0;
1195
1196 /*
1197 * We can skip sending an event for the slave if the slave
1198 * is being modified in the same transaction.
1199 */
1200 for (i = 0; i < xctrls_count; i++) {
1201 if (xctrls[i].id == slave_id)
1202 return;
1203 }
1204
1205 __uvc_find_control(master->entity, slave_id, &mapping, &ctrl, 0);
1206 if (ctrl == NULL)
1207 return;
1208
1209 if (__uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
1210 changes |= V4L2_EVENT_CTRL_CH_VALUE;
1211
1212 uvc_ctrl_send_event(handle, ctrl, mapping, val, changes);
1213}
1214
1185static void uvc_ctrl_send_events(struct uvc_fh *handle, 1215static void uvc_ctrl_send_events(struct uvc_fh *handle,
1186 const struct v4l2_ext_control *xctrls, unsigned int xctrls_count) 1216 const struct v4l2_ext_control *xctrls, unsigned int xctrls_count)
1187{ 1217{
1188 struct uvc_control_mapping *mapping; 1218 struct uvc_control_mapping *mapping;
1189 struct uvc_control *ctrl; 1219 struct uvc_control *ctrl;
1220 u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
1190 unsigned int i; 1221 unsigned int i;
1222 unsigned int j;
1191 1223
1192 for (i = 0; i < xctrls_count; ++i) { 1224 for (i = 0; i < xctrls_count; ++i) {
1193 ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); 1225 ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
1226
1227 for (j = 0; j < ARRAY_SIZE(mapping->slave_ids); ++j) {
1228 if (!mapping->slave_ids[j])
1229 break;
1230 uvc_ctrl_send_slave_event(handle, ctrl,
1231 mapping->slave_ids[j],
1232 xctrls, xctrls_count);
1233 }
1234
1235 /*
1236 * If the master is being modified in the same transaction
1237 * flags may change too.
1238 */
1239 if (mapping->master_id) {
1240 for (j = 0; j < xctrls_count; j++) {
1241 if (xctrls[j].id == mapping->master_id) {
1242 changes |= V4L2_EVENT_CTRL_CH_FLAGS;
1243 break;
1244 }
1245 }
1246 }
1247
1194 uvc_ctrl_send_event(handle, ctrl, mapping, xctrls[i].value, 1248 uvc_ctrl_send_event(handle, ctrl, mapping, xctrls[i].value,
1195 V4L2_EVENT_CTRL_CH_VALUE); 1249 changes);
1196 } 1250 }
1197} 1251}
1198 1252