d09413c44c86e543b48f4efc4fd7a143ae75c3cb
[pandora-kernel.git] / drivers / media / video / pwc / pwc-ctrl.c
1 /* Driver for Philips webcam
2    Functions that send various control messages to the webcam, including
3    video modes.
4    (C) 1999-2003 Nemosoft Unv.
5    (C) 2004-2006 Luc Saillard (luc@saillard.org)
6    (C) 2011 Hans de Goede <hdegoede@redhat.com>
7
8    NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
9    driver and thus may have bugs that are not present in the original version.
10    Please send bug reports and support requests to <luc@saillard.org>.
11
12    NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
13    driver and thus may have bugs that are not present in the original version.
14    Please send bug reports and support requests to <luc@saillard.org>.
15    The decompression routines have been implemented by reverse-engineering the
16    Nemosoft binary pwcx module. Caveat emptor.
17
18    This program is free software; you can redistribute it and/or modify
19    it under the terms of the GNU General Public License as published by
20    the Free Software Foundation; either version 2 of the License, or
21    (at your option) any later version.
22
23    This program is distributed in the hope that it will be useful,
24    but WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26    GNU General Public License for more details.
27
28    You should have received a copy of the GNU General Public License
29    along with this program; if not, write to the Free Software
30    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31 */
32
33 /*
34    Changes
35    2001/08/03  Alvarado   Added methods for changing white balance and
36                           red/green gains
37  */
38
39 /* Control functions for the cam; brightness, contrast, video mode, etc. */
40
41 #ifdef __KERNEL__
42 #include <asm/uaccess.h>
43 #endif
44 #include <asm/errno.h>
45
46 #include "pwc.h"
47 #include "pwc-uncompress.h"
48 #include "pwc-kiara.h"
49 #include "pwc-timon.h"
50 #include "pwc-dec1.h"
51 #include "pwc-dec23.h"
52
53 /* Selectors for status controls used only in this file */
54 #define GET_STATUS_B00                          0x0B00
55 #define SENSOR_TYPE_FORMATTER1                  0x0C00
56 #define GET_STATUS_3000                         0x3000
57 #define READ_RAW_Y_MEAN_FORMATTER               0x3100
58 #define SET_POWER_SAVE_MODE_FORMATTER           0x3200
59 #define MIRROR_IMAGE_FORMATTER                  0x3300
60 #define LED_FORMATTER                           0x3400
61 #define LOWLIGHT                                0x3500
62 #define GET_STATUS_3600                         0x3600
63 #define SENSOR_TYPE_FORMATTER2                  0x3700
64 #define GET_STATUS_3800                         0x3800
65 #define GET_STATUS_4000                         0x4000
66 #define GET_STATUS_4100                         0x4100  /* Get */
67 #define CTL_STATUS_4200                         0x4200  /* [GS] 1 */
68
69 /* Formatters for the Video Endpoint controls [GS]ET_EP_STREAM_CTL */
70 #define VIDEO_OUTPUT_CONTROL_FORMATTER          0x0100
71
72 static const char *size2name[PSZ_MAX] =
73 {
74         "subQCIF",
75         "QSIF",
76         "QCIF",
77         "SIF",
78         "CIF",
79         "VGA",
80 };
81
82 /********/
83
84 /* Entries for the Nala (645/646) camera; the Nala doesn't have compression
85    preferences, so you either get compressed or non-compressed streams.
86
87    An alternate value of 0 means this mode is not available at all.
88  */
89
90 #define PWC_FPS_MAX_NALA 8
91
92 struct Nala_table_entry {
93         char alternate;                 /* USB alternate setting */
94         int compressed;                 /* Compressed yes/no */
95
96         unsigned char mode[3];          /* precomputed mode table */
97 };
98
99 static unsigned int Nala_fps_vector[PWC_FPS_MAX_NALA] = { 4, 5, 7, 10, 12, 15, 20, 24 };
100
101 static struct Nala_table_entry Nala_table[PSZ_MAX][PWC_FPS_MAX_NALA] =
102 {
103 #include "pwc-nala.h"
104 };
105
106 static void pwc_set_image_buffer_size(struct pwc_device *pdev);
107
108 /****************************************************************************/
109
110 static int _send_control_msg(struct pwc_device *pdev,
111         u8 request, u16 value, int index, void *buf, int buflen)
112 {
113         int rc;
114         void *kbuf = NULL;
115
116         if (buflen) {
117                 kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
118                 if (kbuf == NULL)
119                         return -ENOMEM;
120                 memcpy(kbuf, buf, buflen);
121         }
122
123         rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
124                 request,
125                 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
126                 value,
127                 index,
128                 kbuf, buflen, USB_CTRL_SET_TIMEOUT);
129
130         kfree(kbuf);
131         return rc;
132 }
133
134 static int recv_control_msg(struct pwc_device *pdev,
135         u8 request, u16 value, void *buf, int buflen)
136 {
137         int rc;
138         void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
139
140         if (kbuf == NULL)
141                 return -ENOMEM;
142
143         rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
144                 request,
145                 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
146                 value,
147                 pdev->vcinterface,
148                 kbuf, buflen, USB_CTRL_GET_TIMEOUT);
149         memcpy(buf, kbuf, buflen);
150         kfree(kbuf);
151
152         if (rc < 0)
153                 PWC_ERROR("recv_control_msg error %d req %02x val %04x\n",
154                           rc, request, value);
155         return rc;
156 }
157
158 static inline int send_video_command(struct pwc_device *pdev,
159         int index, void *buf, int buflen)
160 {
161         return _send_control_msg(pdev,
162                 SET_EP_STREAM_CTL,
163                 VIDEO_OUTPUT_CONTROL_FORMATTER,
164                 index,
165                 buf, buflen);
166 }
167
168 int send_control_msg(struct pwc_device *pdev,
169         u8 request, u16 value, void *buf, int buflen)
170 {
171         return _send_control_msg(pdev,
172                 request, value, pdev->vcinterface, buf, buflen);
173 }
174
175 static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
176 {
177         unsigned char buf[3];
178         int ret, fps;
179         struct Nala_table_entry *pEntry;
180         int frames2frames[31] =
181         { /* closest match of framerate */
182            0,  0,  0,  0,  4,  /*  0-4  */
183            5,  5,  7,  7, 10,  /*  5-9  */
184           10, 10, 12, 12, 15,  /* 10-14 */
185           15, 15, 15, 20, 20,  /* 15-19 */
186           20, 20, 20, 24, 24,  /* 20-24 */
187           24, 24, 24, 24, 24,  /* 25-29 */
188           24                   /* 30    */
189         };
190         int frames2table[31] =
191         { 0, 0, 0, 0, 0, /*  0-4  */
192           1, 1, 1, 2, 2, /*  5-9  */
193           3, 3, 4, 4, 4, /* 10-14 */
194           5, 5, 5, 5, 5, /* 15-19 */
195           6, 6, 6, 6, 7, /* 20-24 */
196           7, 7, 7, 7, 7, /* 25-29 */
197           7              /* 30    */
198         };
199
200         if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
201                 return -EINVAL;
202         frames = frames2frames[frames];
203         fps = frames2table[frames];
204         pEntry = &Nala_table[size][fps];
205         if (pEntry->alternate == 0)
206                 return -EINVAL;
207
208         memcpy(buf, pEntry->mode, 3);
209         ret = send_video_command(pdev, pdev->vendpoint, buf, 3);
210         if (ret < 0) {
211                 PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret);
212                 return ret;
213         }
214         if (pEntry->compressed && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
215                 ret = pwc_dec1_init(pdev, pdev->type, pdev->release, buf);
216                 if (ret < 0)
217                         return ret;
218         }
219
220         pdev->cmd_len = 3;
221         memcpy(pdev->cmd_buf, buf, 3);
222
223         /* Set various parameters */
224         pdev->vframes = frames;
225         pdev->vsize = size;
226         pdev->valternate = pEntry->alternate;
227         pdev->image = pwc_image_sizes[size];
228         pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
229         if (pEntry->compressed) {
230                 if (pdev->release < 5) { /* 4 fold compression */
231                         pdev->vbandlength = 528;
232                         pdev->frame_size /= 4;
233                 }
234                 else {
235                         pdev->vbandlength = 704;
236                         pdev->frame_size /= 3;
237                 }
238         }
239         else
240                 pdev->vbandlength = 0;
241         return 0;
242 }
243
244
245 static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
246 {
247         unsigned char buf[13];
248         const struct Timon_table_entry *pChoose;
249         int ret, fps;
250
251         if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
252                 return -EINVAL;
253         if (size == PSZ_VGA && frames > 15)
254                 return -EINVAL;
255         fps = (frames / 5) - 1;
256
257         /* Find a supported framerate with progressively higher compression ratios
258            if the preferred ratio is not available.
259         */
260         pChoose = NULL;
261         while (compression <= 3) {
262            pChoose = &Timon_table[size][fps][compression];
263            if (pChoose->alternate != 0)
264              break;
265            compression++;
266         }
267         if (pChoose == NULL || pChoose->alternate == 0)
268                 return -ENOENT; /* Not supported. */
269
270         memcpy(buf, pChoose->mode, 13);
271         if (snapshot)
272                 buf[0] |= 0x80;
273         ret = send_video_command(pdev, pdev->vendpoint, buf, 13);
274         if (ret < 0)
275                 return ret;
276
277         if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
278                 ret = pwc_dec23_init(pdev, pdev->type, buf);
279                 if (ret < 0)
280                         return ret;
281         }
282
283         pdev->cmd_len = 13;
284         memcpy(pdev->cmd_buf, buf, 13);
285
286         /* Set various parameters */
287         pdev->vframes = frames;
288         pdev->vsize = size;
289         pdev->vsnapshot = snapshot;
290         pdev->valternate = pChoose->alternate;
291         pdev->image = pwc_image_sizes[size];
292         pdev->vbandlength = pChoose->bandlength;
293         if (pChoose->bandlength > 0)
294                 pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
295         else
296                 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
297         return 0;
298 }
299
300
301 static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
302 {
303         const struct Kiara_table_entry *pChoose = NULL;
304         int fps, ret;
305         unsigned char buf[12];
306         struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}};
307
308         if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
309                 return -EINVAL;
310         if (size == PSZ_VGA && frames > 15)
311                 return -EINVAL;
312         fps = (frames / 5) - 1;
313
314         /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
315         if (size == PSZ_VGA && frames == 5 && snapshot && pdev->pixfmt != V4L2_PIX_FMT_YUV420)
316         {
317                 /* Only available in case the raw palette is selected or
318                    we have the decompressor available. This mode is
319                    only available in compressed form
320                 */
321                 PWC_DEBUG_SIZE("Choosing VGA/5 BAYER mode.\n");
322                 pChoose = &RawEntry;
323         }
324         else
325         {
326                 /* Find a supported framerate with progressively higher compression ratios
327                    if the preferred ratio is not available.
328                    Skip this step when using RAW modes.
329                 */
330                 snapshot = 0;
331                 while (compression <= 3) {
332                         pChoose = &Kiara_table[size][fps][compression];
333                         if (pChoose->alternate != 0)
334                                 break;
335                         compression++;
336                 }
337         }
338         if (pChoose == NULL || pChoose->alternate == 0)
339                 return -ENOENT; /* Not supported. */
340
341         PWC_TRACE("Using alternate setting %d.\n", pChoose->alternate);
342
343         /* usb_control_msg won't take staticly allocated arrays as argument?? */
344         memcpy(buf, pChoose->mode, 12);
345         if (snapshot)
346                 buf[0] |= 0x80;
347
348         /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */
349         ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12);
350         if (ret < 0)
351                 return ret;
352
353         if (pChoose->bandlength > 0 && pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
354                 ret = pwc_dec23_init(pdev, pdev->type, buf);
355                 if (ret < 0)
356                         return ret;
357         }
358
359         pdev->cmd_len = 12;
360         memcpy(pdev->cmd_buf, buf, 12);
361         /* All set and go */
362         pdev->vframes = frames;
363         pdev->vsize = size;
364         pdev->vsnapshot = snapshot;
365         pdev->valternate = pChoose->alternate;
366         pdev->image = pwc_image_sizes[size];
367         pdev->vbandlength = pChoose->bandlength;
368         if (pdev->vbandlength > 0)
369                 pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
370         else
371                 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
372         PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vsnapshot=%d, vbandlength=%d\n",
373             pdev->frame_size,pdev->vframes,pdev->vsize,pdev->vsnapshot,pdev->vbandlength);
374         return 0;
375 }
376
377
378
379 /**
380    @pdev: device structure
381    @width: viewport width
382    @height: viewport height
383    @frame: framerate, in fps
384    @compression: preferred compression ratio
385    @snapshot: snapshot mode or streaming
386  */
387 int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
388 {
389         int ret, size;
390
391         PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt);
392         size = pwc_decode_size(pdev, width, height);
393         if (size < 0) {
394                 PWC_DEBUG_MODULE("Could not find suitable size.\n");
395                 return -ERANGE;
396         }
397         PWC_TRACE("decode_size = %d.\n", size);
398
399         if (DEVICE_USE_CODEC1(pdev->type)) {
400                 ret = set_video_mode_Nala(pdev, size, frames);
401
402         } else if (DEVICE_USE_CODEC3(pdev->type)) {
403                 ret = set_video_mode_Kiara(pdev, size, frames, compression, snapshot);
404
405         } else {
406                 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
407         }
408         if (ret < 0) {
409                 PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
410                 return ret;
411         }
412         pdev->view.x = width;
413         pdev->view.y = height;
414         pdev->vcompression = compression;
415         pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
416         pwc_set_image_buffer_size(pdev);
417         PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
418         return 0;
419 }
420
421 static unsigned int pwc_get_fps_Nala(struct pwc_device *pdev, unsigned int index, unsigned int size)
422 {
423         unsigned int i;
424
425         for (i = 0; i < PWC_FPS_MAX_NALA; i++) {
426                 if (Nala_table[size][i].alternate) {
427                         if (index--==0) return Nala_fps_vector[i];
428                 }
429         }
430         return 0;
431 }
432
433 static unsigned int pwc_get_fps_Kiara(struct pwc_device *pdev, unsigned int index, unsigned int size)
434 {
435         unsigned int i;
436
437         for (i = 0; i < PWC_FPS_MAX_KIARA; i++) {
438                 if (Kiara_table[size][i][3].alternate) {
439                         if (index--==0) return Kiara_fps_vector[i];
440                 }
441         }
442         return 0;
443 }
444
445 static unsigned int pwc_get_fps_Timon(struct pwc_device *pdev, unsigned int index, unsigned int size)
446 {
447         unsigned int i;
448
449         for (i=0; i < PWC_FPS_MAX_TIMON; i++) {
450                 if (Timon_table[size][i][3].alternate) {
451                         if (index--==0) return Timon_fps_vector[i];
452                 }
453         }
454         return 0;
455 }
456
457 unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size)
458 {
459         unsigned int ret;
460
461         if (DEVICE_USE_CODEC1(pdev->type)) {
462                 ret = pwc_get_fps_Nala(pdev, index, size);
463
464         } else if (DEVICE_USE_CODEC3(pdev->type)) {
465                 ret = pwc_get_fps_Kiara(pdev, index, size);
466
467         } else {
468                 ret = pwc_get_fps_Timon(pdev, index, size);
469         }
470
471         return ret;
472 }
473
474 static void pwc_set_image_buffer_size(struct pwc_device *pdev)
475 {
476         int factor = 0;
477
478         /* for V4L2_PIX_FMT_YUV420 */
479         switch (pdev->pixfmt) {
480         case V4L2_PIX_FMT_YUV420:
481                 factor = 6;
482                 break;
483         case V4L2_PIX_FMT_PWC1:
484         case V4L2_PIX_FMT_PWC2:
485                 factor = 6; /* can be uncompressed YUV420P */
486                 break;
487         }
488
489         /* Set sizes in bytes */
490         pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
491         pdev->view.size  = pdev->view.x  * pdev->view.y  * factor / 4;
492
493         /* Align offset, or you'll get some very weird results in
494            YUV420 mode... x must be multiple of 4 (to get the Y's in
495            place), and y even (or you'll mixup U & V). This is less of a
496            problem for YUV420P.
497          */
498         pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
499         pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
500 }
501
502 int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
503 {
504         int ret;
505         u8 buf;
506
507         ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
508         if (ret < 0)
509                 return ret;
510
511         *data = buf;
512         return 0;
513 }
514
515 int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
516 {
517         int ret;
518
519         ret = send_control_msg(pdev, request, value, &data, sizeof(data));
520         if (ret < 0)
521                 return ret;
522
523         return 0;
524 }
525
526 int pwc_get_s8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
527 {
528         int ret;
529         s8 buf;
530
531         ret = recv_control_msg(pdev, request, value, &buf, sizeof(buf));
532         if (ret < 0)
533                 return ret;
534
535         *data = buf;
536         return 0;
537 }
538
539 int pwc_get_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
540 {
541         int ret;
542         u8 buf[2];
543
544         ret = recv_control_msg(pdev, request, value, buf, sizeof(buf));
545         if (ret < 0)
546                 return ret;
547
548         *data = (buf[1] << 8) | buf[0];
549         return 0;
550 }
551
552 int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
553 {
554         int ret;
555         u8 buf[2];
556
557         buf[0] = data & 0xff;
558         buf[1] = data >> 8;
559         ret = send_control_msg(pdev, request, value, buf, sizeof(buf));
560         if (ret < 0)
561                 return ret;
562
563         return 0;
564 }
565
566 int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
567 {
568         int ret;
569
570         ret = send_control_msg(pdev, SET_STATUS_CTL, value, NULL, 0);
571         if (ret < 0)
572                 return ret;
573
574         return 0;
575 }
576
577 /* POWER */
578 void pwc_camera_power(struct pwc_device *pdev, int power)
579 {
580         char buf;
581         int r;
582
583         if (!pdev->power_save)
584                 return;
585
586         if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
587                 return; /* Not supported by Nala or Timon < release 6 */
588
589         if (power)
590                 buf = 0x00; /* active */
591         else
592                 buf = 0xFF; /* power save */
593         r = send_control_msg(pdev,
594                 SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER,
595                 &buf, sizeof(buf));
596
597         if (r < 0)
598                 PWC_ERROR("Failed to power %s camera (%d)\n",
599                           power ? "on" : "off", r);
600 }
601
602 static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
603 {
604         unsigned char buf;
605
606         /* useful range is 0x01..0x20 */
607         buf = speed / 0x7f0;
608         return send_control_msg(pdev,
609                 SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
610 }
611
612 static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
613 {
614         unsigned char buf;
615         int ret;
616
617         ret = recv_control_msg(pdev,
618                 GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
619         if (ret < 0)
620                 return ret;
621         *value = buf * 0x7f0;
622         return 0;
623 }
624
625
626 static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
627 {
628         unsigned char buf;
629
630         /* useful range is 0x01..0x3F */
631         buf = (delay >> 10);
632         return send_control_msg(pdev,
633                 SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
634 }
635
636 static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
637 {
638         unsigned char buf;
639         int ret;
640
641         ret = recv_control_msg(pdev,
642                 GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
643         if (ret < 0)
644                 return ret;
645         *value = buf << 10;
646         return 0;
647 }
648
649
650 int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
651 {
652         unsigned char buf[2];
653         int r;
654
655         if (pdev->type < 730)
656                 return 0;
657         on_value /= 100;
658         off_value /= 100;
659         if (on_value < 0)
660                 on_value = 0;
661         if (on_value > 0xff)
662                 on_value = 0xff;
663         if (off_value < 0)
664                 off_value = 0;
665         if (off_value > 0xff)
666                 off_value = 0xff;
667
668         buf[0] = on_value;
669         buf[1] = off_value;
670
671         r = send_control_msg(pdev,
672                 SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
673         if (r < 0)
674                 PWC_ERROR("Failed to set LED on/off time (%d)\n", r);
675
676         return r;
677 }
678
679 static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
680 {
681         unsigned char buf[2];
682         int ret;
683
684         if (pdev->type < 730) {
685                 *on_value = -1;
686                 *off_value = -1;
687                 return 0;
688         }
689
690         ret = recv_control_msg(pdev,
691                 GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf));
692         if (ret < 0)
693                 return ret;
694         *on_value = buf[0] * 100;
695         *off_value = buf[1] * 100;
696         return 0;
697 }
698
699 static int _pwc_mpt_reset(struct pwc_device *pdev, int flags)
700 {
701         unsigned char buf;
702
703         buf = flags & 0x03; // only lower two bits are currently used
704         return send_control_msg(pdev,
705                 SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf));
706 }
707
708 int pwc_mpt_reset(struct pwc_device *pdev, int flags)
709 {
710         int ret;
711         ret = _pwc_mpt_reset(pdev, flags);
712         if (ret >= 0) {
713                 pdev->pan_angle = 0;
714                 pdev->tilt_angle = 0;
715         }
716         return ret;
717 }
718
719 static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
720 {
721         unsigned char buf[4];
722
723         /* set new relative angle; angles are expressed in degrees * 100,
724            but cam as .5 degree resolution, hence divide by 200. Also
725            the angle must be multiplied by 64 before it's send to
726            the cam (??)
727          */
728         pan  =  64 * pan  / 100;
729         tilt = -64 * tilt / 100; /* positive tilt is down, which is not what the user would expect */
730         buf[0] = pan & 0xFF;
731         buf[1] = (pan >> 8) & 0xFF;
732         buf[2] = tilt & 0xFF;
733         buf[3] = (tilt >> 8) & 0xFF;
734         return send_control_msg(pdev,
735                 SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf));
736 }
737
738 int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
739 {
740         int ret;
741
742         /* check absolute ranges */
743         if (pan  < pdev->angle_range.pan_min  ||
744             pan  > pdev->angle_range.pan_max  ||
745             tilt < pdev->angle_range.tilt_min ||
746             tilt > pdev->angle_range.tilt_max)
747                 return -ERANGE;
748
749         /* go to relative range, check again */
750         pan  -= pdev->pan_angle;
751         tilt -= pdev->tilt_angle;
752         /* angles are specified in degrees * 100, thus the limit = 36000 */
753         if (pan < -36000 || pan > 36000 || tilt < -36000 || tilt > 36000)
754                 return -ERANGE;
755
756         ret = _pwc_mpt_set_angle(pdev, pan, tilt);
757         if (ret >= 0) {
758                 pdev->pan_angle  += pan;
759                 pdev->tilt_angle += tilt;
760         }
761         if (ret == -EPIPE) /* stall -> out of range */
762                 ret = -ERANGE;
763         return ret;
764 }
765
766 static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *status)
767 {
768         int ret;
769         unsigned char buf[5];
770
771         ret = recv_control_msg(pdev,
772                 GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf));
773         if (ret < 0)
774                 return ret;
775         status->status = buf[0] & 0x7; // 3 bits are used for reporting
776         status->time_pan = (buf[1] << 8) + buf[2];
777         status->time_tilt = (buf[3] << 8) + buf[4];
778         return 0;
779 }
780
781 #ifdef CONFIG_USB_PWC_DEBUG
782 int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
783 {
784         unsigned char buf;
785         int ret = -1, request;
786
787         if (pdev->type < 675)
788                 request = SENSOR_TYPE_FORMATTER1;
789         else if (pdev->type < 730)
790                 return -1; /* The Vesta series doesn't have this call */
791         else
792                 request = SENSOR_TYPE_FORMATTER2;
793
794         ret = recv_control_msg(pdev,
795                 GET_STATUS_CTL, request, &buf, sizeof(buf));
796         if (ret < 0)
797                 return ret;
798         if (pdev->type < 675)
799                 *sensor = buf | 0x100;
800         else
801                 *sensor = buf;
802         return 0;
803 }
804 #endif
805
806  /* End of Add-Ons                                    */
807  /* ************************************************* */
808
809 /* Linux 2.5.something and 2.6 pass direct pointers to arguments of
810    ioctl() calls. With 2.4, you have to do tedious copy_from_user()
811    and copy_to_user() calls. With these macros we circumvent this,
812    and let me maintain only one source file. The functionality is
813    exactly the same otherwise.
814  */
815
816 /* define local variable for arg */
817 #define ARG_DEF(ARG_type, ARG_name)\
818         ARG_type *ARG_name = arg;
819 /* copy arg to local variable */
820 #define ARG_IN(ARG_name) /* nothing */
821 /* argument itself (referenced) */
822 #define ARGR(ARG_name) (*ARG_name)
823 /* argument address */
824 #define ARGA(ARG_name) ARG_name
825 /* copy local variable to arg */
826 #define ARG_OUT(ARG_name) /* nothing */
827
828 /*
829  * Our ctrls use native values, but the old custom pwc ioctl interface expects
830  * values from 0 - 65535, define 2 helper functions to scale things. */
831 static int pwc_ioctl_g_ctrl(struct v4l2_ctrl *ctrl)
832 {
833         return v4l2_ctrl_g_ctrl(ctrl) * 65535 / ctrl->maximum;
834 }
835
836 static int pwc_ioctl_s_ctrl(struct v4l2_ctrl *ctrl, int val)
837 {
838         return v4l2_ctrl_s_ctrl(ctrl, val * ctrl->maximum / 65535);
839 }
840
841 long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
842 {
843         long ret = 0;
844
845         switch(cmd) {
846         case VIDIOCPWCRUSER:
847                 ret = pwc_button_ctrl(pdev, RESTORE_USER_DEFAULTS_FORMATTER);
848                 break;
849
850         case VIDIOCPWCSUSER:
851                 ret = pwc_button_ctrl(pdev, SAVE_USER_DEFAULTS_FORMATTER);
852                 break;
853
854         case VIDIOCPWCFACTORY:
855                 ret = pwc_button_ctrl(pdev, RESTORE_FACTORY_DEFAULTS_FORMATTER);
856                 break;
857
858         case VIDIOCPWCSCQUAL:
859         {
860                 ARG_DEF(int, qual)
861
862                 if (vb2_is_streaming(&pdev->vb_queue)) {
863                         ret = -EBUSY;
864                         break;
865                 }
866
867                 ARG_IN(qual)
868                 if (ARGR(qual) < 0 || ARGR(qual) > 3)
869                         ret = -EINVAL;
870                 else
871                         ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
872                 break;
873         }
874
875         case VIDIOCPWCGCQUAL:
876         {
877                 ARG_DEF(int, qual)
878
879                 ARGR(qual) = pdev->vcompression;
880                 ARG_OUT(qual)
881                 break;
882         }
883
884         case VIDIOCPWCPROBE:
885         {
886                 ARG_DEF(struct pwc_probe, probe)
887
888                 strcpy(ARGR(probe).name, pdev->vdev.name);
889                 ARGR(probe).type = pdev->type;
890                 ARG_OUT(probe)
891                 break;
892         }
893
894         case VIDIOCPWCGSERIAL:
895         {
896                 ARG_DEF(struct pwc_serial, serial)
897
898                 strcpy(ARGR(serial).serial, pdev->serial);
899                 ARG_OUT(serial)
900                 break;
901         }
902
903         case VIDIOCPWCSAGC:
904         {
905                 ARG_DEF(int, agc)
906                 ARG_IN(agc)
907                 ret = v4l2_ctrl_s_ctrl(pdev->autogain, ARGR(agc) < 0);
908                 if (ret == 0 && ARGR(agc) >= 0)
909                         ret = pwc_ioctl_s_ctrl(pdev->gain, ARGR(agc));
910                 break;
911         }
912
913         case VIDIOCPWCGAGC:
914         {
915                 ARG_DEF(int, agc)
916                 if (v4l2_ctrl_g_ctrl(pdev->autogain))
917                         ARGR(agc) = -1;
918                 else
919                         ARGR(agc) = pwc_ioctl_g_ctrl(pdev->gain);
920                 ARG_OUT(agc)
921                 break;
922         }
923
924         case VIDIOCPWCSSHUTTER:
925         {
926                 ARG_DEF(int, shutter)
927                 ARG_IN(shutter)
928                 ret = v4l2_ctrl_s_ctrl(pdev->exposure_auto,
929                                        /* Menu idx 0 = auto, idx 1 = manual */
930                                        ARGR(shutter) >= 0);
931                 if (ret == 0 && ARGR(shutter) >= 0)
932                         ret = pwc_ioctl_s_ctrl(pdev->exposure, ARGR(shutter));
933                 break;
934         }
935
936         case VIDIOCPWCSAWB:
937         {
938                 ARG_DEF(struct pwc_whitebalance, wb)
939                 ARG_IN(wb)
940                 ret = v4l2_ctrl_s_ctrl(pdev->auto_white_balance,
941                                        ARGR(wb).mode);
942                 if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
943                         ret = pwc_ioctl_s_ctrl(pdev->red_balance,
944                                                ARGR(wb).manual_red);
945                 if (ret == 0 && ARGR(wb).mode == PWC_WB_MANUAL)
946                         ret = pwc_ioctl_s_ctrl(pdev->blue_balance,
947                                                ARGR(wb).manual_blue);
948                 break;
949         }
950
951         case VIDIOCPWCGAWB:
952         {
953                 ARG_DEF(struct pwc_whitebalance, wb)
954                 ARGR(wb).mode = v4l2_ctrl_g_ctrl(pdev->auto_white_balance);
955                 ARGR(wb).manual_red = ARGR(wb).read_red =
956                         pwc_ioctl_g_ctrl(pdev->red_balance);
957                 ARGR(wb).manual_blue = ARGR(wb).read_blue =
958                         pwc_ioctl_g_ctrl(pdev->blue_balance);
959                 ARG_OUT(wb)
960                 break;
961         }
962
963         case VIDIOCPWCSAWBSPEED:
964         {
965                 ARG_DEF(struct pwc_wb_speed, wbs)
966
967                 if (ARGR(wbs).control_speed > 0) {
968                         ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
969                 }
970                 if (ARGR(wbs).control_delay > 0) {
971                         ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
972                 }
973                 break;
974         }
975
976         case VIDIOCPWCGAWBSPEED:
977         {
978                 ARG_DEF(struct pwc_wb_speed, wbs)
979
980                 ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
981                 if (ret < 0)
982                         break;
983                 ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
984                 if (ret < 0)
985                         break;
986                 ARG_OUT(wbs)
987                 break;
988         }
989
990         case VIDIOCPWCSLED:
991         {
992                 ARG_DEF(struct pwc_leds, leds)
993
994                 ARG_IN(leds)
995                 ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
996                 break;
997         }
998
999
1000         case VIDIOCPWCGLED:
1001         {
1002                 ARG_DEF(struct pwc_leds, leds)
1003
1004                 ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off);
1005                 ARG_OUT(leds)
1006                 break;
1007         }
1008
1009         case VIDIOCPWCSCONTOUR:
1010         {
1011                 ARG_DEF(int, contour)
1012                 ARG_IN(contour)
1013                 ret = v4l2_ctrl_s_ctrl(pdev->autocontour, ARGR(contour) < 0);
1014                 if (ret == 0 && ARGR(contour) >= 0)
1015                         ret = pwc_ioctl_s_ctrl(pdev->contour, ARGR(contour));
1016                 break;
1017         }
1018
1019         case VIDIOCPWCGCONTOUR:
1020         {
1021                 ARG_DEF(int, contour)
1022                 if (v4l2_ctrl_g_ctrl(pdev->autocontour))
1023                         ARGR(contour) = -1;
1024                 else
1025                         ARGR(contour) = pwc_ioctl_g_ctrl(pdev->contour);
1026                 ARG_OUT(contour)
1027                 break;
1028         }
1029
1030         case VIDIOCPWCSBACKLIGHT:
1031         {
1032                 ARG_DEF(int, backlight)
1033                 ARG_IN(backlight)
1034                 ret = v4l2_ctrl_s_ctrl(pdev->backlight, ARGR(backlight));
1035                 break;
1036         }
1037
1038         case VIDIOCPWCGBACKLIGHT:
1039         {
1040                 ARG_DEF(int, backlight)
1041                 ARGR(backlight) = v4l2_ctrl_g_ctrl(pdev->backlight);
1042                 ARG_OUT(backlight)
1043                 break;
1044         }
1045
1046         case VIDIOCPWCSFLICKER:
1047         {
1048                 ARG_DEF(int, flicker)
1049                 ARG_IN(flicker)
1050                 ret = v4l2_ctrl_s_ctrl(pdev->flicker, ARGR(flicker));
1051                 break;
1052         }
1053
1054         case VIDIOCPWCGFLICKER:
1055         {
1056                 ARG_DEF(int, flicker)
1057                 ARGR(flicker) = v4l2_ctrl_g_ctrl(pdev->flicker);
1058                 ARG_OUT(flicker)
1059                 break;
1060         }
1061
1062         case VIDIOCPWCSDYNNOISE:
1063         {
1064                 ARG_DEF(int, dynnoise)
1065                 ARG_IN(dynnoise)
1066                 ret = v4l2_ctrl_s_ctrl(pdev->noise_reduction, ARGR(dynnoise));
1067                 break;
1068         }
1069
1070         case VIDIOCPWCGDYNNOISE:
1071         {
1072                 ARG_DEF(int, dynnoise)
1073                 ARGR(dynnoise) = v4l2_ctrl_g_ctrl(pdev->noise_reduction);
1074                 ARG_OUT(dynnoise);
1075                 break;
1076         }
1077
1078         case VIDIOCPWCGREALSIZE:
1079         {
1080                 ARG_DEF(struct pwc_imagesize, size)
1081
1082                 ARGR(size).width = pdev->image.x;
1083                 ARGR(size).height = pdev->image.y;
1084                 ARG_OUT(size)
1085                 break;
1086         }
1087
1088         case VIDIOCPWCMPTRESET:
1089         {
1090                 if (pdev->features & FEATURE_MOTOR_PANTILT)
1091                 {
1092                         ARG_DEF(int, flags)
1093
1094                         ARG_IN(flags)
1095                         ret = pwc_mpt_reset(pdev, ARGR(flags));
1096                 }
1097                 else
1098                 {
1099                         ret = -ENXIO;
1100                 }
1101                 break;
1102         }
1103
1104         case VIDIOCPWCMPTGRANGE:
1105         {
1106                 if (pdev->features & FEATURE_MOTOR_PANTILT)
1107                 {
1108                         ARG_DEF(struct pwc_mpt_range, range)
1109
1110                         ARGR(range) = pdev->angle_range;
1111                         ARG_OUT(range)
1112                 }
1113                 else
1114                 {
1115                         ret = -ENXIO;
1116                 }
1117                 break;
1118         }
1119
1120         case VIDIOCPWCMPTSANGLE:
1121         {
1122                 int new_pan, new_tilt;
1123
1124                 if (pdev->features & FEATURE_MOTOR_PANTILT)
1125                 {
1126                         ARG_DEF(struct pwc_mpt_angles, angles)
1127
1128                         ARG_IN(angles)
1129                         /* The camera can only set relative angles, so
1130                            do some calculations when getting an absolute angle .
1131                          */
1132                         if (ARGR(angles).absolute)
1133                         {
1134                                 new_pan  = ARGR(angles).pan;
1135                                 new_tilt = ARGR(angles).tilt;
1136                         }
1137                         else
1138                         {
1139                                 new_pan  = pdev->pan_angle  + ARGR(angles).pan;
1140                                 new_tilt = pdev->tilt_angle + ARGR(angles).tilt;
1141                         }
1142                         ret = pwc_mpt_set_angle(pdev, new_pan, new_tilt);
1143                 }
1144                 else
1145                 {
1146                         ret = -ENXIO;
1147                 }
1148                 break;
1149         }
1150
1151         case VIDIOCPWCMPTGANGLE:
1152         {
1153
1154                 if (pdev->features & FEATURE_MOTOR_PANTILT)
1155                 {
1156                         ARG_DEF(struct pwc_mpt_angles, angles)
1157
1158                         ARGR(angles).absolute = 1;
1159                         ARGR(angles).pan  = pdev->pan_angle;
1160                         ARGR(angles).tilt = pdev->tilt_angle;
1161                         ARG_OUT(angles)
1162                 }
1163                 else
1164                 {
1165                         ret = -ENXIO;
1166                 }
1167                 break;
1168         }
1169
1170         case VIDIOCPWCMPTSTATUS:
1171         {
1172                 if (pdev->features & FEATURE_MOTOR_PANTILT)
1173                 {
1174                         ARG_DEF(struct pwc_mpt_status, status)
1175
1176                         ret = pwc_mpt_get_status(pdev, ARGA(status));
1177                         ARG_OUT(status)
1178                 }
1179                 else
1180                 {
1181                         ret = -ENXIO;
1182                 }
1183                 break;
1184         }
1185
1186         case VIDIOCPWCGVIDCMD:
1187         {
1188                 ARG_DEF(struct pwc_video_command, vcmd);
1189
1190                 ARGR(vcmd).type = pdev->type;
1191                 ARGR(vcmd).release = pdev->release;
1192                 ARGR(vcmd).command_len = pdev->cmd_len;
1193                 memcpy(&ARGR(vcmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
1194                 ARGR(vcmd).bandlength = pdev->vbandlength;
1195                 ARGR(vcmd).frame_size = pdev->frame_size;
1196                 ARG_OUT(vcmd)
1197                 break;
1198         }
1199         /*
1200         case VIDIOCPWCGVIDTABLE:
1201         {
1202                 ARG_DEF(struct pwc_table_init_buffer, table);
1203                 ARGR(table).len = pdev->cmd_len;
1204                 memcpy(&ARGR(table).buffer, pdev->decompress_data, pdev->decompressor->table_size);
1205                 ARG_OUT(table)
1206                 break;
1207         }
1208         */
1209
1210         default:
1211                 ret = -ENOIOCTLCMD;
1212                 break;
1213         }
1214
1215         if (ret > 0)
1216                 return 0;
1217         return ret;
1218 }
1219
1220
1221 /* vim: set cinoptions= formatoptions=croql cindent shiftwidth=8 tabstop=8: */