Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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         {USB_DEVICE(0x093a, 0x010f)},
325         {}
326 };
327 MODULE_DEVICE_TABLE(usb, device_table);
328 
329 /* -- device connect -- */
330 static int sd_probe(struct usb_interface *intf,
331                     const struct usb_device_id *id)
332 {
333         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
334                                THIS_MODULE);
335 }
336 
337 static struct usb_driver sd_driver = {
338         .name = MODULE_NAME,
339         .id_table = device_table,
340         .probe = sd_probe,
341         .disconnect = gspca_disconnect,
342 #ifdef CONFIG_PM
343         .suspend = gspca_suspend,
344         .resume = gspca_resume,
345 #endif
346 };
347 
348 /* -- module insert / remove -- */
349 static int __init sd_mod_init(void)
350 {
351         int ret;
352 
353         ret = usb_register(&sd_driver);
354         if (ret < 0)
355                 return ret;
356         PDEBUG(D_PROBE, "registered");
357         return 0;
358 }
359 static void __exit sd_mod_exit(void)
360 {
361         usb_deregister(&sd_driver);
362         PDEBUG(D_PROBE, "deregistered");
363 }
364 
365 module_init(sd_mod_init);
366 module_exit(sd_mod_exit);
367 
  This page was automatically generated by the LXR engine.