Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[sfrench/cifs-2.6.git] / drivers / media / video / uvc / uvc_ctrl.c
1 /*
2  *      uvc_ctrl.c  --  USB Video Class driver - Controls
3  *
4  *      Copyright (C) 2005-2009
5  *          Laurent Pinchart (laurent.pinchart@skynet.be)
6  *
7  *      This program is free software; you can redistribute it and/or modify
8  *      it under the terms of the GNU General Public License as published by
9  *      the Free Software Foundation; either version 2 of the License, or
10  *      (at your option) any later version.
11  *
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/list.h>
16 #include <linux/module.h>
17 #include <linux/uaccess.h>
18 #include <linux/usb.h>
19 #include <linux/videodev2.h>
20 #include <linux/vmalloc.h>
21 #include <linux/wait.h>
22 #include <asm/atomic.h>
23
24 #include "uvcvideo.h"
25
26 #define UVC_CTRL_NDATA          2
27 #define UVC_CTRL_DATA_CURRENT   0
28 #define UVC_CTRL_DATA_BACKUP    1
29
30 /* ------------------------------------------------------------------------
31  * Controls
32  */
33
34 static struct uvc_control_info uvc_ctrls[] = {
35         {
36                 .entity         = UVC_GUID_UVC_PROCESSING,
37                 .selector       = UVC_PU_BRIGHTNESS_CONTROL,
38                 .index          = 0,
39                 .size           = 2,
40                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
41                                 | UVC_CONTROL_RESTORE,
42         },
43         {
44                 .entity         = UVC_GUID_UVC_PROCESSING,
45                 .selector       = UVC_PU_CONTRAST_CONTROL,
46                 .index          = 1,
47                 .size           = 2,
48                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
49                                 | UVC_CONTROL_RESTORE,
50         },
51         {
52                 .entity         = UVC_GUID_UVC_PROCESSING,
53                 .selector       = UVC_PU_HUE_CONTROL,
54                 .index          = 2,
55                 .size           = 2,
56                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
57                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
58         },
59         {
60                 .entity         = UVC_GUID_UVC_PROCESSING,
61                 .selector       = UVC_PU_SATURATION_CONTROL,
62                 .index          = 3,
63                 .size           = 2,
64                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
65                                 | UVC_CONTROL_RESTORE,
66         },
67         {
68                 .entity         = UVC_GUID_UVC_PROCESSING,
69                 .selector       = UVC_PU_SHARPNESS_CONTROL,
70                 .index          = 4,
71                 .size           = 2,
72                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
73                                 | UVC_CONTROL_RESTORE,
74         },
75         {
76                 .entity         = UVC_GUID_UVC_PROCESSING,
77                 .selector       = UVC_PU_GAMMA_CONTROL,
78                 .index          = 5,
79                 .size           = 2,
80                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
81                                 | UVC_CONTROL_RESTORE,
82         },
83         {
84                 .entity         = UVC_GUID_UVC_PROCESSING,
85                 .selector       = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
86                 .index          = 6,
87                 .size           = 2,
88                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
89                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
90         },
91         {
92                 .entity         = UVC_GUID_UVC_PROCESSING,
93                 .selector       = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
94                 .index          = 7,
95                 .size           = 4,
96                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
97                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
98         },
99         {
100                 .entity         = UVC_GUID_UVC_PROCESSING,
101                 .selector       = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
102                 .index          = 8,
103                 .size           = 2,
104                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
105                                 | UVC_CONTROL_RESTORE,
106         },
107         {
108                 .entity         = UVC_GUID_UVC_PROCESSING,
109                 .selector       = UVC_PU_GAIN_CONTROL,
110                 .index          = 9,
111                 .size           = 2,
112                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
113                                 | UVC_CONTROL_RESTORE,
114         },
115         {
116                 .entity         = UVC_GUID_UVC_PROCESSING,
117                 .selector       = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
118                 .index          = 10,
119                 .size           = 1,
120                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
121                                 | UVC_CONTROL_RESTORE,
122         },
123         {
124                 .entity         = UVC_GUID_UVC_PROCESSING,
125                 .selector       = UVC_PU_HUE_AUTO_CONTROL,
126                 .index          = 11,
127                 .size           = 1,
128                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
129                                 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
130         },
131         {
132                 .entity         = UVC_GUID_UVC_PROCESSING,
133                 .selector       = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
134                 .index          = 12,
135                 .size           = 1,
136                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
137                                 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
138         },
139         {
140                 .entity         = UVC_GUID_UVC_PROCESSING,
141                 .selector       = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
142                 .index          = 13,
143                 .size           = 1,
144                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
145                                 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
146         },
147         {
148                 .entity         = UVC_GUID_UVC_PROCESSING,
149                 .selector       = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
150                 .index          = 14,
151                 .size           = 2,
152                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
153                                 | UVC_CONTROL_RESTORE,
154         },
155         {
156                 .entity         = UVC_GUID_UVC_PROCESSING,
157                 .selector       = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
158                 .index          = 15,
159                 .size           = 2,
160                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
161                                 | UVC_CONTROL_RESTORE,
162         },
163         {
164                 .entity         = UVC_GUID_UVC_PROCESSING,
165                 .selector       = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
166                 .index          = 16,
167                 .size           = 1,
168                 .flags          = UVC_CONTROL_GET_CUR,
169         },
170         {
171                 .entity         = UVC_GUID_UVC_PROCESSING,
172                 .selector       = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
173                 .index          = 17,
174                 .size           = 1,
175                 .flags          = UVC_CONTROL_GET_CUR,
176         },
177         {
178                 .entity         = UVC_GUID_UVC_CAMERA,
179                 .selector       = UVC_CT_SCANNING_MODE_CONTROL,
180                 .index          = 0,
181                 .size           = 1,
182                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
183                                 | UVC_CONTROL_RESTORE,
184         },
185         {
186                 .entity         = UVC_GUID_UVC_CAMERA,
187                 .selector       = UVC_CT_AE_MODE_CONTROL,
188                 .index          = 1,
189                 .size           = 1,
190                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
191                                 | UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES
192                                 | UVC_CONTROL_RESTORE,
193         },
194         {
195                 .entity         = UVC_GUID_UVC_CAMERA,
196                 .selector       = UVC_CT_AE_PRIORITY_CONTROL,
197                 .index          = 2,
198                 .size           = 1,
199                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
200                                 | UVC_CONTROL_RESTORE,
201         },
202         {
203                 .entity         = UVC_GUID_UVC_CAMERA,
204                 .selector       = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
205                 .index          = 3,
206                 .size           = 4,
207                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
208                                 | UVC_CONTROL_RESTORE,
209         },
210         {
211                 .entity         = UVC_GUID_UVC_CAMERA,
212                 .selector       = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
213                 .index          = 4,
214                 .size           = 1,
215                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
216                                 | UVC_CONTROL_RESTORE,
217         },
218         {
219                 .entity         = UVC_GUID_UVC_CAMERA,
220                 .selector       = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
221                 .index          = 5,
222                 .size           = 2,
223                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
224                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
225         },
226         {
227                 .entity         = UVC_GUID_UVC_CAMERA,
228                 .selector       = UVC_CT_FOCUS_RELATIVE_CONTROL,
229                 .index          = 6,
230                 .size           = 2,
231                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
232                                 | UVC_CONTROL_AUTO_UPDATE,
233         },
234         {
235                 .entity         = UVC_GUID_UVC_CAMERA,
236                 .selector       = UVC_CT_IRIS_ABSOLUTE_CONTROL,
237                 .index          = 7,
238                 .size           = 2,
239                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
240                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
241         },
242         {
243                 .entity         = UVC_GUID_UVC_CAMERA,
244                 .selector       = UVC_CT_IRIS_RELATIVE_CONTROL,
245                 .index          = 8,
246                 .size           = 1,
247                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
248                                 | UVC_CONTROL_AUTO_UPDATE,
249         },
250         {
251                 .entity         = UVC_GUID_UVC_CAMERA,
252                 .selector       = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
253                 .index          = 9,
254                 .size           = 2,
255                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
256                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
257         },
258         {
259                 .entity         = UVC_GUID_UVC_CAMERA,
260                 .selector       = UVC_CT_ZOOM_RELATIVE_CONTROL,
261                 .index          = 10,
262                 .size           = 3,
263                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
264                                 | UVC_CONTROL_AUTO_UPDATE,
265         },
266         {
267                 .entity         = UVC_GUID_UVC_CAMERA,
268                 .selector       = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
269                 .index          = 11,
270                 .size           = 8,
271                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
272                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
273         },
274         {
275                 .entity         = UVC_GUID_UVC_CAMERA,
276                 .selector       = UVC_CT_PANTILT_RELATIVE_CONTROL,
277                 .index          = 12,
278                 .size           = 4,
279                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
280                                 | UVC_CONTROL_AUTO_UPDATE,
281         },
282         {
283                 .entity         = UVC_GUID_UVC_CAMERA,
284                 .selector       = UVC_CT_ROLL_ABSOLUTE_CONTROL,
285                 .index          = 13,
286                 .size           = 2,
287                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
288                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
289         },
290         {
291                 .entity         = UVC_GUID_UVC_CAMERA,
292                 .selector       = UVC_CT_ROLL_RELATIVE_CONTROL,
293                 .index          = 14,
294                 .size           = 2,
295                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
296                                 | UVC_CONTROL_AUTO_UPDATE,
297         },
298         {
299                 .entity         = UVC_GUID_UVC_CAMERA,
300                 .selector       = UVC_CT_FOCUS_AUTO_CONTROL,
301                 .index          = 17,
302                 .size           = 1,
303                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
304                                 | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
305         },
306         {
307                 .entity         = UVC_GUID_UVC_CAMERA,
308                 .selector       = UVC_CT_PRIVACY_CONTROL,
309                 .index          = 18,
310                 .size           = 1,
311                 .flags          = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
312                                 | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
313         },
314 };
315
316 static struct uvc_menu_info power_line_frequency_controls[] = {
317         { 0, "Disabled" },
318         { 1, "50 Hz" },
319         { 2, "60 Hz" },
320 };
321
322 static struct uvc_menu_info exposure_auto_controls[] = {
323         { 2, "Auto Mode" },
324         { 1, "Manual Mode" },
325         { 4, "Shutter Priority Mode" },
326         { 8, "Aperture Priority Mode" },
327 };
328
329 static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
330         __u8 query, const __u8 *data)
331 {
332         __s8 zoom = (__s8)data[0];
333
334         switch (query) {
335         case UVC_GET_CUR:
336                 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
337
338         case UVC_GET_MIN:
339         case UVC_GET_MAX:
340         case UVC_GET_RES:
341         case UVC_GET_DEF:
342         default:
343                 return data[2];
344         }
345 }
346
347 static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,
348         __s32 value, __u8 *data)
349 {
350         data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;
351         data[2] = min((int)abs(value), 0xff);
352 }
353
354 static struct uvc_control_mapping uvc_ctrl_mappings[] = {
355         {
356                 .id             = V4L2_CID_BRIGHTNESS,
357                 .name           = "Brightness",
358                 .entity         = UVC_GUID_UVC_PROCESSING,
359                 .selector       = UVC_PU_BRIGHTNESS_CONTROL,
360                 .size           = 16,
361                 .offset         = 0,
362                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
363                 .data_type      = UVC_CTRL_DATA_TYPE_SIGNED,
364         },
365         {
366                 .id             = V4L2_CID_CONTRAST,
367                 .name           = "Contrast",
368                 .entity         = UVC_GUID_UVC_PROCESSING,
369                 .selector       = UVC_PU_CONTRAST_CONTROL,
370                 .size           = 16,
371                 .offset         = 0,
372                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
373                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
374         },
375         {
376                 .id             = V4L2_CID_HUE,
377                 .name           = "Hue",
378                 .entity         = UVC_GUID_UVC_PROCESSING,
379                 .selector       = UVC_PU_HUE_CONTROL,
380                 .size           = 16,
381                 .offset         = 0,
382                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
383                 .data_type      = UVC_CTRL_DATA_TYPE_SIGNED,
384         },
385         {
386                 .id             = V4L2_CID_SATURATION,
387                 .name           = "Saturation",
388                 .entity         = UVC_GUID_UVC_PROCESSING,
389                 .selector       = UVC_PU_SATURATION_CONTROL,
390                 .size           = 16,
391                 .offset         = 0,
392                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
393                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
394         },
395         {
396                 .id             = V4L2_CID_SHARPNESS,
397                 .name           = "Sharpness",
398                 .entity         = UVC_GUID_UVC_PROCESSING,
399                 .selector       = UVC_PU_SHARPNESS_CONTROL,
400                 .size           = 16,
401                 .offset         = 0,
402                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
403                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
404         },
405         {
406                 .id             = V4L2_CID_GAMMA,
407                 .name           = "Gamma",
408                 .entity         = UVC_GUID_UVC_PROCESSING,
409                 .selector       = UVC_PU_GAMMA_CONTROL,
410                 .size           = 16,
411                 .offset         = 0,
412                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
413                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
414         },
415         {
416                 .id             = V4L2_CID_BACKLIGHT_COMPENSATION,
417                 .name           = "Backlight Compensation",
418                 .entity         = UVC_GUID_UVC_PROCESSING,
419                 .selector       = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
420                 .size           = 16,
421                 .offset         = 0,
422                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
423                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
424         },
425         {
426                 .id             = V4L2_CID_GAIN,
427                 .name           = "Gain",
428                 .entity         = UVC_GUID_UVC_PROCESSING,
429                 .selector       = UVC_PU_GAIN_CONTROL,
430                 .size           = 16,
431                 .offset         = 0,
432                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
433                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
434         },
435         {
436                 .id             = V4L2_CID_POWER_LINE_FREQUENCY,
437                 .name           = "Power Line Frequency",
438                 .entity         = UVC_GUID_UVC_PROCESSING,
439                 .selector       = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
440                 .size           = 2,
441                 .offset         = 0,
442                 .v4l2_type      = V4L2_CTRL_TYPE_MENU,
443                 .data_type      = UVC_CTRL_DATA_TYPE_ENUM,
444                 .menu_info      = power_line_frequency_controls,
445                 .menu_count     = ARRAY_SIZE(power_line_frequency_controls),
446         },
447         {
448                 .id             = V4L2_CID_HUE_AUTO,
449                 .name           = "Hue, Auto",
450                 .entity         = UVC_GUID_UVC_PROCESSING,
451                 .selector       = UVC_PU_HUE_AUTO_CONTROL,
452                 .size           = 1,
453                 .offset         = 0,
454                 .v4l2_type      = V4L2_CTRL_TYPE_BOOLEAN,
455                 .data_type      = UVC_CTRL_DATA_TYPE_BOOLEAN,
456         },
457         {
458                 .id             = V4L2_CID_EXPOSURE_AUTO,
459                 .name           = "Exposure, Auto",
460                 .entity         = UVC_GUID_UVC_CAMERA,
461                 .selector       = UVC_CT_AE_MODE_CONTROL,
462                 .size           = 4,
463                 .offset         = 0,
464                 .v4l2_type      = V4L2_CTRL_TYPE_MENU,
465                 .data_type      = UVC_CTRL_DATA_TYPE_BITMASK,
466                 .menu_info      = exposure_auto_controls,
467                 .menu_count     = ARRAY_SIZE(exposure_auto_controls),
468         },
469         {
470                 .id             = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
471                 .name           = "Exposure, Auto Priority",
472                 .entity         = UVC_GUID_UVC_CAMERA,
473                 .selector       = UVC_CT_AE_PRIORITY_CONTROL,
474                 .size           = 1,
475                 .offset         = 0,
476                 .v4l2_type      = V4L2_CTRL_TYPE_BOOLEAN,
477                 .data_type      = UVC_CTRL_DATA_TYPE_BOOLEAN,
478         },
479         {
480                 .id             = V4L2_CID_EXPOSURE_ABSOLUTE,
481                 .name           = "Exposure (Absolute)",
482                 .entity         = UVC_GUID_UVC_CAMERA,
483                 .selector       = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
484                 .size           = 32,
485                 .offset         = 0,
486                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
487                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
488         },
489         {
490                 .id             = V4L2_CID_AUTO_WHITE_BALANCE,
491                 .name           = "White Balance Temperature, Auto",
492                 .entity         = UVC_GUID_UVC_PROCESSING,
493                 .selector       = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
494                 .size           = 1,
495                 .offset         = 0,
496                 .v4l2_type      = V4L2_CTRL_TYPE_BOOLEAN,
497                 .data_type      = UVC_CTRL_DATA_TYPE_BOOLEAN,
498         },
499         {
500                 .id             = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
501                 .name           = "White Balance Temperature",
502                 .entity         = UVC_GUID_UVC_PROCESSING,
503                 .selector       = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
504                 .size           = 16,
505                 .offset         = 0,
506                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
507                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
508         },
509         {
510                 .id             = V4L2_CID_AUTO_WHITE_BALANCE,
511                 .name           = "White Balance Component, Auto",
512                 .entity         = UVC_GUID_UVC_PROCESSING,
513                 .selector       = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
514                 .size           = 1,
515                 .offset         = 0,
516                 .v4l2_type      = V4L2_CTRL_TYPE_BOOLEAN,
517                 .data_type      = UVC_CTRL_DATA_TYPE_BOOLEAN,
518         },
519         {
520                 .id             = V4L2_CID_BLUE_BALANCE,
521                 .name           = "White Balance Blue Component",
522                 .entity         = UVC_GUID_UVC_PROCESSING,
523                 .selector       = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
524                 .size           = 16,
525                 .offset         = 0,
526                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
527                 .data_type      = UVC_CTRL_DATA_TYPE_SIGNED,
528         },
529         {
530                 .id             = V4L2_CID_RED_BALANCE,
531                 .name           = "White Balance Red Component",
532                 .entity         = UVC_GUID_UVC_PROCESSING,
533                 .selector       = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
534                 .size           = 16,
535                 .offset         = 16,
536                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
537                 .data_type      = UVC_CTRL_DATA_TYPE_SIGNED,
538         },
539         {
540                 .id             = V4L2_CID_FOCUS_ABSOLUTE,
541                 .name           = "Focus (absolute)",
542                 .entity         = UVC_GUID_UVC_CAMERA,
543                 .selector       = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
544                 .size           = 16,
545                 .offset         = 0,
546                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
547                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
548         },
549         {
550                 .id             = V4L2_CID_FOCUS_AUTO,
551                 .name           = "Focus, Auto",
552                 .entity         = UVC_GUID_UVC_CAMERA,
553                 .selector       = UVC_CT_FOCUS_AUTO_CONTROL,
554                 .size           = 1,
555                 .offset         = 0,
556                 .v4l2_type      = V4L2_CTRL_TYPE_BOOLEAN,
557                 .data_type      = UVC_CTRL_DATA_TYPE_BOOLEAN,
558         },
559         {
560                 .id             = V4L2_CID_ZOOM_ABSOLUTE,
561                 .name           = "Zoom, Absolute",
562                 .entity         = UVC_GUID_UVC_CAMERA,
563                 .selector       = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
564                 .size           = 16,
565                 .offset         = 0,
566                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
567                 .data_type      = UVC_CTRL_DATA_TYPE_UNSIGNED,
568         },
569         {
570                 .id             = V4L2_CID_ZOOM_CONTINUOUS,
571                 .name           = "Zoom, Continuous",
572                 .entity         = UVC_GUID_UVC_CAMERA,
573                 .selector       = UVC_CT_ZOOM_RELATIVE_CONTROL,
574                 .size           = 0,
575                 .offset         = 0,
576                 .v4l2_type      = V4L2_CTRL_TYPE_INTEGER,
577                 .data_type      = UVC_CTRL_DATA_TYPE_SIGNED,
578                 .get            = uvc_ctrl_get_zoom,
579                 .set            = uvc_ctrl_set_zoom,
580         },
581         {
582                 .id             = V4L2_CID_PRIVACY,
583                 .name           = "Privacy",
584                 .entity         = UVC_GUID_UVC_CAMERA,
585                 .selector       = UVC_CT_PRIVACY_CONTROL,
586                 .size           = 1,
587                 .offset         = 0,
588                 .v4l2_type      = V4L2_CTRL_TYPE_BOOLEAN,
589                 .data_type      = UVC_CTRL_DATA_TYPE_BOOLEAN,
590         },
591 };
592
593 /* ------------------------------------------------------------------------
594  * Utility functions
595  */
596
597 static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
598 {
599         return ctrl->data + id * ctrl->info->size;
600 }
601
602 static inline int uvc_test_bit(const __u8 *data, int bit)
603 {
604         return (data[bit >> 3] >> (bit & 7)) & 1;
605 }
606
607 static inline void uvc_clear_bit(__u8 *data, int bit)
608 {
609         data[bit >> 3] &= ~(1 << (bit & 7));
610 }
611
612 /* Extract the bit string specified by mapping->offset and mapping->size
613  * from the little-endian data stored at 'data' and return the result as
614  * a signed 32bit integer. Sign extension will be performed if the mapping
615  * references a signed data type.
616  */
617 static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
618         __u8 query, const __u8 *data)
619 {
620         int bits = mapping->size;
621         int offset = mapping->offset;
622         __s32 value = 0;
623         __u8 mask;
624
625         data += offset / 8;
626         offset &= 7;
627         mask = ((1LL << bits) - 1) << offset;
628
629         for (; bits > 0; data++) {
630                 __u8 byte = *data & mask;
631                 value |= offset > 0 ? (byte >> offset) : (byte << (-offset));
632                 bits -= 8 - (offset > 0 ? offset : 0);
633                 offset -= 8;
634                 mask = (1 << bits) - 1;
635         }
636
637         /* Sign-extend the value if needed. */
638         if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
639                 value |= -(value & (1 << (mapping->size - 1)));
640
641         return value;
642 }
643
644 /* Set the bit string specified by mapping->offset and mapping->size
645  * in the little-endian data stored at 'data' to the value 'value'.
646  */
647 static void uvc_set_le_value(struct uvc_control_mapping *mapping,
648         __s32 value, __u8 *data)
649 {
650         int bits = mapping->size;
651         int offset = mapping->offset;
652         __u8 mask;
653
654         data += offset / 8;
655         offset &= 7;
656
657         for (; bits > 0; data++) {
658                 mask = ((1LL << bits) - 1) << offset;
659                 *data = (*data & ~mask) | ((value << offset) & mask);
660                 value >>= offset ? offset : 8;
661                 bits -= 8 - offset;
662                 offset = 0;
663         }
664 }
665
666 /* ------------------------------------------------------------------------
667  * Terminal and unit management
668  */
669
670 static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
671 static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;
672 static const __u8 uvc_media_transport_input_guid[16] =
673         UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
674
675 static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16])
676 {
677         switch (UVC_ENTITY_TYPE(entity)) {
678         case UVC_ITT_CAMERA:
679                 return memcmp(uvc_camera_guid, guid, 16) == 0;
680
681         case UVC_ITT_MEDIA_TRANSPORT_INPUT:
682                 return memcmp(uvc_media_transport_input_guid, guid, 16) == 0;
683
684         case UVC_VC_PROCESSING_UNIT:
685                 return memcmp(uvc_processing_guid, guid, 16) == 0;
686
687         case UVC_VC_EXTENSION_UNIT:
688                 return memcmp(entity->extension.guidExtensionCode,
689                               guid, 16) == 0;
690
691         default:
692                 return 0;
693         }
694 }
695
696 /* ------------------------------------------------------------------------
697  * UVC Controls
698  */
699
700 static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
701         struct uvc_control_mapping **mapping, struct uvc_control **control,
702         int next)
703 {
704         struct uvc_control *ctrl;
705         struct uvc_control_mapping *map;
706         unsigned int i;
707
708         if (entity == NULL)
709                 return;
710
711         for (i = 0; i < entity->ncontrols; ++i) {
712                 ctrl = &entity->controls[i];
713                 if (ctrl->info == NULL)
714                         continue;
715
716                 list_for_each_entry(map, &ctrl->info->mappings, list) {
717                         if ((map->id == v4l2_id) && !next) {
718                                 *control = ctrl;
719                                 *mapping = map;
720                                 return;
721                         }
722
723                         if ((*mapping == NULL || (*mapping)->id > map->id) &&
724                             (map->id > v4l2_id) && next) {
725                                 *control = ctrl;
726                                 *mapping = map;
727                         }
728                 }
729         }
730 }
731
732 struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
733         __u32 v4l2_id, struct uvc_control_mapping **mapping)
734 {
735         struct uvc_control *ctrl = NULL;
736         struct uvc_entity *entity;
737         int next = v4l2_id & V4L2_CTRL_FLAG_NEXT_CTRL;
738
739         *mapping = NULL;
740
741         /* Mask the query flags. */
742         v4l2_id &= V4L2_CTRL_ID_MASK;
743
744         /* Find the control. */
745         list_for_each_entry(entity, &chain->entities, chain) {
746                 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
747                 if (ctrl && !next)
748                         return ctrl;
749         }
750
751         if (ctrl == NULL && !next)
752                 uvc_trace(UVC_TRACE_CONTROL, "Control 0x%08x not found.\n",
753                                 v4l2_id);
754
755         return ctrl;
756 }
757
758 int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
759         struct v4l2_queryctrl *v4l2_ctrl)
760 {
761         struct uvc_control *ctrl;
762         struct uvc_control_mapping *mapping;
763         struct uvc_menu_info *menu;
764         unsigned int i;
765         __u8 *data;
766         int ret;
767
768         ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
769         if (ctrl == NULL)
770                 return -EINVAL;
771
772         data = kmalloc(ctrl->info->size, GFP_KERNEL);
773         if (data == NULL)
774                 return -ENOMEM;
775
776         memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
777         v4l2_ctrl->id = mapping->id;
778         v4l2_ctrl->type = mapping->v4l2_type;
779         strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
780         v4l2_ctrl->flags = 0;
781
782         if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
783                 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
784
785         if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
786                 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
787                                      chain->dev->intfnum, ctrl->info->selector,
788                                      data, ctrl->info->size);
789                 if (ret < 0)
790                         goto out;
791                 v4l2_ctrl->default_value =
792                         mapping->get(mapping, UVC_GET_DEF, data);
793         }
794
795         switch (mapping->v4l2_type) {
796         case V4L2_CTRL_TYPE_MENU:
797                 v4l2_ctrl->minimum = 0;
798                 v4l2_ctrl->maximum = mapping->menu_count - 1;
799                 v4l2_ctrl->step = 1;
800
801                 menu = mapping->menu_info;
802                 for (i = 0; i < mapping->menu_count; ++i, ++menu) {
803                         if (menu->value == v4l2_ctrl->default_value) {
804                                 v4l2_ctrl->default_value = i;
805                                 break;
806                         }
807                 }
808
809                 ret = 0;
810                 goto out;
811
812         case V4L2_CTRL_TYPE_BOOLEAN:
813                 v4l2_ctrl->minimum = 0;
814                 v4l2_ctrl->maximum = 1;
815                 v4l2_ctrl->step = 1;
816                 ret = 0;
817                 goto out;
818
819         case V4L2_CTRL_TYPE_BUTTON:
820                 v4l2_ctrl->minimum = 0;
821                 v4l2_ctrl->maximum = 0;
822                 v4l2_ctrl->step = 0;
823                 ret = 0;
824                 goto out;
825
826         default:
827                 break;
828         }
829
830         if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
831                 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
832                                      chain->dev->intfnum, ctrl->info->selector,
833                                      data, ctrl->info->size);
834                 if (ret < 0)
835                         goto out;
836                 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data);
837         }
838         if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
839                 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
840                                      chain->dev->intfnum, ctrl->info->selector,
841                                      data, ctrl->info->size);
842                 if (ret < 0)
843                         goto out;
844                 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data);
845         }
846         if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
847                 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
848                                      chain->dev->intfnum, ctrl->info->selector,
849                                      data, ctrl->info->size);
850                 if (ret < 0)
851                         goto out;
852                 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data);
853         }
854
855         ret = 0;
856 out:
857         kfree(data);
858         return ret;
859 }
860
861
862 /* --------------------------------------------------------------------------
863  * Control transactions
864  *
865  * To make extended set operations as atomic as the hardware allows, controls
866  * are handled using begin/commit/rollback operations.
867  *
868  * At the beginning of a set request, uvc_ctrl_begin should be called to
869  * initialize the request. This function acquires the control lock.
870  *
871  * When setting a control, the new value is stored in the control data field
872  * at position UVC_CTRL_DATA_CURRENT. The control is then marked as dirty for
873  * later processing. If the UVC and V4L2 control sizes differ, the current
874  * value is loaded from the hardware before storing the new value in the data
875  * field.
876  *
877  * After processing all controls in the transaction, uvc_ctrl_commit or
878  * uvc_ctrl_rollback must be called to apply the pending changes to the
879  * hardware or revert them. When applying changes, all controls marked as
880  * dirty will be modified in the UVC device, and the dirty flag will be
881  * cleared. When reverting controls, the control data field
882  * UVC_CTRL_DATA_CURRENT is reverted to its previous value
883  * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the
884  * control lock.
885  */
886 int uvc_ctrl_begin(struct uvc_video_chain *chain)
887 {
888         return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
889 }
890
891 static int uvc_ctrl_commit_entity(struct uvc_device *dev,
892         struct uvc_entity *entity, int rollback)
893 {
894         struct uvc_control *ctrl;
895         unsigned int i;
896         int ret;
897
898         if (entity == NULL)
899                 return 0;
900
901         for (i = 0; i < entity->ncontrols; ++i) {
902                 ctrl = &entity->controls[i];
903                 if (ctrl->info == NULL)
904                         continue;
905
906                 /* Reset the loaded flag for auto-update controls that were
907                  * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
908                  * uvc_ctrl_get from using the cached value.
909                  */
910                 if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE)
911                         ctrl->loaded = 0;
912
913                 if (!ctrl->dirty)
914                         continue;
915
916                 if (!rollback)
917                         ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id,
918                                 dev->intfnum, ctrl->info->selector,
919                                 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
920                                 ctrl->info->size);
921                 else
922                         ret = 0;
923
924                 if (rollback || ret < 0)
925                         memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
926                                uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
927                                ctrl->info->size);
928
929                 ctrl->dirty = 0;
930
931                 if (ret < 0)
932                         return ret;
933         }
934
935         return 0;
936 }
937
938 int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
939 {
940         struct uvc_entity *entity;
941         int ret = 0;
942
943         /* Find the control. */
944         list_for_each_entry(entity, &chain->entities, chain) {
945                 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
946                 if (ret < 0)
947                         goto done;
948         }
949
950 done:
951         mutex_unlock(&chain->ctrl_mutex);
952         return ret;
953 }
954
955 int uvc_ctrl_get(struct uvc_video_chain *chain,
956         struct v4l2_ext_control *xctrl)
957 {
958         struct uvc_control *ctrl;
959         struct uvc_control_mapping *mapping;
960         struct uvc_menu_info *menu;
961         unsigned int i;
962         int ret;
963
964         ctrl = uvc_find_control(chain, xctrl->id, &mapping);
965         if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
966                 return -EINVAL;
967
968         if (!ctrl->loaded) {
969                 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
970                                 chain->dev->intfnum, ctrl->info->selector,
971                                 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
972                                 ctrl->info->size);
973                 if (ret < 0)
974                         return ret;
975
976                 ctrl->loaded = 1;
977         }
978
979         xctrl->value = mapping->get(mapping, UVC_GET_CUR,
980                 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
981
982         if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
983                 menu = mapping->menu_info;
984                 for (i = 0; i < mapping->menu_count; ++i, ++menu) {
985                         if (menu->value == xctrl->value) {
986                                 xctrl->value = i;
987                                 break;
988                         }
989                 }
990         }
991
992         return 0;
993 }
994
995 int uvc_ctrl_set(struct uvc_video_chain *chain,
996         struct v4l2_ext_control *xctrl)
997 {
998         struct uvc_control *ctrl;
999         struct uvc_control_mapping *mapping;
1000         s32 value = xctrl->value;
1001         int ret;
1002
1003         ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1004         if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
1005                 return -EINVAL;
1006
1007         if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
1008                 if (value < 0 || value >= mapping->menu_count)
1009                         return -EINVAL;
1010                 value = mapping->menu_info[value].value;
1011         }
1012
1013         if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) {
1014                 if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) {
1015                         memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1016                                 0, ctrl->info->size);
1017                 } else {
1018                         ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1019                                 ctrl->entity->id, chain->dev->intfnum,
1020                                 ctrl->info->selector,
1021                                 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1022                                 ctrl->info->size);
1023                         if (ret < 0)
1024                                 return ret;
1025                 }
1026
1027                 ctrl->loaded = 1;
1028         }
1029
1030         if (!ctrl->dirty) {
1031                 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1032                        uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1033                        ctrl->info->size);
1034         }
1035
1036         mapping->set(mapping, value,
1037                 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
1038
1039         ctrl->dirty = 1;
1040         ctrl->modified = 1;
1041         return 0;
1042 }
1043
1044 /* --------------------------------------------------------------------------
1045  * Dynamic controls
1046  */
1047
1048 int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1049         struct uvc_xu_control *xctrl, int set)
1050 {
1051         struct uvc_entity *entity;
1052         struct uvc_control *ctrl = NULL;
1053         unsigned int i, found = 0;
1054         __u8 *data;
1055         int ret;
1056
1057         /* Find the extension unit. */
1058         list_for_each_entry(entity, &chain->entities, chain) {
1059                 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
1060                     entity->id == xctrl->unit)
1061                         break;
1062         }
1063
1064         if (entity->id != xctrl->unit) {
1065                 uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n",
1066                         xctrl->unit);
1067                 return -EINVAL;
1068         }
1069
1070         /* Find the control. */
1071         for (i = 0; i < entity->ncontrols; ++i) {
1072                 ctrl = &entity->controls[i];
1073                 if (ctrl->info == NULL)
1074                         continue;
1075
1076                 if (ctrl->info->selector == xctrl->selector) {
1077                         found = 1;
1078                         break;
1079                 }
1080         }
1081
1082         if (!found) {
1083                 uvc_trace(UVC_TRACE_CONTROL,
1084                         "Control " UVC_GUID_FORMAT "/%u not found.\n",
1085                         UVC_GUID_ARGS(entity->extension.guidExtensionCode),
1086                         xctrl->selector);
1087                 return -EINVAL;
1088         }
1089
1090         /* Validate control data size. */
1091         if (ctrl->info->size != xctrl->size)
1092                 return -EINVAL;
1093
1094         if ((set && !(ctrl->info->flags & UVC_CONTROL_SET_CUR)) ||
1095             (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR)))
1096                 return -EINVAL;
1097
1098         if (mutex_lock_interruptible(&chain->ctrl_mutex))
1099                 return -ERESTARTSYS;
1100
1101         memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1102                uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1103                xctrl->size);
1104         data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
1105
1106         if (set && copy_from_user(data, xctrl->data, xctrl->size)) {
1107                 ret = -EFAULT;
1108                 goto out;
1109         }
1110
1111         ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR,
1112                              xctrl->unit, chain->dev->intfnum, xctrl->selector,
1113                              data, xctrl->size);
1114         if (ret < 0)
1115                 goto out;
1116
1117         if (!set && copy_to_user(xctrl->data, data, xctrl->size)) {
1118                 ret = -EFAULT;
1119                 goto out;
1120         }
1121
1122 out:
1123         if (ret)
1124                 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1125                        uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1126                        xctrl->size);
1127
1128         mutex_unlock(&chain->ctrl_mutex);
1129         return ret;
1130 }
1131
1132 /* --------------------------------------------------------------------------
1133  * Suspend/resume
1134  */
1135
1136 /*
1137  * Restore control values after resume, skipping controls that haven't been
1138  * changed.
1139  *
1140  * TODO
1141  * - Don't restore modified controls that are back to their default value.
1142  * - Handle restore order (Auto-Exposure Mode should be restored before
1143  *   Exposure Time).
1144  */
1145 int uvc_ctrl_resume_device(struct uvc_device *dev)
1146 {
1147         struct uvc_control *ctrl;
1148         struct uvc_entity *entity;
1149         unsigned int i;
1150         int ret;
1151
1152         /* Walk the entities list and restore controls when possible. */
1153         list_for_each_entry(entity, &dev->entities, list) {
1154
1155                 for (i = 0; i < entity->ncontrols; ++i) {
1156                         ctrl = &entity->controls[i];
1157
1158                         if (ctrl->info == NULL || !ctrl->modified ||
1159                             (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0)
1160                                 continue;
1161
1162                         printk(KERN_INFO "restoring control " UVC_GUID_FORMAT
1163                                 "/%u/%u\n", UVC_GUID_ARGS(ctrl->info->entity),
1164                                 ctrl->info->index, ctrl->info->selector);
1165                         ctrl->dirty = 1;
1166                 }
1167
1168                 ret = uvc_ctrl_commit_entity(dev, entity, 0);
1169                 if (ret < 0)
1170                         return ret;
1171         }
1172
1173         return 0;
1174 }
1175
1176 /* --------------------------------------------------------------------------
1177  * Control and mapping handling
1178  */
1179
1180 static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
1181         struct uvc_control_info *info)
1182 {
1183         struct uvc_entity *entity;
1184         struct uvc_control *ctrl = NULL;
1185         int ret, found = 0;
1186         unsigned int i;
1187
1188         list_for_each_entry(entity, &dev->entities, list) {
1189                 if (!uvc_entity_match_guid(entity, info->entity))
1190                         continue;
1191
1192                 for (i = 0; i < entity->ncontrols; ++i) {
1193                         ctrl = &entity->controls[i];
1194                         if (ctrl->index == info->index) {
1195                                 found = 1;
1196                                 break;
1197                         }
1198                 }
1199
1200                 if (found)
1201                         break;
1202         }
1203
1204         if (!found)
1205                 return;
1206
1207         if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
1208                 /* Check if the device control information and length match
1209                  * the user supplied information.
1210                  */
1211                 __u32 flags;
1212                 __le16 size;
1213                 __u8 inf;
1214
1215                 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
1216                         dev->intfnum, info->selector, (__u8 *)&size, 2);
1217                 if (ret < 0) {
1218                         uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on "
1219                                 "control " UVC_GUID_FORMAT "/%u (%d).\n",
1220                                 UVC_GUID_ARGS(info->entity), info->selector,
1221                                 ret);
1222                         return;
1223                 }
1224
1225                 if (info->size != le16_to_cpu(size)) {
1226                         uvc_trace(UVC_TRACE_CONTROL, "Control " UVC_GUID_FORMAT
1227                                 "/%u size doesn't match user supplied "
1228                                 "value.\n", UVC_GUID_ARGS(info->entity),
1229                                 info->selector);
1230                         return;
1231                 }
1232
1233                 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
1234                         dev->intfnum, info->selector, &inf, 1);
1235                 if (ret < 0) {
1236                         uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on "
1237                                 "control " UVC_GUID_FORMAT "/%u (%d).\n",
1238                                 UVC_GUID_ARGS(info->entity), info->selector,
1239                                 ret);
1240                         return;
1241                 }
1242
1243                 flags = info->flags;
1244                 if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) ||
1245                     ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) {
1246                         uvc_trace(UVC_TRACE_CONTROL, "Control "
1247                                 UVC_GUID_FORMAT "/%u flags don't match "
1248                                 "supported operations.\n",
1249                                 UVC_GUID_ARGS(info->entity), info->selector);
1250                         return;
1251                 }
1252         }
1253
1254         ctrl->info = info;
1255         ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_NDATA, GFP_KERNEL);
1256         uvc_trace(UVC_TRACE_CONTROL, "Added control " UVC_GUID_FORMAT "/%u "
1257                 "to device %s entity %u\n", UVC_GUID_ARGS(ctrl->info->entity),
1258                 ctrl->info->selector, dev->udev->devpath, entity->id);
1259 }
1260
1261 /*
1262  * Add an item to the UVC control information list, and instantiate a control
1263  * structure for each device that supports the control.
1264  */
1265 int uvc_ctrl_add_info(struct uvc_control_info *info)
1266 {
1267         struct uvc_control_info *ctrl;
1268         struct uvc_device *dev;
1269         int ret = 0;
1270
1271         /* Find matching controls by walking the devices, entities and
1272          * controls list.
1273          */
1274         mutex_lock(&uvc_driver.ctrl_mutex);
1275
1276         /* First check if the list contains a control matching the new one.
1277          * Bail out if it does.
1278          */
1279         list_for_each_entry(ctrl, &uvc_driver.controls, list) {
1280                 if (memcmp(ctrl->entity, info->entity, 16))
1281                         continue;
1282
1283                 if (ctrl->selector == info->selector) {
1284                         uvc_trace(UVC_TRACE_CONTROL, "Control "
1285                                 UVC_GUID_FORMAT "/%u is already defined.\n",
1286                                 UVC_GUID_ARGS(info->entity), info->selector);
1287                         ret = -EEXIST;
1288                         goto end;
1289                 }
1290                 if (ctrl->index == info->index) {
1291                         uvc_trace(UVC_TRACE_CONTROL, "Control "
1292                                 UVC_GUID_FORMAT "/%u would overwrite index "
1293                                 "%d.\n", UVC_GUID_ARGS(info->entity),
1294                                 info->selector, info->index);
1295                         ret = -EEXIST;
1296                         goto end;
1297                 }
1298         }
1299
1300         list_for_each_entry(dev, &uvc_driver.devices, list)
1301                 uvc_ctrl_add_ctrl(dev, info);
1302
1303         INIT_LIST_HEAD(&info->mappings);
1304         list_add_tail(&info->list, &uvc_driver.controls);
1305 end:
1306         mutex_unlock(&uvc_driver.ctrl_mutex);
1307         return ret;
1308 }
1309
1310 int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping)
1311 {
1312         struct uvc_control_info *info;
1313         struct uvc_control_mapping *map;
1314         int ret = -EINVAL;
1315
1316         if (mapping->get == NULL)
1317                 mapping->get = uvc_get_le_value;
1318         if (mapping->set == NULL)
1319                 mapping->set = uvc_set_le_value;
1320
1321         if (mapping->id & ~V4L2_CTRL_ID_MASK) {
1322                 uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s' with "
1323                         "invalid control id 0x%08x\n", mapping->name,
1324                         mapping->id);
1325                 return -EINVAL;
1326         }
1327
1328         mutex_lock(&uvc_driver.ctrl_mutex);
1329         list_for_each_entry(info, &uvc_driver.controls, list) {
1330                 if (memcmp(info->entity, mapping->entity, 16) ||
1331                         info->selector != mapping->selector)
1332                         continue;
1333
1334                 if (info->size * 8 < mapping->size + mapping->offset) {
1335                         uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' would "
1336                                 "overflow control " UVC_GUID_FORMAT "/%u\n",
1337                                 mapping->name, UVC_GUID_ARGS(info->entity),
1338                                 info->selector);
1339                         ret = -EOVERFLOW;
1340                         goto end;
1341                 }
1342
1343                 /* Check if the list contains a mapping matching the new one.
1344                  * Bail out if it does.
1345                  */
1346                 list_for_each_entry(map, &info->mappings, list) {
1347                         if (map->id == mapping->id) {
1348                                 uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' is "
1349                                         "already defined.\n", mapping->name);
1350                                 ret = -EEXIST;
1351                                 goto end;
1352                         }
1353                 }
1354
1355                 mapping->ctrl = info;
1356                 list_add_tail(&mapping->list, &info->mappings);
1357                 uvc_trace(UVC_TRACE_CONTROL, "Adding mapping %s to control "
1358                         UVC_GUID_FORMAT "/%u.\n", mapping->name,
1359                         UVC_GUID_ARGS(info->entity), info->selector);
1360
1361                 ret = 0;
1362                 break;
1363         }
1364 end:
1365         mutex_unlock(&uvc_driver.ctrl_mutex);
1366         return ret;
1367 }
1368
1369 /*
1370  * Prune an entity of its bogus controls using a blacklist. Bogus controls
1371  * are currently the ones that crash the camera or unconditionally return an
1372  * error when queried.
1373  */
1374 static void
1375 uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
1376 {
1377         static const struct {
1378                 struct usb_device_id id;
1379                 u8 index;
1380         } blacklist[] = {
1381                 { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */
1382                 { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */
1383         };
1384
1385         u8 *controls;
1386         unsigned int size;
1387         unsigned int i;
1388
1389         if (UVC_ENTITY_TYPE(entity) != UVC_VC_PROCESSING_UNIT)
1390                 return;
1391
1392         controls = entity->processing.bmControls;
1393         size = entity->processing.bControlSize;
1394
1395         for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
1396                 if (!usb_match_id(dev->intf, &blacklist[i].id))
1397                         continue;
1398
1399                 if (blacklist[i].index >= 8 * size ||
1400                     !uvc_test_bit(controls, blacklist[i].index))
1401                         continue;
1402
1403                 uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, "
1404                         "removing it.\n", entity->id, blacklist[i].index);
1405
1406                 uvc_clear_bit(controls, blacklist[i].index);
1407         }
1408 }
1409
1410 /*
1411  * Initialize device controls.
1412  */
1413 int uvc_ctrl_init_device(struct uvc_device *dev)
1414 {
1415         struct uvc_control_info *info;
1416         struct uvc_control *ctrl;
1417         struct uvc_entity *entity;
1418         unsigned int i;
1419
1420         /* Walk the entities list and instantiate controls */
1421         list_for_each_entry(entity, &dev->entities, list) {
1422                 unsigned int bControlSize = 0, ncontrols = 0;
1423                 __u8 *bmControls = NULL;
1424
1425                 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
1426                         bmControls = entity->extension.bmControls;
1427                         bControlSize = entity->extension.bControlSize;
1428                 } else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) {
1429                         bmControls = entity->processing.bmControls;
1430                         bControlSize = entity->processing.bControlSize;
1431                 } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
1432                         bmControls = entity->camera.bmControls;
1433                         bControlSize = entity->camera.bControlSize;
1434                 }
1435
1436                 uvc_ctrl_prune_entity(dev, entity);
1437
1438                 for (i = 0; i < bControlSize; ++i)
1439                         ncontrols += hweight8(bmControls[i]);
1440
1441                 if (ncontrols == 0)
1442                         continue;
1443
1444                 entity->controls = kzalloc(ncontrols*sizeof *ctrl, GFP_KERNEL);
1445                 if (entity->controls == NULL)
1446                         return -ENOMEM;
1447
1448                 entity->ncontrols = ncontrols;
1449
1450                 ctrl = entity->controls;
1451                 for (i = 0; i < bControlSize * 8; ++i) {
1452                         if (uvc_test_bit(bmControls, i) == 0)
1453                                 continue;
1454
1455                         ctrl->entity = entity;
1456                         ctrl->index = i;
1457                         ctrl++;
1458                 }
1459         }
1460
1461         /* Walk the controls info list and associate them with the device
1462          * controls, then add the device to the global device list. This has
1463          * to be done while holding the controls lock, to make sure
1464          * uvc_ctrl_add_info() will not get called in-between.
1465          */
1466         mutex_lock(&uvc_driver.ctrl_mutex);
1467         list_for_each_entry(info, &uvc_driver.controls, list)
1468                 uvc_ctrl_add_ctrl(dev, info);
1469
1470         list_add_tail(&dev->list, &uvc_driver.devices);
1471         mutex_unlock(&uvc_driver.ctrl_mutex);
1472
1473         return 0;
1474 }
1475
1476 /*
1477  * Cleanup device controls.
1478  */
1479 void uvc_ctrl_cleanup_device(struct uvc_device *dev)
1480 {
1481         struct uvc_entity *entity;
1482         unsigned int i;
1483
1484         /* Remove the device from the global devices list */
1485         mutex_lock(&uvc_driver.ctrl_mutex);
1486         if (dev->list.next != NULL)
1487                 list_del(&dev->list);
1488         mutex_unlock(&uvc_driver.ctrl_mutex);
1489
1490         list_for_each_entry(entity, &dev->entities, list) {
1491                 for (i = 0; i < entity->ncontrols; ++i)
1492                         kfree(entity->controls[i].data);
1493
1494                 kfree(entity->controls);
1495         }
1496 }
1497
1498 void uvc_ctrl_init(void)
1499 {
1500         struct uvc_control_info *ctrl = uvc_ctrls;
1501         struct uvc_control_info *cend = ctrl + ARRAY_SIZE(uvc_ctrls);
1502         struct uvc_control_mapping *mapping = uvc_ctrl_mappings;
1503         struct uvc_control_mapping *mend =
1504                 mapping + ARRAY_SIZE(uvc_ctrl_mappings);
1505
1506         for (; ctrl < cend; ++ctrl)
1507                 uvc_ctrl_add_info(ctrl);
1508
1509         for (; mapping < mend; ++mapping)
1510                 uvc_ctrl_add_mapping(mapping);
1511 }
1512