V4L/DVB (9848): gspca: Webcam 06f8:3004 added in sonixj.
[safe/jmp/linux-2.6] / drivers / media / video / gspca / etoms.c
index 5bb8dc1..3be30b4 100644 (file)
@@ -22,9 +22,6 @@
 
 #include "gspca.h"
 
-#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("Etoms USB Camera Driver");
 MODULE_LICENSE("GPL");
@@ -84,6 +81,7 @@ static struct ctrl sd_ctrls[] = {
         .set = sd_setcontrast,
         .get = sd_getcontrast,
         },
+#define COLOR_IDX 2
        {
         {
          .id = V4L2_CID_SATURATION,
@@ -236,8 +234,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
 {
        struct usb_device *dev = gspca_dev->dev;
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       if (len > sizeof gspca_dev->usb_buf) {
+#ifdef GSPCA_DEBUG
+       if (len > USB_BUF_SZ) {
                err("reg_r: buffer overflow");
                return;
        }
@@ -274,8 +272,8 @@ static void reg_w(struct gspca_dev *gspca_dev,
 {
        struct usb_device *dev = gspca_dev->dev;
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-       if (len > sizeof gspca_dev->usb_buf) {
+#ifdef GSPCA_DEBUG
+       if (len > USB_BUF_SZ) {
                err("reg_w: buffer overflow");
                return;
        }
@@ -292,7 +290,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
 static int i2c_w(struct gspca_dev *gspca_dev,
                 __u8 reg,
                 const __u8 *buffer,
-                __u16 len, __u8 mode)
+                int len, __u8 mode)
 {
        /* buffer should be [D0..D7] */
        __u8 ptchcount;
@@ -464,6 +462,52 @@ static void Et_init2(struct gspca_dev *gspca_dev)
        reg_w_val(gspca_dev, 0x80, 0x20);       /* 0x20; */
 }
 
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       int i;
+       __u8 brightness = sd->brightness;
+
+       for (i = 0; i < 4; i++)
+               reg_w_val(gspca_dev, ET_O_RED + i, brightness);
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       int i;
+       int brightness = 0;
+
+       for (i = 0; i < 4; i++) {
+               reg_r(gspca_dev, ET_O_RED + i, 1);
+               brightness += gspca_dev->usb_buf[0];
+       }
+       sd->brightness = brightness >> 3;
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
+       __u8 contrast = sd->contrast;
+
+       memset(RGBG, contrast, sizeof(RGBG) - 2);
+       reg_w(gspca_dev, ET_G_RED, RGBG, 6);
+}
+
+static void getcontrast(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+       int i;
+       int contrast = 0;
+
+       for (i = 0; i < 4; i++) {
+               reg_r(gspca_dev, ET_G_RED + i, 1);
+               contrast += gspca_dev->usb_buf[0];
+       }
+       sd->contrast = contrast >> 2;
+}
+
 static void setcolors(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
@@ -495,6 +539,16 @@ static void getcolors(struct gspca_dev *gspca_dev)
        }
 }
 
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       if (sd->autogain)
+               sd->ag_cnt = AG_CNT_START;
+       else
+               sd->ag_cnt = -1;
+}
+
 static void Et_init1(struct gspca_dev *gspca_dev)
 {
        __u8 value;
@@ -602,42 +656,28 @@ static int sd_config(struct gspca_dev *gspca_dev,
 {
        struct sd *sd = (struct sd *) gspca_dev;
        struct cam *cam;
-       __u16 vendor;
-       __u16 product;
-
-       vendor = id->idVendor;
-       product = id->idProduct;
-/*     switch (vendor) { */
-/*     case 0x102c:            * Etoms */
-               switch (product) {
-               case 0x6151:
-                       sd->sensor = SENSOR_PAS106;     /* Etoms61x151 */
-                       break;
-               case 0x6251:
-                       sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */
-                       break;
-/*             } */
-/*             break; */
-       }
+
        cam = &gspca_dev->cam;
-       cam->dev_name = (char *) id->driver_info;
        cam->epaddr = 1;
+       sd->sensor = id->driver_info;
        if (sd->sensor == SENSOR_PAS106) {
                cam->cam_mode = sif_mode;
                cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
        } else {
                cam->cam_mode = vga_mode;
                cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+               gspca_dev->ctrl_dis = (1 << COLOR_IDX);
        }
        sd->brightness = BRIGHTNESS_DEF;
        sd->contrast = CONTRAST_DEF;
        sd->colors = COLOR_DEF;
        sd->autogain = AUTOGAIN_DEF;
+       sd->ag_cnt = -1;
        return 0;
 }
 
-/* this function is called at open time */
-static int sd_open(struct gspca_dev *gspca_dev)
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
@@ -651,7 +691,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
 }
 
 /* -- start the camera -- */
-static void sd_start(struct gspca_dev *gspca_dev)
+static int sd_start(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
@@ -660,8 +700,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
        else
                Et_init2(gspca_dev);
 
+       setautogain(gspca_dev);
+
        reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
        et_video(gspca_dev, 1);         /* video on */
+       return 0;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -669,60 +712,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
        et_video(gspca_dev, 0);         /* video off */
 }
 
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
-}
-
-static void sd_close(struct gspca_dev *gspca_dev)
-{
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-       int i;
-       __u8 brightness = sd->brightness;
-
-       for (i = 0; i < 4; i++)
-               reg_w_val(gspca_dev, ET_O_RED + i, brightness);
-}
-
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-       int i;
-       int brightness = 0;
-
-       for (i = 0; i < 4; i++) {
-               reg_r(gspca_dev, ET_O_RED + i, 1);
-               brightness += gspca_dev->usb_buf[0];
-       }
-       sd->brightness = brightness >> 3;
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-       __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
-       __u8 contrast = sd->contrast;
-
-       memset(RGBG, contrast, sizeof(RGBG) - 2);
-       reg_w(gspca_dev, ET_G_RED, RGBG, 6);
-}
-
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-       struct sd *sd = (struct sd *) gspca_dev;
-       int i;
-       int contrast = 0;
-
-       for (i = 0; i < 4; i++) {
-               reg_r(gspca_dev, ET_G_RED + i, 1);
-               contrast += gspca_dev->usb_buf[0];
-       }
-       sd->contrast = contrast >> 2;
-}
-
 static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
@@ -752,15 +741,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
 #define LIMIT(color) \
        (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color))
 
-static void setautogain(struct gspca_dev *gspca_dev)
+static void do_autogain(struct gspca_dev *gspca_dev)
 {
-       __u8 luma = 0;
+       struct sd *sd = (struct sd *) gspca_dev;
+       __u8 luma;
        __u8 luma_mean = 128;
        __u8 luma_delta = 20;
        __u8 spring = 4;
-       int Gbright = 0;
+       int Gbright;
        __u8 r, g, b;
 
+       if (sd->ag_cnt < 0)
+               return;
+       if (--sd->ag_cnt >= 0)
+               return;
+       sd->ag_cnt = AG_CNT_START;
+
        Gbright = Et_getgainG(gspca_dev);
        reg_r(gspca_dev, ET_LUMA_CENTER, 4);
        g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
@@ -787,7 +783,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                        __u8 *data,                     /* isoc packet */
                        int len)                        /* iso packet length */
 {
-       struct sd *sd;
        int seqframe;
 
        seqframe = data[0] & 0x3f;
@@ -802,13 +797,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
                frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
                                        data, 0);
                gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
-               sd = (struct sd *) gspca_dev;
-               if (sd->ag_cnt >= 0) {
-                       if (--sd->ag_cnt < 0) {
-                               sd->ag_cnt = AG_CNT_START;
-                               setautogain(gspca_dev);
-                       }
-               }
                return;
        }
        if (len) {
@@ -881,10 +869,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
        struct sd *sd = (struct sd *) gspca_dev;
 
        sd->autogain = val;
-       if (val)
-               sd->ag_cnt = AG_CNT_START;
-       else
-               sd->ag_cnt = -1;
+       if (gspca_dev->streaming)
+               setautogain(gspca_dev);
        return 0;
 }
 
@@ -902,21 +888,19 @@ static struct sd_desc sd_desc = {
        .ctrls = sd_ctrls,
        .nctrls = ARRAY_SIZE(sd_ctrls),
        .config = sd_config,
-       .open = sd_open,
+       .init = sd_init,
        .start = sd_start,
        .stopN = sd_stopN,
-       .stop0 = sd_stop0,
-       .close = sd_close,
        .pkt_scan = sd_pkt_scan,
+       .dq_callback = do_autogain,
 };
 
 /* -- module initialisation -- */
-#define DVNM(name) .driver_info = (kernel_ulong_t) name
 static __devinitdata struct usb_device_id device_table[] = {
-#ifndef CONFIG_USB_ET61X251
-       {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")},
+       {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
+#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
+       {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
 #endif
-       {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")},
        {}
 };
 
@@ -935,6 +919,10 @@ static struct usb_driver sd_driver = {
        .id_table = device_table,
        .probe = sd_probe,
        .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+       .suspend = gspca_suspend,
+       .resume = gspca_resume,
+#endif
 };
 
 /* -- module insert / remove -- */
@@ -942,7 +930,7 @@ static int __init sd_mod_init(void)
 {
        if (usb_register(&sd_driver) < 0)
                return -1;
-       PDEBUG(D_PROBE, "v%s registered", version);
+       PDEBUG(D_PROBE, "registered");
        return 0;
 }