Merge branch 'r8169-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/romieu...
[cascardo/linux.git] / drivers / media / video / gspca / spca561.c
index a94e627..b659bd0 100644 (file)
@@ -24,8 +24,8 @@
 
 #include "gspca.h"
 
-#define DRIVER_VERSION_NUMBER  KERNEL_VERSION(2, 1, 0)
-static const char version[] = "2.1.0";
+#define DRIVER_VERSION_NUMBER  KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
 
 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
 MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
@@ -97,11 +97,27 @@ static struct ctrl sd_ctrls[] = {
         },
 };
 
-static struct cam_mode sif_mode[] = {
-       {V4L2_PIX_FMT_SPCA561, 160, 120, 3},
-       {V4L2_PIX_FMT_SPCA561, 176, 144, 2},
-       {V4L2_PIX_FMT_SPCA561, 320, 240, 1},
-       {V4L2_PIX_FMT_SPCA561, 352, 288, 0},
+static struct v4l2_pix_format sif_mode[] = {
+       {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+               .bytesperline = 160,
+               .sizeimage = 160 * 120,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .priv = 3},
+       {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+               .bytesperline = 176,
+               .sizeimage = 176 * 144,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .priv = 2},
+       {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
+               .bytesperline = 320,
+               .sizeimage = 320 * 240 * 4 / 8,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .priv = 1},
+       {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
+               .bytesperline = 352,
+               .sizeimage = 352 * 288 * 4 / 8,
+               .colorspace = V4L2_COLORSPACE_SRGB,
+               .priv = 0},
 };
 
 /*
@@ -148,7 +164,8 @@ static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value)
                PDEBUG(D_ERR, "reg write: error %d", ret);
 }
 
-static void write_vector(struct gspca_dev *gspca_dev, __u16 data[][2])
+static void write_vector(struct gspca_dev *gspca_dev,
+                       const __u16 data[][2])
 {
        struct usb_device *dev = gspca_dev->dev;
        int i;
@@ -160,24 +177,28 @@ static void write_vector(struct gspca_dev *gspca_dev, __u16 data[][2])
        }
 }
 
-static void reg_r(struct usb_device *dev,
-                 __u16 index, __u8 *buffer, __u16 length)
+/* read 'len' bytes to gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+                 __u16 index, __u16 length)
 {
-       usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+       usb_control_msg(gspca_dev->dev,
+                       usb_rcvctrlpipe(gspca_dev->dev, 0),
                        0,                      /* request */
                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                        0,                      /* value */
-                       index, buffer, length, 500);
+                       index, gspca_dev->usb_buf, length, 500);
 }
 
-static void reg_w_buf(struct usb_device *dev,
-                     __u16 index, __u8 *buffer, __u16 length)
+static void reg_w_buf(struct gspca_dev *gspca_dev,
+                     __u16 index, const __u8 *buffer, __u16 len)
 {
-       usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+       memcpy(gspca_dev->usb_buf, buffer, len);
+       usb_control_msg(gspca_dev->dev,
+                       usb_sndctrlpipe(gspca_dev->dev, 0),
                        0,                      /* request */
                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                        0,                      /* value */
-                       index, buffer, length, 500);
+                       index, gspca_dev->usb_buf, len, 500);
 }
 
 static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode)
@@ -191,7 +212,6 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
        int retry = 60;
        __u8 DataLow;
        __u8 DataHight;
-       __u8 Data;
 
        DataLow = valeur;
        DataHight = valeur >> 8;
@@ -199,8 +219,8 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
        reg_w_val(gspca_dev->dev, DataLow, 0x8805);
        reg_w_val(gspca_dev->dev, DataHight, 0x8800);
        while (retry--) {
-               reg_r(gspca_dev->dev, 0x8803, &Data, 1);
-               if (!Data)
+               reg_r(gspca_dev, 0x8803, 1);
+               if (!gspca_dev->usb_buf[0])
                        break;
        }
 }
@@ -210,24 +230,25 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
        int retry = 60;
        __u8 value;
        __u8 vallsb;
-       __u8 Data;
 
        reg_w_val(gspca_dev->dev, 0x92, 0x8804);
        reg_w_val(gspca_dev->dev, reg, 0x8801);
        reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802);
        while (retry--) {
-               reg_r(gspca_dev->dev, 0x8803, &Data, 1);
-               if (!Data)
+               reg_r(gspca_dev, 0x8803, 1);
+               if (!gspca_dev->usb_buf)
                        break;
        }
        if (retry == 0)
                return -1;
