aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-10-16 06:13:07 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:44 -0500
commita511ba947600ae263f8c29c86020ba66a901d3e5 (patch)
treed27d646a98aa45f92a2df78eb66d7cfe0f446ff6 /drivers/media
parenteea85b0a629970d462481a80e1d45f4d71fe797f (diff)
V4L/DVB (13178): gspca: Add support for Winbond W9967CF and W9968CF camera's
This patch adds support to gspca for the Winbond W9967CF and W9968CF camera's. This is mostly a port of the existing v4l1 driver to gspca (making it v4l2). But this also features fixes to the bitbanging i2c code (send a nack not an ack after reading the last byte of a transfer), which gets rid of the weird errors which were being seen there, and of the smbus_refresh() hack to get around these errors. Also the vstart settings have been tweaked to work with different frequency filter settings. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/Kconfig11
-rw-r--r--drivers/media/video/gspca/Kconfig5
-rw-r--r--drivers/media/video/gspca/gspca.c22
-rw-r--r--drivers/media/video/gspca/gspca.h1
-rw-r--r--drivers/media/video/gspca/ov519.c115
-rw-r--r--drivers/media/video/gspca/w996Xcf.c589
6 files changed, 713 insertions, 30 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 0ab7ccd8729b..c69f858c9278 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -951,9 +951,13 @@ source "drivers/media/video/usbvideo/Kconfig"
951source "drivers/media/video/et61x251/Kconfig" 951source "drivers/media/video/et61x251/Kconfig"
952 952
953config VIDEO_OVCAMCHIP 953config VIDEO_OVCAMCHIP
954 tristate "OmniVision Camera Chip support" 954 tristate "OmniVision Camera Chip support (DEPRECATED)"
955 depends on I2C && VIDEO_V4L1 955 depends on I2C && VIDEO_V4L1
956 ---help--- 956 ---help---
957 This driver is DEPRECATED please use the gspca ov519 module
958 instead. Note that for the ov511 / ov518 support of the gspca module
959 you need atleast version 0.6.0 of libv4l.
960
957 Support for the OmniVision OV6xxx and OV7xxx series of camera chips. 961 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
958 This driver is intended to be used with the ov511 and w9968cf USB 962 This driver is intended to be used with the ov511 and w9968cf USB
959 camera drivers. 963 camera drivers.
@@ -962,9 +966,12 @@ config VIDEO_OVCAMCHIP
962 module will be called ovcamchip. 966 module will be called ovcamchip.
963 967
964config USB_W9968CF 968config USB_W9968CF
965 tristate "USB W996[87]CF JPEG Dual Mode Camera support" 969 tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
966 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP 970 depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
967 ---help--- 971 ---help---
972 This driver is DEPRECATED please use the gspca ov519 module
973 instead.
974
968 Say Y here if you want support for cameras based on OV681 or 975 Say Y here if you want support for cameras based on OV681 or
969 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips. 976 Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
970 977
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index fe2e490ebc52..cbc2367719f0 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -76,10 +76,11 @@ config USB_GSPCA_MR97310A
76 module will be called gspca_mr97310a. 76 module will be called gspca_mr97310a.
77 77
78config USB_GSPCA_OV519 78config USB_GSPCA_OV519
79 tristate "OV519 USB Camera Driver" 79 tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
80 depends on VIDEO_V4L2 && USB_GSPCA 80 depends on VIDEO_V4L2 && USB_GSPCA
81 help 81 help
82 Say Y here if you want support for cameras based on the OV519 chip. 82 Say Y here if you want support for cameras based on one of these:
83 OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF
83 84
84 To compile this driver as a module, choose M here: the 85 To compile this driver as a module, choose M here: the
85 module will be called gspca_ov519. 86 module will be called gspca_ov519.
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 179cbc14ee51..ebaa2425fb50 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -475,10 +475,18 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
475 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK 475 xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
476 : USB_ENDPOINT_XFER_ISOC; 476 : USB_ENDPOINT_XFER_ISOC;
477 i = gspca_dev->alt; /* previous alt setting */ 477 i = gspca_dev->alt; /* previous alt setting */
478 while (--i >= 0) { 478 if (gspca_dev->cam.reverse_alts) {
479 ep = alt_xfer(&intf->altsetting[i], xfer); 479 while (++i < gspca_dev->nbalt) {
480 if (ep) 480 ep = alt_xfer(&intf->altsetting[i], xfer);
481 break; 481 if (ep)
482 break;
483 }
484 } else {
485 while (--i >= 0) {
486 ep = alt_xfer(&intf->altsetting[i], xfer);
487 if (ep)
488 break;
489 }
482 } 490 }
483 if (ep == NULL) { 491 if (ep == NULL) {
484 err("no transfer endpoint found"); 492 err("no transfer endpoint found");
@@ -599,7 +607,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
599 607
600 /* set the higher alternate setting and 608 /* set the higher alternate setting and
601 * loop until urb submit succeeds */ 609 * loop until urb submit succeeds */
602 gspca_dev->alt = gspca_dev->nbalt; 610 if (gspca_dev->cam.reverse_alts)
611 gspca_dev->alt = 0;
612 else
613 gspca_dev->alt = gspca_dev->nbalt;
614
603 if (gspca_dev->sd_desc->isoc_init) { 615 if (gspca_dev->sd_desc->isoc_init) {
604 ret = gspca_dev->sd_desc->isoc_init(gspca_dev); 616 ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
605 if (ret < 0) 617 if (ret < 0)
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 70b1fd830876..1d761d7cefc6 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -58,6 +58,7 @@ struct cam {
58 u8 npkt; /* number of packets in an ISOC message 58 u8 npkt; /* number of packets in an ISOC message
59 * 0 is the default value: 32 packets */ 59 * 0 is the default value: 32 packets */
60 u32 input_flags; /* value for ENUM_INPUT status flags */ 60 u32 input_flags; /* value for ENUM_INPUT status flags */
61 char reverse_alts; /* Alt settings are in high to low order */
61}; 62};
62 63
63struct gspca_dev; 64struct gspca_dev;
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 4d6a762a6f3d..994a5e927d2d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -64,6 +64,7 @@ struct sd {
64#define BRIDGE_OV518PLUS 3 64#define BRIDGE_OV518PLUS 3
65#define BRIDGE_OV519 4 65#define BRIDGE_OV519 4
66#define BRIDGE_OVFX2 5 66#define BRIDGE_OVFX2 5
67#define BRIDGE_W9968CF 6
67#define BRIDGE_MASK 7 68#define BRIDGE_MASK 7
68 69
69 char invert_led; 70 char invert_led;
@@ -98,8 +99,17 @@ struct sd {
98#define SEN_OV7670 9 99#define SEN_OV7670 9
99#define SEN_OV76BE 10 100#define SEN_OV76BE 10
100#define SEN_OV8610 11 101#define SEN_OV8610 11
102
103 u8 sensor_addr;
104 int sensor_width;
105 int sensor_height;
101}; 106};
102 107
108/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
109 the ov sensors which is already present here. When we have the time we
110 really should move the sensor drivers to v4l2 sub drivers. */
111#include "w996Xcf.c"
112
103/* V4L2 controls supported by the driver */ 113/* V4L2 controls supported by the driver */
104static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 114static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
105static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 115static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
@@ -1471,6 +1481,7 @@ static const struct ov_i2c_regvals norm_7610[] = {
1471}; 1481};
1472 1482
1473static const struct ov_i2c_regvals norm_7620[] = { 1483static const struct ov_i2c_regvals norm_7620[] = {
1484 { 0x12, 0x80 }, /* reset */
1474 { 0x00, 0x00 }, /* gain */ 1485 { 0x00, 0x00 }, /* gain */
1475 { 0x01, 0x80 }, /* blue gain */ 1486 { 0x01, 0x80 }, /* blue gain */
1476 { 0x02, 0x80 }, /* red gain */ 1487 { 0x02, 0x80 }, /* red gain */
@@ -1835,10 +1846,9 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
1835} 1846}
1836 1847
1837/* Write a OV519 register */ 1848/* Write a OV519 register */
1838static int reg_w(struct sd *sd, __u16 index, __u8 value) 1849static int reg_w(struct sd *sd, __u16 index, __u16 value)
1839{ 1850{
1840 int ret; 1851 int ret, req = 0;
1841 int req;
1842 1852
1843 switch (sd->bridge) { 1853 switch (sd->bridge) {
1844 case BRIDGE_OV511: 1854 case BRIDGE_OV511:
@@ -1846,11 +1856,14 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
1846 req = 2; 1856 req = 2;
1847 break; 1857 break;
1848 case BRIDGE_OVFX2: 1858 case BRIDGE_OVFX2:
1859 req = 0x0a;
1860 /* fall through */
1861 case BRIDGE_W9968CF:
1849 ret = usb_control_msg(sd->gspca_dev.dev, 1862 ret = usb_control_msg(sd->gspca_dev.dev,
1850 usb_sndctrlpipe(sd->gspca_dev.dev, 0), 1863 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1851 0x0a, 1864 req,
1852 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1865 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1853 (__u16)value, index, NULL, 0, 500); 1866 value, index, NULL, 0, 500);
1854 goto leave; 1867 goto leave;
1855 default: 1868 default:
1856 req = 1; 1869 req = 1;
@@ -1864,12 +1877,17 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
1864 0, index, 1877 0, index,
1865 sd->gspca_dev.usb_buf, 1, 500); 1878 sd->gspca_dev.usb_buf, 1, 500);
1866leave: 1879leave:
1867 if (ret < 0) 1880 if (ret < 0) {
1868 PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); 1881 PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
1869 return ret; 1882 value, index);
1883 return ret;
1884 }
1885
1886 PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
1887 return 0;
1870} 1888}
1871 1889
1872/* Read from a OV519 register */ 1890/* Read from a OV519 register, note not valid for the w9968cf!! */
1873/* returns: negative is error, pos or zero is data */ 1891/* returns: negative is error, pos or zero is data */
1874static int reg_r(struct sd *sd, __u16 index) 1892static int reg_r(struct sd *sd, __u16 index)
1875{ 1893{
@@ -1894,10 +1912,12 @@ static int reg_r(struct sd *sd, __u16 index)
1894 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1912 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1895 0, index, sd->gspca_dev.usb_buf, 1, 500); 1913 0, index, sd->gspca_dev.usb_buf, 1, 500);
1896 1914
1897 if (ret >= 0) 1915 if (ret >= 0) {
1898 ret = sd->gspca_dev.usb_buf[0]; 1916 ret = sd->gspca_dev.usb_buf[0];
1899 else 1917 PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
1918 } else
1900 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); 1919 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
1920
1901 return ret; 1921 return ret;
1902} 1922}
1903 1923
@@ -1917,6 +1937,7 @@ static int reg_r8(struct sd *sd,
1917 ret = sd->gspca_dev.usb_buf[0]; 1937 ret = sd->gspca_dev.usb_buf[0];
1918 else 1938 else
1919 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); 1939 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
1940
1920 return ret; 1941 return ret;
1921} 1942}
1922 1943
@@ -1962,9 +1983,12 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
1962 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1983 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1963 0, index, 1984 0, index,
1964 sd->gspca_dev.usb_buf, n, 500); 1985 sd->gspca_dev.usb_buf, n, 500);
1965 if (ret < 0) 1986 if (ret < 0) {
1966 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); 1987 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
1967 return ret; 1988 return ret;
1989 }
1990
1991 return 0;
1968} 1992}
1969 1993
1970static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) 1994static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
@@ -2156,12 +2180,13 @@ static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2156 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 2180 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2157 (__u16)value, (__u16)reg, NULL, 0, 500); 2181 (__u16)value, (__u16)reg, NULL, 0, 500);
2158 2182
2159 if (ret >= 0) 2183 if (ret < 0) {
2160 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2161 else
2162 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg); 2184 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
2185 return ret;
2186 }
2163 2187
2164 return ret; 2188 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2189 return 0;
2165} 2190}
2166 2191
2167static int ovfx2_i2c_r(struct sd *sd, __u8 reg) 2192static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
@@ -2195,6 +2220,8 @@ static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
2195 return ov518_i2c_w(sd, reg, value); 2220 return ov518_i2c_w(sd, reg, value);
2196 case BRIDGE_OVFX2: 2221 case BRIDGE_OVFX2:
2197 return ovfx2_i2c_w(sd, reg, value); 2222 return ovfx2_i2c_w(sd, reg, value);
2223 case BRIDGE_W9968CF:
2224 return w9968cf_i2c_w(sd, reg, value);
2198 } 2225 }
2199 return -1; /* Should never happen */ 2226 return -1; /* Should never happen */
2200} 2227}
@@ -2211,6 +2238,8 @@ static int i2c_r(struct sd *sd, __u8 reg)
2211 return ov518_i2c_r(sd, reg); 2238 return ov518_i2c_r(sd, reg);
2212 case BRIDGE_OVFX2: 2239 case BRIDGE_OVFX2:
2213 return ovfx2_i2c_r(sd, reg); 2240 return ovfx2_i2c_r(sd, reg);
2241 case BRIDGE_W9968CF:
2242 return w9968cf_i2c_r(sd, reg);
2214 } 2243 }
2215 return -1; /* Should never happen */ 2244 return -1; /* Should never happen */
2216} 2245}
@@ -2241,6 +2270,8 @@ static int i2c_w_mask(struct sd *sd,
2241 * registers while the camera is streaming */ 2270 * registers while the camera is streaming */
2242static inline int ov51x_stop(struct sd *sd) 2271static inline int ov51x_stop(struct sd *sd)
2243{ 2272{
2273 int ret;
2274
2244 PDEBUG(D_STREAM, "stopping"); 2275 PDEBUG(D_STREAM, "stopping");
2245 sd->stopped = 1; 2276 sd->stopped = 1;
2246 switch (sd->bridge) { 2277 switch (sd->bridge) {
@@ -2254,6 +2285,11 @@ static inline int ov51x_stop(struct sd *sd)
2254 return reg_w(sd, OV519_SYS_RESET1, 0x0f); 2285 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
2255 case BRIDGE_OVFX2: 2286 case BRIDGE_OVFX2:
2256 return reg_w_mask(sd, 0x0f, 0x00, 0x02); 2287 return reg_w_mask(sd, 0x0f, 0x00, 0x02);
2288 case BRIDGE_W9968CF:
2289 ret = reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
2290 ret += reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
2291 ret += reg_w(sd, 0x16, 0x0000); /* stop video capture */
2292 return ret;
2257 } 2293 }
2258 2294
2259 return 0; 2295 return 0;
@@ -2285,6 +2321,8 @@ static inline int ov51x_restart(struct sd *sd)
2285 return reg_w(sd, OV519_SYS_RESET1, 0x00); 2321 return reg_w(sd, OV519_SYS_RESET1, 0x00);
2286 case BRIDGE_OVFX2: 2322 case BRIDGE_OVFX2:
2287 return reg_w_mask(sd, 0x0f, 0x02, 0x02); 2323 return reg_w_mask(sd, 0x0f, 0x02, 0x02);
2324 case BRIDGE_W9968CF:
2325 return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
2288 } 2326 }
2289 2327
2290 return 0; 2328 return 0;
@@ -2338,8 +2376,13 @@ static int ov51x_set_slave_ids(struct sd *sd,
2338{ 2376{
2339 int rc; 2377 int rc;
2340 2378
2341 if (sd->bridge == BRIDGE_OVFX2) 2379 switch (sd->bridge) {
2380 case BRIDGE_OVFX2:
2342 return reg_w(sd, OVFX2_I2C_ADDR, slave); 2381 return reg_w(sd, OVFX2_I2C_ADDR, slave);
2382 case BRIDGE_W9968CF:
2383 sd->sensor_addr = slave;
2384 return 0;
2385 }
2343 2386
2344 rc = reg_w(sd, R51x_I2C_W_SID, slave); 2387 rc = reg_w(sd, R51x_I2C_W_SID, slave);
2345 if (rc < 0) 2388 if (rc < 0)
@@ -2920,6 +2963,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
2920 cam->bulk_nurbs = MAX_NURBS; 2963 cam->bulk_nurbs = MAX_NURBS;
2921 cam->bulk = 1; 2964 cam->bulk = 1;
2922 break; 2965 break;
2966 case BRIDGE_W9968CF:
2967 ret = w9968cf_configure(sd);
2968 cam->reverse_alts = 1;
2969 break;
2923 } 2970 }
2924 2971
2925 if (ret) 2972 if (ret)
@@ -3005,6 +3052,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
3005 cam->nmodes = ARRAY_SIZE(ov519_sif_mode); 3052 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3006 } 3053 }
3007 break; 3054 break;
3055 case BRIDGE_W9968CF:
3056 cam->cam_mode = w9968cf_vga_mode;
3057 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3058 /* if (sd->sif)
3059 cam->nmodes--; */
3060
3061 /* w9968cf needs initialisation once the sensor is known */
3062 if (w9968cf_init(sd) < 0)
3063 goto error;
3064 break;
3008 } 3065 }
3009 sd->brightness = BRIGHTNESS_DEF; 3066 sd->brightness = BRIGHTNESS_DEF;
3010 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) 3067 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
@@ -3753,9 +3810,9 @@ static int set_ov_sensor_window(struct sd *sd)
3753 return ret; 3810 return ret;
3754 3811
3755 i2c_w(sd, 0x17, hwsbase); 3812 i2c_w(sd, 0x17, hwsbase);
3756 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); 3813 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
3757 i2c_w(sd, 0x19, vwsbase); 3814 i2c_w(sd, 0x19, vwsbase);
3758 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); 3815 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
3759 3816
3760 return 0; 3817 return 0;
3761} 3818}
@@ -3766,6 +3823,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
3766 struct sd *sd = (struct sd *) gspca_dev; 3823 struct sd *sd = (struct sd *) gspca_dev;
3767 int ret = 0; 3824 int ret = 0;
3768 3825
3826 /* Default for most bridges, allow bridge_mode_init_regs to override */
3827 sd->sensor_width = sd->gspca_dev.width;
3828 sd->sensor_height = sd->gspca_dev.height;
3829
3769 switch (sd->bridge) { 3830 switch (sd->bridge) {
3770 case BRIDGE_OV511: 3831 case BRIDGE_OV511:
3771 case BRIDGE_OV511PLUS: 3832 case BRIDGE_OV511PLUS:
@@ -3779,6 +3840,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
3779 ret = ov519_mode_init_regs(sd); 3840 ret = ov519_mode_init_regs(sd);
3780 break; 3841 break;
3781 /* case BRIDGE_OVFX2: nothing to do */ 3842 /* case BRIDGE_OVFX2: nothing to do */
3843 case BRIDGE_W9968CF:
3844 ret = w9968cf_mode_init_regs(sd);
3845 break;
3782 } 3846 }
3783 if (ret < 0) 3847 if (ret < 0)
3784 goto out; 3848 goto out;
@@ -3980,6 +4044,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3980 case BRIDGE_OVFX2: 4044 case BRIDGE_OVFX2:
3981 ovfx2_pkt_scan(gspca_dev, frame, data, len); 4045 ovfx2_pkt_scan(gspca_dev, frame, data, len);
3982 break; 4046 break;
4047 case BRIDGE_W9968CF:
4048 w9968cf_pkt_scan(gspca_dev, frame, data, len);
4049 break;
3983 } 4050 }
3984} 4051}
3985 4052
@@ -4275,8 +4342,12 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
4275 struct sd *sd = (struct sd *) gspca_dev; 4342 struct sd *sd = (struct sd *) gspca_dev;
4276 4343
4277 sd->freq = val; 4344 sd->freq = val;
4278 if (gspca_dev->streaming) 4345 if (gspca_dev->streaming) {
4279 setfreq(sd); 4346 setfreq(sd);
4347 /* Ugly but necessary */
4348 if (sd->bridge == BRIDGE_W9968CF)
4349 w9968cf_set_crop_window(sd);
4350 }
4280 return 0; 4351 return 0;
4281} 4352}
4282 4353
@@ -4332,6 +4403,7 @@ static const struct sd_desc sd_desc = {
4332 4403
4333/* -- module initialisation -- */ 4404/* -- module initialisation -- */
4334static const __devinitdata struct usb_device_id device_table[] = { 4405static const __devinitdata struct usb_device_id device_table[] = {
4406 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
4335 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, 4407 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
4336 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, 4408 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4337 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, 4409 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
@@ -4356,6 +4428,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
4356 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, 4428 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
4357 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, 4429 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4358 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, 4430 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
4431 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
4359 {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 }, 4432 {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
4360 {} 4433 {}
4361}; 4434};
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
new file mode 100644
index 000000000000..ba3a28d4f87f
--- /dev/null
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -0,0 +1,589 @@
1/**
2 *
3 * GSPCA sub driver for W996[78]CF JPEG USB Dual Mode Camera Chip.
4 *
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
6 *
7 * This module is adapted from the in kernel v4l1 w9968cf driver:
8 *
9 * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/* Note this is not a stand alone driver, it gets included in ov519.c, this
28 is a bit of a hack, but it needs the driver code for a lot of different
29 ov sensors which is already present in ov519.c (the old v4l1 driver used
30 the ovchipcam framework). When we have the time we really should move
31 the sensor drivers to v4l2 sub drivers, and properly split of this
32 driver from ov519.c */
33
34#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
35
36/* FIXME make this runtime configurable */
37/* Comment/uncomment this for high/low quality of compressed video */
38#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO
39
40#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO
41static const unsigned char Y_QUANTABLE[64] = {
42 16, 11, 10, 16, 24, 40, 51, 61,
43 12, 12, 14, 19, 26, 58, 60, 55,
44 14, 13, 16, 24, 40, 57, 69, 56,
45 14, 17, 22, 29, 51, 87, 80, 62,
46 18, 22, 37, 56, 68, 109, 103, 77,
47 24, 35, 55, 64, 81, 104, 113, 92,
48 49, 64, 78, 87, 103, 121, 120, 101,
49 72, 92, 95, 98, 112, 100, 103, 99
50};
51
52static const unsigned char UV_QUANTABLE[64] = {
53 17, 18, 24, 47, 99, 99, 99, 99,
54 18, 21, 26, 66, 99, 99, 99, 99,
55 24, 26, 56, 99, 99, 99, 99, 99,
56 47, 66, 99, 99, 99, 99, 99, 99,
57 99, 99, 99, 99, 99, 99, 99, 99,
58 99, 99, 99, 99, 99, 99, 99, 99,
59 99, 99, 99, 99, 99, 99, 99, 99,
60 99, 99, 99, 99, 99, 99, 99, 99
61};
62#else
63static const unsigned char Y_QUANTABLE[64] = {
64 8, 5, 5, 8, 12, 20, 25, 30,
65 6, 6, 7, 9, 13, 29, 30, 27,
66 7, 6, 8, 12, 20, 28, 34, 28,
67 7, 8, 11, 14, 25, 43, 40, 31,
68 9, 11, 18, 28, 34, 54, 51, 38,
69 12, 17, 27, 32, 40, 52, 56, 46,
70 24, 32, 39, 43, 51, 60, 60, 50,
71 36, 46, 47, 49, 56, 50, 51, 49
72};
73
74static const unsigned char UV_QUANTABLE[64] = {
75 8, 9, 12, 23, 49, 49, 49, 49,
76 9, 10, 13, 33, 49, 49, 49, 49,
77 12, 13, 28, 49, 49, 49, 49, 49,
78 23, 33, 49, 49, 49, 49, 49, 49,
79 49, 49, 49, 49, 49, 49, 49, 49,
80 49, 49, 49, 49, 49, 49, 49, 49,
81 49, 49, 49, 49, 49, 49, 49, 49,
82 49, 49, 49, 49, 49, 49, 49, 49
83};
84#endif
85
86static const struct v4l2_pix_format w9968cf_vga_mode[] = {
87 {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
88 .bytesperline = 160 * 2,
89 .sizeimage = 160 * 120 * 2,
90 .colorspace = V4L2_COLORSPACE_JPEG},
91 {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
92 .bytesperline = 176 * 2,
93 .sizeimage = 176 * 144 * 2,
94 .colorspace = V4L2_COLORSPACE_JPEG},
95 {320, 240, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
96 .bytesperline = 320 * 2,
97 .sizeimage = 320 * 240 * 2,
98 .colorspace = V4L2_COLORSPACE_JPEG},
99 {352, 288, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
100 .bytesperline = 352 * 2,
101 .sizeimage = 352 * 288 * 2,
102 .colorspace = V4L2_COLORSPACE_JPEG},
103/* {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
104 .bytesperline = 640 * 2,
105 .sizeimage = 640 * 480 * 2,
106 .colorspace = V4L2_COLORSPACE_JPEG}, */
107};
108
109static int reg_w(struct sd *sd, __u16 index, __u16 value);
110
111/*--------------------------------------------------------------------------
112 Write 64-bit data to the fast serial bus registers.
113 Return 0 on success, -1 otherwise.
114 --------------------------------------------------------------------------*/
115static int w9968cf_write_fsb(struct sd *sd, u16* data)
116{
117 struct usb_device* udev = sd->gspca_dev.dev;
118 u16 value;
119 int ret;
120
121 value = *data++;
122 memcpy(sd->gspca_dev.usb_buf, data, 6);
123
124 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
125 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
126 value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
127 if (ret < 0) {
128 PDEBUG(D_ERR, "Write FSB registers failed (%d)", ret);
129 return ret;
130 }
131
132 return 0;
133}
134
135/*--------------------------------------------------------------------------
136 Write data to the serial bus control register.
137 Return 0 on success, a negative number otherwise.
138 --------------------------------------------------------------------------*/
139static int w9968cf_write_sb(struct sd *sd, u16 value)
140{
141 int ret;
142
143 /* We don't use reg_w here, as that would cause all writes when
144 bitbanging i2c to be logged, making the logs impossible to read */
145 ret = usb_control_msg(sd->gspca_dev.dev,
146 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
147 0,
148 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
149 value, 0x01, NULL, 0, 500);
150
151 udelay(W9968CF_I2C_BUS_DELAY);
152
153 if (ret < 0) {
154 PDEBUG(D_ERR, "Write SB reg [01] %04x failed", value);
155 return ret;
156 }
157
158 return 0;
159}
160
161/*--------------------------------------------------------------------------
162 Read data from the serial bus control register.
163 Return 0 on success, a negative number otherwise.
164 --------------------------------------------------------------------------*/
165static int w9968cf_read_sb(struct sd *sd)
166{
167 int ret;
168
169 /* We don't use reg_r here, as the w9968cf is special and has 16
170 bit registers instead of 8 bit */
171 ret = usb_control_msg(sd->gspca_dev.dev,
172 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
173 1,
174 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
175 0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
176 if (ret >= 0)
177 ret = sd->gspca_dev.usb_buf[0] |
178 (sd->gspca_dev.usb_buf[1] << 8);
179 else
180 PDEBUG(D_ERR, "Read SB reg [01] failed");
181
182 udelay(W9968CF_I2C_BUS_DELAY);
183
184 return ret;
185}
186
187/*--------------------------------------------------------------------------
188 Upload quantization tables for the JPEG compression.
189 This function is called by w9968cf_start_transfer().
190 Return 0 on success, a negative number otherwise.
191 --------------------------------------------------------------------------*/
192static int w9968cf_upload_quantizationtables(struct sd *sd)
193{
194 u16 a, b;
195 int ret = 0, i, j;
196
197 ret += reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
198
199 for (i = 0, j = 0; i < 32; i++, j += 2) {
200 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
201 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
202 ret += reg_w(sd, 0x40+i, a);
203 ret += reg_w(sd, 0x60+i, b);
204 }
205 ret += reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
206
207 return ret;
208}
209
210/****************************************************************************
211 * Low-level I2C I/O functions. *
212 * The adapter supports the following I2C transfer functions: *
213 * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
214 * i2c_adap_read_byte_data() *
215 * i2c_adap_read_byte() *
216 ****************************************************************************/
217
218static int w9968cf_smbus_start(struct sd *sd)
219{
220 int ret = 0;
221
222 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
223 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
224
225 return ret;
226}
227
228static int w9968cf_smbus_stop(struct sd *sd)
229{
230 int ret = 0;
231
232 ret += w9968cf_write_sb(sd, 0x0010); /* SDE=1, SDA=0, SCL=0 */
233 ret += w9968cf_write_sb(sd, 0x0011); /* SDE=1, SDA=0, SCL=1 */
234 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
235
236 return ret;
237}
238
239static int w9968cf_smbus_write_byte(struct sd *sd, u8 v)
240{
241 u8 bit;
242 int ret = 0, sda;
243
244 for (bit = 0 ; bit < 8 ; bit++) {
245 sda = (v & 0x80) ? 2 : 0;
246 v <<= 1;
247 /* SDE=1, SDA=sda, SCL=0 */
248 ret += w9968cf_write_sb(sd, 0x10 | sda);
249 /* SDE=1, SDA=sda, SCL=1 */
250 ret += w9968cf_write_sb(sd, 0x11 | sda);
251 /* SDE=1, SDA=sda, SCL=0 */
252 ret += w9968cf_write_sb(sd, 0x10 | sda);
253 }
254
255 return ret;
256}
257
258static int w9968cf_smbus_read_byte(struct sd *sd, u8* v)
259{
260 u8 bit;
261 int ret = 0;
262
263 /* No need to ensure SDA is high as we are always called after
264 read_ack which ends with SDA high */
265 *v = 0;
266 for (bit = 0 ; bit < 8 ; bit++) {
267 *v <<= 1;
268 /* SDE=1, SDA=1, SCL=1 */
269 ret += w9968cf_write_sb(sd, 0x0013);
270 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
271 /* SDE=1, SDA=1, SCL=0 */
272 ret += w9968cf_write_sb(sd, 0x0012);
273 }
274
275 return ret;
276}
277
278static int w9968cf_smbus_write_nack(struct sd *sd)
279{
280 int ret = 0;
281
282 /* No need to ensure SDA is high as we are always called after
283 read_byte which ends with SDA high */
284 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
285 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
286
287 return ret;
288}
289
290static int w9968cf_smbus_read_ack(struct sd *sd)
291{
292 int ret = 0, sda;
293
294 /* Ensure SDA is high before raising clock to avoid a spurious stop */
295 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
296 ret += w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
297 sda = w9968cf_read_sb(sd);
298 ret += w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
299 if (sda < 0)
300 ret += sda;
301 else if (sda & 0x08) {
302 PDEBUG(D_USBI, "Did not receive i2c ACK");
303 ret += -1;
304 }
305
306 return ret;
307}
308
309/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
310static int w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
311{
312 u16* data = (u16 *)sd->gspca_dev.usb_buf;
313 int ret = 0;
314
315 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
316 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
317 data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
318 data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
319 data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
320 data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
321 data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
322 data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
323 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
324 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
325
326 ret += w9968cf_write_fsb(sd, data);
327
328 data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
329 data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
330 data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
331 data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
332 data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
333 data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
334 data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
335 data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
336 data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
337 data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
338 data[3] = 0x001d;
339
340 ret += w9968cf_write_fsb(sd, data);
341
342 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
343 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
344 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
345 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
346 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
347 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
348 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
349 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
350 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
351 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
352 data[3] = 0xfe1d;
353
354 ret += w9968cf_write_fsb(sd, data);
355
356 if (!ret)
357 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
358 else
359 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
360
361 return ret;
362}
363
364/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
365static int w9968cf_i2c_r(struct sd *sd, u8 reg)
366{
367 int ret = 0;
368 u8 value;
369
370 /* Fast serial bus data control disable */
371 ret += w9968cf_write_sb(sd, 0x0013); /* don't change ! */
372
373 ret += w9968cf_smbus_start(sd);
374 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr);
375 ret += w9968cf_smbus_read_ack(sd);
376 ret += w9968cf_smbus_write_byte(sd, reg);
377 ret += w9968cf_smbus_read_ack(sd);
378 ret += w9968cf_smbus_stop(sd);
379 ret += w9968cf_smbus_start(sd);
380 ret += w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
381 ret += w9968cf_smbus_read_ack(sd);
382 ret += w9968cf_smbus_read_byte(sd, &value);
383 /* signal we don't want to read anymore, the v4l1 driver used to
384 send an ack here which is very wrong! (and then fixed
385 the issues this gave by retrying reads) */
386 ret += w9968cf_smbus_write_nack(sd);
387 ret += w9968cf_smbus_stop(sd);
388
389 /* Fast serial bus data control re-enable */
390 ret += w9968cf_write_sb(sd, 0x0030);
391
392 if (!ret) {
393 ret = value;
394 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
395 } else
396 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
397
398 return ret;
399}
400
401
402/*--------------------------------------------------------------------------
403 Turn on the LED on some webcams. A beep should be heard too.
404 Return 0 on success, a negative number otherwise.
405 --------------------------------------------------------------------------*/
406static int w9968cf_configure(struct sd *sd)
407{
408 int ret = 0;
409
410 ret += reg_w(sd, 0x00, 0xff00); /* power-down */
411 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
412 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
413 ret += reg_w(sd, 0x01, 0x0010); /* serial bus, SDS high */
414 ret += reg_w(sd, 0x01, 0x0000); /* serial bus, SDS low */
415 ret += reg_w(sd, 0x01, 0x0010); /* ..high 'beep-beep' */
416 ret += reg_w(sd, 0x01, 0x0030); /* Set sda scl to FSB mode */
417
418 if (ret)
419 PDEBUG(D_ERR, "Couldn't turn on the LED");
420
421 sd->stopped = 1;
422
423 return ret;
424}
425
426static int w9968cf_init(struct sd *sd)
427{
428 int ret = 0;
429 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
430 y0 = 0x0000,
431 u0 = y0 + hw_bufsize/2,
432 v0 = u0 + hw_bufsize/4,
433 y1 = v0 + hw_bufsize/4,
434 u1 = y1 + hw_bufsize/2,
435 v1 = u1 + hw_bufsize/4;
436
437 ret += reg_w(sd, 0x00, 0xff00); /* power off */
438 ret += reg_w(sd, 0x00, 0xbf10); /* power on */
439
440 ret += reg_w(sd, 0x03, 0x405d); /* DRAM timings */
441 ret += reg_w(sd, 0x04, 0x0030); /* SDRAM timings */
442
443 ret += reg_w(sd, 0x20, y0 & 0xffff); /* Y buf.0, low */
444 ret += reg_w(sd, 0x21, y0 >> 16); /* Y buf.0, high */
445 ret += reg_w(sd, 0x24, u0 & 0xffff); /* U buf.0, low */
446 ret += reg_w(sd, 0x25, u0 >> 16); /* U buf.0, high */
447 ret += reg_w(sd, 0x28, v0 & 0xffff); /* V buf.0, low */
448 ret += reg_w(sd, 0x29, v0 >> 16); /* V buf.0, high */
449
450 ret += reg_w(sd, 0x22, y1 & 0xffff); /* Y buf.1, low */
451 ret += reg_w(sd, 0x23, y1 >> 16); /* Y buf.1, high */
452 ret += reg_w(sd, 0x26, u1 & 0xffff); /* U buf.1, low */
453 ret += reg_w(sd, 0x27, u1 >> 16); /* U buf.1, high */
454 ret += reg_w(sd, 0x2a, v1 & 0xffff); /* V buf.1, low */
455 ret += reg_w(sd, 0x2b, v1 >> 16); /* V buf.1, high */
456
457 ret += reg_w(sd, 0x32, y1 & 0xffff); /* JPEG buf 0 low */
458 ret += reg_w(sd, 0x33, y1 >> 16); /* JPEG buf 0 high */
459
460 ret += reg_w(sd, 0x34, y1 & 0xffff); /* JPEG buf 1 low */
461 ret += reg_w(sd, 0x35, y1 >> 16); /* JPEG bug 1 high */
462
463 ret += reg_w(sd, 0x36, 0x0000);/* JPEG restart interval */
464 ret += reg_w(sd, 0x37, 0x0804);/*JPEG VLE FIFO threshold*/
465 ret += reg_w(sd, 0x38, 0x0000);/* disable hw up-scaling */
466 ret += reg_w(sd, 0x3f, 0x0000); /* JPEG/MCTL test data */
467
468 return ret;
469}
470
471static int w9968cf_set_crop_window(struct sd *sd)
472{
473 int ret = 0, start_cropx, start_cropy, x, y, fw, fh, cw, ch,
474 max_width, max_height;
475
476 if (sd->sif) {
477 max_width = 352;
478 max_height = 288;
479 } else {
480 max_width = 640;
481 max_height = 480;
482 }
483
484 if (sd->sensor == SEN_OV7620) {
485 /* Sigh, this is dependend on the clock / framerate changes
486 made by the frequency control, sick. */
487 if (sd->freq == 1) {
488 start_cropx = 279;
489 start_cropy = 35;
490 } else {
491 start_cropx = 103;
492 start_cropy = 35;
493 }
494 } else {
495 start_cropx = 320;
496 start_cropy = 35;
497 }
498
499 /* Work around to avoid FP arithmetics */
500 #define SC(x) ((x) << 10)
501
502 /* Scaling factors */
503 fw = SC(sd->gspca_dev.width) / max_width;
504 fh = SC(sd->gspca_dev.height) / max_height;
505
506 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.width)/fh;
507 ch = (fw >= fh) ? SC(sd->gspca_dev.height)/fw : max_height;
508
509 sd->sensor_width = max_width;
510 sd->sensor_height = max_height;
511
512 x = (max_width - cw) / 2;
513 y = (max_height - ch) / 2;
514
515 ret += reg_w(sd, 0x10, start_cropx + x);
516 ret += reg_w(sd, 0x11, start_cropy + y);
517 ret += reg_w(sd, 0x12, start_cropx + x + cw);
518 ret += reg_w(sd, 0x13, start_cropy + y + ch);
519
520 return ret;
521}
522
523static int w9968cf_mode_init_regs(struct sd *sd)
524{
525 int ret = 0, val, vs_polarity, hs_polarity;
526
527 ret += w9968cf_set_crop_window(sd);
528
529 ret += reg_w(sd, 0x14, sd->gspca_dev.width);
530 ret += reg_w(sd, 0x15, sd->gspca_dev.height);
531
532 /* JPEG width & height */
533 ret += reg_w(sd, 0x30, sd->gspca_dev.width);
534 ret += reg_w(sd, 0x31, sd->gspca_dev.height);
535
536 /* Y & UV frame buffer strides (in WORD) */
537 ret += reg_w(sd, 0x2c, sd->gspca_dev.width);
538
539 ret += reg_w(sd, 0x00, 0xbf17); /* reset everything */
540 ret += reg_w(sd, 0x00, 0xbf10); /* normal operation */
541
542 /* Transfer size */
543 /* FIXME JPEG * 4 ?? */
544 val = sd->gspca_dev.width * sd->gspca_dev.height;
545 ret += reg_w(sd, 0x3d, val & 0xffff); /* low bits */
546 ret += reg_w(sd, 0x3e, val >> 16); /* high bits */
547
548 /* Video Capture Control Register */
549 if (sd->sensor == SEN_OV7620) {
550 /* Seems to work around a bug in the image sensor */
551 vs_polarity = 1;
552 hs_polarity = 1;
553 } else {
554 vs_polarity = 1;
555 hs_polarity = 0;
556 }
557
558 val = (vs_polarity << 12) | (hs_polarity << 11);
559
560 val |= 0x0080; /* Enable HW double buffering */
561
562 /* val |= 0x0020; enable clamping */
563 /* val |= 0x0008; enable (1-2-1) filter */
564 /* val |= 0x000c; enable (2-3-6-3-2) filter */
565
566 val |= 0x8000; /* capt. enable */
567
568 ret += reg_w(sd, 0x16, val);
569
570 sd->gspca_dev.empty_packet = 0;
571
572 return ret;
573}
574
575static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
576 struct gspca_frame *frame, /* target */
577 __u8 *data, /* isoc packet */
578 int len) /* iso packet length */
579{
580 /* An empty packet signals EOF */
581 if (gspca_dev->empty_packet) {
582 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
583 data, len);
584 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
585 NULL, 0);
586 gspca_dev->empty_packet = 0;
587 }
588 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
589}