V4L/DVB: Remove obsolete zc0301 v4l driver
[pandora-kernel.git] / drivers / media / video / gspca / zc3xx.c
index d02aa5c..4473f0f 100644 (file)
@@ -22,7 +22,6 @@
 #define MODULE_NAME "zc3xx"
 
 #include <linux/input.h>
-#include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
 
@@ -40,15 +39,16 @@ static int force_sensor = -1;
 struct sd {
        struct gspca_dev gspca_dev;     /* !! must be the first item */
 
+       u8 brightness;
        u8 contrast;
        u8 gamma;
        u8 autogain;
        u8 lightfreq;
        u8 sharpness;
        u8 quality;                     /* image quality */
-#define QUALITY_MIN 40
-#define QUALITY_MAX 60
-#define QUALITY_DEF 50
+#define QUALITY_MIN 50
+#define QUALITY_MAX 80
+#define QUALITY_DEF 70
 
        u8 sensor;              /* Type of image sensor chip */
 /* !! values used in different tables */
@@ -75,10 +75,12 @@ struct sd {
 #define SENSOR_MAX 19
        unsigned short chip_revision;
 
-       u8 *jpeg_hdr;
+       u8 jpeg_hdr[JPEG_HDR_SZ];
 };
 
 /* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
@@ -91,6 +93,20 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
 
 static const struct ctrl sd_ctrls[] = {
+       {
+           {
+               .id      = V4L2_CID_BRIGHTNESS,
+               .type    = V4L2_CTRL_TYPE_INTEGER,
+               .name    = "Brightness",
+               .minimum = 0,
+               .maximum = 255,
+               .step    = 1,
+#define BRIGHTNESS_DEF 128
+               .default_value = BRIGHTNESS_DEF,
+           },
+           .set = sd_setbrightness,
+           .get = sd_getbrightness,
+       },
        {
            {
                .id      = V4L2_CID_CONTRAST,
@@ -132,7 +148,7 @@ static const struct ctrl sd_ctrls[] = {
            .set = sd_setautogain,
            .get = sd_getautogain,
        },
-#define LIGHTFREQ_IDX 3
+#define LIGHTFREQ_IDX 4
        {
            {
                .id      = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -6011,9 +6027,12 @@ static void setcontrast(struct gspca_dev *gspca_dev)
        struct sd *sd = (struct sd *) gspca_dev;
        struct usb_device *dev = gspca_dev->dev;
        const u8 *Tgamma;
-       int g, i, k, adj, gp;
+       int g, i, brightness, contrast, adj, gp1, gp2;
        u8 gr[16];
-       static const u8 delta_tb[16] =          /* delta for contrast */
+       static const u8 delta_b[16] =           /* delta for brightness */
+               {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d,
+                0x1d, 0x1b, 0x1b, 0x1b, 0x19, 0x18, 0x18, 0x18};
+       static const u8 delta_c[16] =           /* delta for contrast */
                {0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06,
                 0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02};
        static const u8 gamma_tb[6][16] = {
@@ -6033,30 +6052,30 @@ static void setcontrast(struct gspca_dev *gspca_dev)
 
        Tgamma = gamma_tb[sd->gamma - 1];
 
-       k = ((int) sd->contrast - 128);         /* -128 / 128 */
+       contrast = ((int) sd->contrast - 128);          /* -128 / 127 */
+       brightness = ((int) sd->brightness - 128);      /* -128 / 92 */
        adj = 0;
-       gp = 0;
+       gp1 = gp2 = 0;
        for (i = 0; i < 16; i++) {
-               g = Tgamma[i] - delta_tb[i] * k / 256 - adj / 2;
+               g = Tgamma[i] + delta_b[i] * brightness / 256
+                               - delta_c[i] * contrast / 256 - adj / 2;
                if (g > 0xff)
                        g = 0xff;
                else if (g < 0)
                        g = 0;
                reg_w(dev, g, 0x0120 + i);      /* gamma */
-               if (k > 0)
+               if (contrast > 0)
                        adj--;
-               else
+               else if (contrast < 0)
                        adj++;
-
-               if (i != 0) {
-                       if (gp == 0)
-                               gr[i - 1] = 0;
-                       else
-                               gr[i - 1] = g - gp;
-               }
-               gp = g;
+               if (i > 1)
+                       gr[i - 1] = (g - gp2) / 2;
+               else if (i != 0)
+                       gr[0] = gp1 == 0 ? 0 : (g - gp1);
+               gp2 = gp1;
+               gp1 = g;
        }
-       gr[15] = gr[14] / 2;
+       gr[15] = (0xff - gp2) / 2;
        for (i = 0; i < 16; i++)
                reg_w(dev, gr[i], 0x0130 + i);  /* gradient */
 }
@@ -6744,6 +6763,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
                cam->nmodes = ARRAY_SIZE(broken_vga_mode);
                break;
        }
+       sd->brightness = BRIGHTNESS_DEF;
        sd->contrast = CONTRAST_DEF;
        sd->gamma = gamma[sd->sensor];
        sd->autogain = AUTOGAIN_DEF;
@@ -6798,9 +6818,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
        };
 
        /* create the JPEG header */
-       sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
-       if (!sd->jpeg_hdr)
-               return -ENOMEM;
        jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
                        0x21);          /* JPEG 422 */
        jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -6918,10 +6935,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
                reg_w(dev, 0x00, 0x0007);       /* (from win traces) */
                reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
                break;
-       case SENSOR_PAS202B:
-               reg_w(dev, 0x32, 0x0007);       /* (from win traces) */
-               reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
-               break;
        }
        return 0;
 }
@@ -6931,7 +6944,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
 {
        struct sd *sd = (struct sd *) gspca_dev;
 
-       kfree(sd->jpeg_hdr);
        if (!gspca_dev->present)
                return;
        send_unknown(gspca_dev->dev, sd->sensor);
@@ -6962,6 +6974,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       sd->brightness = val;
+       if (gspca_dev->streaming)
+               setcontrast(gspca_dev);
+       return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+       struct sd *sd = (struct sd *) gspca_dev;
+
+       *val = sd->brightness;
+       return 0;
+}
+
 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
 {
        struct sd *sd = (struct sd *) gspca_dev;
@@ -7163,9 +7193,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x046d, 0x08aa)},
        {USB_DEVICE(0x046d, 0x08ac)},
        {USB_DEVICE(0x046d, 0x08ad)},
-#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
        {USB_DEVICE(0x046d, 0x08ae)},
-#endif
        {USB_DEVICE(0x046d, 0x08af)},
        {USB_DEVICE(0x046d, 0x08b9)},
        {USB_DEVICE(0x046d, 0x08d7)},