Changes:

- Delete the correct entry in the outgoing queue during DQBUF
- Implement correct image downscaling selection through VIDIOC_S_[CROP|FTM]
- Replace darkness controls with brightness (simple swapping) for PAS106B and
  PAS202BCB
- Implement gain control for TAS5110C1B and TAS5130D1B
- Add a note to the documentation about correct image downscaling selection

Signed-off-by: Luca Risolia <[EMAIL PROTECTED]>

Greg, please apply.

Thanks,
        Luca


diff -uprN -X dontdiff linux-2.6.7/Documentation/usb/sn9c102.txt 
devel-2.6.7/Documentation/usb/sn9c102.txt
--- linux-2.6.7/Documentation/usb/sn9c102.txt   2004-08-12 04:03:13.000000000 +0200
+++ devel-2.6.7/Documentation/usb/sn9c102.txt   2004-08-12 04:25:22.000000000 +0200
@@ -14,10 +14,10 @@ Index
 4.  Module dependencies
 5.  Module loading
 6.  Module parameters
-7.  Device control through "sysfs"
+7.  Optional device control through "sysfs"
 8.  Supported devices
 9.  How to add support for new image sensors
-10. Note for V4L2 developers
+10. Notes for V4L2 application developers
 11. Contact information
 12. Credits
 
@@ -148,8 +148,8 @@ Default:        2
 -------------------------------------------------------------------------------
 
 
-7. Device control through "sysfs"
-=================================
+7. Optional device control through "sysfs"
+==========================================
 It is possible to read and write both the SN9C10[12] and the image sensor
 registers by using the "sysfs" filesystem interface.
 
@@ -206,7 +206,7 @@ Vendor ID  Product ID
 0xc45      0x6029
 0xc45      0x602a
 0xc45      0x602c
-0xc45      0x8001
+0xc45      0x6030
 
 The list above does NOT imply that all those devices work with this driver: up
 until now only the ones that mount the following image sensors are supported.
@@ -242,19 +242,27 @@ At the moment, not yet supported image s
 MI03 (VGA), OV7620 (VGA).
 
 
-10. Note for V4L2 developers
-============================
+10. Notes for V4L2 application developers
+=========================================
 This driver follows the V4L2 API specifications. In particular, it enforces two
 rules:
 
-1) Exactly one I/O method, either "mmap" or "read", is associated with each
+- exactly one I/O method, either "mmap" or "read", is associated with each
 file descriptor. Once it is selected, the application must close and reopen the
-device to switch to the other I/O method.
+device to switch to the other I/O method;
 
-2) Previously mapped buffer memory must always be unmapped before calling any
-of the "VIDIOC_S_CROP", "VIDIOC_TRY_FMT" and "VIDIOC_S_FMT" ioctl's. In case,
-the same number of buffers as before will be allocated again to match the size
-of the new video frames, so you have to map them again before any I/O attempts.
+- previously mapped buffer memory must always be unmapped before calling any
+of the "VIDIOC_S_CROP", "VIDIOC_TRY_FMT" and "VIDIOC_S_FMT" ioctl's. The same
+number of buffers as before will be allocated again to match the size of the
+new video frames, so you have to map them again before any I/O attempts.
+
+Consistently with the hardware limits, this driver also supports image
+downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions.
+However the V4L2 API specifications don't correctly define how the scaling
+factor can be choosen arbitrarily by the "negotiation" of the "source" and
+"target" rectangles. To work around this flaw, we have added the convention
+that, during the negotiation, whenever the "VIDIOC_S_CROP" ioctl is issued, the
+scaling factor is restored to 1.
 
 
 11. Contact information
