/* Note this is not a stand alone driver, it gets included in ov519.c, this isabitofahack,butitneedsthedrivercodeforalotofdifferent ovsensorswhichisalreadypresentinov519.c(theoldv4l1driverused theovchipcamframework).Whenwehavethetimewereallyshouldmove thesensordriverstov4l2subdrivers,andproperlysplitofthis
driver from ov519.c */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define W9968CF_I2C_BUS_DELAY 4/* delay in us for I2C bit r/w operations */
/* Avoid things going to fast for the bridge with a xhci host */
udelay(150);
/* We don't use reg_w here, as that would cause all writes when
bitbanging i2c to be logged, making the logs impossible to read */
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0), 0,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, 0x01, NULL, 0, 500);
/* Avoid things going to fast for the bridge with a xhci host */
udelay(150);
/* We don't use reg_r here, as the w9968cf is special and has 16
bit registers instead of 8 bit */
ret = usb_control_msg(sd->gspca_dev.dev,
usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 1,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0x01, sd->gspca_dev.usb_buf, 2, 500); if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0] |
(sd->gspca_dev.usb_buf[1] << 8);
} else {
pr_err("Read SB reg [01] failed\n");
sd->gspca_dev.usb_err = ret; /* *Makesurethebufferiszeroedtoavoiduninitialized *values.
*/
memset(sd->gspca_dev.usb_buf, 0, 2);
}
udelay(W9968CF_I2C_BUS_DELAY);
return ret;
}
/*-------------------------------------------------------------------------- UploadquantizationtablesfortheJPEGcompression. Thisfunctioniscalledbyw9968cf_start_transfer(). Return0onsuccess,anegativenumberotherwise.
--------------------------------------------------------------------------*/ staticvoid w9968cf_upload_quantizationtables(struct sd *sd)
{
u16 a, b; int i, j;
reg_w(sd, 0x39, 0x0010); /* JPEG clock enable */
for (i = 0, j = 0; i < 32; i++, j += 2) {
a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8);
b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8);
reg_w(sd, 0x40 + i, a);
reg_w(sd, 0x60 + i, b);
}
reg_w(sd, 0x39, 0x0012); /* JPEG encoder enable */
}
/* No need to ensure SDA is high as we are always called after
read_ack which ends with SDA high */
*v = 0; for (bit = 0 ; bit < 8 ; bit++) {
*v <<= 1; /* SDE=1, SDA=1, SCL=1 */
w9968cf_write_sb(sd, 0x0013);
*v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0; /* SDE=1, SDA=1, SCL=0 */
w9968cf_write_sb(sd, 0x0012);
}
}
staticvoid w9968cf_smbus_write_nack(struct sd *sd)
{ /* No need to ensure SDA is high as we are always called after
read_byte which ends with SDA high */
w9968cf_write_sb(sd, 0x0013); /* SDE=1, SDA=1, SCL=1 */
w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
}
/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */ staticint w9968cf_i2c_r(struct sd *sd, u8 reg)
{ struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; int ret = 0;
u8 value;
/* Fast serial bus data control disable */
w9968cf_write_sb(sd, 0x0013); /* don't change ! */
w9968cf_smbus_start(sd);
w9968cf_smbus_write_byte(sd, sd->sensor_addr);
w9968cf_smbus_read_ack(sd);
w9968cf_smbus_write_byte(sd, reg);
w9968cf_smbus_read_ack(sd);
w9968cf_smbus_stop(sd);
w9968cf_smbus_start(sd);
w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
w9968cf_smbus_read_ack(sd);
w9968cf_smbus_read_byte(sd, &value); /* signal we don't want to read anymore, the v4l1 driver used to sendanackherewhichisverywrong!(andthenfixed
the issues this gave by retrying reads) */
w9968cf_smbus_write_nack(sd);
w9968cf_smbus_stop(sd);
/* Fast serial bus data control re-enable */
w9968cf_write_sb(sd, 0x0030);
/* Transfer size in WORDS (for UYVY format only) */
val = sd->gspca_dev.pixfmt.width * sd->gspca_dev.pixfmt.height;
reg_w(sd, 0x3d, val & 0xffff); /* low bits */
reg_w(sd, 0x3e, val >> 16); /* high bits */
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
V4L2_PIX_FMT_JPEG) { /* We may get called multiple times (usb isoc bw negotiat.) */
jpeg_define(sd->jpeg_hdr, sd->gspca_dev.pixfmt.height,
sd->gspca_dev.pixfmt.width, 0x22); /* JPEG 420 */
jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
w9968cf_upload_quantizationtables(sd);
v4l2_ctrl_grab(sd->jpegqual, true);
}
/* Video Capture Control Register */ if (sd->sensor == SEN_OV7620) { /* Seems to work around a bug in the image sensor */
vs_polarity = 1;
hs_polarity = 1;
} else {
vs_polarity = 1;
hs_polarity = 0;
}
val = (vs_polarity << 12) | (hs_polarity << 11);
/* NOTE: We may not have enough memory to do double buffering while doingcompression(amountofmemorydifferspermodelcam). Soweusethesecondimagebufferalsoasjpegstreambuffer
(see w9968cf_init), and disable double buffering. */ if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
V4L2_PIX_FMT_JPEG) { /* val |= 0x0002; YUV422P */
val |= 0x0003; /* YUV420P */
} else
val |= 0x0080; /* Enable HW double buffering */
/* val |= 0x0020; enable clamping */ /* val |= 0x0008; enable (1-2-1) filter */ /* val |= 0x000c; enable (2-3-6-3-2) filter */
/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF forthenextframe).Thisseemstosimplynotbetruewhenoperating inJPEGmode,inthiscasetheremaybeemptypacketswithinthe frame.SoinJPEGmodeusetheJPEGSOImarkertodetectSOF.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.