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