Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

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

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