]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/mr97310a.c
Merge branch 'x86-setup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-omap-h63xx.git] / drivers / media / video / gspca / mr97310a.c
1 /*
2  * Mars MR97310A library
3  *
4  * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20
21 #define MODULE_NAME "mr97310a"
22
23 #include "gspca.h"
24
25 MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
26 MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
27 MODULE_LICENSE("GPL");
28
29 /* specific webcam descriptor */
30 struct sd {
31         struct gspca_dev gspca_dev;  /* !! must be the first item */
32         u8 sof_read;
33 };
34
35 /* V4L2 controls supported by the driver */
36 static struct ctrl sd_ctrls[] = {
37 };
38
39 static const struct v4l2_pix_format vga_mode[] = {
40         {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
41                 .bytesperline = 160,
42                 .sizeimage = 160 * 120,
43                 .colorspace = V4L2_COLORSPACE_SRGB,
44                 .priv = 4},
45         {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
46                 .bytesperline = 176,
47                 .sizeimage = 176 * 144,
48                 .colorspace = V4L2_COLORSPACE_SRGB,
49                 .priv = 3},
50         {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
51                 .bytesperline = 320,
52                 .sizeimage = 320 * 240,
53                 .colorspace = V4L2_COLORSPACE_SRGB,
54                 .priv = 2},
55         {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
56                 .bytesperline = 352,
57                 .sizeimage = 352 * 288,
58                 .colorspace = V4L2_COLORSPACE_SRGB,
59                 .priv = 1},
60         {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
61                 .bytesperline = 640,
62                 .sizeimage = 640 * 480,
63                 .colorspace = V4L2_COLORSPACE_SRGB,
64                 .priv = 0},
65 };
66
67 /* the bytes to write are in gspca_dev->usb_buf */
68 static int reg_w(struct gspca_dev *gspca_dev, int len)
69 {
70         int rc;
71
72         rc = usb_bulk_msg(gspca_dev->dev,
73                           usb_sndbulkpipe(gspca_dev->dev, 4),
74                           gspca_dev->usb_buf, len, NULL, 500);
75         if (rc < 0)
76                 PDEBUG(D_ERR, "reg write [%02x] error %d",
77                        gspca_dev->usb_buf[0], rc);
78         return rc;
79 }
80
81 /* this function is called at probe time */
82 static int sd_config(struct gspca_dev *gspca_dev,
83                      const struct usb_device_id *id)
84 {
85         struct cam *cam;
86
87         cam = &gspca_dev->cam;
88         cam->cam_mode = vga_mode;
89         cam->nmodes = ARRAY_SIZE(vga_mode);
90         return 0;
91 }
92
93 /* this function is called at probe and resume time */
94 static int sd_init(struct gspca_dev *gspca_dev)
95 {
96         return 0;
97 }
98
99 static int sd_start(struct gspca_dev *gspca_dev)
100 {
101         struct sd *sd = (struct sd *) gspca_dev;
102         __u8 *data = gspca_dev->usb_buf;
103         int err_code;
104
105         sd->sof_read = 0;
106
107         /* Note:  register descriptions guessed from MR97113A driver */
108
109         data[0] = 0x01;
110         data[1] = 0x01;
111         err_code = reg_w(gspca_dev, 2);
112         if (err_code < 0)
113                 return err_code;
114
115         data[0] = 0x00;
116         data[1] = 0x0d;
117         data[2] = 0x01;
118         data[5] = 0x2b;
119         data[7] = 0x00;
120         data[9] = 0x50;  /* reg 8, no scale down */
121         data[10] = 0xc0;
122
123         switch (gspca_dev->width) {
124         case 160:
125                 data[9] |= 0x0c;  /* reg 8, 4:1 scale down */
126                 /* fall thru */
127         case 320:
128                 data[9] |= 0x04;  /* reg 8, 2:1 scale down */
129                 /* fall thru */
130         case 640:
131         default:
132                 data[3] = 0x50;  /* reg 2, H size */
133                 data[4] = 0x78;  /* reg 3, V size */
134                 data[6] = 0x04;  /* reg 5, H start */
135                 data[8] = 0x03;  /* reg 7, V start */
136                 break;
137
138         case 176:
139                 data[9] |= 0x04;  /* reg 8, 2:1 scale down */
140                 /* fall thru */
141         case 352:
142                 data[3] = 0x2c;  /* reg 2, H size */
143                 data[4] = 0x48;  /* reg 3, V size */
144                 data[6] = 0x94;  /* reg 5, H start */
145                 data[8] = 0x63;  /* reg 7, V start */
146                 break;
147         }
148
149         err_code = reg_w(gspca_dev, 11);
150         if (err_code < 0)
151                 return err_code;
152
153         data[0] = 0x0a;
154         data[1] = 0x80;
155         err_code = reg_w(gspca_dev, 2);
156         if (err_code < 0)
157                 return err_code;
158
159         data[0] = 0x14;
160         data[1] = 0x0a;
161         err_code = reg_w(gspca_dev, 2);
162         if (err_code < 0)
163                 return err_code;
164
165         data[0] = 0x1b;
166         data[1] = 0x00;
167         err_code = reg_w(gspca_dev, 2);
168         if (err_code < 0)
169                 return err_code;
170
171         data[0] = 0x15;
172         data[1] = 0x16;
173         err_code = reg_w(gspca_dev, 2);
174         if (err_code < 0)
175                 return err_code;
176
177         data[0] = 0x16;
178         data[1] = 0x10;
179         err_code = reg_w(gspca_dev, 2);
180         if (err_code < 0)
181                 return err_code;
182
183         data[0] = 0x17;
184         data[1] = 0x3a;
185         err_code = reg_w(gspca_dev, 2);
186         if (err_code < 0)
187                 return err_code;
188
189         data[0] = 0x18;
190         data[1] = 0x68;
191         err_code = reg_w(gspca_dev, 2);
192         if (err_code < 0)
193                 return err_code;
194
195         data[0] = 0x1f;
196         data[1] = 0x00;
197         data[2] = 0x02;
198         data[3] = 0x06;
199         data[4] = 0x59;
200         data[5] = 0x0c;
201         data[6] = 0x16;
202         data[7] = 0x00;
203         data[8] = 0x07;
204         data[9] = 0x00;
205         data[10] = 0x01;
206         err_code = reg_w(gspca_dev, 11);
207         if (err_code < 0)
208                 return err_code;
209
210         data[0] = 0x1f;
211         data[1] = 0x04;
212         data[2] = 0x11;
213         data[3] = 0x01;
214         err_code = reg_w(gspca_dev, 4);
215         if (err_code < 0)
216                 return err_code;
217
218         data[0] = 0x1f;
219         data[1] = 0x00;
220         data[2] = 0x0a;
221         data[3] = 0x00;
222         data[4] = 0x01;
223         data[5] = 0x00;
224         data[6] = 0x00;
225         data[7] = 0x01;
226         data[8] = 0x00;
227         data[9] = 0x0a;
228         err_code = reg_w(gspca_dev, 10);
229         if (err_code < 0)
230                 return err_code;
231
232         data[0] = 0x1f;
233         data[1] = 0x04;
234         data[2] = 0x11;
235         data[3] = 0x01;
236         err_code = reg_w(gspca_dev, 4);
237         if (err_code < 0)
238                 return err_code;
239
240         data[0] = 0x1f;
241         data[1] = 0x00;
242         data[2] = 0x12;
243         data[3] = 0x00;
244         data[4] = 0x63;
245         data[5] = 0x00;
246         data[6] = 0x70;
247         data[7] = 0x00;
248         data[8] = 0x00;
249         err_code = reg_w(gspca_dev, 9);
250         if (err_code < 0)
251                 return err_code;
252
253         data[0] = 0x1f;
254         data[1] = 0x04;
255         data[2] = 0x11;
256         data[3] = 0x01;
257         err_code = reg_w(gspca_dev, 4);
258         if (err_code < 0)
259                 return err_code;
260
261         data[0] = 0x00;
262         data[1] = 0x4d;  /* ISOC transfering enable... */
263         err_code = reg_w(gspca_dev, 2);
264         return err_code;
265 }
266
267 static void sd_stopN(struct gspca_dev *gspca_dev)
268 {
269         int result;
270
271         gspca_dev->usb_buf[0] = 1;
272         gspca_dev->usb_buf[1] = 0;
273         result = reg_w(gspca_dev, 2);
274         if (result < 0)
275                 PDEBUG(D_ERR, "Camera Stop failed");
276 }
277
278 /* Include pac common sof detection functions */
279 #include "pac_common.h"
280
281 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
282                         struct gspca_frame *frame,    /* target */
283                         __u8 *data,                   /* isoc packet */
284                         int len)                      /* iso packet length */
285 {
286         unsigned char *sof;
287
288         sof = pac_find_sof(gspca_dev, data, len);
289         if (sof) {
290                 int n;
291
292                 /* finish decoding current frame */
293                 n = sof - data;
294                 if (n > sizeof pac_sof_marker)
295                         n -= sizeof pac_sof_marker;
296                 else
297                         n = 0;
298                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
299                                         data, n);
300                 /* Start next frame. */
301                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
302                         pac_sof_marker, sizeof pac_sof_marker);
303                 len -= sof - data;
304                 data = sof;
305         }
306         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
307 }
308
309 /* sub-driver description */
310 static const struct sd_desc sd_desc = {
311         .name = MODULE_NAME,
312         .ctrls = sd_ctrls,
313         .nctrls = ARRAY_SIZE(sd_ctrls),
314         .config = sd_config,
315         .init = sd_init,
316         .start = sd_start,
317         .stopN = sd_stopN,
318         .pkt_scan = sd_pkt_scan,
319 };
320
321 /* -- module initialisation -- */
322 static const __devinitdata struct usb_device_id device_table[] = {
323         {USB_DEVICE(0x08ca, 0x0111)},
324         {}
325 };
326 MODULE_DEVICE_TABLE(usb, device_table);
327
328 /* -- device connect -- */
329 static int sd_probe(struct usb_interface *intf,
330                     const struct usb_device_id *id)
331 {
332         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
333                                THIS_MODULE);
334 }
335
336 static struct usb_driver sd_driver = {
337         .name = MODULE_NAME,
338         .id_table = device_table,
339         .probe = sd_probe,
340         .disconnect = gspca_disconnect,
341 #ifdef CONFIG_PM
342         .suspend = gspca_suspend,
343         .resume = gspca_resume,
344 #endif
345 };
346
347 /* -- module insert / remove -- */
348 static int __init sd_mod_init(void)
349 {
350         if (usb_register(&sd_driver) < 0)
351                 return -1;
352         PDEBUG(D_PROBE, "registered");
353         return 0;
354 }
355 static void __exit sd_mod_exit(void)
356 {
357         usb_deregister(&sd_driver);
358         PDEBUG(D_PROBE, "deregistered");
359 }
360
361 module_init(sd_mod_init);
362 module_exit(sd_mod_exit);