arm: fix compile failure in mach-shmobile/board-ag5evm.c
[linux-2.6-block.git] / drivers / media / video / pwc / pwc-v4l.c
1 /* Linux driver for Philips webcam
2    USB and Video4Linux interface part.
3    (C) 1999-2004 Nemosoft Unv.
4    (C) 2004-2006 Luc Saillard (luc@saillard.org)
5    (C) 2011 Hans de Goede <hdegoede@redhat.com>
6
7    NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
8    driver and thus may have bugs that are not present in the original version.
9    Please send bug reports and support requests to <luc@saillard.org>.
10    The decompression routines have been implemented by reverse-engineering the
11    Nemosoft binary pwcx module. Caveat emptor.
12
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
27 */
28
29 #include <linux/errno.h>
30 #include <linux/init.h>
31 #include <linux/mm.h>
32 #include <linux/module.h>
33 #include <linux/poll.h>
34 #include <linux/vmalloc.h>
35 #include <linux/jiffies.h>
36 #include <asm/io.h>
37
38 #include "pwc.h"
39
40 #define PWC_CID_CUSTOM(ctrl) ((V4L2_CID_USER_BASE | 0xf000) + custom_ ## ctrl)
41
42 static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
43 static int pwc_s_ctrl(struct v4l2_ctrl *ctrl);
44
45 static const struct v4l2_ctrl_ops pwc_ctrl_ops = {
46         .g_volatile_ctrl = pwc_g_volatile_ctrl,
47         .s_ctrl = pwc_s_ctrl,
48 };
49
50 enum { awb_indoor, awb_outdoor, awb_fl, awb_manual, awb_auto };
51 enum { custom_autocontour, custom_contour, custom_noise_reduction,
52         custom_save_user, custom_restore_user, custom_restore_factory };
53
54 const char * const pwc_auto_whitebal_qmenu[] = {
55         "Indoor (Incandescant Lighting) Mode",
56         "Outdoor (Sunlight) Mode",
57         "Indoor (Fluorescent Lighting) Mode",
58         "Manual Mode",
59         "Auto Mode",
60         NULL
61 };
62
63 static const struct v4l2_ctrl_config pwc_auto_white_balance_cfg = {
64         .ops    = &pwc_ctrl_ops,
65         .id     = V4L2_CID_AUTO_WHITE_BALANCE,
66         .type   = V4L2_CTRL_TYPE_MENU,
67         .max    = awb_auto,
68         .qmenu  = pwc_auto_whitebal_qmenu,
69 };
70
71 static const struct v4l2_ctrl_config pwc_autocontour_cfg = {
72         .ops    = &pwc_ctrl_ops,
73         .id     = PWC_CID_CUSTOM(autocontour),
74         .type   = V4L2_CTRL_TYPE_BOOLEAN,
75         .name   = "Auto contour",
76         .min    = 0,
77         .max    = 1,
78         .step   = 1,
79 };
80
81 static const struct v4l2_ctrl_config pwc_contour_cfg = {
82         .ops    = &pwc_ctrl_ops,
83         .id     = PWC_CID_CUSTOM(contour),
84         .type   = V4L2_CTRL_TYPE_INTEGER,
85         .name   = "Contour",
86         .flags  = V4L2_CTRL_FLAG_SLIDER,
87         .min    = 0,
88         .max    = 63,
89         .step   = 1,
90 };
91
92 static const struct v4l2_ctrl_config pwc_backlight_cfg = {
93         .ops    = &pwc_ctrl_ops,
94         .id     = V4L2_CID_BACKLIGHT_COMPENSATION,
95         .type   = V4L2_CTRL_TYPE_BOOLEAN,
96         .min    = 0,
97         .max    = 1,
98         .step   = 1,
99 };
100
101 static const struct v4l2_ctrl_config pwc_flicker_cfg = {
102         .ops    = &pwc_ctrl_ops,
103         .id     = V4L2_CID_BAND_STOP_FILTER,
104         .type   = V4L2_CTRL_TYPE_BOOLEAN,
105         .min    = 0,
106         .max    = 1,
107         .step   = 1,
108 };
109
110 static const struct v4l2_ctrl_config pwc_noise_reduction_cfg = {
111         .ops    = &pwc_ctrl_ops,
112         .id     = PWC_CID_CUSTOM(noise_reduction),
113         .type   = V4L2_CTRL_TYPE_INTEGER,
114         .name   = "Dynamic Noise Reduction",
115         .min    = 0,
116         .max    = 3,
117         .step   = 1,
118 };
119
120 static const struct v4l2_ctrl_config pwc_save_user_cfg = {
121         .ops    = &pwc_ctrl_ops,
122         .id     = PWC_CID_CUSTOM(save_user),
123         .type   = V4L2_CTRL_TYPE_BUTTON,
124         .name    = "Save User Settings",
125 };
126
127 static const struct v4l2_ctrl_config pwc_restore_user_cfg = {
128         .ops    = &pwc_ctrl_ops,
129         .id     = PWC_CID_CUSTOM(restore_user),
130         .type   = V4L2_CTRL_TYPE_BUTTON,
131         .name    = "Restore User Settings",
132 };
133
134 static const struct v4l2_ctrl_config pwc_restore_factory_cfg = {
135         .ops    = &pwc_ctrl_ops,
136         .id     = PWC_CID_CUSTOM(restore_factory),
137         .type   = V4L2_CTRL_TYPE_BUTTON,
138         .name    = "Restore Factory Settings",
139 };
140
141 int pwc_init_controls(struct pwc_device *pdev)
142 {
143         struct v4l2_ctrl_handler *hdl;
144         struct v4l2_ctrl_config cfg;
145         int r, def;
146
147         hdl = &pdev->ctrl_handler;
148         r = v4l2_ctrl_handler_init(hdl, 20);
149         if (r)
150                 return r;
151
152         /* Brightness, contrast, saturation, gamma */
153         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, BRIGHTNESS_FORMATTER, &def);
154         if (r || def > 127)
155                 def = 63;
156         pdev->brightness = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
157                                 V4L2_CID_BRIGHTNESS, 0, 127, 1, def);
158
159         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, CONTRAST_FORMATTER, &def);
160         if (r || def > 63)
161                 def = 31;
162         pdev->contrast = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
163                                 V4L2_CID_CONTRAST, 0, 63, 1, def);
164
165         if (pdev->type >= 675) {
166                 if (pdev->type < 730)
167                         pdev->saturation_fmt = SATURATION_MODE_FORMATTER2;
168                 else
169                         pdev->saturation_fmt = SATURATION_MODE_FORMATTER1;
170                 r = pwc_get_s8_ctrl(pdev, GET_CHROM_CTL, pdev->saturation_fmt,
171                                     &def);
172                 if (r || def < -100 || def > 100)
173                         def = 0;
174                 pdev->saturation = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
175                                       V4L2_CID_SATURATION, -100, 100, 1, def);
176         }
177
178         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, GAMMA_FORMATTER, &def);
179         if (r || def > 31)
180                 def = 15;
181         pdev->gamma = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
182                                 V4L2_CID_GAMMA, 0, 31, 1, def);
183
184         /* auto white balance, red gain, blue gain */
185         r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, WB_MODE_FORMATTER, &def);
186         if (r || def > awb_auto)
187                 def = awb_auto;
188         cfg = pwc_auto_white_balance_cfg;
189         cfg.name = v4l2_ctrl_get_name(cfg.id);
190         cfg.def = def;
191         pdev->auto_white_balance = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
192         /* check auto controls to avoid NULL deref in v4l2_ctrl_auto_cluster */
193         if (!pdev->auto_white_balance)
194                 return hdl->error;
195
196         r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
197                             PRESET_MANUAL_RED_GAIN_FORMATTER, &def);
198         if (r)
199                 def = 127;
200         pdev->red_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
201                                 V4L2_CID_RED_BALANCE, 0, 255, 1, def);
202
203         r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
204                             PRESET_MANUAL_BLUE_GAIN_FORMATTER, &def);
205         if (r)
206                 def = 127;
207         pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
208                                 V4L2_CID_BLUE_BALANCE, 0, 255, 1, def);
209
210         v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual, true);
211
212         /* autogain, gain */
213         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AGC_MODE_FORMATTER, &def);
214         if (r || (def != 0 && def != 0xff))
215                 def = 0;
216         /* Note a register value if 0 means auto gain is on */
217         pdev->autogain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
218                                 V4L2_CID_AUTOGAIN, 0, 1, 1, def == 0);
219         if (!pdev->autogain)
220                 return hdl->error;
221
222         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_AGC_FORMATTER, &def);
223         if (r || def > 63)
224                 def = 31;
225         pdev->gain = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
226                                 V4L2_CID_GAIN, 0, 63, 1, def);
227
228         /* auto exposure, exposure */
229         if (DEVICE_USE_CODEC2(pdev->type)) {
230                 r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, SHUTTER_MODE_FORMATTER,
231                                     &def);
232                 if (r || (def != 0 && def != 0xff))
233                         def = 0;
234                 /*
235                  * def = 0 auto, def = ff manual
236                  * menu idx 0 = auto, idx 1 = manual
237                  */
238                 pdev->exposure_auto = v4l2_ctrl_new_std_menu(hdl,
239                                         &pwc_ctrl_ops,
240                                         V4L2_CID_EXPOSURE_AUTO,
241                                         1, 0, def != 0);
242                 if (!pdev->exposure_auto)
243                         return hdl->error;
244
245                 /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
246                 r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
247                                      READ_SHUTTER_FORMATTER, &def);
248                 if (r || def > 655)
249                         def = 655;
250                 pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
251                                         V4L2_CID_EXPOSURE, 0, 655, 1, def);
252                 /* CODEC2: separate auto gain & auto exposure */
253                 v4l2_ctrl_auto_cluster(2, &pdev->autogain, 0, true);
254                 v4l2_ctrl_auto_cluster(2, &pdev->exposure_auto,
255                                        V4L2_EXPOSURE_MANUAL, true);
256         } else if (DEVICE_USE_CODEC3(pdev->type)) {
257                 /* GET_LUM_CTL, PRESET_SHUTTER_FORMATTER is unreliable */
258                 r = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
259                                      READ_SHUTTER_FORMATTER, &def);
260                 if (r || def > 255)
261                         def = 255;
262                 pdev->exposure = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
263                                         V4L2_CID_EXPOSURE, 0, 255, 1, def);
264                 /* CODEC3: both gain and exposure controlled by autogain */
265                 pdev->autogain_expo_cluster[0] = pdev->autogain;
266                 pdev->autogain_expo_cluster[1] = pdev->gain;
267                 pdev->autogain_expo_cluster[2] = pdev->exposure;
268                 v4l2_ctrl_auto_cluster(3, pdev->autogain_expo_cluster,
269                                        0, true);
270         }
271
272         /* color / bw setting */
273         r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL, COLOUR_MODE_FORMATTER,
274                          &def);
275         if (r || (def != 0 && def != 0xff))
276                 def = 0xff;
277         /* def = 0 bw, def = ff color, menu idx 0 = color, idx 1 = bw */
278         pdev->colorfx = v4l2_ctrl_new_std_menu(hdl, &pwc_ctrl_ops,
279                                 V4L2_CID_COLORFX, 1, 0, def == 0);
280
281         /* autocontour, contour */
282         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &def);
283         if (r || (def != 0 && def != 0xff))
284                 def = 0;
285         cfg = pwc_autocontour_cfg;
286         cfg.def = def == 0;
287         pdev->autocontour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
288         if (!pdev->autocontour)
289                 return hdl->error;
290
291         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &def);
292         if (r || def > 63)
293                 def = 31;
294         cfg = pwc_contour_cfg;
295         cfg.def = def;
296         pdev->contour = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
297
298         v4l2_ctrl_auto_cluster(2, &pdev->autocontour, 0, false);
299
300         /* backlight */
301         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
302                             BACK_LIGHT_COMPENSATION_FORMATTER, &def);
303         if (r || (def != 0 && def != 0xff))
304                 def = 0;
305         cfg = pwc_backlight_cfg;
306         cfg.name = v4l2_ctrl_get_name(cfg.id);
307         cfg.def = def == 0;
308         pdev->backlight = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
309
310         /* flikker rediction */
311         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
312                             FLICKERLESS_MODE_FORMATTER, &def);
313         if (r || (def != 0 && def != 0xff))
314                 def = 0;
315         cfg = pwc_flicker_cfg;
316         cfg.name = v4l2_ctrl_get_name(cfg.id);
317         cfg.def = def == 0;
318         pdev->flicker = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
319
320         /* Dynamic noise reduction */
321         r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL,
322                             DYNAMIC_NOISE_CONTROL_FORMATTER, &def);
323         if (r || def > 3)
324                 def = 2;
325         cfg = pwc_noise_reduction_cfg;
326         cfg.def = def;
327         pdev->noise_reduction = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
328
329         /* Save / Restore User / Factory Settings */
330         pdev->save_user = v4l2_ctrl_new_custom(hdl, &pwc_save_user_cfg, NULL);
331         pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg,
332                                                   NULL);
333         if (pdev->restore_user)
334                 pdev->restore_user->flags |= V4L2_CTRL_FLAG_UPDATE;
335         pdev->restore_factory = v4l2_ctrl_new_custom(hdl,
336                                                      &pwc_restore_factory_cfg,
337                                                      NULL);
338         if (pdev->restore_factory)
339                 pdev->restore_factory->flags |= V4L2_CTRL_FLAG_UPDATE;
340
341         if (!(pdev->features & FEATURE_MOTOR_PANTILT))
342                 return hdl->error;
343
344         /* Motor pan / tilt / reset */
345         pdev->motor_pan = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
346                                 V4L2_CID_PAN_RELATIVE, -4480, 4480, 64, 0);
347         if (!pdev->motor_pan)
348                 return hdl->error;
349         pdev->motor_tilt = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
350                                 V4L2_CID_TILT_RELATIVE, -1920, 1920, 64, 0);
351         pdev->motor_pan_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
352                                 V4L2_CID_PAN_RESET, 0, 0, 0, 0);
353         pdev->motor_tilt_reset = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
354                                 V4L2_CID_TILT_RESET, 0, 0, 0, 0);
355         v4l2_ctrl_cluster(4, &pdev->motor_pan);
356
357         return hdl->error;
358 }
359
360 static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f)
361 {
362         memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
363         f->fmt.pix.width        = pdev->view.x;
364         f->fmt.pix.height       = pdev->view.y;
365         f->fmt.pix.field        = V4L2_FIELD_NONE;
366         if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
367                 f->fmt.pix.pixelformat  = V4L2_PIX_FMT_YUV420;
368                 f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2;
369                 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
370         } else {
371                 /* vbandlength contains 4 lines ...  */
372                 f->fmt.pix.bytesperline = pdev->vbandlength/4;
373                 f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame);
374                 if (DEVICE_USE_CODEC1(pdev->type))
375                         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_PWC1;
376                 else
377                         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_PWC2;
378         }
379         PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
380                         "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
381                         f->fmt.pix.width,
382                         f->fmt.pix.height,
383                         f->fmt.pix.bytesperline,
384                         f->fmt.pix.sizeimage,
385                         (f->fmt.pix.pixelformat)&255,
386                         (f->fmt.pix.pixelformat>>8)&255,
387                         (f->fmt.pix.pixelformat>>16)&255,
388                         (f->fmt.pix.pixelformat>>24)&255);
389 }
390
391 /* ioctl(VIDIOC_TRY_FMT) */
392 static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
393 {
394         if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
395                 PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
396                 return -EINVAL;
397         }
398
399         switch (f->fmt.pix.pixelformat) {
400                 case V4L2_PIX_FMT_YUV420:
401                         break;
402                 case V4L2_PIX_FMT_PWC1:
403                         if (DEVICE_USE_CODEC23(pdev->type)) {
404                                 PWC_DEBUG_IOCTL("codec1 is only supported for old pwc webcam\n");
405                                 return -EINVAL;
406                         }
407                         break;
408                 case V4L2_PIX_FMT_PWC2:
409                         if (DEVICE_USE_CODEC1(pdev->type)) {
410                                 PWC_DEBUG_IOCTL("codec23 is only supported for new pwc webcam\n");
411                                 return -EINVAL;
412                         }
413                         break;
414                 default:
415                         PWC_DEBUG_IOCTL("Unsupported pixel format\n");
416                         return -EINVAL;
417
418         }
419
420         if (f->fmt.pix.width > pdev->view_max.x)
421                 f->fmt.pix.width = pdev->view_max.x;
422         else if (f->fmt.pix.width < pdev->view_min.x)
423                 f->fmt.pix.width = pdev->view_min.x;
424
425         if (f->fmt.pix.height > pdev->view_max.y)
426                 f->fmt.pix.height = pdev->view_max.y;
427         else if (f->fmt.pix.height < pdev->view_min.y)
428                 f->fmt.pix.height = pdev->view_min.y;
429
430         return 0;
431 }
432
433 /* ioctl(VIDIOC_SET_FMT) */
434
435 static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
436 {
437         struct pwc_device *pdev = video_drvdata(file);
438         int ret, fps, snapshot, compression, pixelformat;
439
440         if (!pdev->udev)
441                 return -ENODEV;
442
443         if (pdev->capt_file != NULL &&
444             pdev->capt_file != file)
445                 return -EBUSY;
446
447         pdev->capt_file = file;
448
449         ret = pwc_vidioc_try_fmt(pdev, f);
450         if (ret<0)
451                 return ret;
452
453         pixelformat = f->fmt.pix.pixelformat;
454         compression = pdev->vcompression;
455         snapshot = 0;
456         fps = pdev->vframes;
457         if (f->fmt.pix.priv) {
458                 compression = (f->fmt.pix.priv & PWC_QLT_MASK) >> PWC_QLT_SHIFT;
459                 snapshot = !!(f->fmt.pix.priv & PWC_FPS_SNAPSHOT);
460                 fps = (f->fmt.pix.priv & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
461                 if (fps == 0)
462                         fps = pdev->vframes;
463         }
464
465         if (pixelformat != V4L2_PIX_FMT_YUV420 &&
466             pixelformat != V4L2_PIX_FMT_PWC1 &&
467             pixelformat != V4L2_PIX_FMT_PWC2)
468                 return -EINVAL;
469
470         if (vb2_is_streaming(&pdev->vb_queue))
471                 return -EBUSY;
472
473         PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
474                         "compression=%d snapshot=%d format=%c%c%c%c\n",
475                         f->fmt.pix.width, f->fmt.pix.height, fps,
476                         compression, snapshot,
477                         (pixelformat)&255,
478                         (pixelformat>>8)&255,
479                         (pixelformat>>16)&255,
480                         (pixelformat>>24)&255);
481
482         ret = pwc_set_video_mode(pdev,
483                                  f->fmt.pix.width,
484                                  f->fmt.pix.height,
485                                  fps,
486                                  compression,
487                                  snapshot);
488
489         PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
490
491         if (ret)
492                 return ret;
493
494         pdev->pixfmt = pixelformat;
495
496         pwc_vidioc_fill_fmt(pdev, f);
497
498         return 0;
499
500 }
501
502 static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
503 {
504         struct pwc_device *pdev = video_drvdata(file);
505
506         if (!pdev->udev)
507                 return -ENODEV;
508
509         strcpy(cap->driver, PWC_NAME);
510         strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
511         usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
512         cap->capabilities =
513                 V4L2_CAP_VIDEO_CAPTURE  |
514                 V4L2_CAP_STREAMING      |
515                 V4L2_CAP_READWRITE;
516         return 0;
517 }
518
519 static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
520 {
521         if (i->index)   /* Only one INPUT is supported */
522                 return -EINVAL;
523
524         strcpy(i->name, "usb");
525         return 0;
526 }
527
528 static int pwc_g_input(struct file *file, void *fh, unsigned int *i)
529 {
530         *i = 0;
531         return 0;
532 }
533
534 static int pwc_s_input(struct file *file, void *fh, unsigned int i)
535 {
536         return i ? -EINVAL : 0;
537 }
538
539 static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
540 {
541         struct pwc_device *pdev =
542                 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
543         int ret = 0;
544
545         /*
546          * Sometimes it can take quite long for the pwc to complete usb control
547          * transfers, so release the modlock to give streaming by another
548          * process / thread the chance to continue with a dqbuf.
549          */
550         mutex_unlock(&pdev->modlock);
551
552         /*
553          * Take the udev-lock to protect against the disconnect handler
554          * completing and setting dev->udev to NULL underneath us. Other code
555          * does not need to do this since it is protected by the modlock.
556          */
557         mutex_lock(&pdev->udevlock);
558
559         if (!pdev->udev) {
560                 ret = -ENODEV;
561                 goto leave;
562         }
563
564         switch (ctrl->id) {
565         case V4L2_CID_AUTO_WHITE_BALANCE:
566                 if (pdev->color_bal_valid &&
567                         (pdev->auto_white_balance->val != awb_auto ||
568                          time_before(jiffies,
569                                 pdev->last_color_bal_update + HZ / 4))) {
570                         pdev->red_balance->val  = pdev->last_red_balance;
571                         pdev->blue_balance->val = pdev->last_blue_balance;
572                         break;
573                 }
574                 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
575                                       READ_RED_GAIN_FORMATTER,
576                                       &pdev->red_balance->val);
577                 if (ret)
578                         break;
579                 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
580                                       READ_BLUE_GAIN_FORMATTER,
581                                       &pdev->blue_balance->val);
582                 if (ret)
583                         break;
584                 pdev->last_red_balance  = pdev->red_balance->val;
585                 pdev->last_blue_balance = pdev->blue_balance->val;
586                 pdev->last_color_bal_update = jiffies;
587                 pdev->color_bal_valid = true;
588                 break;
589         case V4L2_CID_AUTOGAIN:
590                 if (pdev->gain_valid && time_before(jiffies,
591                                 pdev->last_gain_update + HZ / 4)) {
592                         pdev->gain->val = pdev->last_gain;
593                         break;
594                 }
595                 ret = pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
596                                       READ_AGC_FORMATTER, &pdev->gain->val);
597                 if (ret)
598                         break;
599                 pdev->last_gain = pdev->gain->val;
600                 pdev->last_gain_update = jiffies;
601                 pdev->gain_valid = true;
602                 if (!DEVICE_USE_CODEC3(pdev->type))
603                         break;
604                 /* Fall through for CODEC3 where autogain also controls expo */
605         case V4L2_CID_EXPOSURE_AUTO:
606                 if (pdev->exposure_valid && time_before(jiffies,
607                                 pdev->last_exposure_update + HZ / 4)) {
608                         pdev->exposure->val = pdev->last_exposure;
609                         break;
610                 }
611                 ret = pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
612                                        READ_SHUTTER_FORMATTER,
613                                        &pdev->exposure->val);
614                 if (ret)
615                         break;
616                 pdev->last_exposure = pdev->exposure->val;
617                 pdev->last_exposure_update = jiffies;
618                 pdev->exposure_valid = true;
619                 break;
620         default:
621                 ret = -EINVAL;
622         }
623
624         if (ret)
625                 PWC_ERROR("g_ctrl %s error %d\n", ctrl->name, ret);
626
627 leave:
628         mutex_unlock(&pdev->udevlock);
629         mutex_lock(&pdev->modlock);
630         return ret;
631 }
632
633 static int pwc_set_awb(struct pwc_device *pdev)
634 {
635         int ret;
636
637         if (pdev->auto_white_balance->is_new) {
638                 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
639                                       WB_MODE_FORMATTER,
640                                       pdev->auto_white_balance->val);
641                 if (ret)
642                         return ret;
643
644                 if (pdev->auto_white_balance->val != awb_manual)
645                         pdev->color_bal_valid = false; /* Force cache update */
646         }
647         if (pdev->auto_white_balance->val != awb_manual)
648                 return 0;
649
650         if (pdev->red_balance->is_new) {
651                 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
652                                       PRESET_MANUAL_RED_GAIN_FORMATTER,
653                                       pdev->red_balance->val);
654                 if (ret)
655                         return ret;
656         }
657
658         if (pdev->blue_balance->is_new) {
659                 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
660                                       PRESET_MANUAL_BLUE_GAIN_FORMATTER,
661                                       pdev->blue_balance->val);
662                 if (ret)
663                         return ret;
664         }
665         return 0;
666 }
667
668 /* For CODEC2 models which have separate autogain and auto exposure */
669 static int pwc_set_autogain(struct pwc_device *pdev)
670 {
671         int ret;
672
673         if (pdev->autogain->is_new) {
674                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
675                                       AGC_MODE_FORMATTER,
676                                       pdev->autogain->val ? 0 : 0xff);
677                 if (ret)
678                         return ret;
679
680                 if (pdev->autogain->val)
681                         pdev->gain_valid = false; /* Force cache update */
682         }
683
684         if (pdev->autogain->val)
685                 return 0;
686
687         if (pdev->gain->is_new) {
688                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
689                                       PRESET_AGC_FORMATTER,
690                                       pdev->gain->val);
691                 if (ret)
692                         return ret;
693         }
694         return 0;
695 }
696
697 /* For CODEC2 models which have separate autogain and auto exposure */
698 static int pwc_set_exposure_auto(struct pwc_device *pdev)
699 {
700         int ret;
701         int is_auto = pdev->exposure_auto->val == V4L2_EXPOSURE_AUTO;
702
703         if (pdev->exposure_auto->is_new) {
704                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
705                                       SHUTTER_MODE_FORMATTER,
706                                       is_auto ? 0 : 0xff);
707                 if (ret)
708                         return ret;
709
710                 if (is_auto)
711                         pdev->exposure_valid = false; /* Force cache update */
712         }
713
714         if (is_auto)
715                 return 0;
716
717         if (pdev->exposure->is_new) {
718                 ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
719                                        PRESET_SHUTTER_FORMATTER,
720                                        pdev->exposure->val);
721                 if (ret)
722                         return ret;
723         }
724         return 0;
725 }
726
727 /* For CODEC3 models which have autogain controlling both gain and exposure */
728 static int pwc_set_autogain_expo(struct pwc_device *pdev)
729 {
730         int ret;
731
732         if (pdev->autogain->is_new) {
733                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
734                                       AGC_MODE_FORMATTER,
735                                       pdev->autogain->val ? 0 : 0xff);
736                 if (ret)
737                         return ret;
738
739                 if (pdev->autogain->val) {
740                         pdev->gain_valid     = false; /* Force cache update */
741                         pdev->exposure_valid = false; /* Force cache update */
742                 }
743         }
744
745         if (pdev->autogain->val)
746                 return 0;
747
748         if (pdev->gain->is_new) {
749                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
750                                       PRESET_AGC_FORMATTER,
751                                       pdev->gain->val);
752                 if (ret)
753                         return ret;
754         }
755
756         if (pdev->exposure->is_new) {
757                 ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
758                                        PRESET_SHUTTER_FORMATTER,
759                                        pdev->exposure->val);
760                 if (ret)
761                         return ret;
762         }
763         return 0;
764 }
765
766 static int pwc_set_motor(struct pwc_device *pdev)
767 {
768         int ret;
769         u8 buf[4];
770
771         buf[0] = 0;
772         if (pdev->motor_pan_reset->is_new)
773                 buf[0] |= 0x01;
774         if (pdev->motor_tilt_reset->is_new)
775                 buf[0] |= 0x02;
776         if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
777                 ret = send_control_msg(pdev, SET_MPT_CTL,
778                                        PT_RESET_CONTROL_FORMATTER, buf, 1);
779                 if (ret < 0)
780                         return ret;
781         }
782
783         memset(buf, 0, sizeof(buf));
784         if (pdev->motor_pan->is_new) {
785                 buf[0] = pdev->motor_pan->val & 0xFF;
786                 buf[1] = (pdev->motor_pan->val >> 8);
787         }
788         if (pdev->motor_tilt->is_new) {
789                 buf[2] = pdev->motor_tilt->val & 0xFF;
790                 buf[3] = (pdev->motor_tilt->val >> 8);
791         }
792         if (pdev->motor_pan->is_new || pdev->motor_tilt->is_new) {
793                 ret = send_control_msg(pdev, SET_MPT_CTL,
794                                        PT_RELATIVE_CONTROL_FORMATTER,
795                                        buf, sizeof(buf));
796                 if (ret < 0)
797                         return ret;
798         }
799
800         return 0;
801 }
802
803 static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
804 {
805         struct pwc_device *pdev =
806                 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
807         int ret = 0;
808
809         /* See the comments on locking in pwc_g_volatile_ctrl */
810         mutex_unlock(&pdev->modlock);
811         mutex_lock(&pdev->udevlock);
812
813         if (!pdev->udev) {
814                 ret = -ENODEV;
815                 goto leave;
816         }
817
818         switch (ctrl->id) {
819         case V4L2_CID_BRIGHTNESS:
820                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
821                                       BRIGHTNESS_FORMATTER, ctrl->val);
822                 break;
823         case V4L2_CID_CONTRAST:
824                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
825                                       CONTRAST_FORMATTER, ctrl->val);
826                 break;
827         case V4L2_CID_SATURATION:
828                 ret = pwc_set_s8_ctrl(pdev, SET_CHROM_CTL,
829                                       pdev->saturation_fmt, ctrl->val);
830                 break;
831         case V4L2_CID_GAMMA:
832                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
833                                       GAMMA_FORMATTER, ctrl->val);
834                 break;
835         case V4L2_CID_AUTO_WHITE_BALANCE:
836                 ret = pwc_set_awb(pdev);
837                 break;
838         case V4L2_CID_AUTOGAIN:
839                 if (DEVICE_USE_CODEC2(pdev->type))
840                         ret = pwc_set_autogain(pdev);
841                 else if (DEVICE_USE_CODEC3(pdev->type))
842                         ret = pwc_set_autogain_expo(pdev);
843                 else
844                         ret = -EINVAL;
845                 break;
846         case V4L2_CID_EXPOSURE_AUTO:
847                 if (DEVICE_USE_CODEC2(pdev->type))
848                         ret = pwc_set_exposure_auto(pdev);
849                 else
850                         ret = -EINVAL;
851                 break;
852         case V4L2_CID_COLORFX:
853                 ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
854                                       COLOUR_MODE_FORMATTER,
855                                       ctrl->val ? 0 : 0xff);
856                 break;
857         case PWC_CID_CUSTOM(autocontour):
858                 if (pdev->autocontour->is_new) {
859                         ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
860                                         AUTO_CONTOUR_FORMATTER,
861                                         pdev->autocontour->val ? 0 : 0xff);
862                 }
863                 if (ret == 0 && pdev->contour->is_new) {
864                         ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
865                                               PRESET_CONTOUR_FORMATTER,
866                                               pdev->contour->val);
867                 }
868                 break;
869         case V4L2_CID_BACKLIGHT_COMPENSATION:
870                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
871                                       BACK_LIGHT_COMPENSATION_FORMATTER,
872                                       ctrl->val ? 0 : 0xff);
873                 break;
874         case V4L2_CID_BAND_STOP_FILTER:
875                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
876                                       FLICKERLESS_MODE_FORMATTER,
877                                       ctrl->val ? 0 : 0xff);
878                 break;
879         case PWC_CID_CUSTOM(noise_reduction):
880                 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
881                                       DYNAMIC_NOISE_CONTROL_FORMATTER,
882                                       ctrl->val);
883                 break;
884         case PWC_CID_CUSTOM(save_user):
885                 ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
886                 break;
887         case PWC_CID_CUSTOM(restore_user):
888                 ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
889                 break;
890         case PWC_CID_CUSTOM(restore_factory):
891                 ret = pwc_button_ctrl(pdev,
892                                       RESTORE_FACTORY_DEFAULTS_FORMATTER);
893                 break;
894         case V4L2_CID_PAN_RELATIVE:
895                 ret = pwc_set_motor(pdev);
896                 break;
897         default:
898                 ret = -EINVAL;
899         }
900
901         if (ret)
902                 PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret);
903
904 leave:
905         mutex_unlock(&pdev->udevlock);
906         mutex_lock(&pdev->modlock);
907         return ret;
908 }
909
910 static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
911 {
912         struct pwc_device *pdev = video_drvdata(file);
913
914         /* We only support two format: the raw format, and YUV */
915         switch (f->index) {
916         case 0:
917                 /* RAW format */
918                 f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2;
919                 f->flags = V4L2_FMT_FLAG_COMPRESSED;
920                 strlcpy(f->description, "Raw Philips Webcam", sizeof(f->description));
921                 break;
922         case 1:
923                 f->pixelformat = V4L2_PIX_FMT_YUV420;
924                 strlcpy(f->description, "4:2:0, planar, Y-Cb-Cr", sizeof(f->description));
925                 break;
926         default:
927                 return -EINVAL;
928         }
929         return 0;
930 }
931
932 static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
933 {
934         struct pwc_device *pdev = video_drvdata(file);
935
936         PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
937                         pdev->image.x, pdev->image.y);
938         pwc_vidioc_fill_fmt(pdev, f);
939         return 0;
940 }
941
942 static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
943 {
944         struct pwc_device *pdev = video_drvdata(file);
945
946         return pwc_vidioc_try_fmt(pdev, f);
947 }
948
949 static int pwc_reqbufs(struct file *file, void *fh,
950                        struct v4l2_requestbuffers *rb)
951 {
952         struct pwc_device *pdev = video_drvdata(file);
953
954         if (pdev->capt_file != NULL &&
955             pdev->capt_file != file)
956                 return -EBUSY;
957
958         pdev->capt_file = file;
959
960         return vb2_reqbufs(&pdev->vb_queue, rb);
961 }
962
963 static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
964 {
965         struct pwc_device *pdev = video_drvdata(file);
966
967         return vb2_querybuf(&pdev->vb_queue, buf);
968 }
969
970 static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
971 {
972         struct pwc_device *pdev = video_drvdata(file);
973
974         if (!pdev->udev)
975                 return -ENODEV;
976
977         if (pdev->capt_file != file)
978                 return -EBUSY;
979
980         return vb2_qbuf(&pdev->vb_queue, buf);
981 }
982
983 static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
984 {
985         struct pwc_device *pdev = video_drvdata(file);
986
987         if (!pdev->udev)
988                 return -ENODEV;
989
990         if (pdev->capt_file != file)
991                 return -EBUSY;
992
993         return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK);
994 }
995
996 static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
997 {
998         struct pwc_device *pdev = video_drvdata(file);
999
1000         if (!pdev->udev)
1001                 return -ENODEV;
1002
1003         if (pdev->capt_file != file)
1004                 return -EBUSY;
1005
1006         return vb2_streamon(&pdev->vb_queue, i);
1007 }
1008
1009 static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1010 {
1011         struct pwc_device *pdev = video_drvdata(file);
1012
1013         if (!pdev->udev)
1014                 return -ENODEV;
1015
1016         if (pdev->capt_file != file)
1017                 return -EBUSY;
1018
1019         return vb2_streamoff(&pdev->vb_queue, i);
1020 }
1021
1022 static int pwc_enum_framesizes(struct file *file, void *fh,
1023                                          struct v4l2_frmsizeenum *fsize)
1024 {
1025         struct pwc_device *pdev = video_drvdata(file);
1026         unsigned int i = 0, index = fsize->index;
1027
1028         if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
1029                 for (i = 0; i < PSZ_MAX; i++) {
1030                         if (pdev->image_mask & (1UL << i)) {
1031                                 if (!index--) {
1032                                         fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1033                                         fsize->discrete.width = pwc_image_sizes[i].x;
1034                                         fsize->discrete.height = pwc_image_sizes[i].y;
1035                                         return 0;
1036                                 }
1037                         }
1038                 }
1039         } else if (fsize->index == 0 &&
1040                         ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
1041                          (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
1042
1043                 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1044                 fsize->discrete.width = pdev->abs_max.x;
1045                 fsize->discrete.height = pdev->abs_max.y;
1046                 return 0;
1047         }
1048         return -EINVAL;
1049 }
1050
1051 static int pwc_enum_frameintervals(struct file *file, void *fh,
1052                                            struct v4l2_frmivalenum *fival)
1053 {
1054         struct pwc_device *pdev = video_drvdata(file);
1055         int size = -1;
1056         unsigned int i;
1057
1058         for (i = 0; i < PSZ_MAX; i++) {
1059                 if (pwc_image_sizes[i].x == fival->width &&
1060                                 pwc_image_sizes[i].y == fival->height) {
1061                         size = i;
1062                         break;
1063                 }
1064         }
1065
1066         /* TODO: Support raw format */
1067         if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420)
1068                 return -EINVAL;
1069
1070         i = pwc_get_fps(pdev, fival->index, size);
1071         if (!i)
1072                 return -EINVAL;
1073
1074         fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1075         fival->discrete.numerator = 1;
1076         fival->discrete.denominator = i;
1077
1078         return 0;
1079 }
1080
1081 static int pwc_log_status(struct file *file, void *priv)
1082 {
1083         struct pwc_device *pdev = video_drvdata(file);
1084
1085         v4l2_ctrl_handler_log_status(&pdev->ctrl_handler, PWC_NAME);
1086         return 0;
1087 }
1088
1089 static long pwc_default(struct file *file, void *fh, bool valid_prio,
1090                         int cmd, void *arg)
1091 {
1092         struct pwc_device *pdev = video_drvdata(file);
1093
1094         return pwc_ioctl(pdev, cmd, arg);
1095 }
1096
1097 const struct v4l2_ioctl_ops pwc_ioctl_ops = {
1098         .vidioc_querycap                    = pwc_querycap,
1099         .vidioc_enum_input                  = pwc_enum_input,
1100         .vidioc_g_input                     = pwc_g_input,
1101         .vidioc_s_input                     = pwc_s_input,
1102         .vidioc_enum_fmt_vid_cap            = pwc_enum_fmt_vid_cap,
1103         .vidioc_g_fmt_vid_cap               = pwc_g_fmt_vid_cap,
1104         .vidioc_s_fmt_vid_cap               = pwc_s_fmt_vid_cap,
1105         .vidioc_try_fmt_vid_cap             = pwc_try_fmt_vid_cap,
1106         .vidioc_reqbufs                     = pwc_reqbufs,
1107         .vidioc_querybuf                    = pwc_querybuf,
1108         .vidioc_qbuf                        = pwc_qbuf,
1109         .vidioc_dqbuf                       = pwc_dqbuf,
1110         .vidioc_streamon                    = pwc_streamon,
1111         .vidioc_streamoff                   = pwc_streamoff,
1112         .vidioc_log_status                  = pwc_log_status,
1113         .vidioc_enum_framesizes             = pwc_enum_framesizes,
1114         .vidioc_enum_frameintervals         = pwc_enum_frameintervals,
1115         .vidioc_default             = pwc_default,
1116 };
1117
1118
1119 /* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */