Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 173972
b: refs/heads/master
c: a511ba9
h: refs/heads/master
v: v3
  • Loading branch information
Hans de Goede authored and Mauro Carvalho Chehab committed Dec 5, 2009
1 parent e3b26dc commit 7eee20a
Show file tree
Hide file tree
Showing 7 changed files with 714 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: eea85b0a629970d462481a80e1d45f4d71fe797f
refs/heads/master: a511ba947600ae263f8c29c86020ba66a901d3e5
11 changes: 9 additions & 2 deletions trunk/drivers/media/video/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -951,9 +951,13 @@ source "drivers/media/video/usbvideo/Kconfig"
source "drivers/media/video/et61x251/Kconfig"

config VIDEO_OVCAMCHIP
tristate "OmniVision Camera Chip support"
tristate "OmniVision Camera Chip support (DEPRECATED)"
depends on I2C && VIDEO_V4L1
---help---
This driver is DEPRECATED please use the gspca ov519 module
instead. Note that for the ov511 / ov518 support of the gspca module
you need atleast version 0.6.0 of libv4l.

Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
This driver is intended to be used with the ov511 and w9968cf USB
camera drivers.
Expand All @@ -962,9 +966,12 @@ config VIDEO_OVCAMCHIP
module will be called ovcamchip.

config USB_W9968CF
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
---help---
This driver is DEPRECATED please use the gspca ov519 module
instead.

Say Y here if you want support for cameras based on OV681 or
Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.

Expand Down
5 changes: 3 additions & 2 deletions trunk/drivers/media/video/gspca/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ config USB_GSPCA_MR97310A
module will be called gspca_mr97310a.

config USB_GSPCA_OV519
tristate "OV519 USB Camera Driver"
tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
Say Y here if you want support for cameras based on the OV519 chip.
Say Y here if you want support for cameras based on one of these:
OV511(+), OV518(+), OV519, OVFX2, W9967CF, W9968CF

To compile this driver as a module, choose M here: the
module will be called gspca_ov519.
Expand Down
22 changes: 17 additions & 5 deletions trunk/drivers/media/video/gspca/gspca.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,10 +475,18 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
xfer = gspca_dev->cam.bulk ? USB_ENDPOINT_XFER_BULK
: USB_ENDPOINT_XFER_ISOC;
i = gspca_dev->alt; /* previous alt setting */
while (--i >= 0) {
ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
break;
if (gspca_dev->cam.reverse_alts) {
while (++i < gspca_dev->nbalt) {
ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
break;
}
} else {
while (--i >= 0) {
ep = alt_xfer(&intf->altsetting[i], xfer);
if (ep)
break;
}
}
if (ep == NULL) {
err("no transfer endpoint found");
Expand Down Expand Up @@ -599,7 +607,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)

/* set the higher alternate setting and
* loop until urb submit succeeds */
gspca_dev->alt = gspca_dev->nbalt;
if (gspca_dev->cam.reverse_alts)
gspca_dev->alt = 0;
else
gspca_dev->alt = gspca_dev->nbalt;

if (gspca_dev->sd_desc->isoc_init) {
ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
if (ret < 0)
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/media/video/gspca/gspca.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct cam {
u8 npkt; /* number of packets in an ISOC message
* 0 is the default value: 32 packets */
u32 input_flags; /* value for ENUM_INPUT status flags */
char reverse_alts; /* Alt settings are in high to low order */
};

struct gspca_dev;
Expand Down
115 changes: 94 additions & 21 deletions trunk/drivers/media/video/gspca/ov519.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct sd {
#define BRIDGE_OV518PLUS 3
#define BRIDGE_OV519 4
#define BRIDGE_OVFX2 5
#define BRIDGE_W9968CF 6
#define BRIDGE_MASK 7

char invert_led;
Expand Down Expand Up @@ -98,8 +99,17 @@ struct sd {
#define SEN_OV7670 9
#define SEN_OV76BE 10
#define SEN_OV8610 11

u8 sensor_addr;
int sensor_width;
int sensor_height;
};

/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
the ov sensors which is already present here. When we have the time we
really should move the sensor drivers to v4l2 sub drivers. */
#include "w996Xcf.c"

/* 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);
Expand Down Expand Up @@ -1471,6 +1481,7 @@ static const struct ov_i2c_regvals norm_7610[] = {
};

static const struct ov_i2c_regvals norm_7620[] = {
{ 0x12, 0x80 }, /* reset */
{ 0x00, 0x00 }, /* gain */
{ 0x01, 0x80 }, /* blue gain */
{ 0x02, 0x80 }, /* red gain */
Expand Down Expand Up @@ -1835,22 +1846,24 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
}

/* Write a OV519 register */
static int reg_w(struct sd *sd, __u16 index, __u8 value)
static int reg_w(struct sd *sd, __u16 index, __u16 value)
{
int ret;
int req;
int ret, req = 0;

switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
req = 2;
break;
case BRIDGE_OVFX2:
req = 0x0a;
/* fall through */
case BRIDGE_W9968CF:
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
0x0a,
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
(__u16)value, index, NULL, 0, 500);
value, index, NULL, 0, 500);
goto leave;
default:
req = 1;
Expand All @@ -1864,12 +1877,17 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
0, index,
sd->gspca_dev.usb_buf, 1, 500);
leave:
if (ret < 0)
PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value);
return ret;
if (ret < 0) {
PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
value, index);
return ret;
}

PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
return 0;
}

/* Read from a OV519 register */
/* Read from a OV519 register, note not valid for the w9968cf!! */
/* returns: negative is error, pos or zero is data */
static int reg_r(struct sd *sd, __u16 index)
{
Expand All @@ -1894,10 +1912,12 @@ static int reg_r(struct sd *sd, __u16 index)
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index, sd->gspca_dev.usb_buf, 1, 500);

if (ret >= 0)
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
else
PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
} else
PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);

return ret;
}

Expand All @@ -1917,6 +1937,7 @@ static int reg_r8(struct sd *sd,
ret = sd->gspca_dev.usb_buf[0];
else
PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);

return ret;
}

Expand Down Expand Up @@ -1962,9 +1983,12 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index,
sd->gspca_dev.usb_buf, n, 500);
if (ret < 0)
if (ret < 0) {
PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
return ret;
return ret;
}

return 0;
}

static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
Expand Down Expand Up @@ -2156,12 +2180,13 @@ static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
(__u16)value, (__u16)reg, NULL, 0, 500);

if (ret >= 0)
PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
else
if (ret < 0) {
PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
return ret;
}

return ret;
PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
return 0;
}

static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
Expand Down Expand Up @@ -2195,6 +2220,8 @@ static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
return ov518_i2c_w(sd, reg, value);
case BRIDGE_OVFX2:
return ovfx2_i2c_w(sd, reg, value);
case BRIDGE_W9968CF:
return w9968cf_i2c_w(sd, reg, value);
}
return -1; /* Should never happen */
}
Expand All @@ -2211,6 +2238,8 @@ static int i2c_r(struct sd *sd, __u8 reg)
return ov518_i2c_r(sd, reg);
case BRIDGE_OVFX2:
return ovfx2_i2c_r(sd, reg);
case BRIDGE_W9968CF:
return w9968cf_i2c_r(sd, reg);
}
return -1; /* Should never happen */
}
Expand Down Expand Up @@ -2241,6 +2270,8 @@ static int i2c_w_mask(struct sd *sd,
* registers while the camera is streaming */
static inline int ov51x_stop(struct sd *sd)
{
int ret;

PDEBUG(D_STREAM, "stopping");
sd->stopped = 1;
switch (sd->bridge) {
Expand All @@ -2254,6 +2285,11 @@ static inline int ov51x_stop(struct sd *sd)
return reg_w(sd, OV519_SYS_RESET1, 0x0f);
case BRIDGE_OVFX2:
return reg_w_mask(sd, 0x0f, 0x00, 0x02);
case BRIDGE_W9968CF:
ret = reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
ret += reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
ret += reg_w(sd, 0x16, 0x0000); /* stop video capture */
return ret;
}

return 0;
Expand Down Expand Up @@ -2285,6 +2321,8 @@ static inline int ov51x_restart(struct sd *sd)
return reg_w(sd, OV519_SYS_RESET1, 0x00);
case BRIDGE_OVFX2:
return reg_w_mask(sd, 0x0f, 0x02, 0x02);
case BRIDGE_W9968CF:
return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
}

return 0;
Expand Down Expand Up @@ -2338,8 +2376,13 @@ static int ov51x_set_slave_ids(struct sd *sd,
{
int rc;

if (sd->bridge == BRIDGE_OVFX2)
switch (sd->bridge) {
case BRIDGE_OVFX2:
return reg_w(sd, OVFX2_I2C_ADDR, slave);
case BRIDGE_W9968CF:
sd->sensor_addr = slave;
return 0;
}

rc = reg_w(sd, R51x_I2C_W_SID, slave);
if (rc < 0)
Expand Down Expand Up @@ -2920,6 +2963,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->bulk_nurbs = MAX_NURBS;
cam->bulk = 1;
break;
case BRIDGE_W9968CF:
ret = w9968cf_configure(sd);
cam->reverse_alts = 1;
break;
}

if (ret)
Expand Down Expand Up @@ -3005,6 +3052,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
}
break;
case BRIDGE_W9968CF:
cam->cam_mode = w9968cf_vga_mode;
cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
/* if (sd->sif)
cam->nmodes--; */

/* w9968cf needs initialisation once the sensor is known */
if (w9968cf_init(sd) < 0)
goto error;
break;
}
sd->brightness = BRIGHTNESS_DEF;
if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
Expand Down Expand Up @@ -3753,9 +3810,9 @@ static int set_ov_sensor_window(struct sd *sd)
return ret;