-       reg_r(gspca_dev->dev, 0x8800, &value, 1);
-       reg_r(gspca_dev->dev, 0x8805, &vallsb, 1);
+       reg_r(gspca_dev, 0x8800, 1);
+       value = gspca_dev->usb_buf[0];
+       reg_r(gspca_dev, 0x8805, 1);
+       vallsb = gspca_dev->usb_buf[0];
        return ((int) value << 8) | vallsb;
 }
 
-static __u16 spca561_init_data[][2] = {
+static const __u16 spca561_init_data[][2] = {
        {0x0000, 0x8114},       /* Software GPIO output data */
        {0x0001, 0x8114},       /* Software GPIO output data */
        {0x0000, 0x8112},       /* Some kind of reset */
@@ -437,7 +458,7 @@ static void sensor_reset(struct gspca_dev *gspca_dev)
 }
 
 /******************** QC Express etch2 stuff ********************/
-static __u16 Pb100_1map8300[][2] = {
+static const __u16 Pb100_1map8300[][2] = {
        /* reg, value */
        {0x8320, 0x3304},
 
@@ -452,14 +473,14 @@ static __u16 Pb100_1map8300[][2] = {
        {0x8302, 0x000e},
        {}
 };
-static __u16 Pb100_2map8300[][2] = {
+static const __u16 Pb100_2map8300[][2] = {
        /* reg, value */
        {0x8339, 0x0000},
        {0x8307, 0x00aa},
        {}
 };
 
-static __u16 spca561_161rev12A_data1[][2] = {
+static const __u16 spca561_161rev12A_data1[][2] = {
        {0x21, 0x8118},
        {0x01, 0x8114},
        {0x00, 0x8112},
@@ -467,7 +488,7 @@ static __u16 spca561_161rev12A_data1[][2] = {
        {0x04, 0x8802},         /* windows uses 08 */
        {}
 };
-static __u16 spca561_161rev12A_data2[][2] = {
+static const __u16 spca561_161rev12A_data2[][2] = {
        {0x21, 0x8118},
        {0x10, 0x8500},
        {0x07, 0x8601},
@@ -513,7 +534,7 @@ static __u16 spca561_161rev12A_data2[][2] = {
 };
 
 static void sensor_mapwrite(struct gspca_dev *gspca_dev,
-                           __u16 sensormap[][2])
+                           const __u16 sensormap[][2])
 {
        int i = 0;
        __u8 usbval[2];
@@ -521,7 +542,7 @@ static void sensor_mapwrite(struct gspca_dev *gspca_dev,
        while (sensormap[i][0]) {
                usbval[0] = sensormap[i][1];
                usbval[1] = sensormap[i][1] >> 8;
-               reg_w_buf(gspca_dev->dev, sensormap[i][0], usbval, 2);
+               reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2);
                i++;
        }
 }
@@ -539,7 +560,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
                     const struct usb_device_id *id)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       struct usb_device *dev = gspca_dev->dev;
        struct cam *cam;
        __u16 vendor, product;
        __u8 data1, data2;
@@ -548,11 +568,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
         * prove that we can communicate with the device.  This works, which
         * confirms at we are communicating properly and that the device
         * is a 561. */
-       reg_r(dev, 0x8104, &data1, 1);
-       reg_r(dev, 0x8105, &data2, 1);
+       reg_r(gspca_dev, 0x8104, 1);
+       data1 = gspca_dev->usb_buf[0];
+       reg_r(gspca_dev, 0x8105, 1);
+       data2 = gspca_dev->usb_buf[0];
        vendor = (data2 << 8) | data1;
-       reg_r(dev, 0x8106, &data1, 1);
-       reg_r(dev, 0x8107, &data2, 1);
+       reg_r(gspca_dev, 0x8106, 1);
+       data1 = gspca_dev->usb_buf[0];
+       reg_r(gspca_dev, 0x8107, 1);
+       data2 = gspca_dev->usb_buf[0];
        product = (data2 << 8) | data1;
        if (vendor != id->idVendor || product != id->idProduct) {
                PDEBUG(D_PROBE, "Bad vendor / product from device");
@@ -636,8 +660,8 @@ static void setcontrast(struct gspca_dev *gspca_dev)
                Reg8391[0] = expotimes & 0xff;  /* exposure */
                Reg8391[1] = 0x18 | (expotimes >> 8);
                Reg8391[2] = sd->brightness;    /* gain */
-               reg_w_buf(dev, 0x8391, Reg8391, 8);
-               reg_w_buf(dev, 0x8390, Reg8391, 8);
+               reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
+               reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
                break;
            }
        }
@@ -651,7 +675,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
        __u8 Reg8307[] = { 0xaa, 0x00 };
        int mode;
 
-       mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode;
+       mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
        switch (sd->chip_revision) {
        case Rev072A:
                switch (mode) {
@@ -694,10 +718,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
                         * is sufficient to push raw frames at ~20fps */
                        reg_w_val(dev, 0x8500, mode);
                }               /* -- qq@kuku.eu.org */
-               reg_w_buf(dev, 0x8307, Reg8307, 2);
-               reg_w_val(dev, 0x8700, Clck);   /* 0x8f 0x85 0x27 clock */
-               reg_w_val(dev, 0x8112, 0x1e | 0x20);
-               reg_w_val(dev, 0x850b, 0x03);
+               reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
+               reg_w_val(gspca_dev->dev, 0x8700, Clck);
+                                               /* 0x8f 0x85 0x27 clock */
+               reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
+               reg_w_val(gspca_dev->dev, 0x850b, 0x03);
                setcontrast(gspca_dev);
                break;
        }
@@ -732,10 +757,14 @@ static void setautogain(struct gspca_dev *gspca_dev)
 
        switch (sd->chip_revision) {
        case Rev072A:
-               reg_r(gspca_dev->dev, 0x8621, &Gr, 1);
-               reg_r(gspca_dev->dev, 0x8622, &R, 1);
-               reg_r(gspca_dev->dev, 0x8623, &B, 1);
-               reg_r(gspca_dev->dev, 0x8624, &Gb, 1);
+               reg_r(gspca_dev, 0x8621, 1);
+               Gr = gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8622, 1);
+               R = gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8623, 1);
+               B = gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8624, 1);
+               Gb = gspca_dev->usb_buf[0];
                y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
                /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
                /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
@@ -808,7 +837,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                        gspca_frame_add(gspca_dev, FIRST_PACKET,
                                        frame, data, len);
                } else {
-                       /*fixme: which format?*/
+                       /* raw bayer (with a header, which we skip) */
                        data += 20;
                        len -= 20;
                        gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -847,20 +876,19 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 static void getbrightness(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       __u8 value;
        __u16 tot;
 
        switch (sd->chip_revision) {
        case Rev072A:
                tot = 0;
-               reg_r(gspca_dev->dev, 0x8611, &value, 1);
-               tot += value;
-               reg_r(gspca_dev->dev, 0x8612, &value, 1);
-               tot += value;
-               reg_r(gspca_dev->dev, 0x8613, &value, 1);
-               tot += value;
-               reg_r(gspca_dev->dev, 0x8614, &value, 1);
-               tot += value;
+               reg_r(gspca_dev, 0x8611, 1);
+               tot += gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8612, 1);
+               tot += gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8613, 1);
+               tot += gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8614, 1);
+               tot += gspca_dev->usb_buf[0];
                sd->brightness = tot >> 2;
                break;
        default:
@@ -873,20 +901,19 @@ static void getbrightness(struct gspca_dev *gspca_dev)
 static void getcontrast(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
-       __u8 value;
        __u16 tot;
 
        switch (sd->chip_revision) {
        case Rev072A:
                tot = 0;
-               reg_r(gspca_dev->dev, 0x8651, &value, 1);
-               tot += value;
-               reg_r(gspca_dev->dev, 0x8652, &value, 1);
-               tot += value;
-               reg_r(gspca_dev->dev, 0x8653, &value, 1);
-               tot += value;
-               reg_r(gspca_dev->dev, 0x8654, &value, 1);
-               tot += value;
+               reg_r(gspca_dev, 0x8651, 1);
+               tot += gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8652, 1);
+               tot += gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8653, 1);
+               tot += gspca_dev->usb_buf[0];
+               reg_r(gspca_dev, 0x8654, 1);
+               tot += gspca_dev->usb_buf[0];
                sd->contrast = tot << 6;
                break;
        default:
@@ -956,7 +983,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
 }
 
 /* sub-driver description */
-static struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc = {
        .name = MODULE_NAME,
        .ctrls = sd_ctrls,
        .nctrls = ARRAY_SIZE(sd_ctrls),
@@ -971,7 +998,7 @@ static struct sd_desc sd_desc = {
 
 /* -- module initialisation -- */
 #define DVNM(name) .driver_info = (kernel_ulong_t) name
-static __devinitdata struct usb_device_id device_table[] = {
+static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")},
        {USB_DEVICE(0x041e, 0x403b),  DVNM("Creative Webcam Vista (VF0010)")},
        {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")},