V4L/DVB (9856): gspca: Use u8 values for USB control messages in ov534.
[linux-2.6] / drivers / media / video / gspca / ov534.c
1 /*
2  * ov534/ov772x gspca driver
3  * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
4  *
5  * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
6  * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
7  * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23
24 #define MODULE_NAME "ov534"
25
26 #include "gspca.h"
27
28 #define OV534_REG_ADDRESS       0xf1    /* ? */
29 #define OV534_REG_SUBADDR       0xf2
30 #define OV534_REG_WRITE         0xf3
31 #define OV534_REG_READ          0xf4
32 #define OV534_REG_OPERATION     0xf5
33 #define OV534_REG_STATUS        0xf6
34
35 #define OV534_OP_WRITE_3        0x37
36 #define OV534_OP_WRITE_2        0x33
37 #define OV534_OP_READ_2         0xf9
38
39 #define CTRL_TIMEOUT 500
40
41 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
42 MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
43 MODULE_LICENSE("GPL");
44
45 /* global parameters */
46 static int frame_rate;
47
48 /* specific webcam descriptor */
49 struct sd {
50         struct gspca_dev gspca_dev;     /* !! must be the first item */
51 };
52
53 /* V4L2 controls supported by the driver */
54 static struct ctrl sd_ctrls[] = {
55 };
56
57 static struct v4l2_pix_format vga_mode[] = {
58         {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
59          .bytesperline = 640 * 2,
60          .sizeimage = 640 * 480 * 2,
61          .colorspace = V4L2_COLORSPACE_JPEG,
62          .priv = 0},
63 };
64
65 static void ov534_reg_write(struct usb_device *udev, u16 reg, u8 val)
66 {
67         u8 data = val;
68         int ret;
69
70         PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
71         ret = usb_control_msg(udev,
72                               usb_sndctrlpipe(udev, 0),
73                               0x1,
74                               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
75                               0x0, reg, &data, 1, CTRL_TIMEOUT);
76         if (ret < 0)
77                 PDEBUG(D_ERR, "write failed");
78 }
79
80 static u8 ov534_reg_read(struct usb_device *udev, u16 reg)
81 {
82         u8 data;
83         int ret;
84
85         ret = usb_control_msg(udev,
86                               usb_rcvctrlpipe(udev, 0),
87                               0x1,
88                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
89                               0x0, reg, &data, 1, CTRL_TIMEOUT);
90         PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, data);
91         if (ret < 0)
92                 PDEBUG(D_ERR, "read failed");
93         return data;
94 }
95
96 static void ov534_reg_verify_write(struct usb_device *udev, u16 reg, u8 val)
97 {
98         u8 data;
99
100         ov534_reg_write(udev, reg, val);
101         data = ov534_reg_read(udev, reg);
102         if (data != val) {
103                 PDEBUG(D_ERR | D_USBO,
104                        "unexpected result from read: 0x%02x != 0x%02x", val,
105                        data);
106         }
107 }
108
109 /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
110  * (direction and output)? */
111 static void ov534_set_led(struct usb_device *udev, int status)
112 {
113         u8 data;
114
115         PDEBUG(D_CONF, "led status: %d", status);
116
117         data = ov534_reg_read(udev, 0x21);
118         data |= 0x80;
119         ov534_reg_write(udev, 0x21, data);
120
121         data = ov534_reg_read(udev, 0x23);
122         if (status)
123                 data |= 0x80;
124         else
125                 data &= ~(0x80);
126
127         ov534_reg_write(udev, 0x23, data);
128 }
129
130 static int sccb_check_status(struct usb_device *udev)
131 {
132         u8 data;
133         int i;
134
135         for (i = 0; i < 5; i++) {
136                 data = ov534_reg_read(udev, OV534_REG_STATUS);
137
138                 switch (data) {
139                 case 0x00:
140                         return 1;
141                 case 0x04:
142                         return 0;
143                 case 0x03:
144                         break;
145                 default:
146                         PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5\n",
147                                data, i + 1);
148                 }
149         }
150         return 0;
151 }
152
153 static void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val)
154 {
155         PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
156         ov534_reg_write(udev, OV534_REG_SUBADDR, reg);
157         ov534_reg_write(udev, OV534_REG_WRITE, val);
158         ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
159
160         if (!sccb_check_status(udev))
161                 PDEBUG(D_ERR, "sccb_reg_write failed");
162 }
163
164 /* setup method */
165 static void ov534_setup(struct usb_device *udev)
166 {
167         ov534_reg_verify_write(udev, 0xe7, 0x3a);
168
169         ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60);
170         ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60);
171         ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60);
172         ov534_reg_write(udev, OV534_REG_ADDRESS, 0x42);
173
174         ov534_reg_verify_write(udev, 0xc2, 0x0c);
175         ov534_reg_verify_write(udev, 0x88, 0xf8);
176         ov534_reg_verify_write(udev, 0xc3, 0x69);
177         ov534_reg_verify_write(udev, 0x89, 0xff);
178         ov534_reg_verify_write(udev, 0x76, 0x03);
179         ov534_reg_verify_write(udev, 0x92, 0x01);
180         ov534_reg_verify_write(udev, 0x93, 0x18);
181         ov534_reg_verify_write(udev, 0x94, 0x10);
182         ov534_reg_verify_write(udev, 0x95, 0x10);
183         ov534_reg_verify_write(udev, 0xe2, 0x00);
184         ov534_reg_verify_write(udev, 0xe7, 0x3e);
185
186         ov534_reg_write(udev, 0x1c, 0x0a);
187         ov534_reg_write(udev, 0x1d, 0x22);
188         ov534_reg_write(udev, 0x1d, 0x06);
189
190         ov534_reg_verify_write(udev, 0x96, 0x00);
191
192         ov534_reg_write(udev, 0x97, 0x20);
193         ov534_reg_write(udev, 0x97, 0x20);
194         ov534_reg_write(udev, 0x97, 0x20);
195         ov534_reg_write(udev, 0x97, 0x0a);
196         ov534_reg_write(udev, 0x97, 0x3f);
197         ov534_reg_write(udev, 0x97, 0x4a);
198         ov534_reg_write(udev, 0x97, 0x20);
199         ov534_reg_write(udev, 0x97, 0x15);
200         ov534_reg_write(udev, 0x97, 0x0b);
201
202         ov534_reg_verify_write(udev, 0x8e, 0x40);
203         ov534_reg_verify_write(udev, 0x1f, 0x81);
204         ov534_reg_verify_write(udev, 0x34, 0x05);
205         ov534_reg_verify_write(udev, 0xe3, 0x04);
206         ov534_reg_verify_write(udev, 0x88, 0x00);
207         ov534_reg_verify_write(udev, 0x89, 0x00);
208         ov534_reg_verify_write(udev, 0x76, 0x00);
209         ov534_reg_verify_write(udev, 0xe7, 0x2e);
210         ov534_reg_verify_write(udev, 0x31, 0xf9);
211         ov534_reg_verify_write(udev, 0x25, 0x42);
212         ov534_reg_verify_write(udev, 0x21, 0xf0);
213
214         ov534_reg_write(udev, 0x1c, 0x00);
215         ov534_reg_write(udev, 0x1d, 0x40);
216         ov534_reg_write(udev, 0x1d, 0x02);
217         ov534_reg_write(udev, 0x1d, 0x00);
218         ov534_reg_write(udev, 0x1d, 0x02);
219         ov534_reg_write(udev, 0x1d, 0x57);
220         ov534_reg_write(udev, 0x1d, 0xff);
221
222         ov534_reg_verify_write(udev, 0x8d, 0x1c);
223         ov534_reg_verify_write(udev, 0x8e, 0x80);
224         ov534_reg_verify_write(udev, 0xe5, 0x04);
225
226         ov534_set_led(udev, 1);
227
228         sccb_reg_write(udev, 0x12, 0x80);
229         sccb_reg_write(udev, 0x11, 0x01);
230         sccb_reg_write(udev, 0x11, 0x01);
231         sccb_reg_write(udev, 0x11, 0x01);
232         sccb_reg_write(udev, 0x11, 0x01);
233         sccb_reg_write(udev, 0x11, 0x01);
234         sccb_reg_write(udev, 0x11, 0x01);
235         sccb_reg_write(udev, 0x11, 0x01);
236         sccb_reg_write(udev, 0x11, 0x01);
237         sccb_reg_write(udev, 0x11, 0x01);
238         sccb_reg_write(udev, 0x11, 0x01);
239         sccb_reg_write(udev, 0x11, 0x01);
240
241         ov534_set_led(udev, 0);
242
243         sccb_reg_write(udev, 0x3d, 0x03);
244         sccb_reg_write(udev, 0x17, 0x26);
245         sccb_reg_write(udev, 0x18, 0xa0);
246         sccb_reg_write(udev, 0x19, 0x07);
247         sccb_reg_write(udev, 0x1a, 0xf0);
248         sccb_reg_write(udev, 0x32, 0x00);
249         sccb_reg_write(udev, 0x29, 0xa0);
250         sccb_reg_write(udev, 0x2c, 0xf0);
251         sccb_reg_write(udev, 0x65, 0x20);
252         sccb_reg_write(udev, 0x11, 0x01);
253         sccb_reg_write(udev, 0x42, 0x7f);
254         sccb_reg_write(udev, 0x63, 0xe0);
255         sccb_reg_write(udev, 0x64, 0xff);
256         sccb_reg_write(udev, 0x66, 0x00);
257         sccb_reg_write(udev, 0x13, 0xf0);
258         sccb_reg_write(udev, 0x0d, 0x41);
259         sccb_reg_write(udev, 0x0f, 0xc5);
260         sccb_reg_write(udev, 0x14, 0x11);
261
262         ov534_set_led(udev, 1);
263
264         sccb_reg_write(udev, 0x22, 0x7f);
265         sccb_reg_write(udev, 0x23, 0x03);
266         sccb_reg_write(udev, 0x24, 0x40);
267         sccb_reg_write(udev, 0x25, 0x30);
268         sccb_reg_write(udev, 0x26, 0xa1);
269         sccb_reg_write(udev, 0x2a, 0x00);
270         sccb_reg_write(udev, 0x2b, 0x00);
271         sccb_reg_write(udev, 0x6b, 0xaa);
272         sccb_reg_write(udev, 0x13, 0xff);
273
274         ov534_set_led(udev, 0);
275
276         sccb_reg_write(udev, 0x90, 0x05);
277         sccb_reg_write(udev, 0x91, 0x01);
278         sccb_reg_write(udev, 0x92, 0x03);
279         sccb_reg_write(udev, 0x93, 0x00);
280         sccb_reg_write(udev, 0x94, 0x60);
281         sccb_reg_write(udev, 0x95, 0x3c);
282         sccb_reg_write(udev, 0x96, 0x24);
283         sccb_reg_write(udev, 0x97, 0x1e);
284         sccb_reg_write(udev, 0x98, 0x62);
285         sccb_reg_write(udev, 0x99, 0x80);
286         sccb_reg_write(udev, 0x9a, 0x1e);
287         sccb_reg_write(udev, 0x9b, 0x08);
288         sccb_reg_write(udev, 0x9c, 0x20);
289         sccb_reg_write(udev, 0x9e, 0x81);
290
291         ov534_set_led(udev, 1);
292
293         sccb_reg_write(udev, 0xa6, 0x04);
294         sccb_reg_write(udev, 0x7e, 0x0c);
295         sccb_reg_write(udev, 0x7f, 0x16);
296         sccb_reg_write(udev, 0x80, 0x2a);
297         sccb_reg_write(udev, 0x81, 0x4e);
298         sccb_reg_write(udev, 0x82, 0x61);
299         sccb_reg_write(udev, 0x83, 0x6f);
300         sccb_reg_write(udev, 0x84, 0x7b);
301         sccb_reg_write(udev, 0x85, 0x86);
302         sccb_reg_write(udev, 0x86, 0x8e);
303         sccb_reg_write(udev, 0x87, 0x97);
304         sccb_reg_write(udev, 0x88, 0xa4);
305         sccb_reg_write(udev, 0x89, 0xaf);
306         sccb_reg_write(udev, 0x8a, 0xc5);
307         sccb_reg_write(udev, 0x8b, 0xd7);
308         sccb_reg_write(udev, 0x8c, 0xe8);
309         sccb_reg_write(udev, 0x8d, 0x20);
310
311         sccb_reg_write(udev, 0x0c, 0x90);
312
313         ov534_reg_verify_write(udev, 0xc0, 0x50);
314         ov534_reg_verify_write(udev, 0xc1, 0x3c);
315         ov534_reg_verify_write(udev, 0xc2, 0x0c);
316
317         ov534_set_led(udev, 1);
318
319         sccb_reg_write(udev, 0x2b, 0x00);
320         sccb_reg_write(udev, 0x22, 0x7f);
321         sccb_reg_write(udev, 0x23, 0x03);
322         sccb_reg_write(udev, 0x11, 0x01);
323         sccb_reg_write(udev, 0x0c, 0xd0);
324         sccb_reg_write(udev, 0x64, 0xff);
325         sccb_reg_write(udev, 0x0d, 0x41);
326
327         sccb_reg_write(udev, 0x14, 0x41);
328         sccb_reg_write(udev, 0x0e, 0xcd);
329         sccb_reg_write(udev, 0xac, 0xbf);
330         sccb_reg_write(udev, 0x8e, 0x00);
331         sccb_reg_write(udev, 0x0c, 0xd0);
332
333         ov534_reg_write(udev, 0xe0, 0x09);
334         ov534_set_led(udev, 0);
335 }
336
337 /* this function is called at probe time */
338 static int sd_config(struct gspca_dev *gspca_dev,
339                      const struct usb_device_id *id)
340 {
341         struct cam *cam;
342
343         cam = &gspca_dev->cam;
344
345         cam->epaddr = 0x01;
346         cam->cam_mode = vga_mode;
347         cam->nmodes = ARRAY_SIZE(vga_mode);
348
349         cam->bulk_size = vga_mode[0].sizeimage;
350         cam->bulk_nurbs = 2;
351
352         PDEBUG(D_PROBE, "bulk_size = %d", cam->bulk_size);
353
354         return 0;
355 }
356
357 /* this function is called at probe and resume time */
358 static int sd_init(struct gspca_dev *gspca_dev)
359 {
360         int fr;
361
362         ov534_setup(gspca_dev->dev);
363
364         fr = frame_rate;
365
366         switch (fr) {
367         case 50:
368                 sccb_reg_write(gspca_dev->dev, 0x11, 0x01);
369                 sccb_reg_write(gspca_dev->dev, 0x0d, 0x41);
370                 ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02);
371                 break;
372         case 40:
373                 sccb_reg_write(gspca_dev->dev, 0x11, 0x02);
374                 sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1);
375                 ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04);
376                 break;
377 /*      case 30: */
378         default:
379                 fr = 30;
380                 sccb_reg_write(gspca_dev->dev, 0x11, 0x04);
381                 sccb_reg_write(gspca_dev->dev, 0x0d, 0x81);
382                 ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02);
383                 break;
384         case 15:
385                 sccb_reg_write(gspca_dev->dev, 0x11, 0x03);
386                 sccb_reg_write(gspca_dev->dev, 0x0d, 0x41);
387                 ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04);
388                 break;
389         }
390
391         PDEBUG(D_PROBE, "frame_rate: %d", fr);
392
393         return 0;
394 }
395
396 static int sd_start(struct gspca_dev *gspca_dev)
397 {
398         PDEBUG(D_PROBE, "width = %d, height = %d",
399                gspca_dev->width, gspca_dev->height);
400
401         gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height * 2;
402
403         /* start streaming data */
404         ov534_set_led(gspca_dev->dev, 1);
405         ov534_reg_write(gspca_dev->dev, 0xe0, 0x00);
406
407         return 0;
408 }
409
410 static void sd_stopN(struct gspca_dev *gspca_dev)
411 {
412         /* stop streaming data */
413         ov534_reg_write(gspca_dev->dev, 0xe0, 0x09);
414         ov534_set_led(gspca_dev->dev, 0);
415 }
416
417 static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
418                         __u8 *data, int len)
419 {
420         /*
421          * The current camera setup doesn't stream the last pixel, so we set it
422          * to a dummy value
423          */
424         __u8 last_pixel[4] = { 0, 0, 0, 0 };
425         int framesize = gspca_dev->cam.bulk_size;
426
427         if (len == framesize - 4) {
428                 frame =
429                     gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
430                 frame =
431                     gspca_frame_add(gspca_dev, LAST_PACKET, frame, last_pixel,
432                                     4);
433         } else
434                 PDEBUG(D_PACK, "packet len = %d, framesize = %d", len,
435                        framesize);
436 }
437
438 /* sub-driver description */
439 static const struct sd_desc sd_desc = {
440         .name     = MODULE_NAME,
441         .ctrls    = sd_ctrls,
442         .nctrls   = ARRAY_SIZE(sd_ctrls),
443         .config   = sd_config,
444         .init     = sd_init,
445         .start    = sd_start,
446         .stopN    = sd_stopN,
447         .pkt_scan = sd_pkt_scan,
448 };
449
450 /* -- module initialisation -- */
451 static const __devinitdata struct usb_device_id device_table[] = {
452         {USB_DEVICE(0x06f8, 0x3002)},   /* Hercules Blog Webcam */
453         {USB_DEVICE(0x06f8, 0x3003)},   /* Hercules Dualpix HD Weblog */
454         {USB_DEVICE(0x1415, 0x2000)},   /* Sony HD Eye for PS3 (SLEH 00201) */
455         {}
456 };
457
458 MODULE_DEVICE_TABLE(usb, device_table);
459
460 /* -- device connect -- */
461 static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
462 {
463         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
464                                THIS_MODULE);
465 }
466
467 static struct usb_driver sd_driver = {
468         .name       = MODULE_NAME,
469         .id_table   = device_table,
470         .probe      = sd_probe,
471         .disconnect = gspca_disconnect,
472 #ifdef CONFIG_PM
473         .suspend    = gspca_suspend,
474         .resume     = gspca_resume,
475 #endif
476 };
477
478 /* -- module insert / remove -- */
479 static int __init sd_mod_init(void)
480 {
481         if (usb_register(&sd_driver) < 0)
482                 return -1;
483         PDEBUG(D_PROBE, "registered");
484         return 0;
485 }
486
487 static void __exit sd_mod_exit(void)
488 {
489         usb_deregister(&sd_driver);
490         PDEBUG(D_PROBE, "deregistered");
491 }
492
493 module_init(sd_mod_init);
494 module_exit(sd_mod_exit);
495
496 module_param(frame_rate, int, 0644);
497 MODULE_PARM_DESC(frame_rate, "Frame rate (15, 30, 40, 50)");