i2c_w(sd, 0x17, hwsbase);
i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
i2c_w(sd, 0x19, vwsbase);
i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));

return 0;
}
Expand All @@ -3766,6 +3823,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int ret = 0;

/* Default for most bridges, allow bridge_mode_init_regs to override */
sd->sensor_width = sd->gspca_dev.width;
sd->sensor_height = sd->gspca_dev.height;

switch (sd->bridge) {
case BRIDGE_OV511:
case BRIDGE_OV511PLUS:
Expand All @@ -3779,6 +3840,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
ret = ov519_mode_init_regs(sd);
break;
/* case BRIDGE_OVFX2: nothing to do */
case BRIDGE_W9968CF:
ret = w9968cf_mode_init_regs(sd);
break;
}
if (ret < 0)
goto out;
Expand Down Expand Up @@ -3980,6 +4044,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
case BRIDGE_OVFX2:
ovfx2_pkt_scan(gspca_dev, frame, data, len);
break;
case BRIDGE_W9968CF:
w9968cf_pkt_scan(gspca_dev, frame, data, len);
break;
}
}

Expand Down Expand Up @@ -4275,8 +4342,12 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
struct sd *sd = (struct sd *) gspca_dev;

sd->freq = val;
if (gspca_dev->streaming)
if (gspca_dev->streaming) {
setfreq(sd);
/* Ugly but necessary */
if (sd->bridge == BRIDGE_W9968CF)
w9968cf_set_crop_window(sd);
}
return 0;
}

Expand Down Expand Up @@ -4332,6 +4403,7 @@ static const struct sd_desc sd_desc = {

/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
Expand All @@ -4356,6 +4428,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
{USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
{USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
{USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
{USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
{}
};
Expand Down
Loading

0 comments on commit 7eee20a

Please sign in to comment.