diff -uprN -X dontdiff linux-2.6.7/drivers/usb/media/sn9c102_core.c 
devel-2.6.7/drivers/usb/media/sn9c102_core.c
--- linux-2.6.7/drivers/usb/media/sn9c102_core.c        2004-08-12 04:04:08.000000000 
+0200
+++ devel-2.6.7/drivers/usb/media/sn9c102_core.c        2004-08-12 04:15:32.000000000 
+0200
@@ -31,6 +31,7 @@
 #include <linux/time.h>
 #include <linux/delay.h>
 #include <linux/stddef.h>
+#include <linux/compiler.h>
 #include <linux/ioctl.h>
 #include <linux/poll.h>
 #include <linux/stat.h>
@@ -1731,13 +1732,15 @@ static int sn9c102_v4l2_ioctl(struct ino
                rect->width &= ~15L;
                rect->height &= ~15L;
 
-               { /* calculate the actual scaling factor */
+               if (SN9C102_PRESERVE_IMGSCALE) {
+                       /* Calculate the actual scaling factor */
                        u32 a, b;
                        a = rect->width * rect->height;
                        b = pix_format->width * pix_format->height;
                        scale = b ? (u8)((a / b) < 4 ? 1 :
                                        ((a / b) < 16 ? 2 : 4)) : 1;
-               }
+               } else
+                       scale = 1;
 
                if (cam->stream == STREAM_ON) {
                        cam->stream = STREAM_INTERRUPT;
@@ -2111,7 +2114,7 @@ static int sn9c102_v4l2_ioctl(struct ino
                spin_lock_irqsave(&cam->queue_lock, lock_flags);
                f = list_entry(cam->outqueue.next, struct sn9c102_frame_t,
                               frame);
-               list_del(&cam->outqueue);
+               list_del(cam->outqueue.next);
                spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
 
                f->state = F_UNUSED;
diff -uprN -X dontdiff linux-2.6.7/drivers/usb/media/sn9c102.h 
devel-2.6.7/drivers/usb/media/sn9c102.h
--- linux-2.6.7/drivers/usb/media/sn9c102.h     2004-08-12 04:04:08.000000000 +0200
+++ devel-2.6.7/drivers/usb/media/sn9c102.h     2004-08-12 04:16:47.000000000 +0200
@@ -40,6 +40,7 @@
 #define SN9C102_DEBUG
 #define SN9C102_DEBUG_LEVEL       2
 #define SN9C102_MAX_DEVICES       64
+#define SN9C102_PRESERVE_IMGSCALE 0
 #define SN9C102_MAX_FRAMES        32
 #define SN9C102_URBS              2
 #define SN9C102_ISO_PACKETS       7
@@ -52,8 +53,8 @@
 #define SN9C102_MODULE_AUTHOR   "(C) 2004 Luca Risolia"
 #define SN9C102_AUTHOR_EMAIL    "<[EMAIL PROTECTED]>"
 #define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.07"
-#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 7)
+#define SN9C102_MODULE_VERSION  "1:1.08"
+#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 8)
 
 SN9C102_ID_TABLE;
 SN9C102_SENSOR_TABLE;
diff -uprN -X dontdiff linux-2.6.7/drivers/usb/media/sn9c102_pas106b.c 
devel-2.6.7/drivers/usb/media/sn9c102_pas106b.c
--- linux-2.6.7/drivers/usb/media/sn9c102_pas106b.c     2004-08-12 04:04:08.000000000 
+0200
+++ devel-2.6.7/drivers/usb/media/sn9c102_pas106b.c     2004-08-12 04:15:47.000000000 
+0200
@@ -109,7 +109,7 @@ static int pas106b_set_ctrl(struct sn9c1
                err += sn9c102_i2c_write(cam, 0x0e, ctrl->value & 0x1f);
                break;
        case V4L2_CID_BRIGHTNESS:
-               err += sn9c102_i2c_write(cam, 0x0d, ctrl->value & 0x1f);
+               err += sn9c102_i2c_write(cam, 0x0d, 0x1f-(ctrl->value & 0x1f));
                break;
        case V4L2_CID_CONTRAST:
                err += sn9c102_i2c_write(cam, 0x0f, ctrl->value & 0x03);
@@ -180,11 +180,11 @@ static struct sn9c102_sensor pas106b = {
                {
                        .id = V4L2_CID_BRIGHTNESS,
                        .type = V4L2_CTRL_TYPE_INTEGER,
-                       .name = "darkness",
+                       .name = "brightness",
                        .minimum = 0x00,
                        .maximum = 0x1f,
                        .step = 0x01,
-                       .default_value = 0x00,
+                       .default_value = 0x1f,
                        .flags = 0,
                },
                {
diff -uprN -X dontdiff linux-2.6.7/drivers/usb/media/sn9c102_pas202bcb.c 
devel-2.6.7/drivers/usb/media/sn9c102_pas202bcb.c
--- linux-2.6.7/drivers/usb/media/sn9c102_pas202bcb.c   2004-08-12 04:04:08.000000000 
+0200
+++ devel-2.6.7/drivers/usb/media/sn9c102_pas202bcb.c   2004-08-12 04:15:54.000000000 
+0200
@@ -104,7 +104,7 @@ static int pas202bcb_set_ctrl(struct sn9
                err += sn9c102_i2c_write(cam, 0x10, ctrl->value & 0x1f);
                break;
        case V4L2_CID_BRIGHTNESS:
-               err += sn9c102_i2c_write(cam, 0x06, ctrl->value & 0x0f);
+               err += sn9c102_i2c_write(cam, 0x06, 0x0f-(ctrl->value & 0x0f));
                break;
        default:
                return -EINVAL;
@@ -173,11 +173,11 @@ static struct sn9c102_sensor pas202bcb =
                {
                        .id = V4L2_CID_BRIGHTNESS,
                        .type = V4L2_CTRL_TYPE_INTEGER,
-                       .name = "darkness",
+                       .name = "brightness",
                        .minimum = 0x00,
                        .maximum = 0x0f,
                        .step = 0x01,
-                       .default_value = 0x00,
+                       .default_value = 0x0f,
                        .flags = 0,
                },
        },
diff -uprN -X dontdiff linux-2.6.7/drivers/usb/media/sn9c102_tas5110c1b.c 
devel-2.6.7/drivers/usb/media/sn9c102_tas5110c1b.c
--- linux-2.6.7/drivers/usb/media/sn9c102_tas5110c1b.c  2004-08-12 04:04:08.000000000 
+0200
+++ devel-2.6.7/drivers/usb/media/sn9c102_tas5110c1b.c  2004-08-12 04:16:12.000000000 
+0200
@@ -27,7 +27,6 @@ static struct sn9c102_sensor tas5110c1b;
 
 static int tas5110c1b_init(struct sn9c102_device* cam)
 {
-       const u8 DARKNESS = 0xb7;
        int err = 0;
 
        err += sn9c102_write_reg(cam, 0x01, 0x01);
@@ -41,13 +40,26 @@ static int tas5110c1b_init(struct sn9c10
 
        err += sn9c102_i2c_try_raw_write(cam, &tas5110c1b, 4, 0x11, 0x00, 0xc0,
                                         0x80, 0, 0);
-       err += sn9c102_i2c_try_raw_write(cam, &tas5110c1b, 4, 0x11, 0x02, 0x20,
-                                        DARKNESS, 0, 0);
 
        return err;
 }
 
 
+static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, 
+                               const struct v4l2_control* ctrl)
+{
+       switch (ctrl->id) {
+       case V4L2_CID_GAIN:
+               return sn9c102_i2c_try_raw_write(cam, &tas5110c1b, 4, 0x11,
+                                                0x02, 0x20,
+                                                0xff - (ctrl->value & 0xff),
+                                                0, 0);
+       default:
+               return -EINVAL;
+       }
+}
+
+
 static int tas5110c1b_set_crop(struct sn9c102_device* cam, 
                                const struct v4l2_rect* rect)
 {
@@ -74,6 +86,19 @@ static struct sn9c102_sensor tas5110c1b 
        .frequency = SN9C102_I2C_100KHZ,
        .interface = SN9C102_I2C_3WIRES,
        .init = &tas5110c1b_init,
+       .qctrl = {
+               {
+                       .id = V4L2_CID_GAIN,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "global gain",
+                       .minimum = 0x00,
+                       .maximum = 0xff,
+                       .step = 0x01,
+                       .default_value = 0x48,
+                       .flags = 0,
+               },
+       },
+       .set_ctrl = &tas5110c1b_set_ctrl,
        .cropcap = {
                .bounds = {
                        .left = 0,
diff -uprN -X dontdiff linux-2.6.7/drivers/usb/media/sn9c102_tas5130d1b.c 
devel-2.6.7/drivers/usb/media/sn9c102_tas5130d1b.c
--- linux-2.6.7/drivers/usb/media/sn9c102_tas5130d1b.c  2004-08-12 04:04:08.000000000 
+0200
+++ devel-2.6.7/drivers/usb/media/sn9c102_tas5130d1b.c  2004-08-12 04:16:20.000000000 
+0200
@@ -27,7 +27,6 @@ static struct sn9c102_sensor tas5130d1b;
 
 static int tas5130d1b_init(struct sn9c102_device* cam)
 {
-       const u8 DARKNESS = 0xff, CONTRAST = 0xb0, GAIN = 0x08;
        int err = 0;
 
        err += sn9c102_write_reg(cam, 0x01, 0x01);
@@ -39,19 +38,28 @@ static int tas5130d1b_init(struct sn9c10
        err += sn9c102_write_reg(cam, 0x60, 0x17);
        err += sn9c102_write_reg(cam, 0x07, 0x18);
 
-       err += sn9c102_i2c_try_raw_write(cam, &tas5130d1b, 4, 0x11, 0x00, 0x80,
-                                        0x00, 0, 0);
-       err += sn9c102_i2c_try_raw_write(cam, &tas5130d1b, 4, 0x11, 0x00, 0xc0,
-                                        GAIN, 0, 0);
        err += sn9c102_i2c_try_raw_write(cam, &tas5130d1b, 4, 0x11, 0x00, 0x40,
-                                        CONTRAST, 0, 0);
-       err += sn9c102_i2c_try_raw_write(cam, &tas5130d1b, 4, 0x11, 0x02, 0x20,
-                                        DARKNESS, 0, 0);
+                                        0x47, 0, 0);
 
        return err;
 }
 
 
+static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, 
+                               const struct v4l2_control* ctrl)
+{
+       switch (ctrl->id) {
+       case V4L2_CID_GAIN:
+               return sn9c102_i2c_try_raw_write(cam, &tas5130d1b, 4, 0x11,
+                                                0x02, 0x20,
+                                                0xff - (ctrl->value & 0xff),
+                                                0, 0);
+       default:
+               return -EINVAL;
+       }
+}
+
+
 static int tas5130d1b_set_crop(struct sn9c102_device* cam, 
                                const struct v4l2_rect* rect)
 {
@@ -78,6 +86,19 @@ static struct sn9c102_sensor tas5130d1b 
        .frequency = SN9C102_I2C_100KHZ,
        .interface = SN9C102_I2C_3WIRES,
        .init = &tas5130d1b_init,
+       .qctrl = {
+               {
+                       .id = V4L2_CID_GAIN,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "global gain",
+                       .minimum = 0x00,
+                       .maximum = 0xff,
+                       .step = 0x01,
+                       .default_value = 0x00,
+                       .flags = 0,
+               },
+       },
+       .set_ctrl = &tas5130d1b_set_ctrl,
        .cropcap = {
                .bounds = {
                        .left = 0,

Attachment: pgpWOxetUI8yD.pgp
Description: PGP signature

Reply via email to