Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Pixart PAC7302 driver
0004  *
0005  * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
0006  * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
0007  *
0008  * Separated from Pixart PAC7311 library by Márton Németh
0009  * Camera button input handling by Márton Németh <nm127@freemail.hu>
0010  * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
0011  */
0012 
0013 /*
0014  * Some documentation about various registers as determined by trial and error.
0015  *
0016  * Register page 0:
0017  *
0018  * Address  Description
0019  * 0x01     Red balance control
0020  * 0x02     Green balance control
0021  * 0x03     Blue balance control
0022  *           The Windows driver uses a quadratic approach to map
0023  *           the settable values (0-200) on register values:
0024  *           min=0x20, default=0x40, max=0x80
0025  * 0x0f-0x20    Color and saturation control
0026  * 0xa2-0xab    Brightness, contrast and gamma control
0027  * 0xb6     Sharpness control (bits 0-4)
0028  *
0029  * Register page 1:
0030  *
0031  * Address  Description
0032  * 0x78     Global control, bit 6 controls the LED (inverted)
0033  * 0x80     Compression balance, 2 interesting settings:
0034  *      0x0f Default
0035  *      0x50 Values >= this switch the camera to a lower compression,
0036  *           using the same table for both luminance and chrominance.
0037  *           This gives a sharper picture. Only usable when running
0038  *           at < 15 fps! Note currently the driver does not use this
0039  *           as the quality gain is small and the generated JPG-s are
0040  *           only understood by v4l-utils >= 0.8.9
0041  *
0042  * Register page 3:
0043  *
0044  * Address  Description
0045  * 0x02     Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
0046  *      the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
0047  * 0x03     Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
0048  * 0x04     Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
0049  *      63 -> ~27 fps, the 2 msb's must always be 1 !!
0050  * 0x05     Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
0051  *      1 -> ~30 fps, 2 -> ~20 fps
0052  * 0x0e     Exposure bits 0-7, 0-448, 0 = use full frame time
0053  * 0x0f     Exposure bit 8, 0-448, 448 = no exposure at all
0054  * 0x10     Gain 0-31
0055  * 0x12     Another gain 0-31, unlike 0x10 this one seems to start with an
0056  *      amplification value of 1 rather then 0 at its lowest setting
0057  * 0x21     Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
0058  * 0x80     Another framerate control, best left at 1, moving it from 1 to
0059  *      2 causes the framerate to become 3/4th of what it was, and
0060  *      also seems to cause pixel averaging, resulting in an effective
0061  *      resolution of 320x240 and thus a much blockier image
0062  *
0063  * The registers are accessed in the following functions:
0064  *
0065  * Page | Register   | Function
0066  * -----+------------+---------------------------------------------------
0067  *  0   | 0x01       | setredbalance()
0068  *  0   | 0x03       | setbluebalance()
0069  *  0   | 0x0f..0x20 | setcolors()
0070  *  0   | 0xa2..0xab | setbrightcont()
0071  *  0   | 0xb6       | setsharpness()
0072  *  0   | 0xc6       | setwhitebalance()
0073  *  0   | 0xdc       | setbrightcont(), setcolors()
0074  *  3   | 0x02       | setexposure()
0075  *  3   | 0x10, 0x12 | setgain()
0076  *  3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
0077  *  3   | 0x21       | sethvflip()
0078  */
0079 
0080 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0081 
0082 #include <linux/input.h>
0083 #include "gspca.h"
0084 /* Include pac common sof detection functions */
0085 #include "pac_common.h"
0086 
0087 #define PAC7302_RGB_BALANCE_MIN       0
0088 #define PAC7302_RGB_BALANCE_MAX     200
0089 #define PAC7302_RGB_BALANCE_DEFAULT 100
0090 #define PAC7302_GAIN_DEFAULT         15
0091 #define PAC7302_GAIN_KNEE        42
0092 #define PAC7302_EXPOSURE_DEFAULT     66 /* 33 ms / 30 fps */
0093 #define PAC7302_EXPOSURE_KNEE       133 /* 66 ms / 15 fps */
0094 
0095 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, Thomas Kaiser thomas@kaiser-linux.li");
0096 MODULE_DESCRIPTION("Pixart PAC7302");
0097 MODULE_LICENSE("GPL");
0098 
0099 struct sd {
0100     struct gspca_dev gspca_dev;     /* !! must be the first item */
0101 
0102     struct { /* brightness / contrast cluster */
0103         struct v4l2_ctrl *brightness;
0104         struct v4l2_ctrl *contrast;
0105     };
0106     struct v4l2_ctrl *saturation;
0107     struct v4l2_ctrl *white_balance;
0108     struct v4l2_ctrl *red_balance;
0109     struct v4l2_ctrl *blue_balance;
0110     struct { /* flip cluster */
0111         struct v4l2_ctrl *hflip;
0112         struct v4l2_ctrl *vflip;
0113     };
0114     struct v4l2_ctrl *sharpness;
0115     u8 flags;
0116 #define FL_HFLIP 0x01       /* mirrored by default */
0117 #define FL_VFLIP 0x02       /* vertical flipped by default */
0118 
0119     u8 sof_read;
0120     s8 autogain_ignore_frames;
0121 
0122     atomic_t avg_lum;
0123 };
0124 
0125 static const struct v4l2_pix_format vga_mode[] = {
0126     {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
0127         .bytesperline = 640,
0128         .sizeimage = 640 * 480 * 3 / 8 + 590,
0129         .colorspace = V4L2_COLORSPACE_JPEG,
0130     },
0131 };
0132 
0133 #define LOAD_PAGE3      255
0134 #define END_OF_SEQUENCE     0
0135 
0136 static const u8 init_7302[] = {
0137 /*  index,value */
0138     0xff, 0x01,     /* page 1 */
0139     0x78, 0x00,     /* deactivate */
0140     0xff, 0x01,
0141     0x78, 0x40,     /* led off */
0142 };
0143 static const u8 start_7302[] = {
0144 /*  index, len, [value]* */
0145     0xff, 1,    0x00,       /* page 0 */
0146     0x00, 12,   0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
0147             0x00, 0x00, 0x00, 0x00,
0148     0x0d, 24,   0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
0149             0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
0150             0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
0151     0x26, 2,    0xaa, 0xaa,
0152     0x2e, 1,    0x31,
0153     0x38, 1,    0x01,
0154     0x3a, 3,    0x14, 0xff, 0x5a,
0155     0x43, 11,   0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
0156             0x00, 0x54, 0x11,
0157     0x55, 1,    0x00,
0158     0x62, 4,    0x10, 0x1e, 0x1e, 0x18,
0159     0x6b, 1,    0x00,
0160     0x6e, 3,    0x08, 0x06, 0x00,
0161     0x72, 3,    0x00, 0xff, 0x00,
0162     0x7d, 23,   0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
0163             0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
0164             0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
0165     0xa2, 10,   0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
0166             0xd2, 0xeb,
0167     0xaf, 1,    0x02,
0168     0xb5, 2,    0x08, 0x08,
0169     0xb8, 2,    0x08, 0x88,
0170     0xc4, 4,    0xae, 0x01, 0x04, 0x01,
0171     0xcc, 1,    0x00,
0172     0xd1, 11,   0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
0173             0xc1, 0xd7, 0xec,
0174     0xdc, 1,    0x01,
0175     0xff, 1,    0x01,       /* page 1 */
0176     0x12, 3,    0x02, 0x00, 0x01,
0177     0x3e, 2,    0x00, 0x00,
0178     0x76, 5,    0x01, 0x20, 0x40, 0x00, 0xf2,
0179     0x7c, 1,    0x00,
0180     0x7f, 10,   0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
0181             0x02, 0x00,
0182     0x96, 5,    0x01, 0x10, 0x04, 0x01, 0x04,
0183     0xc8, 14,   0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
0184             0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
0185     0xd8, 1,    0x01,
0186     0xdb, 2,    0x00, 0x01,
0187     0xde, 7,    0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
0188     0xe6, 4,    0x00, 0x00, 0x00, 0x01,
0189     0xeb, 1,    0x00,
0190     0xff, 1,    0x02,       /* page 2 */
0191     0x22, 1,    0x00,
0192     0xff, 1,    0x03,       /* page 3 */
0193     0, LOAD_PAGE3,          /* load the page 3 */
0194     0x11, 1,    0x01,
0195     0xff, 1,    0x02,       /* page 2 */
0196     0x13, 1,    0x00,
0197     0x22, 4,    0x1f, 0xa4, 0xf0, 0x96,
0198     0x27, 2,    0x14, 0x0c,
0199     0x2a, 5,    0xc8, 0x00, 0x18, 0x12, 0x22,
0200     0x64, 8,    0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
0201     0x6e, 1,    0x08,
0202     0xff, 1,    0x01,       /* page 1 */
0203     0x78, 1,    0x00,
0204     0, END_OF_SEQUENCE      /* end of sequence */
0205 };
0206 
0207 #define SKIP        0xaa
0208 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
0209 static const u8 page3_7302[] = {
0210     0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
0211     0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
0212     0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0213     0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
0214     0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
0215     0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
0216     0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
0217     0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0218     0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
0219     SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
0220     0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0221     0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
0222     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0223     0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
0224     0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
0225     0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
0226     0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
0227     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0228     0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
0229     0x00
0230 };
0231 
0232 static void reg_w_buf(struct gspca_dev *gspca_dev,
0233         u8 index,
0234           const u8 *buffer, int len)
0235 {
0236     int ret;
0237 
0238     if (gspca_dev->usb_err < 0)
0239         return;
0240     memcpy(gspca_dev->usb_buf, buffer, len);
0241     ret = usb_control_msg(gspca_dev->dev,
0242             usb_sndctrlpipe(gspca_dev->dev, 0),
0243             0,      /* request */
0244             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0245             0,      /* value */
0246             index, gspca_dev->usb_buf, len,
0247             500);
0248     if (ret < 0) {
0249         pr_err("reg_w_buf failed i: %02x error %d\n",
0250                index, ret);
0251         gspca_dev->usb_err = ret;
0252     }
0253 }
0254 
0255 
0256 static void reg_w(struct gspca_dev *gspca_dev,
0257         u8 index,
0258         u8 value)
0259 {
0260     int ret;
0261 
0262     if (gspca_dev->usb_err < 0)
0263         return;
0264     gspca_dev->usb_buf[0] = value;
0265     ret = usb_control_msg(gspca_dev->dev,
0266             usb_sndctrlpipe(gspca_dev->dev, 0),
0267             0,          /* request */
0268             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0269             0, index, gspca_dev->usb_buf, 1,
0270             500);
0271     if (ret < 0) {
0272         pr_err("reg_w() failed i: %02x v: %02x error %d\n",
0273                index, value, ret);
0274         gspca_dev->usb_err = ret;
0275     }
0276 }
0277 
0278 static void reg_w_seq(struct gspca_dev *gspca_dev,
0279         const u8 *seq, int len)
0280 {
0281     while (--len >= 0) {
0282         reg_w(gspca_dev, seq[0], seq[1]);
0283         seq += 2;
0284     }
0285 }
0286 
0287 /* load the beginning of a page */
0288 static void reg_w_page(struct gspca_dev *gspca_dev,
0289             const u8 *page, int len)
0290 {
0291     int index;
0292     int ret = 0;
0293 
0294     if (gspca_dev->usb_err < 0)
0295         return;
0296     for (index = 0; index < len; index++) {
0297         if (page[index] == SKIP)        /* skip this index */
0298             continue;
0299         gspca_dev->usb_buf[0] = page[index];
0300         ret = usb_control_msg(gspca_dev->dev,
0301                 usb_sndctrlpipe(gspca_dev->dev, 0),
0302                 0,          /* request */
0303             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0304                 0, index, gspca_dev->usb_buf, 1,
0305                 500);
0306         if (ret < 0) {
0307             pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
0308                    index, page[index], ret);
0309             gspca_dev->usb_err = ret;
0310             break;
0311         }
0312     }
0313 }
0314 
0315 /* output a variable sequence */
0316 static void reg_w_var(struct gspca_dev *gspca_dev,
0317             const u8 *seq,
0318             const u8 *page3, unsigned int page3_len)
0319 {
0320     int index, len;
0321 
0322     for (;;) {
0323         index = *seq++;
0324         len = *seq++;
0325         switch (len) {
0326         case END_OF_SEQUENCE:
0327             return;
0328         case LOAD_PAGE3:
0329             reg_w_page(gspca_dev, page3, page3_len);
0330             break;
0331         default:
0332             if (len > USB_BUF_SZ) {
0333                 gspca_err(gspca_dev, "Incorrect variable sequence\n");
0334                 return;
0335             }
0336             while (len > 0) {
0337                 if (len < 8) {
0338                     reg_w_buf(gspca_dev,
0339                         index, seq, len);
0340                     seq += len;
0341                     break;
0342                 }
0343                 reg_w_buf(gspca_dev, index, seq, 8);
0344                 seq += 8;
0345                 index += 8;
0346                 len -= 8;
0347             }
0348         }
0349     }
0350     /* not reached */
0351 }
0352 
0353 /* this function is called at probe time for pac7302 */
0354 static int sd_config(struct gspca_dev *gspca_dev,
0355             const struct usb_device_id *id)
0356 {
0357     struct sd *sd = (struct sd *) gspca_dev;
0358     struct cam *cam;
0359 
0360     cam = &gspca_dev->cam;
0361 
0362     cam->cam_mode = vga_mode;   /* only 640x480 */
0363     cam->nmodes = ARRAY_SIZE(vga_mode);
0364 
0365     sd->flags = id->driver_info;
0366     return 0;
0367 }
0368 
0369 static void setbrightcont(struct gspca_dev *gspca_dev)
0370 {
0371     struct sd *sd = (struct sd *) gspca_dev;
0372     int i, v;
0373     static const u8 max[10] =
0374         {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
0375          0xd4, 0xec};
0376     static const u8 delta[10] =
0377         {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
0378          0x11, 0x0b};
0379 
0380     reg_w(gspca_dev, 0xff, 0x00);       /* page 0 */
0381     for (i = 0; i < 10; i++) {
0382         v = max[i];
0383         v += (sd->brightness->val - (s32)sd->brightness->maximum)
0384             * 150 / (s32)sd->brightness->maximum; /* 200 ? */
0385         v -= delta[i] * sd->contrast->val / (s32)sd->contrast->maximum;
0386         if (v < 0)
0387             v = 0;
0388         else if (v > 0xff)
0389             v = 0xff;
0390         reg_w(gspca_dev, 0xa2 + i, v);
0391     }
0392     reg_w(gspca_dev, 0xdc, 0x01);
0393 }
0394 
0395 static void setcolors(struct gspca_dev *gspca_dev)
0396 {
0397     struct sd *sd = (struct sd *) gspca_dev;
0398     int i, v;
0399     static const int a[9] =
0400         {217, -212, 0, -101, 170, -67, -38, -315, 355};
0401     static const int b[9] =
0402         {19, 106, 0, 19, 106, 1, 19, 106, 1};
0403 
0404     reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
0405     reg_w(gspca_dev, 0x11, 0x01);
0406     reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
0407     for (i = 0; i < 9; i++) {
0408         v = a[i] * sd->saturation->val / (s32)sd->saturation->maximum;
0409         v += b[i];
0410         reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
0411         reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
0412     }
0413     reg_w(gspca_dev, 0xdc, 0x01);
0414 }
0415 
0416 static void setwhitebalance(struct gspca_dev *gspca_dev)
0417 {
0418     struct sd *sd = (struct sd *) gspca_dev;
0419 
0420     reg_w(gspca_dev, 0xff, 0x00);       /* page 0 */
0421     reg_w(gspca_dev, 0xc6, sd->white_balance->val);
0422 
0423     reg_w(gspca_dev, 0xdc, 0x01);
0424 }
0425 
0426 static u8 rgbbalance_ctrl_to_reg_value(s32 rgb_ctrl_val)
0427 {
0428     const unsigned int k = 1000;    /* precision factor */
0429     unsigned int norm;
0430 
0431     /* Normed value [0...k] */
0432     norm = k * (rgb_ctrl_val - PAC7302_RGB_BALANCE_MIN)
0433             / (PAC7302_RGB_BALANCE_MAX - PAC7302_RGB_BALANCE_MIN);
0434     /* Qudratic apporach improves control at small (register) values: */
0435     return 64 * norm * norm / (k*k)  +  32 * norm / k  +  32;
0436     /* Y = 64*X*X + 32*X + 32
0437      * => register values 0x20-0x80; Windows driver uses these limits */
0438 
0439     /* NOTE: for full value range (0x00-0xff) use
0440      *         Y = 254*X*X + X
0441      *         => 254 * norm * norm / (k*k)  +  1 * norm / k    */
0442 }
0443 
0444 static void setredbalance(struct gspca_dev *gspca_dev)
0445 {
0446     struct sd *sd = (struct sd *) gspca_dev;
0447 
0448     reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
0449     reg_w(gspca_dev, 0x01,
0450           rgbbalance_ctrl_to_reg_value(sd->red_balance->val));
0451 
0452     reg_w(gspca_dev, 0xdc, 0x01);
0453 }
0454 
0455 static void setbluebalance(struct gspca_dev *gspca_dev)
0456 {
0457     struct sd *sd = (struct sd *) gspca_dev;
0458 
0459     reg_w(gspca_dev, 0xff, 0x00);           /* page 0 */
0460     reg_w(gspca_dev, 0x03,
0461           rgbbalance_ctrl_to_reg_value(sd->blue_balance->val));
0462 
0463     reg_w(gspca_dev, 0xdc, 0x01);
0464 }
0465 
0466 static void setgain(struct gspca_dev *gspca_dev)
0467 {
0468     u8 reg10, reg12;
0469 
0470     if (gspca_dev->gain->val < 32) {
0471         reg10 = gspca_dev->gain->val;
0472         reg12 = 0;
0473     } else {
0474         reg10 = 31;
0475         reg12 = gspca_dev->gain->val - 31;
0476     }
0477 
0478     reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
0479     reg_w(gspca_dev, 0x10, reg10);
0480     reg_w(gspca_dev, 0x12, reg12);
0481 
0482     /* load registers to sensor (Bit 0, auto clear) */
0483     reg_w(gspca_dev, 0x11, 0x01);
0484 }
0485 
0486 static void setexposure(struct gspca_dev *gspca_dev)
0487 {
0488     u8 clockdiv;
0489     u16 exposure;
0490 
0491     /*
0492      * Register 2 of frame 3 contains the clock divider configuring the
0493      * no fps according to the formula: 90 / reg. sd->exposure is the
0494      * desired exposure time in 0.5 ms.
0495      */
0496     clockdiv = (90 * gspca_dev->exposure->val + 1999) / 2000;
0497 
0498     /*
0499      * Note clockdiv = 3 also works, but when running at 30 fps, depending
0500      * on the scene being recorded, the camera switches to another
0501      * quantization table for certain JPEG blocks, and we don't know how
0502      * to decompress these blocks. So we cap the framerate at 15 fps.
0503      */
0504     if (clockdiv < 6)
0505         clockdiv = 6;
0506     else if (clockdiv > 63)
0507         clockdiv = 63;
0508 
0509     /*
0510      * Register 2 MUST be a multiple of 3, except when between 6 and 12?
0511      * Always round up, otherwise we cannot get the desired frametime
0512      * using the partial frame time exposure control.
0513      */
0514     if (clockdiv < 6 || clockdiv > 12)
0515         clockdiv = ((clockdiv + 2) / 3) * 3;
0516 
0517     /*
0518      * frame exposure time in ms = 1000 * clockdiv / 90    ->
0519      * exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90)
0520      */
0521     exposure = (gspca_dev->exposure->val * 45 * 448) / (1000 * clockdiv);
0522     /* 0 = use full frametime, 448 = no exposure, reverse it */
0523     exposure = 448 - exposure;
0524 
0525     reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
0526     reg_w(gspca_dev, 0x02, clockdiv);
0527     reg_w(gspca_dev, 0x0e, exposure & 0xff);
0528     reg_w(gspca_dev, 0x0f, exposure >> 8);
0529 
0530     /* load registers to sensor (Bit 0, auto clear) */
0531     reg_w(gspca_dev, 0x11, 0x01);
0532 }
0533 
0534 static void sethvflip(struct gspca_dev *gspca_dev)
0535 {
0536     struct sd *sd = (struct sd *) gspca_dev;
0537     u8 data, hflip, vflip;
0538 
0539     hflip = sd->hflip->val;
0540     if (sd->flags & FL_HFLIP)
0541         hflip = !hflip;
0542     vflip = sd->vflip->val;
0543     if (sd->flags & FL_VFLIP)
0544         vflip = !vflip;
0545 
0546     reg_w(gspca_dev, 0xff, 0x03);           /* page 3 */
0547     data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
0548     reg_w(gspca_dev, 0x21, data);
0549 
0550     /* load registers to sensor (Bit 0, auto clear) */
0551     reg_w(gspca_dev, 0x11, 0x01);
0552 }
0553 
0554 static void setsharpness(struct gspca_dev *gspca_dev)
0555 {
0556     struct sd *sd = (struct sd *) gspca_dev;
0557 
0558     reg_w(gspca_dev, 0xff, 0x00);       /* page 0 */
0559     reg_w(gspca_dev, 0xb6, sd->sharpness->val);
0560 
0561     reg_w(gspca_dev, 0xdc, 0x01);
0562 }
0563 
0564 /* this function is called at probe and resume time for pac7302 */
0565 static int sd_init(struct gspca_dev *gspca_dev)
0566 {
0567     reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
0568     return gspca_dev->usb_err;
0569 }
0570 
0571 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
0572 {
0573     struct gspca_dev *gspca_dev =
0574         container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0575     struct sd *sd = (struct sd *)gspca_dev;
0576 
0577     gspca_dev->usb_err = 0;
0578 
0579     if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
0580         /* when switching to autogain set defaults to make sure
0581            we are on a valid point of the autogain gain /
0582            exposure knee graph, and give this change time to
0583            take effect before doing autogain. */
0584         gspca_dev->exposure->val    = PAC7302_EXPOSURE_DEFAULT;
0585         gspca_dev->gain->val        = PAC7302_GAIN_DEFAULT;
0586         sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
0587     }
0588 
0589     if (!gspca_dev->streaming)
0590         return 0;
0591 
0592     switch (ctrl->id) {
0593     case V4L2_CID_BRIGHTNESS:
0594         setbrightcont(gspca_dev);
0595         break;
0596     case V4L2_CID_SATURATION:
0597         setcolors(gspca_dev);
0598         break;
0599     case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
0600         setwhitebalance(gspca_dev);
0601         break;
0602     case V4L2_CID_RED_BALANCE:
0603         setredbalance(gspca_dev);
0604         break;
0605     case V4L2_CID_BLUE_BALANCE:
0606         setbluebalance(gspca_dev);
0607         break;
0608     case V4L2_CID_AUTOGAIN:
0609         if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
0610             setexposure(gspca_dev);
0611         if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
0612             setgain(gspca_dev);
0613         break;
0614     case V4L2_CID_HFLIP:
0615         sethvflip(gspca_dev);
0616         break;
0617     case V4L2_CID_SHARPNESS:
0618         setsharpness(gspca_dev);
0619         break;
0620     default:
0621         return -EINVAL;
0622     }
0623     return gspca_dev->usb_err;
0624 }
0625 
0626 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
0627     .s_ctrl = sd_s_ctrl,
0628 };
0629 
0630 /* this function is called at probe time */
0631 static int sd_init_controls(struct gspca_dev *gspca_dev)
0632 {
0633     struct sd *sd = (struct sd *) gspca_dev;
0634     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0635 
0636     gspca_dev->vdev.ctrl_handler = hdl;
0637     v4l2_ctrl_handler_init(hdl, 12);
0638 
0639     sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0640                     V4L2_CID_BRIGHTNESS, 0, 32, 1, 16);
0641     sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0642                     V4L2_CID_CONTRAST, 0, 255, 1, 127);
0643 
0644     sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0645                     V4L2_CID_SATURATION, 0, 255, 1, 127);
0646     sd->white_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0647                     V4L2_CID_WHITE_BALANCE_TEMPERATURE,
0648                     0, 255, 1, 55);
0649     sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0650                     V4L2_CID_RED_BALANCE,
0651                     PAC7302_RGB_BALANCE_MIN,
0652                     PAC7302_RGB_BALANCE_MAX,
0653                     1, PAC7302_RGB_BALANCE_DEFAULT);
0654     sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0655                     V4L2_CID_BLUE_BALANCE,
0656                     PAC7302_RGB_BALANCE_MIN,
0657                     PAC7302_RGB_BALANCE_MAX,
0658                     1, PAC7302_RGB_BALANCE_DEFAULT);
0659 
0660     gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0661                     V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
0662     gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0663                     V4L2_CID_EXPOSURE, 0, 1023, 1,
0664                     PAC7302_EXPOSURE_DEFAULT);
0665     gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0666                     V4L2_CID_GAIN, 0, 62, 1,
0667                     PAC7302_GAIN_DEFAULT);
0668 
0669     sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0670         V4L2_CID_HFLIP, 0, 1, 1, 0);
0671     sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0672         V4L2_CID_VFLIP, 0, 1, 1, 0);
0673 
0674     sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0675                     V4L2_CID_SHARPNESS, 0, 15, 1, 8);
0676 
0677     if (hdl->error) {
0678         pr_err("Could not initialize controls\n");
0679         return hdl->error;
0680     }
0681 
0682     v4l2_ctrl_cluster(2, &sd->brightness);
0683     v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
0684     v4l2_ctrl_cluster(2, &sd->hflip);
0685     return 0;
0686 }
0687 
0688 /* -- start the camera -- */
0689 static int sd_start(struct gspca_dev *gspca_dev)
0690 {
0691     struct sd *sd = (struct sd *) gspca_dev;
0692 
0693     reg_w_var(gspca_dev, start_7302,
0694         page3_7302, sizeof(page3_7302));
0695 
0696     sd->sof_read = 0;
0697     sd->autogain_ignore_frames = 0;
0698     atomic_set(&sd->avg_lum, 270 + sd->brightness->val);
0699 
0700     /* start stream */
0701     reg_w(gspca_dev, 0xff, 0x01);
0702     reg_w(gspca_dev, 0x78, 0x01);
0703 
0704     return gspca_dev->usb_err;
0705 }
0706 
0707 static void sd_stopN(struct gspca_dev *gspca_dev)
0708 {
0709 
0710     /* stop stream */
0711     reg_w(gspca_dev, 0xff, 0x01);
0712     reg_w(gspca_dev, 0x78, 0x00);
0713 }
0714 
0715 /* called on streamoff with alt 0 and on disconnect for pac7302 */
0716 static void sd_stop0(struct gspca_dev *gspca_dev)
0717 {
0718     if (!gspca_dev->present)
0719         return;
0720     reg_w(gspca_dev, 0xff, 0x01);
0721     reg_w(gspca_dev, 0x78, 0x40);
0722 }
0723 
0724 static void do_autogain(struct gspca_dev *gspca_dev)
0725 {
0726     struct sd *sd = (struct sd *) gspca_dev;
0727     int avg_lum = atomic_read(&sd->avg_lum);
0728     int desired_lum;
0729     const int deadzone = 30;
0730 
0731     if (sd->autogain_ignore_frames < 0)
0732         return;
0733 
0734     if (sd->autogain_ignore_frames > 0) {
0735         sd->autogain_ignore_frames--;
0736     } else {
0737         desired_lum = 270 + sd->brightness->val;
0738 
0739         if (gspca_expo_autogain(gspca_dev, avg_lum, desired_lum,
0740                     deadzone, PAC7302_GAIN_KNEE,
0741                     PAC7302_EXPOSURE_KNEE))
0742             sd->autogain_ignore_frames =
0743                         PAC_AUTOGAIN_IGNORE_FRAMES;
0744     }
0745 }
0746 
0747 /* JPEG header */
0748 static const u8 jpeg_header[] = {
0749     0xff, 0xd8, /* SOI: Start of Image */
0750 
0751     0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
0752     0x00, 0x11, /* length = 17 bytes (including this length field) */
0753     0x08,       /* Precision: 8 */
0754     0x02, 0x80, /* height = 640 (image rotated) */
0755     0x01, 0xe0, /* width = 480 */
0756     0x03,       /* Number of image components: 3 */
0757     0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
0758     0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
0759     0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
0760 
0761     0xff, 0xda, /* SOS: Start Of Scan */
0762     0x00, 0x0c, /* length = 12 bytes (including this length field) */
0763     0x03,       /* number of components: 3 */
0764     0x01, 0x00, /* selector 1, table 0x00 */
0765     0x02, 0x11, /* selector 2, table 0x11 */
0766     0x03, 0x11, /* selector 3, table 0x11 */
0767     0x00, 0x3f, /* Spectral selection: 0 .. 63 */
0768     0x00        /* Successive approximation: 0 */
0769 };
0770 
0771 /* this function is run at interrupt level */
0772 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
0773             u8 *data,           /* isoc packet */
0774             int len)            /* iso packet length */
0775 {
0776     struct sd *sd = (struct sd *) gspca_dev;
0777     u8 *image;
0778     u8 *sof;
0779 
0780     sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
0781     if (sof) {
0782         int n, lum_offset, footer_length;
0783 
0784         /*
0785          * 6 bytes after the FF D9 EOF marker a number of lumination
0786          * bytes are send corresponding to different parts of the
0787          * image, the 14th and 15th byte after the EOF seem to
0788          * correspond to the center of the image.
0789          */
0790         lum_offset = 61 + sizeof pac_sof_marker;
0791         footer_length = 74;
0792 
0793         /* Finish decoding current frame */
0794         n = (sof - data) - (footer_length + sizeof pac_sof_marker);
0795         if (n < 0) {
0796             gspca_dev->image_len += n;
0797         } else {
0798             gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
0799         }
0800 
0801         image = gspca_dev->image;
0802         if (image != NULL
0803          && image[gspca_dev->image_len - 2] == 0xff
0804          && image[gspca_dev->image_len - 1] == 0xd9)
0805             gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
0806 
0807         n = sof - data;
0808         len -= n;
0809         data = sof;
0810 
0811         /* Get average lumination */
0812         if (gspca_dev->last_packet_type == LAST_PACKET &&
0813                 n >= lum_offset)
0814             atomic_set(&sd->avg_lum, data[-lum_offset] +
0815                         data[-lum_offset + 1]);
0816 
0817         /* Start the new frame with the jpeg header */
0818         /* The PAC7302 has the image rotated 90 degrees */
0819         gspca_frame_add(gspca_dev, FIRST_PACKET,
0820                 jpeg_header, sizeof jpeg_header);
0821     }
0822     gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
0823 }
0824 
0825 #ifdef CONFIG_VIDEO_ADV_DEBUG
0826 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
0827             const struct v4l2_dbg_register *reg)
0828 {
0829     u8 index;
0830     u8 value;
0831 
0832     /*
0833      * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
0834      *             long on the USB bus)
0835      */
0836     if (reg->match.addr == 0 &&
0837         (reg->reg < 0x000000ff) &&
0838         (reg->val <= 0x000000ff)
0839     ) {
0840         /* Currently writing to page 0 is only supported. */
0841         /* reg_w() only supports 8bit index */
0842         index = reg->reg;
0843         value = reg->val;
0844 
0845         /*
0846          * Note that there shall be no access to other page
0847          * by any other function between the page switch and
0848          * the actual register write.
0849          */
0850         reg_w(gspca_dev, 0xff, 0x00);       /* page 0 */
0851         reg_w(gspca_dev, index, value);
0852 
0853         reg_w(gspca_dev, 0xdc, 0x01);
0854     }
0855     return gspca_dev->usb_err;
0856 }
0857 #endif
0858 
0859 #if IS_ENABLED(CONFIG_INPUT)
0860 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
0861             u8 *data,       /* interrupt packet data */
0862             int len)        /* interrupt packet length */
0863 {
0864     int ret = -EINVAL;
0865     u8 data0, data1;
0866 
0867     if (len == 2) {
0868         data0 = data[0];
0869         data1 = data[1];
0870         if ((data0 == 0x00 && data1 == 0x11) ||
0871             (data0 == 0x22 && data1 == 0x33) ||
0872             (data0 == 0x44 && data1 == 0x55) ||
0873             (data0 == 0x66 && data1 == 0x77) ||
0874             (data0 == 0x88 && data1 == 0x99) ||
0875             (data0 == 0xaa && data1 == 0xbb) ||
0876             (data0 == 0xcc && data1 == 0xdd) ||
0877             (data0 == 0xee && data1 == 0xff)) {
0878             input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
0879             input_sync(gspca_dev->input_dev);
0880             input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
0881             input_sync(gspca_dev->input_dev);
0882             ret = 0;
0883         }
0884     }
0885 
0886     return ret;
0887 }
0888 #endif
0889 
0890 /* sub-driver description for pac7302 */
0891 static const struct sd_desc sd_desc = {
0892     .name = KBUILD_MODNAME,
0893     .config = sd_config,
0894     .init = sd_init,
0895     .init_controls = sd_init_controls,
0896     .start = sd_start,
0897     .stopN = sd_stopN,
0898     .stop0 = sd_stop0,
0899     .pkt_scan = sd_pkt_scan,
0900     .dq_callback = do_autogain,
0901 #ifdef CONFIG_VIDEO_ADV_DEBUG
0902     .set_register = sd_dbg_s_register,
0903 #endif
0904 #if IS_ENABLED(CONFIG_INPUT)
0905     .int_pkt_scan = sd_int_pkt_scan,
0906 #endif
0907 };
0908 
0909 /* -- module initialisation -- */
0910 static const struct usb_device_id device_table[] = {
0911     {USB_DEVICE(0x06f8, 0x3009)},
0912     {USB_DEVICE(0x06f8, 0x301b)},
0913     {USB_DEVICE(0x093a, 0x2620)},
0914     {USB_DEVICE(0x093a, 0x2621)},
0915     {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
0916     {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
0917     {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
0918     {USB_DEVICE(0x093a, 0x2625)},
0919     {USB_DEVICE(0x093a, 0x2626)},
0920     {USB_DEVICE(0x093a, 0x2627), .driver_info = FL_VFLIP},
0921     {USB_DEVICE(0x093a, 0x2628)},
0922     {USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
0923     {USB_DEVICE(0x093a, 0x262a)},
0924     {USB_DEVICE(0x093a, 0x262c)},
0925     {USB_DEVICE(0x145f, 0x013c)},
0926     {USB_DEVICE(0x1ae7, 0x2001)}, /* SpeedLink Snappy Mic SL-6825-SBK */
0927     {}
0928 };
0929 MODULE_DEVICE_TABLE(usb, device_table);
0930 
0931 /* -- device connect -- */
0932 static int sd_probe(struct usb_interface *intf,
0933             const struct usb_device_id *id)
0934 {
0935     return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
0936                 THIS_MODULE);
0937 }
0938 
0939 static struct usb_driver sd_driver = {
0940     .name = KBUILD_MODNAME,
0941     .id_table = device_table,
0942     .probe = sd_probe,
0943     .disconnect = gspca_disconnect,
0944 #ifdef CONFIG_PM
0945     .suspend = gspca_suspend,
0946     .resume = gspca_resume,
0947     .reset_resume = gspca_resume,
0948 #endif
0949 };
0950 
0951 module_usb_driver(sd_driver);