Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/media/usb/gspca/pac7302.c

  1 /*
  2  * Pixart PAC7302 driver
  3  *
  4  * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
  5  * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
  6  *
  7  * Separated from Pixart PAC7311 library by Márton Németh
  8  * Camera button input handling by Márton Németh <nm127@freemail.hu>
  9  * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
 10  *
 11  * This program is free software; you can redistribute it and/or modify
 12  * it under the terms of the GNU General Public License as published by
 13  * the Free Software Foundation; either version 2 of the License, or
 14  * any later version.
 15  *
 16  * This program is distributed in the hope that it will be useful,
 17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 19  * GNU General Public License for more details.
 20  *
 21  * You should have received a copy of the GNU General Public License
 22  * along with this program; if not, write to the Free Software
 23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 24  */
 25 
 26 /*
 27  * Some documentation about various registers as determined by trial and error.
 28  *
 29  * Register page 0:
 30  *
 31  * Address      Description
 32  * 0x01         Red balance control
 33  * 0x02         Green balance control
 34  * 0x03         Blue balance control
 35  *                   The Windows driver uses a quadratic approach to map
 36  *                   the settable values (0-200) on register values:
 37  *                   min=0x20, default=0x40, max=0x80
 38  * 0x0f-0x20    Color and saturation control
 39  * 0xa2-0xab    Brightness, contrast and gamma control
 40  * 0xb6         Sharpness control (bits 0-4)
 41  *
 42  * Register page 1:
 43  *
 44  * Address      Description
 45  * 0x78         Global control, bit 6 controls the LED (inverted)
 46  * 0x80         Compression balance, 2 interesting settings:
 47  *              0x0f Default
 48  *              0x50 Values >= this switch the camera to a lower compression,
 49  *                   using the same table for both luminance and chrominance.
 50  *                   This gives a sharper picture. Only usable when running
 51  *                   at < 15 fps! Note currently the driver does not use this
 52  *                   as the quality gain is small and the generated JPG-s are
 53  *                   only understood by v4l-utils >= 0.8.9
 54  *
 55  * Register page 3:
 56  *
 57  * Address      Description
 58  * 0x02         Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
 59  *              the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
 60  * 0x03         Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
 61  * 0x04         Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
 62  *              63 -> ~27 fps, the 2 msb's must always be 1 !!
 63  * 0x05         Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
 64  *              1 -> ~30 fps, 2 -> ~20 fps
 65  * 0x0e         Exposure bits 0-7, 0-448, 0 = use full frame time
 66  * 0x0f         Exposure bit 8, 0-448, 448 = no exposure at all
 67  * 0x10         Gain 0-31
 68  * 0x12         Another gain 0-31, unlike 0x10 this one seems to start with an
 69  *              amplification value of 1 rather then 0 at its lowest setting
 70  * 0x21         Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
 71  * 0x80         Another framerate control, best left at 1, moving it from 1 to
 72  *              2 causes the framerate to become 3/4th of what it was, and
 73  *              also seems to cause pixel averaging, resulting in an effective
 74  *              resolution of 320x240 and thus a much blockier image
 75  *
 76  * The registers are accessed in the following functions:
 77  *
 78  * Page | Register   | Function
 79  * -----+------------+---------------------------------------------------
 80  *  0   | 0x01       | setredbalance()
 81  *  0   | 0x03       | setbluebalance()
 82  *  0   | 0x0f..0x20 | setcolors()
 83  *  0   | 0xa2..0xab | setbrightcont()
 84  *  0   | 0xb6       | setsharpness()
 85  *  0   | 0xc6       | setwhitebalance()
 86  *  0   | 0xdc       | setbrightcont(), setcolors()
 87  *  3   | 0x02       | setexposure()
 88  *  3   | 0x10, 0x12 | setgain()
 89  *  3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
 90  *  3   | 0x21       | sethvflip()
 91  */
 92 
 93 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 94 
 95 #include <linux/input.h>
 96 #include "gspca.h"
 97 /* Include pac common sof detection functions */
 98 #include "pac_common.h"
 99 
100 #define PAC7302_RGB_BALANCE_MIN           0
101 #define PAC7302_RGB_BALANCE_MAX         200
102 #define PAC7302_RGB_BALANCE_DEFAULT     100
103 #define PAC7302_GAIN_DEFAULT             15
104 #define PAC7302_GAIN_KNEE                42
105 #define PAC7302_EXPOSURE_DEFAULT         66 /* 33 ms / 30 fps */
106 #define PAC7302_EXPOSURE_KNEE           133 /* 66 ms / 15 fps */
107 
108 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
109                 "Thomas Kaiser thomas@kaiser-linux.li");
110 MODULE_DESCRIPTION("Pixart PAC7302");
111 MODULE_LICENSE("GPL");
112 
113 struct sd {
114         struct gspca_dev gspca_dev;             /* !! must be the first item */
115 
116         struct { /* brightness / contrast cluster */
117                 struct v4l2_ctrl *brightness;
118                 struct v4l2_ctrl *contrast;
119         };
120         struct v4l2_ctrl *saturation;
121         struct v4l2_ctrl *white_balance;
122         struct v4l2_ctrl *red_balance;
123         struct v4l2_ctrl *blue_balance;
124         struct { /* flip cluster */
125                 struct v4l2_ctrl *hflip;
126                 struct v4l2_ctrl *vflip;
127         };
128         struct v4l2_ctrl *sharpness;
129         u8 flags;
130 #define FL_HFLIP 0x01           /* mirrored by default */
131 #define FL_VFLIP 0x02           /* vertical flipped by default */
132 
133         u8 sof_read;
134         s8 autogain_ignore_frames;
135 
136         atomic_t avg_lum;
137 };
138 
139 static const struct v4l2_pix_format vga_mode[] = {
140         {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
141                 .bytesperline = 640,
142                 .sizeimage = 640 * 480 * 3 / 8 + 590,
143                 .colorspace = V4L2_COLORSPACE_JPEG,
144         },
145 };
146 
147 #define LOAD_PAGE3              255
148 #define END_OF_SEQUENCE         0
149 
150 static const u8 init_7302[] = {
151 /*      index,value */
152         0xff, 0x01,             /* page 1 */
153         0x78, 0x00,             /* deactivate */
154         0xff, 0x01,
155         0x78, 0x40,             /* led off */
156 };
157 static const u8 start_7302[] = {
158 /*      index, len, [value]* */
159         0xff, 1,        0x00,           /* page 0 */
160         0x00, 12,       0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
161                         0x00, 0x00, 0x00, 0x00,
162         0x0d, 24,       0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
163                         0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
164                         0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
165         0x26, 2,        0xaa, 0xaa,
166         0x2e, 1,        0x31,
167         0x38, 1,        0x01,
168         0x3a, 3,        0x14, 0xff, 0x5a,
169         0x43, 11,       0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
170                         0x00, 0x54, 0x11,
171         0x55, 1,        0x00,
172         0x62, 4,        0x10, 0x1e, 0x1e, 0x18,
173         0x6b, 1,        0x00,
174         0x6e, 3,        0x08, 0x06, 0x00,
175         0x72, 3,        0x00, 0xff, 0x00,
176         0x7d, 23,       0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
177                         0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
178                         0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
179         0xa2, 10,       0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
180                         0xd2, 0xeb,
181         0xaf, 1,        0x02,
182         0xb5, 2,        0x08, 0x08,
183         0xb8, 2,        0x08, 0x88,
184         0xc4, 4,        0xae, 0x01, 0x04, 0x01,
185         0xcc, 1,        0x00,
186         0xd1, 11,       0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
187                         0xc1, 0xd7, 0xec,
188         0xdc, 1,        0x01,
189         0xff, 1,        0x01,           /* page 1 */
190         0x12, 3,        0x02, 0x00, 0x01,
191         0x3e, 2,        0x00, 0x00,
192         0x76, 5,        0x01, 0x20, 0x40, 0x00, 0xf2,
193         0x7c, 1,        0x00,
194         0x7f, 10,       0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
195                         0x02, 0x00,
196         0x96, 5,        0x01, 0x10, 0x04, 0x01, 0x04,
197         0xc8, 14,       0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
198                         0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
199         0xd8, 1,        0x01,
200         0xdb, 2,        0x00, 0x01,
201         0xde, 7,        0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
202         0xe6, 4,        0x00, 0x00, 0x00, 0x01,
203         0xeb, 1,        0x00,
204         0xff, 1,        0x02,           /* page 2 */
205         0x22, 1,        0x00,
206         0xff, 1,        0x03,           /* page 3 */
207         0, LOAD_PAGE3,                  /* load the page 3 */
208         0x11, 1,        0x01,
209         0xff, 1,        0x02,           /* page 2 */
210         0x13, 1,        0x00,
211         0x22, 4,        0x1f, 0xa4, 0xf0, 0x96,
212         0x27, 2,        0x14, 0x0c,
213         0x2a, 5,        0xc8, 0x00, 0x18, 0x12, 0x22,
214         0x64, 8,        0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
215         0x6e, 1,        0x08,
216         0xff, 1,        0x01,           /* page 1 */
217         0x78, 1,        0x00,
218         0, END_OF_SEQUENCE              /* end of sequence */
219 };
220 
221 #define SKIP            0xaa
222 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
223 static const u8 page3_7302[] = {
224         0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
225         0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
226         0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227         0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
228         0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
229         0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
230         0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
231         0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232         0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
233         SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
234         0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235         0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
236         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237         0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
238         0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
239         0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
240         0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
241         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242         0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
243         0x00
244 };
245 
246 static void reg_w_buf(struct gspca_dev *gspca_dev,
247                 u8 index,
248                   const u8 *buffer, int len)
249 {
250         int ret;
251 
252         if (gspca_dev->usb_err < 0)
253                 return;
254         memcpy(gspca_dev->usb_buf, buffer, len);
255         ret = usb_control_msg(gspca_dev->dev,
256                         usb_sndctrlpipe(gspca_dev->dev, 0),
257                         0,              /* request */
258                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
259                         0,              /* value */
260                         index, gspca_dev->usb_buf, len,
261                         500);
262         if (ret < 0) {
263                 pr_err("reg_w_buf failed i: %02x error %d\n",
264                        index, ret);
265                 gspca_dev->usb_err = ret;
266         }
267 }
268 
269 
270 static void reg_w(struct gspca_dev *gspca_dev,
271                 u8 index,
272                 u8 value)
273 {
274         int ret;
275 
276         if (gspca_dev->usb_err < 0)
277                 return;
278         gspca_dev->usb_buf[0] = value;
279         ret = usb_control_msg(gspca_dev->dev,
280                         usb_sndctrlpipe(gspca_dev->dev, 0),
281                         0,                      /* request */
282                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
283                         0, index, gspca_dev->usb_buf, 1,
284                         500);
285         if (ret < 0) {
286                 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
287                        index, value, ret);
288                 gspca_dev->usb_err = ret;
289         }
290 }
291 
292 static void reg_w_seq(struct gspca_dev *gspca_dev,
293                 const u8 *seq, int len)
294 {
295         while (--len >= 0) {
296                 reg_w(gspca_dev, seq[0], seq[1]);
297                 seq += 2;
298         }
299 }
300 
301 /* load the beginning of a page */
302 static void reg_w_page(struct gspca_dev *gspca_dev,
303                         const u8 *page, int len)
304 {
305         int index;
306         int ret = 0;
307 
308         if (gspca_dev->usb_err < 0)
309                 return;
310         for (index = 0; index < len; index++) {
311                 if (page[index] == SKIP)                /* skip this index */
312                         continue;
313                 gspca_dev->usb_buf[0] = page[index];
314                 ret = usb_control_msg(gspca_dev->dev,
315                                 usb_sndctrlpipe(gspca_dev->dev, 0),
316                                 0,                      /* request */
317                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
318                                 0, index, gspca_dev->usb_buf, 1,
319                                 500);
320                 if (ret < 0) {
321                         pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
322                                index, page[index], ret);
323                         gspca_dev->usb_err = ret;
324                         break;
325                 }
326         }
327 }
328 
329 /* output a variable sequence */
330 static void reg_w_var(struct gspca_dev *gspca_dev,
331                         const u8 *seq,
332                         const u8 *page3, unsigned int page3_len)
333 {
334         int index, len;
335 
336         for (;;) {
337                 index = *seq++;
338                 len = *seq++;
339                 switch (len) {
340                 case END_OF_SEQUENCE:
341                         return;
342                 case LOAD_PAGE3:
343                         reg_w_page(gspca_dev, page3, page3_len);
344                         break;
345                 default:
346                         if (len > USB_BUF_SZ) {
347                                 PERR("Incorrect variable sequence");
348                                 return;
349                         }
350                         while (len > 0) {
351                                 if (len < 8) {
352                                         reg_w_buf(gspca_dev,
353                                                 index, seq, len);
354                                         seq += len;
355                                         break;
356                                 }
357                                 reg_w_buf(gspca_dev, index, seq, 8);
358                                 seq += 8;
359                                 index += 8;
360                                 len -= 8;
361                         }
362                 }
363         }
364         /* not reached */
365 }
366 
367 /* this function is called at probe time for pac7302 */
368 static int sd_config(struct gspca_dev *gspca_dev,
369                         const struct usb_device_id *id)
370 {
371         struct sd *sd = (struct sd *) gspca_dev;
372         struct cam *cam;
373 
374         cam = &gspca_dev->cam;
375 
376         cam->cam_mode = vga_mode;       /* only 640x480 */
377         cam->nmodes = ARRAY_SIZE(vga_mode);
378 
379         sd->flags = id->driver_info;
380         return 0;
381 }
382 
383 static void setbrightcont(struct gspca_dev *gspca_dev)
384 {
385         struct sd *sd = (struct sd *) gspca_dev;
386         int i, v;
387         static const u8 max[10] =
388                 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
389                  0xd4, 0xec};
390         static const u8 delta[10] =
391                 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
392                  0x11, 0x0b};
393 
394         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
395         for (i = 0; i < 10; i++) {
396                 v = max[i];
397                 v += (sd->brightness->val - (s32)sd->brightness->maximum)
398                         * 150 / (s32)sd->brightness->maximum; /* 200 ? */
399                 v -= delta[i] * sd->contrast->val / (s32)sd->contrast->maximum;
400                 if (v < 0)
401                         v = 0;
402                 else if (v > 0xff)
403                         v = 0xff;
404                 reg_w(gspca_dev, 0xa2 + i, v);
405         }
406         reg_w(gspca_dev, 0xdc, 0x01);
407 }
408 
409 static void setcolors(struct gspca_dev *gspca_dev)
410 {
411         struct sd *sd = (struct sd *) gspca_dev;
412         int i, v;
413         static const int a[9] =
414                 {217, -212, 0, -101, 170, -67, -38, -315, 355};
415         static const int b[9] =
416                 {19, 106, 0, 19, 106, 1, 19, 106, 1};
417 
418         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
419         reg_w(gspca_dev, 0x11, 0x01);
420         reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
421         for (i = 0; i < 9; i++) {
422                 v = a[i] * sd->saturation->val / (s32)sd->saturation->maximum;
423                 v += b[i];
424                 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
425                 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
426         }
427         reg_w(gspca_dev, 0xdc, 0x01);
428 }
429 
430 static void setwhitebalance(struct gspca_dev *gspca_dev)
431 {
432         struct sd *sd = (struct sd *) gspca_dev;
433 
434         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
435         reg_w(gspca_dev, 0xc6, sd->white_balance->val);
436 
437         reg_w(gspca_dev, 0xdc, 0x01);
438 }
439 
440 static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
441 {
442         const unsigned int k = 1000;    /* precision factor */
443         unsigned int norm;
444 
445         /* Normed value [0...k] */
446         norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
447                     / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
448         /* Qudratic apporach improves control at small (register) values: */
449         return 64 * norm * norm / (k*k)  +  32 * norm / k  +  32;
450         /* Y = 64*X*X + 32*X + 32
451          * => register values 0x20-0x80; Windows driver uses these limits */
452 
453         /* NOTE: for full value range (0x00-0xff) use
454          *         Y = 254*X*X + X
455          *         => 254 * norm * norm / (k*k)  +  1 * norm / k        */
456 }
457 
458 static void setredbalance(struct gspca_dev *gspca_dev)
459 {
460         struct sd *sd = (struct sd *) gspca_dev;
461 
462         reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
463         reg_w(gspca_dev, 0x01,
464               rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
465 
466         reg_w(gspca_dev, 0xdc, 0x01);
467 }
468 
469 static void setbluebalance(struct gspca_dev *gspca_dev)
470 {
471         struct sd *sd = (struct sd *) gspca_dev;
472 
473         reg_w(gspca_dev, 0xff, 0x00);                   /* page 0 */
474         reg_w(gspca_dev, 0x03,
475               rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
476 
477         reg_w(gspca_dev, 0xdc, 0x01);
478 }
479 
480 static void setgain(struct gspca_dev *gspca_dev)
481 {
482         u8 reg10, reg12;
483 
484         if (gspca_dev->gain->val < 32) {
485                 reg10 = gspca_dev->gain->val;
486                 reg12 = 0;
487         } else {
488                 reg10 = 31;
489                 reg12 = gspca_dev->gain->val - 31;
490         }
491 
492         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
493         reg_w(gspca_dev, 0x10, reg10);
494         reg_w(gspca_dev, 0x12, reg12);
495 
496         /* load registers to sensor (Bit 0, auto clear) */
497         reg_w(gspca_dev, 0x11, 0x01);
498 }
499 
500 static void setexposure(struct gspca_dev *gspca_dev)
501 {
502         u8 clockdiv;
503         u16 exposure;
504 
505         /*
506          * Register 2 of frame 3 contains the clock divider configuring the
507          * no fps according to the formula: 90 / reg. sd->exposure is the
508          * desired exposure time in 0.5 ms.
509          */
510         clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
511 
512         /*
513          * Note clockdiv = 3 also works, but when running at 30 fps, depending
514          * on the scene being recorded, the camera switches to another
515          * quantization table for certain JPEG blocks, and we don't know how
516          * to decompress these blocks. So we cap the framerate at 15 fps.
517          */
518         if (clockdiv < 6)
519                 clockdiv = 6;
520         else if (clockdiv > 63)
521                 clockdiv = 63;
522 
523         /*
524          * Register 2 MUST be a multiple of 3, except when between 6 and 12?
525          * Always round up, otherwise we cannot get the desired frametime
526          * using the partial frame time exposure control.
527          */
528         if (clockdiv < 6 || clockdiv > 12)
529                 clockdiv = ((clockdiv + 2) / 3) * 3;
530 
531         /*
532          * frame exposure time in ms = 1000 * clockdiv / 90    ->
533          * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
534          */
535         exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
536         /* 0 = use full frametime, 448 = no exposure, reverse it */
537         exposure = 448 - exposure;
538 
539         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
540         reg_w(gspca_dev, 0x02, clockdiv);
541         reg_w(gspca_dev, 0x0e, exposure & 0xff);
542         reg_w(gspca_dev, 0x0f, exposure >> 8);
543 
544         /* load registers to sensor (Bit 0, auto clear) */
545         reg_w(gspca_dev, 0x11, 0x01);
546 }
547 
548 static void sethvflip(struct gspca_dev *gspca_dev)
549 {
550         struct sd *sd = (struct sd *) gspca_dev;
551         u8 data, hflip, vflip;
552 
553         hflip = sd->hflip->val;
554         if (sd->flags & FL_HFLIP)
555                 hflip = !hflip;
556         vflip = sd->vflip->val;
557         if (sd->flags & FL_VFLIP)
558                 vflip = !vflip;
559 
560         reg_w(gspca_dev, 0xff, 0x03);                   /* page 3 */
561         data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
562         reg_w(gspca_dev, 0x21, data);
563 
564         /* load registers to sensor (Bit 0, auto clear) */
565         reg_w(gspca_dev, 0x11, 0x01);
566 }
567 
568 static void setsharpness(struct gspca_dev *gspca_dev)
569 {
570         struct sd *sd = (struct sd *) gspca_dev;
571 
572         reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
573         reg_w(gspca_dev, 0xb6, sd->sharpness->val);
574 
575         reg_w(gspca_dev, 0xdc, 0x01);
576 }
577 
578 /* this function is called at probe and resume time for pac7302 */
579 static int sd_init(struct gspca_dev *gspca_dev)
580 {
581         reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
582         return gspca_dev->usb_err;
583 }
584 
585 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
586 {
587         struct gspca_dev *gspca_dev =
588                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
589         struct sd *sd = (struct sd *)gspca_dev;
590 
591         gspca_dev->usb_err = 0;
592 
593         if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
594                 /* when switching to autogain set defaults to make sure
595                    we are on a valid point of the autogain gain /
596                    exposure knee graph, and give this change time to
597                    take effect before doing autogain. */
598                 gspca_dev->exposure->val    = PAC7302_EXPOSURE_DEFAULT;
599                 gspca_dev->gain->val        = PAC7302_GAIN_DEFAULT;
600                 sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
601         }
602 
603         if (!gspca_dev->streaming)
604                 return 0;
605 
606         switch (ctrl->id) {
607         case V4L2_CID_BRIGHTNESS:
608                 setbrightcont(gspca_dev);
609                 break;
610         case V4L2_CID_SATURATION:
611                 setcolors(gspca_dev);
612                 break;
613         case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
614                 setwhitebalance(gspca_dev);
615                 break;
616         case V4L2_CID_RED_BALANCE:
617                 setredbalance(gspca_dev);
618                 break;
619         case V4L2_CID_BLUE_BALANCE:
620                 setbluebalance(gspca_dev);
621                 break;
622         case V4L2_CID_AUTOGAIN:
623                 if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
624                         setexposure(gspca_dev);
625                 if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
626                         setgain(gspca_dev);
627                 break;
628         case V4L2_CID_HFLIP:
629                 sethvflip(gspca_dev);
630                 break;
631         case V4L2_CID_SHARPNESS:
632                 setsharpness(gspca_dev);
633                 break;
634         default:
635                 return -EINVAL;
636         }
637         return gspca_dev->usb_err;
638 }
639 
640 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
641         .s_ctrl = sd_s_ctrl,
642 };
643 
644 /* this function is called at probe time */
645 static int sd_init_controls(struct gspca_dev *gspca_dev)
646 {
647         struct sd *sd = (struct sd *) gspca_dev;
648         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
649 
650         gspca_dev->vdev.ctrl_handler = hdl;
651         v4l2_ctrl_handler_init(hdl, 12);
652 
653         sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
654                                         V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
655         sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
656                                         V4L2_CID_CONTRAST, 0, 255, 1, 127);
657 
658         sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
659                                         V4L2_CID_SATURATION, 0, 255, 1, 127);
660         sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
661                                         V4L2_CID_WHITE_BALANCE_TEMPERATURE,
662                                         0, 255, 1, 55);
663         sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
664                                         V4L2_CID_RED_BALANCE,
665                                         PAC7302_RGB_BALANCE_MIN,
666                                         PAC7302_RGB_BALANCE_MAX,
667                                         1, PAC7302_RGB_BALANCE_DEFAULT);
668         sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
669                                         V4L2_CID_BLUE_BALANCE,
670                                         PAC7302_RGB_BALANCE_MIN,
671                                         PAC7302_RGB_BALANCE_MAX,
672                                         1, PAC7302_RGB_BALANCE_DEFAULT);
673 
674         gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
675                                         V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
676         gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
677                                         V4L2_CID_EXPOSURE, 0, 1023, 1,
678                                         PAC7302_EXPOSURE_DEFAULT);
679         gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
680                                         V4L2_CID_GAIN, 0, 62, 1,
681                                         PAC7302_GAIN_DEFAULT);
682 
683         sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
684                 V4L2_CID_HFLIP, 0, 1, 1, 0);
685         sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
686                 V4L2_CID_VFLIP, 0, 1, 1, 0);
687 
688         sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
689                                         V4L2_CID_SHARPNESS, 0, 15, 1, 8);
690 
691         if (hdl->error) {
692                 pr_err("Could not initialize controls\n");
693                 return hdl->error;
694         }
695 
696         v4l2_ctrl_cluster(2, &sd->brightness);
697         v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
698         v4l2_ctrl_cluster(2, &sd->hflip);
699         return 0;
700 }
701 
702 /* -- start the camera -- */
703 static int sd_start(struct gspca_dev *gspca_dev)
704 {
705         struct sd *sd = (struct sd *) gspca_dev;
706 
707         reg_w_var(gspca_dev, start_7302,
708                 page3_7302, sizeof(page3_7302));
709 
710         sd->sof_read = 0;
711         sd->autogain_ignore_frames = 0;
712         atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
713 
714         /* start stream */
715         reg_w(gspca_dev, 0xff, 0x01);
716         reg_w(gspca_dev, 0x78, 0x01);
717 
718         return gspca_dev->usb_err;
719 }
720 
721 static void sd_stopN(struct gspca_dev *gspca_dev)
722 {
723 
724         /* stop stream */
725         reg_w(gspca_dev, 0xff, 0x01);
726         reg_w(gspca_dev, 0x78, 0x00);
727 }
728 
729 /* called on streamoff with alt 0 and on disconnect for pac7302 */
730 static void sd_stop0(struct gspca_dev *gspca_dev)
731 {
732         if (!gspca_dev->present)
733                 return;
734         reg_w(gspca_dev, 0xff, 0x01);
735         reg_w(gspca_dev, 0x78, 0x40);
736 }
737 
738 static void do_autogain(struct gspca_dev *gspca_dev)
739 {
740         struct sd *sd = (struct sd *) gspca_dev;
741         int avg_lum = atomic_read(&sd->avg_lum);
742         int desired_lum;
743         const int deadzone = 30;
744 
745         if (sd->autogain_ignore_frames < 0)
746                 return;
747 
748         if (sd->autogain_ignore_frames > 0) {
749                 sd->autogain_ignore_frames--;
750         } else {
751                 desired_lum = 270 + sd->brightness->val;
752 
753                 if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
754                                         deadzone, PAC7302_GAIN_KNEE,
755                                         PAC7302_EXPOSURE_KNEE))
756                         sd->autogain_ignore_frames =
757                                                 PAC_AUTOGAIN_IGNORE_FRAMES;
758         }
759 }
760 
761 /* JPEG header */
762 static const u8 jpeg_header[] = {
763         0xff, 0xd8,     /* SOI: Start of Image */
764 
765         0xff, 0xc0,     /* SOF0: Start of Frame (Baseline DCT) */
766         0x00, 0x11,     /* length = 17 bytes (including this length field) */
767         0x08,           /* Precision: 8 */
768         0x02, 0x80,     /* height = 640 (image rotated) */
769         0x01, 0xe0,     /* width = 480 */
770         0x03,           /* Number of image components: 3 */
771         0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
772         0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
773         0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
774 
775         0xff, 0xda,     /* SOS: Start Of Scan */
776         0x00, 0x0c,     /* length = 12 bytes (including this length field) */
777         0x03,           /* number of components: 3 */
778         0x01, 0x00,     /* selector 1, table 0x00 */
779         0x02, 0x11,     /* selector 2, table 0x11 */
780         0x03, 0x11,     /* selector 3, table 0x11 */
781         0x00, 0x3f,     /* Spectral selection: 0 .. 63 */
782         0x00            /* Successive approximation: 0 */
783 };
784 
785 /* this function is run at interrupt level */
786 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
787                         u8 *data,                       /* isoc packet */
788                         int len)                        /* iso packet length */
789 {
790         struct sd *sd = (struct sd *) gspca_dev;
791         u8 *image;
792         u8 *sof;
793 
794         sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
795         if (sof) {
796                 int n, lum_offset, footer_length;
797 
798                 /*
799                  * 6 bytes after the FF D9 EOF marker a number of lumination
800                  * bytes are send corresponding to different parts of the
801                  * image, the 14th and 15th byte after the EOF seem to
802                  * correspond to the center of the image.
803                  */
804                 lum_offset = 61 + sizeof pac_sof_marker;
805                 footer_length = 74;
806 
807                 /* Finish decoding current frame */
808                 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
809                 if (n < 0) {
810                         gspca_dev->image_len += n;
811                         n = 0;
812                 } else {
813                         gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
814                 }
815 
816                 image = gspca_dev->image;
817                 if (image != NULL
818                  && image[gspca_dev->image_len - 2] == 0xff
819                  && image[gspca_dev->image_len - 1] == 0xd9)
820                         gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
821 
822                 n = sof - data;
823                 len -= n;
824                 data = sof;
825 
826                 /* Get average lumination */
827                 if (gspca_dev->last_packet_type == LAST_PACKET &&
828                                 n >= lum_offset)
829                         atomic_set(&sd->avg_lum, data[-lum_offset] +
830                                                 data[-lum_offset + 1]);
831 
832                 /* Start the new frame with the jpeg header */
833                 /* The PAC7302 has the image rotated 90 degrees */
834                 gspca_frame_add(gspca_dev, FIRST_PACKET,
835                                 jpeg_header, sizeof jpeg_header);
836         }
837         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
838 }
839 
840 #ifdef CONFIG_VIDEO_ADV_DEBUG
841 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
842                         const struct v4l2_dbg_register *reg)
843 {
844         u8 index;
845         u8 value;
846 
847         /*
848          * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
849          *                     long on the USB bus)
850          */
851         if (reg->match.addr == 0 &&
852             (reg->reg < 0x000000ff) &&
853             (reg->val <= 0x000000ff)
854         ) {
855                 /* Currently writing to page 0 is only supported. */
856                 /* reg_w() only supports 8bit index */
857                 index = reg->reg;
858                 value = reg->val;
859 
860                 /*
861                  * Note that there shall be no access to other page
862                  * by any other function between the page switch and
863                  * the actual register write.
864                  */
865                 reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
866                 reg_w(gspca_dev, index, value);
867 
868                 reg_w(gspca_dev, 0xdc, 0x01);
869         }
870         return gspca_dev->usb_err;
871 }
872 #endif
873 
874 #if IS_ENABLED(CONFIG_INPUT)
875 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
876                         u8 *data,               /* interrupt packet data */
877                         int len)                /* interrupt packet length */
878 {
879         int ret = -EINVAL;
880         u8 data0, data1;
881 
882         if (len == 2) {
883                 data0 = data[0];
884                 data1 = data[1];
885                 if ((data0 == 0x00 && data1 == 0x11) ||
886                     (data0 == 0x22 && data1 == 0x33) ||
887                     (data0 == 0x44 && data1 == 0x55) ||
888                     (data0 == 0x66 && data1 == 0x77) ||
889                     (data0 == 0x88 && data1 == 0x99) ||
890                     (data0 == 0xaa && data1 == 0xbb) ||
891                     (data0 == 0xcc && data1 == 0xdd) ||
892                     (data0 == 0xee && data1 == 0xff)) {
893                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
894                         input_sync(gspca_dev->input_dev);
895                         input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
896                         input_sync(gspca_dev->input_dev);
897                         ret = 0;
898                 }
899         }
900 
901         return ret;
902 }
903 #endif
904 
905 /* sub-driver description for pac7302 */
906 static const struct sd_desc sd_desc = {
907         .name = KBUILD_MODNAME,
908         .config = sd_config,
909         .init = sd_init,
910         .init_controls = sd_init_controls,
911         .start = sd_start,
912         .stopN = sd_stopN,
913         .stop0 = sd_stop0,
914         .pkt_scan = sd_pkt_scan,
915         .dq_callback = do_autogain,
916 #ifdef CONFIG_VIDEO_ADV_DEBUG
917         .set_register = sd_dbg_s_register,
918 #endif
919 #if IS_ENABLED(CONFIG_INPUT)
920         .int_pkt_scan = sd_int_pkt_scan,
921 #endif
922 };
923 
924 /* -- module initialisation -- */
925 static const struct usb_device_id device_table[] = {
926         {USB_DEVICE(0x06f8, 0x3009)},
927         {USB_DEVICE(0x06f8, 0x301b)},
928         {USB_DEVICE(0x093a, 0x2620)},
929         {USB_DEVICE(0x093a, 0x2621)},
930         {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
931         {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
932         {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
933         {USB_DEVICE(0x093a, 0x2625)},
934         {USB_DEVICE(0x093a, 0x2626)},
935         {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
936         {USB_DEVICE(0x093a, 0x2628)},
937         {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
938         {USB_DEVICE(0x093a, 0x262a)},
939         {USB_DEVICE(0x093a, 0x262c)},
940         {USB_DEVICE(0x145f, 0x013c)},
941         {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
942         {}
943 };
944 MODULE_DEVICE_TABLE(usb, device_table);
945 
946 /* -- device connect -- */
947 static int sd_probe(struct usb_interface *intf,
948                         const struct usb_device_id *id)
949 {
950         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
951                                 THIS_MODULE);
952 }
953 
954 static struct usb_driver sd_driver = {
955         .name = KBUILD_MODNAME,
956         .id_table = device_table,
957         .probe = sd_probe,
958         .disconnect = gspca_disconnect,
959 #ifdef CONFIG_PM
960         .suspend = gspca_suspend,
961         .resume = gspca_resume,
962         .reset_resume = gspca_resume,
963 #endif
964 };
965 
966 module_usb_driver(sd_driver);
967 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us