forked from luck/tmp_suning_uos_patched
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (23 commits) V4L/DVB (8617): uvcvideo: don't use stack-based buffers for USB transfers. V4L/DVB (8616): uvcvideo: Add support for two Bison Electronics webcams V4L/DVB (8611): Add suspend/resume to pxa_camera driver V4L/DVB (8610): Add suspend/resume capabilities to soc_camera. V4L/DVB (8609): media: Clean up platform_driver_unregister() bogosity. V4L/DVB (8607): cxusb: fix OOPS and broken tuning regression on FusionHDTV Dual Digital 4 V4L/DVB (8605): gspca: Fix of gspca_zc3xx oops - 2.6.27-rc1 V4L/DVB (8604): gspca: Fix of "scheduling while atomic" crash. V4L/DVB (8602): gspca: Fix small bugs, simplify and cleanup ov519. V4L/DVB (8582): set mts_firmware for em2882 based Pinnacle Hybrid Pro V4L/DVB (8574): gspca: Bad bytesperlines of pixelformat in spca505/506/508 and vc023x. V4L/DVB (8573): gspca: Bad scan of frame in spca505/506/508. V4L/DVB (8572): gspca: Webcam 0c45:6143 in documentation. V4L/DVB (8571): gspca: Don't use CONFIG_VIDEO_ADV_DEBUG as a compile option. V4L/DVB (8569): gspca: Set back the old values of Sonix sn9c120 and cleanup source. V4L/DVB (8567): gspca: hflip and vflip controls added for ov519 - ov7670 plus init cleanup. V4L/DVB (8564): fix vino driver build error V4L/DVB (8563): fix drivers/media/video/arv.c compilation V4L/DVB (8562): DVB_DRX397XD: remove FW_LOADER select V4L/DVB (8558): media/video/Kconfig: fix a typo ...
This commit is contained in:
commit
b80b601f00
|
@ -226,6 +226,7 @@ sonixj 0c45:6130 Sonix Pccam
|
|||
sonixj 0c45:6138 Sn9c120 Mo4000
|
||||
sonixj 0c45:613b Surfer SN-206
|
||||
sonixj 0c45:613c Sonix Pccam168
|
||||
sonixj 0c45:6143 Sonix Pccam168
|
||||
sunplus 0d64:0303 Sunplus FashionCam DXG
|
||||
etoms 102c:6151 Qcam Sangha CIF
|
||||
etoms 102c:6251 Qcam xxxxxx VGA
|
||||
|
|
|
@ -565,7 +565,8 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
|
||||
static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg)
|
||||
{
|
||||
struct dvb_usb_device *d = ptr;
|
||||
struct dvb_usb_adapter *adap = ptr;
|
||||
struct dvb_usb_device *d = adap->dev;
|
||||
|
||||
switch (command) {
|
||||
case XC2028_TUNER_RESET:
|
||||
|
@ -593,9 +594,9 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
.callback = dvico_bluebird_xc2028_callback,
|
||||
};
|
||||
static struct xc2028_ctrl ctl = {
|
||||
.fname = "xc3028-dvico-au-01.fw",
|
||||
.fname = "xc3028-v27.fw",
|
||||
.max_len = 64,
|
||||
.scode_table = XC3028_FE_ZARLINK456,
|
||||
.demod = XC3028_FE_ZARLINK456,
|
||||
};
|
||||
|
||||
fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
|
||||
|
|
|
@ -135,9 +135,8 @@ config DVB_CX22702
|
|||
|
||||
config DVB_DRX397XD
|
||||
tristate "Micronas DRX3975D/DRX3977D based"
|
||||
depends on DVB_CORE && I2C && HOTPLUG
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
select FW_LOADER
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
|
|
|
@ -630,7 +630,7 @@ config VIDEO_ZORAN_ZR36060
|
|||
depends on VIDEO_ZORAN
|
||||
help
|
||||
Say Y to support Zoran boards based on 36060 chips.
|
||||
This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33
|
||||
This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33
|
||||
and 33 R10 and AverMedia 6 boards.
|
||||
|
||||
config VIDEO_ZORAN_BUZ
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/videodev.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
@ -755,7 +756,6 @@ static const struct file_operations ar_fops = {
|
|||
|
||||
static struct video_device ar_template = {
|
||||
.name = "Colour AR VGA",
|
||||
.type = VID_TYPE_CAPTURE,
|
||||
.fops = &ar_fops,
|
||||
.release = ar_release,
|
||||
.minor = -1,
|
||||
|
|
|
@ -1015,6 +1015,7 @@ struct em28xx_board em28xx_boards[] = {
|
|||
.valid = EM28XX_BOARD_NOT_VALIDATED,
|
||||
.vchannels = 3,
|
||||
.tuner_type = TUNER_XC2028,
|
||||
.mts_firmware = 1,
|
||||
.decoder = EM28XX_TVP5150,
|
||||
.input = { {
|
||||
.type = EM28XX_VMUX_TELEVISION,
|
||||
|
|
|
@ -123,7 +123,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
|
|||
{
|
||||
struct usb_device *dev = gspca_dev->dev;
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (len > sizeof gspca_dev->usb_buf) {
|
||||
err("reg_r: buffer overflow");
|
||||
return;
|
||||
|
@ -163,7 +163,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
|||
{
|
||||
struct usb_device *dev = gspca_dev->dev;
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (len > sizeof gspca_dev->usb_buf) {
|
||||
err("reg_w: buffer overflow");
|
||||
return;
|
||||
|
|
|
@ -233,7 +233,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
|
|||
{
|
||||
struct usb_device *dev = gspca_dev->dev;
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (len > sizeof gspca_dev->usb_buf) {
|
||||
err("reg_r: buffer overflow");
|
||||
return;
|
||||
|
@ -271,7 +271,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
|||
{
|
||||
struct usb_device *dev = gspca_dev->dev;
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (len > sizeof gspca_dev->usb_buf) {
|
||||
err("reg_w: buffer overflow");
|
||||
return;
|
||||
|
@ -461,6 +461,52 @@ static void Et_init2(struct gspca_dev *gspca_dev)
|
|||
reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */
|
||||
}
|
||||
|
||||
static void setbrightness(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
__u8 brightness = sd->brightness;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
reg_w_val(gspca_dev, ET_O_RED + i, brightness);
|
||||
}
|
||||
|
||||
static void getbrightness(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
int brightness = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
reg_r(gspca_dev, ET_O_RED + i, 1);
|
||||
brightness += gspca_dev->usb_buf[0];
|
||||
}
|
||||
sd->brightness = brightness >> 3;
|
||||
}
|
||||
|
||||
static void setcontrast(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
__u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
|
||||
__u8 contrast = sd->contrast;
|
||||
|
||||
memset(RGBG, contrast, sizeof(RGBG) - 2);
|
||||
reg_w(gspca_dev, ET_G_RED, RGBG, 6);
|
||||
}
|
||||
|
||||
static void getcontrast(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
int contrast = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
reg_r(gspca_dev, ET_G_RED + i, 1);
|
||||
contrast += gspca_dev->usb_buf[0];
|
||||
}
|
||||
sd->contrast = contrast >> 2;
|
||||
}
|
||||
|
||||
static void setcolors(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
@ -492,6 +538,16 @@ static void getcolors(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (sd->autogain)
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
else
|
||||
sd->ag_cnt = -1;
|
||||
}
|
||||
|
||||
static void Et_init1(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
__u8 value;
|
||||
|
@ -614,6 +670,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
sd->contrast = CONTRAST_DEF;
|
||||
sd->colors = COLOR_DEF;
|
||||
sd->autogain = AUTOGAIN_DEF;
|
||||
sd->ag_cnt = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -641,6 +698,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
else
|
||||
Et_init2(gspca_dev);
|
||||
|
||||
setautogain(gspca_dev);
|
||||
|
||||
reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
|
||||
et_video(gspca_dev, 1); /* video on */
|
||||
}
|
||||
|
@ -658,52 +717,6 @@ static void sd_close(struct gspca_dev *gspca_dev)
|
|||
{
|
||||
}
|
||||
|
||||
static void setbrightness(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
__u8 brightness = sd->brightness;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
reg_w_val(gspca_dev, ET_O_RED + i, brightness);
|
||||
}
|
||||
|
||||
static void getbrightness(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
int brightness = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
reg_r(gspca_dev, ET_O_RED + i, 1);
|
||||
brightness += gspca_dev->usb_buf[0];
|
||||
}
|
||||
sd->brightness = brightness >> 3;
|
||||
}
|
||||
|
||||
static void setcontrast(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
__u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
|
||||
__u8 contrast = sd->contrast;
|
||||
|
||||
memset(RGBG, contrast, sizeof(RGBG) - 2);
|
||||
reg_w(gspca_dev, ET_G_RED, RGBG, 6);
|
||||
}
|
||||
|
||||
static void getcontrast(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
int contrast = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
reg_r(gspca_dev, ET_G_RED + i, 1);
|
||||
contrast += gspca_dev->usb_buf[0];
|
||||
}
|
||||
sd->contrast = contrast >> 2;
|
||||
}
|
||||
|
||||
static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
@ -733,15 +746,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
|
|||
#define LIMIT(color) \
|
||||
(unsigned char)((color > 0xff)?0xff:((color < 0)?0:color))
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
static void do_autogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
__u8 luma = 0;
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
__u8 luma;
|
||||
__u8 luma_mean = 128;
|
||||
__u8 luma_delta = 20;
|
||||
__u8 spring = 4;
|
||||
int Gbright = 0;
|
||||
int Gbright;
|
||||
__u8 r, g, b;
|
||||
|
||||
if (sd->ag_cnt < 0)
|
||||
return;
|
||||
if (--sd->ag_cnt >= 0)
|
||||
return;
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
|
||||
Gbright = Et_getgainG(gspca_dev);
|
||||
reg_r(gspca_dev, ET_LUMA_CENTER, 4);
|
||||
g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
|
||||
|
@ -768,7 +788,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
__u8 *data, /* isoc packet */
|
||||
int len) /* iso packet length */
|
||||
{
|
||||
struct sd *sd;
|
||||
int seqframe;
|
||||
|
||||
seqframe = data[0] & 0x3f;
|
||||
|
@ -783,13 +802,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
|
||||
data, 0);
|
||||
gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
|
||||
sd = (struct sd *) gspca_dev;
|
||||
if (sd->ag_cnt >= 0) {
|
||||
if (--sd->ag_cnt < 0) {
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
setautogain(gspca_dev);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (len) {
|
||||
|
@ -862,10 +874,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
|||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->autogain = val;
|
||||
if (val)
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
else
|
||||
sd->ag_cnt = -1;
|
||||
if (gspca_dev->streaming)
|
||||
setautogain(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -889,6 +899,7 @@ static struct sd_desc sd_desc = {
|
|||
.stop0 = sd_stop0,
|
||||
.close = sd_close,
|
||||
.pkt_scan = sd_pkt_scan,
|
||||
.dq_callback = do_autogain,
|
||||
};
|
||||
|
||||
/* -- module initialisation -- */
|
||||
|
|
|
@ -47,7 +47,7 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
static int video_nr = -1;
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
int gspca_debug = D_ERR | D_PROBE;
|
||||
EXPORT_SYMBOL(gspca_debug);
|
||||
|
||||
|
@ -677,7 +677,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
|
|||
w = fmt->fmt.pix.width;
|
||||
h = fmt->fmt.pix.height;
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (gspca_debug & D_CONF)
|
||||
PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h);
|
||||
#endif
|
||||
|
@ -785,7 +785,7 @@ static int dev_open(struct inode *inode, struct file *file)
|
|||
}
|
||||
gspca_dev->users++;
|
||||
file->private_data = gspca_dev;
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
/* activate the v4l2 debug */
|
||||
if (gspca_debug & D_V4L2)
|
||||
gspca_dev->vdev.debug |= 3;
|
||||
|
@ -904,7 +904,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
|||
if (ctrl->id != ctrls->qctrl.id)
|
||||
continue;
|
||||
if (ctrl->value < ctrls->qctrl.minimum
|
||||
&& ctrl->value > ctrls->qctrl.maximum)
|
||||
|| ctrl->value > ctrls->qctrl.maximum)
|
||||
return -ERANGE;
|
||||
PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
|
||||
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
|
||||
|
@ -1080,7 +1080,7 @@ static int vidioc_streamon(struct file *file, void *priv,
|
|||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (gspca_debug & D_STREAM) {
|
||||
PDEBUG_MODE("stream on OK",
|
||||
gspca_dev->pixfmt,
|
||||
|
@ -1913,7 +1913,7 @@ static void __exit gspca_exit(void)
|
|||
module_init(gspca_init);
|
||||
module_exit(gspca_exit);
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
module_param_named(debug, gspca_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug,
|
||||
"Debug (bit) 0x01:error 0x02:probe 0x04:config"
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
#include <media/v4l2-common.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
/* compilation option */
|
||||
#define GSPCA_DEBUG 1
|
||||
|
||||
#ifdef GSPCA_DEBUG
|
||||
/* GSPCA our debug messages */
|
||||
extern int gspca_debug;
|
||||
#define PDEBUG(level, fmt, args...) \
|
||||
|
|
|
@ -40,14 +40,15 @@ struct sd {
|
|||
struct gspca_dev gspca_dev; /* !! must be the first item */
|
||||
|
||||
/* Determined by sensor type */
|
||||
short maxwidth;
|
||||
short maxheight;
|
||||
char sif;
|
||||
|
||||
unsigned char primary_i2c_slave; /* I2C write id of sensor */
|
||||
|
||||
unsigned char brightness;
|
||||
unsigned char contrast;
|
||||
unsigned char colors;
|
||||
__u8 hflip;
|
||||
__u8 vflip;
|
||||
|
||||
char compress; /* Should the next frame be compressed? */
|
||||
char compress_inited; /* Are compression params uploaded? */
|
||||
|
@ -77,9 +78,12 @@ 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_setcolors(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
|
||||
static struct ctrl sd_ctrls[] = {
|
||||
#define SD_BRIGHTNESS 0
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_BRIGHTNESS,
|
||||
|
@ -88,12 +92,12 @@ static struct ctrl sd_ctrls[] = {
|
|||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
.default_value = 127,
|
||||
#define BRIGHTNESS_DEF 127
|
||||
.default_value = BRIGHTNESS_DEF,
|
||||
},
|
||||
.set = sd_setbrightness,
|
||||
.get = sd_getbrightness,
|
||||
},
|
||||
#define SD_CONTRAST 1
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_CONTRAST,
|
||||
|
@ -102,31 +106,61 @@ static struct ctrl sd_ctrls[] = {
|
|||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
.default_value = 127,
|
||||
#define CONTRAST_DEF 127
|
||||
.default_value = CONTRAST_DEF,
|
||||
},
|
||||
.set = sd_setcontrast,
|
||||
.get = sd_getcontrast,
|
||||
},
|
||||
#define SD_COLOR 2
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_SATURATION,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Saturation",
|
||||
.name = "Color",
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
.default_value = 127,
|
||||
#define COLOR_DEF 127
|
||||
.default_value = COLOR_DEF,
|
||||
},
|
||||
.set = sd_setcolors,
|
||||
.get = sd_getcolors,
|
||||
},
|
||||
/* next controls work with ov7670 only */
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_HFLIP,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
.name = "Mirror",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.step = 1,
|
||||
#define HFLIP_DEF 0
|
||||
.default_value = HFLIP_DEF,
|
||||
},
|
||||
.set = sd_sethflip,
|
||||
.get = sd_gethflip,
|
||||
},
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_VFLIP,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
.name = "Vflip",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.step = 1,
|
||||
#define VFLIP_DEF 0
|
||||
.default_value = VFLIP_DEF,
|
||||
},
|
||||
.set = sd_setvflip,
|
||||
.get = sd_getvflip,
|
||||
},
|
||||
};
|
||||
|
||||
static struct v4l2_pix_format vga_mode[] = {
|
||||
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
||||
.bytesperline = 320,
|
||||
.sizeimage = 320 * 240 * 3 / 8 + 589,
|
||||
.sizeimage = 320 * 240 * 3 / 8 + 590,
|
||||
.colorspace = V4L2_COLORSPACE_JPEG,
|
||||
.priv = 1},
|
||||
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
||||
|
@ -138,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = {
|
|||
static struct v4l2_pix_format sif_mode[] = {
|
||||
{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
||||
.bytesperline = 176,
|
||||
.sizeimage = 176 * 144 * 3 / 8 + 589,
|
||||
.sizeimage = 176 * 144 * 3 / 8 + 590,
|
||||
.colorspace = V4L2_COLORSPACE_JPEG,
|
||||
.priv = 1},
|
||||
{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
||||
.bytesperline = 352,
|
||||
.sizeimage = 352 * 288 * 3 / 8 + 589,
|
||||
.sizeimage = 352 * 288 * 3 / 8 + 590,
|
||||
.colorspace = V4L2_COLORSPACE_JPEG,
|
||||
.priv = 0},
|
||||
};
|
||||
|
@ -225,6 +259,7 @@ static struct v4l2_pix_format sif_mode[] = {
|
|||
#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
|
||||
#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
|
||||
#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
|
||||
#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
|
||||
#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
|
||||
#define OV7670_REG_AEW 0x24 /* AGC upper limit */
|
||||
#define OV7670_REG_AEB 0x25 /* AGC lower limit */
|
||||
|
@ -258,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = {
|
|||
#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
|
||||
#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
|
||||
|
||||
struct ovsensor_window {
|
||||
short x;
|
||||
short y;
|
||||
short width;
|
||||
short height;
|
||||
/* int format; */
|
||||
short quarter; /* Scale width and height down 2x */
|
||||
short clockdiv; /* Clock divisor setting */
|
||||
};
|
||||
|
||||
static unsigned char ov7670_abs_to_sm(unsigned char v)
|
||||
{
|
||||
if (v > 127)
|
||||
|
@ -499,19 +524,6 @@ static int init_ov_sensor(struct sd *sd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Switch on standard JPEG compression. Returns 0 for success. */
|
||||
static int ov519_init_compression(struct sd *sd)
|
||||
{
|
||||
if (!sd->compress_inited) {
|
||||
if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) {
|
||||
PDEBUG(D_ERR, "Error switching to compressed mode");
|
||||
return -EIO;
|
||||
}
|
||||
sd->compress_inited = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the read and write slave IDs. The "slave" argument is the write slave,
|
||||
* and the read slave will be set to (slave + 1).
|
||||
* This should not be called from outside the i2c I/O functions.
|
||||
|
@ -681,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd)
|
|||
return -1;
|
||||
}
|
||||
if ((rc & 3) == 1) {
|
||||
PDEBUG(D_PROBE, "Sensor is an OV8610");
|
||||
sd->sensor = SEN_OV8610;
|
||||
} else {
|
||||
PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
|
||||
return -1;
|
||||
}
|
||||
PDEBUG(D_PROBE, "Writing 8610 registers");
|
||||
if (write_i2c_regvals(sd,
|
||||
norm_8610,
|
||||
sizeof norm_8610 / sizeof norm_8610[0]))
|
||||
if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
|
||||
return -1;
|
||||
|
||||
/* Set sensor-specific vars */
|
||||
sd->maxwidth = 640;
|
||||
sd->maxheight = 480;
|
||||
/* sd->sif = 0; already done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -825,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
{ OV7670_REG_COM7, OV7670_COM7_RESET },
|
||||
{ OV7670_REG_TSLB, 0x04 }, /* OV */
|
||||
{ OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
|
||||
{ OV7670_REG_CLKRC, 0x1 },
|
||||
{ OV7670_REG_CLKRC, 0x01 },
|
||||
/*
|
||||
* Set the hardware window. These values from OV don't entirely
|
||||
* make sense - hstop is less than hstart. But they work...
|
||||
|
@ -839,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
{ 0x70, 0x3a }, { 0x71, 0x35 },
|
||||
{ 0x72, 0x11 }, { 0x73, 0xf0 },
|
||||
{ 0xa2, 0x02 },
|
||||
/* jfm */
|
||||
/* { OV7670_REG_COM10, 0x0 }, */
|
||||
/* { OV7670_REG_COM10, 0x0 }, */
|
||||
|
||||
/* Gamma curve values */
|
||||
{ 0x7a, 0x20 },
|
||||
/* jfm:win 7b=1c */
|
||||
{ 0x7b, 0x10 },
|
||||
/* jfm:win 7c=28 */
|
||||
{ 0x7c, 0x1e },
|
||||
/* jfm:win 7d=3c */
|
||||
{ 0x7d, 0x35 },
|
||||
{ 0x7e, 0x5a }, { 0x7f, 0x69 },
|
||||
{ 0x80, 0x76 }, { 0x81, 0x80 },
|
||||
|
@ -864,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
| OV7670_COM8_BFILT },
|
||||
{ OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 },
|
||||
{ OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
|
||||
/* jfm:win 14=38 */
|
||||
{ OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
|
||||
{ OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 },
|
||||
{ OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 },
|
||||
{ OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 },
|
||||
{ OV7670_REG_HAECC2, 0x68 },
|
||||
/* jfm:win a1=0b */
|
||||
{ 0xa1, 0x03 }, /* magic */
|
||||
{ OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 },
|
||||
{ OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 },
|
||||
|
@ -884,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
/* Almost all of these are magic "reserved" values. */
|
||||
{ OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b },
|
||||
{ 0x16, 0x02 },
|
||||
/* jfm */
|
||||
/* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */
|
||||
{ OV7670_REG_MVFP, 0x07 },
|
||||
{ 0x21, 0x02 }, { 0x22, 0x91 },
|
||||
{ 0x29, 0x07 }, { 0x33, 0x0b },
|
||||
|
@ -930,7 +930,10 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
{ OV7670_REG_EDGE, 0 },
|
||||
{ 0x75, 0x05 }, { 0x76, 0xe1 },
|
||||
{ 0x4c, 0 }, { 0x77, 0x01 },
|
||||
{ OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 },
|
||||
{ OV7670_REG_COM13, OV7670_COM13_GAMMA
|
||||
| OV7670_COM13_UVSAT
|
||||
| 2}, /* was 3 */
|
||||
{ 0x4b, 0x09 },
|
||||
{ 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
|
||||
{ 0x56, 0x40 },
|
||||
|
||||
|
@ -956,30 +959,10 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
{ 0x79, 0x03 }, { 0xc8, 0x40 },
|
||||
{ 0x79, 0x05 }, { 0xc8, 0x30 },
|
||||
{ 0x79, 0x26 },
|
||||
|
||||
/* Format YUV422 */
|
||||
{ OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */
|
||||
{ OV7670_REG_RGB444, 0 }, /* No RGB444 please */
|
||||
{ OV7670_REG_COM1, 0 },
|
||||
{ OV7670_REG_COM15, OV7670_COM15_R00FF },
|
||||
{ OV7670_REG_COM9, 0x18 },
|
||||
/* 4x gain ceiling; 0x8 is reserved bit */
|
||||
{ 0x4f, 0x80 }, /* "matrix coefficient 1" */
|
||||
{ 0x50, 0x80 }, /* "matrix coefficient 2" */
|
||||
{ 0x52, 0x22 }, /* "matrix coefficient 4" */
|
||||
{ 0x53, 0x5e }, /* "matrix coefficient 5" */
|
||||
{ 0x54, 0x80 }, /* "matrix coefficient 6" */
|
||||
{ OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT },
|
||||
};
|
||||
};
|
||||
|
||||
PDEBUG(D_PROBE, "starting OV7xx0 configuration");
|
||||
|
||||
/* jfm:already done? */
|
||||
if (init_ov_sensor(sd) < 0)
|
||||
PDEBUG(D_ERR, "Failed to read sensor ID");
|
||||
else
|
||||
PDEBUG(D_PROBE, "OV7xx0 initialized");
|
||||
|
||||
/* Detect sensor (sub)type */
|
||||
rc = i2c_r(sd, OV7610_REG_COM_I);
|
||||
|
||||
|
@ -1025,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
return low;
|
||||
}
|
||||
if (high == 0x76) {
|
||||
if (low == 0x30) {
|
||||
switch (low) {
|
||||
case 0x30:
|
||||
PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
|
||||
sd->sensor = SEN_OV7630;
|
||||
} else if (low == 0x40) {
|
||||
break;
|
||||
case 0x40:
|
||||
PDEBUG(D_PROBE, "Sensor is an OV7645");
|
||||
sd->sensor = SEN_OV7640; /* FIXME */
|
||||
} else if (low == 0x45) {
|
||||
break;
|
||||
case 0x45:
|
||||
PDEBUG(D_PROBE, "Sensor is an OV7645B");
|
||||
sd->sensor = SEN_OV7640; /* FIXME */
|
||||
} else if (low == 0x48) {
|
||||
break;
|
||||
case 0x48:
|
||||
PDEBUG(D_PROBE, "Sensor is an OV7648");
|
||||
sd->sensor = SEN_OV7640; /* FIXME */
|
||||
} else {
|
||||
PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low);
|
||||
break;
|
||||
default:
|
||||
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
|
@ -1050,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (sd->sensor == SEN_OV7620) {
|
||||
switch (sd->sensor) {
|
||||
case SEN_OV7620:
|
||||
PDEBUG(D_PROBE, "Writing 7620 registers");
|
||||
if (write_i2c_regvals(sd, norm_7620,
|
||||
sizeof norm_7620 / sizeof norm_7620[0]))
|
||||
if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
|
||||
return -1;
|
||||
} else if (sd->sensor == SEN_OV7630) {
|
||||
break;
|
||||
case SEN_OV7630:
|
||||
PDEBUG(D_ERR, "7630 is not supported by this driver version");
|
||||
return -1;
|
||||
} else if (sd->sensor == SEN_OV7640) {
|
||||
case SEN_OV7640:
|
||||
PDEBUG(D_PROBE, "Writing 7640 registers");
|
||||
if (write_i2c_regvals(sd, norm_7640,
|
||||
sizeof norm_7640 / sizeof norm_7640[0]))
|
||||
if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
|
||||
return -1;
|
||||
} else if (sd->sensor == SEN_OV7670) {
|
||||
break;
|
||||
case SEN_OV7670:
|
||||
PDEBUG(D_PROBE, "Writing 7670 registers");
|
||||
if (write_i2c_regvals(sd, norm_7670,
|
||||
sizeof norm_7670 / sizeof norm_7670[0]))
|
||||
if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
|
||||
return -1;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
PDEBUG(D_PROBE, "Writing 7610 registers");
|
||||
if (write_i2c_regvals(sd, norm_7610,
|
||||
sizeof norm_7610 / sizeof norm_7610[0]))
|
||||
if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set sensor-specific vars */
|
||||
sd->maxwidth = 640;
|
||||
sd->maxheight = 480;
|
||||
/* sd->sif = 0; already done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1231,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd)
|
|||
/* Ugh. The first two bits are the version bits, but
|
||||
* the entire register value must be used. I guess OVT
|
||||
* underestimated how many variants they would make. */
|
||||
if (rc == 0x00) {
|
||||
switch (rc) {
|
||||
case 0x00:
|
||||
sd->sensor = SEN_OV6630;
|
||||
PDEBUG(D_ERR,
|
||||
"WARNING: Sensor is an OV66308. Your camera may have");
|
||||
PDEBUG(D_ERR, "been misdetected in previous driver versions.");
|
||||
} else if (rc == 0x01) {
|
||||
break;
|
||||
case 0x01:
|
||||
sd->sensor = SEN_OV6620;
|
||||
PDEBUG(D_PROBE, "Sensor is an OV6620");
|
||||
} else if (rc == 0x02) {
|
||||
break;
|
||||
case 0x02:
|
||||
sd->sensor = SEN_OV6630;
|
||||
PDEBUG(D_PROBE, "Sensor is an OV66308AE");
|
||||
} else if (rc == 0x03) {
|
||||
break;
|
||||
case 0x03:
|
||||
sd->sensor = SEN_OV6630;
|
||||
PDEBUG(D_PROBE, "Sensor is an OV66308AF");
|
||||
} else if (rc == 0x90) {
|
||||
break;
|
||||
case 0x90:
|
||||
sd->sensor = SEN_OV6630;
|
||||
PDEBUG(D_ERR,
|
||||
"WARNING: Sensor is an OV66307. Your camera may have");
|
||||
PDEBUG(D_ERR, "been misdetected in previous driver versions.");
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set sensor-specific vars */
|
||||
sd->maxwidth = 352;
|
||||
sd->maxheight = 288;
|
||||
sd->sif = 1;
|
||||
|
||||
if (sd->sensor == SEN_OV6620) {
|
||||
PDEBUG(D_PROBE, "Writing 6x20 registers");
|
||||
if (write_i2c_regvals(sd, norm_6x20,
|
||||
sizeof norm_6x20 / sizeof norm_6x20[0]))
|
||||
if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
|
||||
return -1;
|
||||
} else {
|
||||
PDEBUG(D_PROBE, "Writing 6x30 registers");
|
||||
if (write_i2c_regvals(sd, norm_6x30,
|
||||
sizeof norm_6x30 / sizeof norm_6x30[0]))
|
||||
if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1276,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd)
|
|||
/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
|
||||
static void ov51x_led_control(struct sd *sd, int on)
|
||||
{
|
||||
PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off");
|
||||
|
||||
/* if (sd->bridge == BRG_OV511PLUS) */
|
||||
/* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */
|
||||
/* else if (sd->bridge == BRG_OV519) */
|
||||
reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
|
||||
/* else if (sd->bclass == BCL_OV518) */
|
||||
/* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */
|
||||
/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */
|
||||
reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
|
||||
}
|
||||
|
||||
/* this function is called at probe time */
|
||||
|
@ -1293,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
struct cam *cam;
|
||||
|
||||
/* (from ov519_configure) */
|
||||
static const struct ov_regvals init_519[] = {
|
||||
{ 0x5a, 0x6d }, /* EnableSystem */
|
||||
/* jfm trace usbsnoop3-1.txt */
|
||||
/* jfm 53 = fb */
|
||||
{ 0x53, 0x9b },
|
||||
{ 0x54, 0xff }, /* set bit2 to enable jpeg */
|
||||
{ 0x5d, 0x03 },
|
||||
|
@ -1314,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
|
||||
if (write_regvals(sd, init_519, ARRAY_SIZE(init_519)))
|
||||
goto error;
|
||||
/* jfm: not seen in windows trace */
|
||||
if (ov519_init_compression(sd))
|
||||
goto error;
|
||||
ov51x_led_control(sd, 0); /* turn LED off */
|
||||
|
||||
/* Test for 76xx */
|
||||
|
@ -1365,16 +1343,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
|
||||
cam = &gspca_dev->cam;
|
||||
cam->epaddr = OV511_ENDPOINT_ADDRESS;
|
||||
if (sd->maxwidth == 640) {
|
||||
if (!sd->sif) {
|
||||
cam->cam_mode = vga_mode;
|
||||
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
|
||||
cam->nmodes = ARRAY_SIZE(vga_mode);
|
||||
} else {
|
||||
cam->cam_mode = sif_mode;
|
||||
cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
|
||||
cam->nmodes = ARRAY_SIZE(sif_mode);
|
||||
}
|
||||
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
|
||||
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
|
||||
sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
|
||||
sd->brightness = BRIGHTNESS_DEF;
|
||||
sd->contrast = CONTRAST_DEF;
|
||||
sd->colors = COLOR_DEF;
|
||||
sd->hflip = HFLIP_DEF;
|
||||
sd->vflip = VFLIP_DEF;
|
||||
return 0;
|
||||
error:
|
||||
PDEBUG(D_ERR, "OV519 Config failed");
|
||||
|
@ -1394,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
|
|||
*
|
||||
* Do not put any sensor-specific code in here (including I2C I/O functions)
|
||||
*/
|
||||
static int ov519_mode_init_regs(struct sd *sd,
|
||||
int width, int height)
|
||||
static int ov519_mode_init_regs(struct sd *sd)
|
||||
{
|
||||
static const struct ov_regvals mode_init_519_ov7670[] = {
|
||||
{ 0x5d, 0x03 }, /* Turn off suspend mode */
|
||||
|
@ -1441,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd,
|
|||
/* windows reads 0x55 at this point, why? */
|
||||
};
|
||||
|
||||
/* int hi_res; */
|
||||
|
||||
PDEBUG(D_CONF, "mode init %dx%d", width, height);
|
||||
|
||||
/* if (width >= 800 && height >= 600)
|
||||
hi_res = 1;
|
||||
else
|
||||
hi_res = 0; */
|
||||
|
||||
/* if (ov51x_stop(sd) < 0)
|
||||
return -EIO; */
|
||||
|
||||
/******** Set the mode ********/
|
||||
if (sd->sensor != SEN_OV7670) {
|
||||
if (write_regvals(sd, mode_init_519,
|
||||
ARRAY_SIZE(mode_init_519)))
|
||||
return -EIO;
|
||||
if (sd->sensor == SEN_OV7640) {
|
||||
/* Select 8-bit input mode */
|
||||
reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
|
||||
}
|
||||
} else {
|
||||
if (write_regvals(sd, mode_init_519_ov7670,
|
||||
ARRAY_SIZE(mode_init_519_ov7670)))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (sd->sensor == SEN_OV7640) {
|
||||
/* Select 8-bit input mode */
|
||||
reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
|
||||
}
|
||||
|
||||
reg_w(sd, OV519_CAM_H_SIZE, width >> 4);
|
||||
reg_w(sd, OV519_CAM_V_SIZE, height >> 3);
|
||||
reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4);
|
||||
reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3);
|
||||
reg_w(sd, OV519_CAM_X_OFFSETL, 0x00);
|
||||
reg_w(sd, OV519_CAM_X_OFFSETH, 0x00);
|
||||
reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00);
|
||||
|
@ -1485,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd,
|
|||
|
||||
/* FIXME: These are only valid at the max resolution. */
|
||||
sd->clockdiv = 0;
|
||||
if (sd->sensor == SEN_OV7640) {
|
||||
switch (sd->sensor) {
|
||||
case SEN_OV7640:
|
||||
switch (sd->frame_rate) {
|
||||
/*jfm: default was 30 fps */
|
||||
/*fixme: default was 30 fps */
|
||||
case 30:
|
||||
reg_w(sd, 0xa4, 0x0c);
|
||||
reg_w(sd, 0x23, 0xff);
|
||||
|
@ -1517,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd,
|
|||
sd->clockdiv = 1;
|
||||
break;
|
||||
}
|
||||
} else if (sd->sensor == SEN_OV8610) {
|
||||
break;
|
||||
case SEN_OV8610:
|
||||
switch (sd->frame_rate) {
|
||||
default: /* 15 fps */
|
||||
/* case 15: */
|
||||
|
@ -1533,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd,
|
|||
reg_w(sd, 0x23, 0x1b);
|
||||
break;
|
||||
}
|
||||
sd->clockdiv = 0;
|
||||
} else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */
|
||||
break;
|
||||
case SEN_OV7670: /* guesses, based on 7640 */
|
||||
PDEBUG(D_STREAM, "Setting framerate to %d fps",
|
||||
(sd->frame_rate == 0) ? 15 : sd->frame_rate);
|
||||
reg_w(sd, 0xa4, 0x10);
|
||||
switch (sd->frame_rate) {
|
||||
case 30:
|
||||
reg_w(sd, 0xa4, 0x10);
|
||||
reg_w(sd, 0x23, 0xff);
|
||||
break;
|
||||
case 20:
|
||||
reg_w(sd, 0xa4, 0x10);
|
||||
reg_w(sd, 0x23, 0x1b);
|
||||
break;
|
||||
default: /* 15 fps */
|
||||
/* case 15: */
|
||||
reg_w(sd, 0xa4, 0x10);
|
||||
default:
|
||||
/* case 15: */
|
||||
reg_w(sd, 0x23, 0xff);
|
||||
sd->clockdiv = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* if (ov51x_restart(sd) < 0)
|
||||
return -EIO; */
|
||||
|
||||
/* Reset it just for good measure */
|
||||
/* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0)
|
||||
return -EIO; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mode_init_ov_sensor_regs(struct sd *sd,
|
||||
struct ovsensor_window *win)
|
||||
static int mode_init_ov_sensor_regs(struct sd *sd)
|
||||
{
|
||||
int qvga = win->quarter;
|
||||
struct gspca_dev *gspca_dev;
|
||||
int qvga;
|
||||
|
||||
gspca_dev = &sd->gspca_dev;
|
||||
qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
|
||||
|
||||
/******** Mode (VGA/QVGA) and sensor specific regs ********/
|
||||
switch (sd->sensor) {
|
||||
|
@ -1611,8 +1575,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
|
|||
OV7670_COM7_FMT_MASK);
|
||||
break;
|
||||
case SEN_OV6620:
|
||||
i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
|
||||
break;
|
||||
case SEN_OV6630:
|
||||
i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
|
||||
break;
|
||||
|
@ -1621,24 +1583,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
|
|||
}
|
||||
|
||||
/******** Palette-specific regs ********/
|
||||
/* Need to do work here for the OV7670 */
|
||||
if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
|
||||
/* not valid on the OV6620/OV7620/6630? */
|
||||
i2c_w_mask(sd, 0x0e, 0x00, 0x40);
|
||||
}
|
||||
|
||||
if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
|
||||
/* not valid on the OV6620/OV7620/6630? */
|
||||
i2c_w_mask(sd, 0x0e, 0x00, 0x40);
|
||||
}
|
||||
/* The OV518 needs special treatment. Although both the OV518
|
||||
* and the OV6630 support a 16-bit video bus, only the 8 bit Y
|
||||
* bus is actually used. The UV bus is tied to ground.
|
||||
* Therefore, the OV6630 needs to be in 8-bit multiplexed
|
||||
* output mode */
|
||||
|
||||
/* The OV518 needs special treatment. Although both the OV518
|
||||
* and the OV6630 support a 16-bit video bus, only the 8 bit Y
|
||||
* bus is actually used. The UV bus is tied to ground.
|
||||
* Therefore, the OV6630 needs to be in 8-bit multiplexed
|
||||
* output mode */
|
||||
/* OV7640 is 8-bit only */
|
||||
|
||||
/* OV7640 is 8-bit only */
|
||||
|
||||
if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640)
|
||||
i2c_w_mask(sd, 0x13, 0x00, 0x20);
|
||||
/* } */
|
||||
if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640)
|
||||
i2c_w_mask(sd, 0x13, 0x00, 0x20);
|
||||
|
||||
/******** Clock programming ********/
|
||||
/* The OV6620 needs special handling. This prevents the
|
||||
|
@ -1647,14 +1606,14 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
|
|||
|
||||
/* Clock down */
|
||||
i2c_w(sd, 0x2a, 0x04);
|
||||
i2c_w(sd, 0x11, win->clockdiv);
|
||||
i2c_w(sd, 0x11, sd->clockdiv);
|
||||
i2c_w(sd, 0x2a, 0x84);
|
||||
/* This next setting is critical. It seems to improve
|
||||
* the gain or the contrast. The "reserved" bits seem
|
||||
* to have some effect in this case. */
|
||||
i2c_w(sd, 0x2d, 0x85);
|
||||
} else if (win->clockdiv >= 0) {
|
||||
i2c_w(sd, 0x11, win->clockdiv);
|
||||
} else if (sd->clockdiv >= 0) {
|
||||
i2c_w(sd, 0x11, sd->clockdiv);
|
||||
}
|
||||
|
||||
/******** Special Features ********/
|
||||
|
@ -1674,7 +1633,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
|
|||
/* is fully tested. */
|
||||
/* 7620/6620/6630? don't have register 0x35, so play it safe */
|
||||
if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
|
||||
if (win->width == 640 /*&& win->height == 480*/)
|
||||
if (!qvga)
|
||||
i2c_w(sd, 0x35, 0x9e);
|
||||
else
|
||||
i2c_w(sd, 0x35, 0x1e);
|
||||
|
@ -1682,13 +1641,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int set_ov_sensor_window(struct sd *sd,
|
||||
struct ovsensor_window *win)
|
||||
static void sethvflip(struct sd *sd)
|
||||
{
|
||||
if (sd->sensor != SEN_OV7670)
|
||||
return;
|
||||
if (sd->gspca_dev.streaming)
|
||||
ov51x_stop(sd);
|
||||
i2c_w_mask(sd, OV7670_REG_MVFP,
|
||||
OV7670_MVFP_MIRROR * sd->hflip
|
||||
| OV7670_MVFP_VFLIP * sd->vflip,
|
||||
OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
|
||||
if (sd->gspca_dev.streaming)
|
||||
ov51x_restart(sd);
|
||||
}
|
||||
|
||||
static int set_ov_sensor_window(struct sd *sd)
|
||||
{
|
||||
struct gspca_dev *gspca_dev;
|
||||
int qvga;
|
||||
int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
|
||||
int ret, hstart, hstop, vstop, vstart;
|
||||
__u8 v;
|
||||
|
||||
gspca_dev = &sd->gspca_dev;
|
||||
qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
|
||||
|
||||
/* The different sensor ICs handle setting up of window differently.
|
||||
* IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
|
||||
switch (sd->sensor) {
|
||||
|
@ -1733,7 +1710,7 @@ static int set_ov_sensor_window(struct sd *sd,
|
|||
switch (sd->sensor) {
|
||||
case SEN_OV6620:
|
||||
case SEN_OV6630:
|
||||
if (win->quarter) { /* QCIF */
|
||||
if (qvga) { /* QCIF */
|
||||
hwscale = 0;
|
||||
vwscale = 0;
|
||||
} else { /* CIF */
|
||||
|
@ -1743,7 +1720,7 @@ static int set_ov_sensor_window(struct sd *sd,
|
|||
}
|
||||
break;
|
||||
case SEN_OV8610:
|
||||
if (win->quarter) { /* QSVGA */
|
||||
if (qvga) { /* QSVGA */
|
||||
hwscale = 1;
|
||||
vwscale = 1;
|
||||
} else { /* SVGA */
|
||||
|
@ -1752,7 +1729,7 @@ static int set_ov_sensor_window(struct sd *sd,
|
|||
}
|
||||
break;
|
||||
default: /* SEN_OV7xx0 */
|
||||
if (win->quarter) { /* QVGA */
|
||||
if (qvga) { /* QVGA */
|
||||
hwscale = 1;
|
||||
vwscale = 0;
|
||||
} else { /* VGA */
|
||||
|
@ -1761,7 +1738,7 @@ static int set_ov_sensor_window(struct sd *sd,
|
|||
}
|
||||
}
|
||||
|
||||
ret = mode_init_ov_sensor_regs(sd, win);
|
||||
ret = mode_init_ov_sensor_regs(sd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1782,7 +1759,7 @@ static int set_ov_sensor_window(struct sd *sd,
|
|||
/* I can hard code this for OV7670s */
|
||||
/* Yes, these numbers do look odd, but they're tested and work! */
|
||||
if (sd->sensor == SEN_OV7670) {
|
||||
if (win->quarter) { /* QVGA from ov7670.c by
|
||||
if (qvga) { /* QVGA from ov7670.c by
|
||||
* Jonathan Corbet */
|
||||
hstart = 164;
|
||||
hstop = 20;
|
||||
|
@ -1796,75 +1773,45 @@ static int set_ov_sensor_window(struct sd *sd,
|
|||
}
|
||||
/* OV7670 hardware window registers are split across
|
||||
* multiple locations */
|
||||
i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff);
|
||||
i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff);
|
||||
i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
|
||||
i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
|
||||
v = i2c_r(sd, OV7670_REG_HREF);
|
||||
v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
|
||||
msleep(10); /* need to sleep between read and write to
|
||||
* same reg! */
|
||||
i2c_w(sd, OV7670_REG_HREF, v);
|
||||
|
||||
i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff);
|
||||
i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff);
|
||||
i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
|
||||
i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
|
||||
v = i2c_r(sd, OV7670_REG_VREF);
|
||||
v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
|
||||
msleep(10); /* need to sleep between read and write to
|
||||
* same reg! */
|
||||
i2c_w(sd, OV7670_REG_VREF, v);
|
||||
|
||||
sethvflip(sd);
|
||||
} else {
|
||||
i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale));
|
||||
i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale));
|
||||
i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale));
|
||||
i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale));
|
||||
i2c_w(sd, 0x17, hwsbase);
|
||||
i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
|
||||
i2c_w(sd, 0x19, vwsbase);
|
||||
i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov_sensor_mode_setup(struct sd *sd,
|
||||
int width, int height)
|
||||
{
|
||||
struct ovsensor_window win;
|
||||
|
||||
/* win.format = mode; */
|
||||
|
||||
/* Unless subcapture is enabled,
|
||||
* center the image window and downsample
|
||||
* if possible to increase the field of view */
|
||||
/* NOTE: OV518(+) and OV519 does downsampling on its own */
|
||||
win.width = width;
|
||||
win.height = height;
|
||||
if (width == sd->maxwidth)
|
||||
win.quarter = 0;
|
||||
else
|
||||
win.quarter = 1;
|
||||
|
||||
/* Center it */
|
||||
win.x = (win.width - width) / 2;
|
||||
win.y = (win.height - height) / 2;
|
||||
|
||||
/* Clock is determined by OV519 frame rate code */
|
||||
win.clockdiv = sd->clockdiv;
|
||||
|
||||
PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv);
|
||||
return set_ov_sensor_window(sd, &win);
|
||||
}
|
||||
|
||||
/* -- start the camera -- */
|
||||
static void sd_start(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height);
|
||||
ret = ov519_mode_init_regs(sd);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height);
|
||||
ret = set_ov_sensor_window(sd);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = ov51x_restart((struct sd *) gspca_dev);
|
||||
ret = ov51x_restart(sd);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
|
||||
|
@ -1938,12 +1885,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int val;
|
||||
/* int was_streaming; */
|
||||
|
||||
val = sd->brightness;
|
||||
PDEBUG(D_CONF, "brightness:%d", val);
|
||||
/* was_streaming = gspca_dev->streaming;
|
||||
* if (was_streaming)
|
||||
/* if (gspca_dev->streaming)
|
||||
* ov51x_stop(sd); */
|
||||
switch (sd->sensor) {
|
||||
case SEN_OV8610:
|
||||
|
@ -1961,12 +1906,12 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|||
i2c_w(sd, OV7610_REG_BRT, val);
|
||||
break;
|
||||
case SEN_OV7670:
|
||||
/*jfm - from windblows
|
||||
/*win trace
|
||||
* i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
|
||||
i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
|
||||
break;
|
||||
}
|
||||
/* if (was_streaming)
|
||||
/* if (gspca_dev->streaming)
|
||||
* ov51x_restart(sd); */
|
||||
}
|
||||
|
||||
|
@ -1974,12 +1919,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int val;
|
||||
/* int was_streaming; */
|
||||
|
||||
val = sd->contrast;
|
||||
PDEBUG(D_CONF, "contrast:%d", val);
|
||||
/* was_streaming = gspca_dev->streaming;
|
||||
if (was_streaming)
|
||||
/* if (gspca_dev->streaming)
|
||||
ov51x_stop(sd); */
|
||||
switch (sd->sensor) {
|
||||
case SEN_OV7610:
|
||||
|
@ -2016,7 +1959,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|||
i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
|
||||
break;
|
||||
}
|
||||
/* if (was_streaming)
|
||||
/* if (gspca_dev->streaming)
|
||||
ov51x_restart(sd); */
|
||||
}
|
||||
|
||||
|
@ -2024,12 +1967,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int val;
|
||||
/* int was_streaming; */
|
||||
|
||||
val = sd->colors;
|
||||
PDEBUG(D_CONF, "saturation:%d", val);
|
||||
/* was_streaming = gspca_dev->streaming;
|
||||
if (was_streaming)
|
||||
/* if (gspca_dev->streaming)
|
||||
ov51x_stop(sd); */
|
||||
switch (sd->sensor) {
|
||||
case SEN_OV8610:
|
||||
|
@ -2055,7 +1996,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|||
/* set REG_COM13 values for UV sat auto mode */
|
||||
break;
|
||||
}
|
||||
/* if (was_streaming)
|
||||
/* if (gspca_dev->streaming)
|
||||
ov51x_restart(sd); */
|
||||
}
|
||||
|
||||
|
@ -2110,6 +2051,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->hflip = val;
|
||||
sethvflip(sd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->hflip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->vflip = val;
|
||||
sethvflip(sd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->vflip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sub-driver description */
|
||||
static const struct sd_desc sd_desc = {
|
||||
.name = MODULE_NAME,
|
||||
|
@ -2178,4 +2153,3 @@ module_exit(sd_mod_exit);
|
|||
|
||||
module_param(frame_rate, int, 0644);
|
||||
MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ MODULE_LICENSE("GPL");
|
|||
struct sd {
|
||||
struct gspca_dev gspca_dev; /* !! must be the first item */
|
||||
|
||||
int avg_lum;
|
||||
int lum_sum;
|
||||
atomic_t avg_lum;
|
||||
atomic_t do_gain;
|
||||
|
||||
unsigned char brightness;
|
||||
unsigned char contrast;
|
||||
|
@ -271,6 +273,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
sd->contrast = CONTRAST_DEF;
|
||||
sd->colors = COLOR_DEF;
|
||||
sd->autogain = AUTOGAIN_DEF;
|
||||
sd->ag_cnt = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -311,6 +314,18 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|||
PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (sd->autogain) {
|
||||
sd->lum_sum = 0;
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
} else {
|
||||
sd->ag_cnt = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* this function is called at open time */
|
||||
static int sd_open(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
|
@ -320,8 +335,6 @@ static int sd_open(struct gspca_dev *gspca_dev)
|
|||
|
||||
static void sd_start(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
reg_w(gspca_dev, 0xff, 0x01);
|
||||
reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
|
||||
reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
|
||||
|
@ -394,6 +407,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
setcontrast(gspca_dev);
|
||||
setbrightness(gspca_dev);
|
||||
setcolors(gspca_dev);
|
||||
setautogain(gspca_dev);
|
||||
|
||||
/* set correct resolution */
|
||||
switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
|
||||
|
@ -431,13 +445,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
reg_w(gspca_dev, 0xff, 0x01);
|
||||
reg_w(gspca_dev, 0x78, 0x04);
|
||||
reg_w(gspca_dev, 0x78, 0x05);
|
||||
|
||||
if (sd->autogain) {
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
sd->avg_lum = 0;
|
||||
} else {
|
||||
sd->ag_cnt = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sd_stopN(struct gspca_dev *gspca_dev)
|
||||
|
@ -473,13 +480,20 @@ static void sd_close(struct gspca_dev *gspca_dev)
|
|||
reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev, int luma)
|
||||
static void do_autogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int luma;
|
||||
int luma_mean = 128;
|
||||
int luma_delta = 20;
|
||||
__u8 spring = 5;
|
||||
int Gbright;
|
||||
|
||||
if (!atomic_read(&sd->do_gain))
|
||||
return;
|
||||
atomic_set(&sd->do_gain, 0);
|
||||
|
||||
luma = atomic_read(&sd->avg_lum);
|
||||
Gbright = reg_r(gspca_dev, 0x02);
|
||||
PDEBUG(D_FRAM, "luma mean %d", luma);
|
||||
if (luma < luma_mean - luma_delta ||
|
||||
|
@ -523,12 +537,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
|
||||
/* start of frame */
|
||||
if (sd->ag_cnt >= 0 && p > 28) {
|
||||
sd->avg_lum += data[p - 23];
|
||||
sd->lum_sum += data[p - 23];
|
||||
if (--sd->ag_cnt < 0) {
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
setautogain(gspca_dev,
|
||||
sd->avg_lum / AG_CNT_START);
|
||||
sd->avg_lum = 0;
|
||||
atomic_set(&sd->avg_lum,
|
||||
sd->lum_sum / AG_CNT_START);
|
||||
sd->lum_sum = 0;
|
||||
atomic_set(&sd->do_gain, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,12 +692,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
|||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->autogain = val;
|
||||
if (val) {
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
sd->avg_lum = 0;
|
||||
} else {
|
||||
sd->ag_cnt = -1;
|
||||
}
|
||||
if (gspca_dev->streaming)
|
||||
setautogain(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -706,6 +717,7 @@ static struct sd_desc sd_desc = {
|
|||
.stop0 = sd_stop0,
|
||||
.close = sd_close,
|
||||
.pkt_scan = sd_pkt_scan,
|
||||
.dq_callback = do_autogain,
|
||||
};
|
||||
|
||||
/* -- module initialisation -- */
|
||||
|
|
|
@ -408,7 +408,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
|||
const __u8 *buffer,
|
||||
int len)
|
||||
{
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (len > sizeof gspca_dev->usb_buf) {
|
||||
PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
|
||||
return;
|
||||
|
|
|
@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
|
|||
struct sd {
|
||||
struct gspca_dev gspca_dev; /* !! must be the first item */
|
||||
|
||||
int avg_lum;
|
||||
atomic_t avg_lum;
|
||||
unsigned int exposure;
|
||||
|
||||
unsigned short brightness;
|
||||
|
@ -148,55 +148,58 @@ static struct v4l2_pix_format vga_mode[] = {
|
|||
|
||||
/*Data from sn9c102p+hv71331r */
|
||||
static const __u8 sn_hv7131[] = {
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
|
||||
0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11,
|
||||
/* rega regb regc regd rege regf reg10 reg11 */
|
||||
0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */
|
||||
/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
|
||||
0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00,
|
||||
/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
||||
0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
||||
/* reg8 reg9 rega regb regc regd rege regf */
|
||||
0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
|
||||
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
||||
0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
|
||||
/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
||||
0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const __u8 sn_mi0360[] = {
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
|
||||
0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d,
|
||||
/* rega regb regc regd rege regf reg10 reg11 */
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00,
|
||||
/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
|
||||
0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00,
|
||||
/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
||||
0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
||||
/* reg8 reg9 rega regb regc regd rege regf */
|
||||
0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
||||
0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
|
||||
/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const __u8 sn_mo4000[] = {
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
|
||||
0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81,
|
||||
/* reg9 rega regb regc regd rege regf reg10 reg11*/
|
||||
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
|
||||
0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00,
|
||||
/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b,
|
||||
0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7,
|
||||
0xd3, 0xdf, 0xea, 0xf5
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
||||
0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
|
||||
/* reg8 reg9 rega regb regc regd rege regf */
|
||||
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
||||
0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
|
||||
/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const __u8 sn_ov7648[] = {
|
||||
0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65,
|
||||
0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82,
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
||||
0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
||||
/* reg8 reg9 rega regb regc regd rege regf */
|
||||
0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
|
||||
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
||||
0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
|
||||
/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const __u8 sn_ov7660[] = {
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
|
||||
0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81,
|
||||
/* reg9 rega regb regc regd rege regf reg10 reg11*/
|
||||
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
|
||||
/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
|
||||
0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00,
|
||||
/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
||||
0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
||||
/* reg8 reg9 rega regb regc regd rege regf */
|
||||
0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
||||
0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
|
||||
/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
/* sequence specific to the sensors - !! index = SENSOR_xxx */
|
||||
|
@ -212,10 +215,6 @@ static const __u8 regsn20[] = {
|
|||
0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
|
||||
0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
|
||||
};
|
||||
static const __u8 regsn20_sn9c120[] = {
|
||||
0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90,
|
||||
0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff
|
||||
};
|
||||
static const __u8 regsn20_sn9c325[] = {
|
||||
0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
|
||||
0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
|
||||
|
@ -227,21 +226,6 @@ static const __u8 reg84[] = {
|
|||
/* 0x00, 0x00, 0x00, 0x00, 0x00 */
|
||||
0xf7, 0x0f, 0x0a, 0x00, 0x00
|
||||
};
|
||||
static const __u8 reg84_sn9c120_1[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x00, 0x00
|
||||
};
|
||||
static const __u8 reg84_sn9c120_2[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x02, 0x3b
|
||||
};
|
||||
static const __u8 reg84_sn9c120_3[] = {
|
||||
0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f,
|
||||
0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f,
|
||||
0xf5, 0x0f, 0x0c, 0x02, 0x3b
|
||||
};
|
||||
static const __u8 reg84_sn9c325[] = {
|
||||
0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
|
||||
0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
|
||||
|
@ -360,17 +344,15 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|||
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
|
||||
/* (delay 20ms) */
|
||||
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
|
||||
/* Outformat ?? rawRGB */
|
||||
/* Outformat = rawRGB */
|
||||
{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
|
||||
{0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
|
||||
/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */
|
||||
{0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
|
||||
/* GAIN BLUE RED VREF */
|
||||
{0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
|
||||
/* COM 1 BAVE GEAVE AECHH */
|
||||
{0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
|
||||
{0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
|
||||
{0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10},
|
||||
/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */
|
||||
{0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
|
||||
/* AECH CLKRC COM7 COM8 */
|
||||
{0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
|
||||
{0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
|
||||
|
@ -379,8 +361,8 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|||
{0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
|
||||
{0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
|
||||
/* BOS GBOS GROS ROS (BGGR offset) */
|
||||
{0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10},
|
||||
/* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */
|
||||
/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
|
||||
{0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
|
||||
/* AEW AEB VPT BBIAS */
|
||||
{0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
|
||||
/* GbBIAS RSVD EXHCH EXHCL */
|
||||
|
@ -407,9 +389,9 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|||
{0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
|
||||
/* LCC1 LCC2 LCC3 LCC4 */
|
||||
{0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
|
||||
{0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10},
|
||||
{0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
|
||||
{0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
|
||||
/* band gap reference [0..3] DBLV */
|
||||
/* band gap reference [0:3] DBLV */
|
||||
{0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
|
||||
{0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
|
||||
{0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
|
||||
|
@ -419,37 +401,35 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|||
{0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
|
||||
{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
|
||||
{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
|
||||
{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
|
||||
/****** (some exchanges in the win trace) ******/
|
||||
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
|
||||
/* bits[3..0]reserved */
|
||||
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
/* VREF vertical frame ctrl */
|
||||
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */
|
||||
{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
/* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */
|
||||
{0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
|
||||
{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
|
||||
{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
|
||||
{0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
|
||||
/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
|
||||
/****** (some exchanges in the win trace) ******/
|
||||
{0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
|
||||
{0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */
|
||||
{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
|
||||
{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
|
||||
{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
|
||||
/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
|
||||
/****** (some exchanges in the win trace) ******/
|
||||
/**********startsensor KO if changed !!****/
|
||||
/******!! startsensor KO if changed !!****/
|
||||
{0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
|
||||
{0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
|
||||
/* here may start the isoc exchanges */
|
||||
{}
|
||||
};
|
||||
/* reg0x04 reg0x07 reg 0x10 */
|
||||
/* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */
|
||||
/* reg 0x04 reg 0x07 reg 0x10 */
|
||||
/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
|
||||
|
||||
static const __u8 ov7648_sensor_init[][8] = {
|
||||
{0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
|
||||
|
@ -680,13 +660,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
|
|||
const __u8 *reg9a;
|
||||
static const __u8 reg9a_def[] =
|
||||
{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
|
||||
static const __u8 reg9a_sn9c120[] = /* from win trace */
|
||||
{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
|
||||
static const __u8 reg9a_sn9c325[] =
|
||||
{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
|
||||
static const __u8 regd4[] = {0x60, 0x00, 0x00};
|
||||
|
||||
reg_w1(gspca_dev, 0xf1, 0x00);
|
||||
reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/
|
||||
reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/
|
||||
|
||||
/* configure gpio */
|
||||
reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
|
||||
|
@ -696,25 +675,17 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
|
|||
case BRIDGE_SN9C325:
|
||||
reg9a = reg9a_sn9c325;
|
||||
break;
|
||||
case BRIDGE_SN9C120:
|
||||
reg9a = reg9a_sn9c120;
|
||||
break;
|
||||
default:
|
||||
reg9a = reg9a_def;
|
||||
break;
|
||||
}
|
||||
reg_w(gspca_dev, 0x9a, reg9a, 6);
|
||||
|
||||
reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */
|
||||
reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
|
||||
|
||||
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
|
||||
|
||||
switch (sd->bridge) {
|
||||
case BRIDGE_SN9C120: /* from win trace */
|
||||
reg_w1(gspca_dev, 0x01, 0x61);
|
||||
reg_w1(gspca_dev, 0x17, 0x20);
|
||||
reg_w1(gspca_dev, 0x01, 0x60);
|
||||
break;
|
||||
case BRIDGE_SN9C325:
|
||||
reg_w1(gspca_dev, 0x01, 0x43);
|
||||
reg_w1(gspca_dev, 0x17, 0xae);
|
||||
|
@ -810,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
sd->contrast = CONTRAST_DEF;
|
||||
sd->colors = COLOR_DEF;
|
||||
sd->autogain = AUTOGAIN_DEF;
|
||||
sd->ag_cnt = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -823,10 +796,11 @@ static int sd_open(struct gspca_dev *gspca_dev)
|
|||
|
||||
/* setup a selector by bridge */
|
||||
reg_w1(gspca_dev, 0xf1, 0x01);
|
||||
reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
|
||||
reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
|
||||
reg_r(gspca_dev, 0x00, 1);
|
||||
reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
|
||||
reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
|
||||
regF1 = gspca_dev->usb_buf[0];
|
||||
PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
|
||||
switch (sd->bridge) {
|
||||
case BRIDGE_SN9C102P:
|
||||
if (regF1 != 0x11)
|
||||
|
@ -937,15 +911,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|||
sd->exposure = setexposure(gspca_dev, expo);
|
||||
break;
|
||||
case SENSOR_MI0360:
|
||||
expo = sd->brightness >> 4;
|
||||
sd->exposure = setexposure(gspca_dev, expo);
|
||||
break;
|
||||
case SENSOR_MO4000:
|
||||
expo = sd->brightness >> 4;
|
||||
sd->exposure = setexposure(gspca_dev, expo);
|
||||
break;
|
||||
case SENSOR_OV7660:
|
||||
return; /*jfm??*/
|
||||
}
|
||||
|
||||
k2 = sd->brightness >> 10;
|
||||
|
@ -958,8 +927,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|||
__u8 k2;
|
||||
__u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
|
||||
|
||||
if (sd->sensor == SENSOR_OV7660)
|
||||
return; /*jfm??*/
|
||||
k2 = sd->contrast;
|
||||
contrast[2] = k2;
|
||||
contrast[0] = (k2 + 1) >> 1;
|
||||
|
@ -981,20 +948,32 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|||
reg_w1(gspca_dev, 0x05, data);
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_HV7131R:
|
||||
case SENSOR_MO4000:
|
||||
case SENSOR_MI0360:
|
||||
if (sd->autogain)
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
else
|
||||
sd->ag_cnt = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -- start the camera -- */
|
||||
static void sd_start(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
__u8 data;
|
||||
__u8 reg1;
|
||||
__u8 reg17;
|
||||
__u8 reg1, reg17, reg18;
|
||||
const __u8 *sn9c1xx;
|
||||
int mode;
|
||||
static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
|
||||
static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
|
||||
static const __u8 CA_sn9c120[] =
|
||||
{ 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
|
||||
static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
|
||||
static const __u8 CE_sn9c325[] =
|
||||
{ 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */
|
||||
|
@ -1002,9 +981,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
sn9c1xx = sn_tb[(int) sd->sensor];
|
||||
configure_gpio(gspca_dev, sn9c1xx);
|
||||
|
||||
/*fixme:jfm this sequence should appear at end of sd_start */
|
||||
/* with
|
||||
reg_w1(gspca_dev, 0x01, 0x44); */
|
||||
/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
|
||||
reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
|
||||
reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
|
||||
reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
|
||||
|
@ -1016,20 +993,16 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
reg_w1(gspca_dev, 0xc7, 0x00);
|
||||
reg_w1(gspca_dev, 0xc8, 0x50);
|
||||
reg_w1(gspca_dev, 0xc9, 0x3c);
|
||||
/*fixme:jfm end of ending sequence */
|
||||
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
|
||||
switch (sd->bridge) {
|
||||
case BRIDGE_SN9C325:
|
||||
data = 0xae;
|
||||
break;
|
||||
case BRIDGE_SN9C120:
|
||||
data = 0xa0;
|
||||
reg17 = 0xae;
|
||||
break;
|
||||
default:
|
||||
data = 0x60;
|
||||
reg17 = 0x60;
|
||||
break;
|
||||
}
|
||||
reg_w1(gspca_dev, 0x17, data);
|
||||
reg_w1(gspca_dev, 0x17, reg17);
|
||||
reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
|
||||
reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
|
||||
reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
|
||||
|
@ -1044,20 +1017,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
reg_w1(gspca_dev, 0x9a, 0x0a);
|
||||
reg_w1(gspca_dev, 0x99, 0x60);
|
||||
break;
|
||||
case BRIDGE_SN9C120:
|
||||
reg_w(gspca_dev, 0x20, regsn20_sn9c120,
|
||||
sizeof regsn20_sn9c120);
|
||||
for (i = 0; i < 2; i++)
|
||||
reg_w(gspca_dev, 0x84, reg84_sn9c120_1,
|
||||
sizeof reg84_sn9c120_1);
|
||||
for (i = 0; i < 6; i++)
|
||||
reg_w(gspca_dev, 0x84, reg84_sn9c120_2,
|
||||
sizeof reg84_sn9c120_2);
|
||||
reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
|
||||
sizeof reg84_sn9c120_3);
|
||||
reg_w1(gspca_dev, 0x9a, 0x05);
|
||||
reg_w1(gspca_dev, 0x99, 0x5b);
|
||||
break;
|
||||
default:
|
||||
reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
|
||||
for (i = 0; i < 8; i++)
|
||||
|
@ -1107,22 +1066,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
/* reg1 = 0x44; */
|
||||
/* reg1 = 0x46; (done) */
|
||||
} else {
|
||||
reg17 = 0xa2; /* 640 */
|
||||
reg1 = 0x40;
|
||||
reg17 = 0x22; /* 640 MCKSIZE */
|
||||
reg1 = 0x06;
|
||||
}
|
||||
break;
|
||||
}
|
||||
reg_w(gspca_dev, 0xc0, C0, 6);
|
||||
reg_w(gspca_dev, 0xca, CA, 4);
|
||||
switch (sd->bridge) {
|
||||
case BRIDGE_SN9C120: /*jfm ?? */
|
||||
reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
|
||||
break;
|
||||
default:
|
||||
reg_w(gspca_dev, 0xca, CA, 4);
|
||||
break;
|
||||
}
|
||||
switch (sd->bridge) {
|
||||
case BRIDGE_SN9C120: /*jfm ?? */
|
||||
case BRIDGE_SN9C325:
|
||||
reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
|
||||
break;
|
||||
|
@ -1133,19 +1084,19 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
|
||||
/* here change size mode 0 -> VGA; 1 -> CIF */
|
||||
data = 0x40 | sn9c1xx[0x18] | (mode << 4);
|
||||
reg_w1(gspca_dev, 0x18, data);
|
||||
reg18 = sn9c1xx[0x18] | (mode << 4);
|
||||
reg_w1(gspca_dev, 0x18, reg18 | 0x40);
|
||||
|
||||
reg_w(gspca_dev, 0x100, qtable4, 0x40);
|
||||
reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
|
||||
|
||||
data = sn9c1xx[0x18] | (mode << 4);
|
||||
reg_w1(gspca_dev, 0x18, data);
|
||||
reg_w1(gspca_dev, 0x18, reg18);
|
||||
|
||||
reg_w1(gspca_dev, 0x17, reg17);
|
||||
reg_w1(gspca_dev, 0x01, reg1);
|
||||
setbrightness(gspca_dev);
|
||||
setcontrast(gspca_dev);
|
||||
setautogain(gspca_dev);
|
||||
}
|
||||
|
||||
static void sd_stopN(struct gspca_dev *gspca_dev)
|
||||
|
@ -1168,12 +1119,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
i2c_w8(gspca_dev, stopmi0360);
|
||||
data = 0x29;
|
||||
break;
|
||||
case SENSOR_MO4000:
|
||||
break;
|
||||
case SENSOR_OV7648:
|
||||
data = 0x29;
|
||||
break;
|
||||
default:
|
||||
/* case SENSOR_MO4000: */
|
||||
/* case SENSOR_OV7660: */
|
||||
break;
|
||||
}
|
||||
|
@ -1193,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev)
|
|||
{
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
static void do_autogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
/* Thanks S., without your advice, autobright should not work :) */
|
||||
int delta;
|
||||
int expotimes = 0;
|
||||
int expotimes;
|
||||
__u8 luma_mean = 130;
|
||||
__u8 luma_delta = 20;
|
||||
|
||||
delta = sd->avg_lum;
|
||||
/* Thanks S., without your advice, autobright should not work :) */
|
||||
if (sd->ag_cnt < 0)
|
||||
return;
|
||||
if (--sd->ag_cnt >= 0)
|
||||
return;
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
|
||||
delta = atomic_read(&sd->avg_lum);
|
||||
PDEBUG(D_FRAM, "mean lum %d", delta);
|
||||
if (delta < luma_mean - luma_delta ||
|
||||
delta > luma_mean + luma_delta) {
|
||||
switch (sd->sensor) {
|
||||
|
@ -1214,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
|||
sd->exposure = setexposure(gspca_dev,
|
||||
(unsigned int) (expotimes << 8));
|
||||
break;
|
||||
case SENSOR_MO4000:
|
||||
case SENSOR_MI0360:
|
||||
default:
|
||||
/* case SENSOR_MO4000: */
|
||||
/* case SENSOR_MI0360: */
|
||||
expotimes = sd->exposure;
|
||||
expotimes += (luma_mean - delta) >> 6;
|
||||
if (expotimes < 0)
|
||||
|
@ -1228,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
}
|
||||
|
||||
/* scan the URB packets */
|
||||
/* This function is run at interrupt level. */
|
||||
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
struct gspca_frame *frame, /* target */
|
||||
__u8 *data, /* isoc packet */
|
||||
|
@ -1244,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
frame, data, sof + 2);
|
||||
if (sd->ag_cnt < 0)
|
||||
return;
|
||||
if (--sd->ag_cnt >= 0)
|
||||
return;
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
/* w1 w2 w3 */
|
||||
/* w4 w5 w6 */
|
||||
/* w7 w8 */
|
||||
|
@ -1261,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
/* w5 */
|
||||
avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
|
||||
avg_lum >>= 4;
|
||||
sd->avg_lum = avg_lum;
|
||||
PDEBUG(D_PACK, "mean lum %d", avg_lum);
|
||||
setautogain(gspca_dev);
|
||||
atomic_set(&sd->avg_lum, avg_lum);
|
||||
return;
|
||||
}
|
||||
if (gspca_dev->last_packet_type == LAST_PACKET) {
|
||||
|
@ -1300,6 +1255,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev)
|
|||
(hexpo << 10) | (mexpo << 2) | lexpo);
|
||||
return (hexpo << 10) | (mexpo << 2) | lexpo;
|
||||
default:
|
||||
/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
|
||||
/* case SENSOR_OV7660: */
|
||||
/* read sensor exposure */
|
||||
i2c_r5(gspca_dev, 0x04);
|
||||
|
@ -1318,14 +1274,12 @@ static void getbrightness(struct gspca_dev *gspca_dev)
|
|||
/* hardcoded registers seem not readable */
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_HV7131R:
|
||||
/* sd->brightness = 0x7fff; */
|
||||
sd->brightness = getexposure(gspca_dev) >> 4;
|
||||
break;
|
||||
case SENSOR_MI0360:
|
||||
sd->brightness = getexposure(gspca_dev) << 4;
|
||||
break;
|
||||
case SENSOR_MO4000:
|
||||
/* sd->brightness = 0x1fff; */
|
||||
sd->brightness = getexposure(gspca_dev) << 4;
|
||||
break;
|
||||
}
|
||||
|
@ -1391,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
|||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->autogain = val;
|
||||
if (val)
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
else
|
||||
sd->ag_cnt = -1;
|
||||
if (gspca_dev->streaming)
|
||||
setautogain(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1418,6 +1370,7 @@ static const struct sd_desc sd_desc = {
|
|||
.stop0 = sd_stop0,
|
||||
.close = sd_close,
|
||||
.pkt_scan = sd_pkt_scan,
|
||||
.dq_callback = do_autogain,
|
||||
};
|
||||
|
||||
/* -- module initialisation -- */
|
||||
|
|
|
@ -61,27 +61,27 @@ static struct ctrl sd_ctrls[] = {
|
|||
|
||||
static struct v4l2_pix_format vga_mode[] = {
|
||||
{160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 160 * 3,
|
||||
.bytesperline = 160,
|
||||
.sizeimage = 160 * 120 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 5},
|
||||
{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 176 * 3,
|
||||
.bytesperline = 176,
|
||||
.sizeimage = 176 * 144 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 4},
|
||||
{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 320 * 3,
|
||||
.bytesperline = 320,
|
||||
.sizeimage = 320 * 240 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 2},
|
||||
{352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 352 * 3,
|
||||
.bytesperline = 352,
|
||||
.sizeimage = 352 * 288 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 1},
|
||||
{640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 640 * 3,
|
||||
.bytesperline = 640,
|
||||
.sizeimage = 640 * 480 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 0},
|
||||
|
@ -776,7 +776,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
default:
|
||||
data += 1;
|
||||
len -= 1;
|
||||
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
|
||||
gspca_frame_add(gspca_dev, INTER_PACKET, frame,
|
||||
data, len);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -112,27 +112,27 @@ static struct ctrl sd_ctrls[] = {
|
|||
|
||||
static struct v4l2_pix_format vga_mode[] = {
|
||||
{160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 160 * 3,
|
||||
.bytesperline = 160,
|
||||
.sizeimage = 160 * 120 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 5},
|
||||
{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 176 * 3,
|
||||
.bytesperline = 176,
|
||||
.sizeimage = 176 * 144 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 4},
|
||||
{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 320 * 3,
|
||||
.bytesperline = 320,
|
||||
.sizeimage = 320 * 240 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 2},
|
||||
{352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 352 * 3,
|
||||
.bytesperline = 352,
|
||||
.sizeimage = 352 * 288 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 1},
|
||||
{640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
|
||||
.bytesperline = 640 * 3,
|
||||
.bytesperline = 640,
|
||||
.sizeimage = 640 * 480 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 0},
|
||||
|
@ -588,7 +588,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
default:
|
||||
data += 1;
|
||||
len -= 1;
|
||||
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
|
||||
gspca_frame_add(gspca_dev, INTER_PACKET, frame,
|
||||
data, len);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -63,23 +63,23 @@ static struct ctrl sd_ctrls[] = {
|
|||
};
|
||||
|
||||
static struct v4l2_pix_format sif_mode[] = {
|
||||
{160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
|
||||
.bytesperline = 160 * 3,
|
||||
{160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
|
||||
.bytesperline = 160,
|
||||
.sizeimage = 160 * 120 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 3},
|
||||
{176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
|
||||
.bytesperline = 176 * 3,
|
||||
{176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
|
||||
.bytesperline = 176,
|
||||
.sizeimage = 176 * 144 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 2},
|
||||
{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
|
||||
.bytesperline = 320 * 3,
|
||||
{320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
|
||||
.bytesperline = 320,
|
||||
.sizeimage = 320 * 240 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 1},
|
||||
{352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
|
||||
.bytesperline = 352 * 3,
|
||||
{352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
|
||||
.bytesperline = 352,
|
||||
.sizeimage = 352 * 288 * 3 / 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 0},
|
||||
|
@ -1583,7 +1583,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
default:
|
||||
data += 1;
|
||||
len -= 1;
|
||||
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
|
||||
gspca_frame_add(gspca_dev, INTER_PACKET, frame,
|
||||
data, len);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (sd->chip_revision == Rev072A) {
|
||||
if (sd->autogain)
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
else
|
||||
sd->ag_cnt = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sd_start(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|||
reg_w_val(dev, 0x8500, mode); /* mode */
|
||||
reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
|
||||
reg_w_val(dev, 0x8112, 0x10 | 0x20);
|
||||
setautogain(gspca_dev);
|
||||
break;
|
||||
default:
|
||||
/* case Rev012A: */
|
||||
|
@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev)
|
|||
reg_w_val(gspca_dev->dev, 0x8114, 0);
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
static void do_autogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int expotimes = 0;
|
||||
int pixelclk = 0;
|
||||
int gainG = 0;
|
||||
int expotimes;
|
||||
int pixelclk;
|
||||
int gainG;
|
||||
__u8 R, Gr, Gb, B;
|
||||
int y;
|
||||
__u8 luma_mean = 110;
|
||||
__u8 luma_delta = 20;
|
||||
__u8 spring = 4;
|
||||
|
||||
if (sd->ag_cnt < 0)
|
||||
return;
|
||||
if (--sd->ag_cnt >= 0)
|
||||
return;
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
|
||||
switch (sd->chip_revision) {
|
||||
case Rev072A:
|
||||
reg_r(gspca_dev, 0x8621, 1);
|
||||
|
@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
__u8 *data, /* isoc packet */
|
||||
int len) /* iso packet length */
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
switch (data[0]) {
|
||||
case 0: /* start of frame */
|
||||
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
|
||||
data, 0);
|
||||
if (sd->ag_cnt >= 0) {
|
||||
if (--sd->ag_cnt < 0) {
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
setautogain(gspca_dev);
|
||||
}
|
||||
}
|
||||
data += SPCA561_OFFSET_DATA;
|
||||
len -= SPCA561_OFFSET_DATA;
|
||||
if (data[1] & 0x10) {
|
||||
|
@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
|||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->autogain = val;
|
||||
if (val)
|
||||
sd->ag_cnt = AG_CNT_START;
|
||||
else
|
||||
sd->ag_cnt = -1;
|
||||
if (gspca_dev->streaming)
|
||||
setautogain(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = {
|
|||
.stop0 = sd_stop0,
|
||||
.close = sd_close,
|
||||
.pkt_scan = sd_pkt_scan,
|
||||
.dq_callback = do_autogain,
|
||||
};
|
||||
|
||||
/* -- module initialisation -- */
|
||||
|
|
|
@ -88,12 +88,12 @@ static struct ctrl sd_ctrls[] = {
|
|||
|
||||
static struct v4l2_pix_format vc0321_mode[] = {
|
||||
{320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
|
||||
.bytesperline = 320 * 2,
|
||||
.bytesperline = 320,
|
||||
.sizeimage = 320 * 240 * 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 1},
|
||||
{640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
|
||||
.bytesperline = 640 * 2,
|
||||
.bytesperline = 640,
|
||||
.sizeimage = 640 * 480 * 2,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.priv = 0},
|
||||
|
|
|
@ -6469,7 +6469,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|||
NULL, Tgradient_1, Tgradient_2,
|
||||
Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
|
||||
};
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
__u8 v[16];
|
||||
#endif
|
||||
|
||||
|
@ -6487,7 +6487,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|||
else if (g <= 0)
|
||||
g = 1;
|
||||
reg_w(dev, g, 0x0120 + i); /* gamma */
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (gspca_debug & D_CONF)
|
||||
v[i] = g;
|
||||
#endif
|
||||
|
@ -6507,7 +6507,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|||
g = 1;
|
||||
}
|
||||
reg_w(dev, g, 0x0130 + i); /* gradient */
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
#ifdef GSPCA_DEBUG
|
||||
if (gspca_debug & D_CONF)
|
||||
v[i] = g;
|
||||
#endif
|
||||
|
|
|
@ -128,6 +128,8 @@ struct pxa_camera_dev {
|
|||
|
||||
struct pxa_buffer *active;
|
||||
struct pxa_dma_desc *sg_tail[3];
|
||||
|
||||
u32 save_cicr[5];
|
||||
};
|
||||
|
||||
static const char *pxa_cam_driver_description = "PXA_Camera";
|
||||
|
@ -997,10 +999,64 @@ static int pxa_camera_querycap(struct soc_camera_host *ici,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
|
||||
{
|
||||
struct soc_camera_host *ici =
|
||||
to_soc_camera_host(icd->dev.parent);
|
||||
struct pxa_camera_dev *pcdev = ici->priv;
|
||||
int i = 0, ret = 0;
|
||||
|
||||
pcdev->save_cicr[i++] = CICR0;
|
||||
pcdev->save_cicr[i++] = CICR1;
|
||||
pcdev->save_cicr[i++] = CICR2;
|
||||
pcdev->save_cicr[i++] = CICR3;
|
||||
pcdev->save_cicr[i++] = CICR4;
|
||||
|
||||
if ((pcdev->icd) && (pcdev->icd->ops->suspend))
|
||||
ret = pcdev->icd->ops->suspend(pcdev->icd, state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pxa_camera_resume(struct soc_camera_device *icd)
|
||||
{
|
||||
struct soc_camera_host *ici =
|
||||
to_soc_camera_host(icd->dev.parent);
|
||||
struct pxa_camera_dev *pcdev = ici->priv;
|
||||
int i = 0, ret = 0;
|
||||
|
||||
DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD;
|
||||
DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD;
|
||||
DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD;
|
||||
|
||||
CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB;
|
||||
CICR1 = pcdev->save_cicr[i++];
|
||||
CICR2 = pcdev->save_cicr[i++];
|
||||
CICR3 = pcdev->save_cicr[i++];
|
||||
CICR4 = pcdev->save_cicr[i++];
|
||||
|
||||
if ((pcdev->icd) && (pcdev->icd->ops->resume))
|
||||
ret = pcdev->icd->ops->resume(pcdev->icd);
|
||||
|
||||
/* Restart frame capture if active buffer exists */
|
||||
if (!ret && pcdev->active) {
|
||||
/* Reset the FIFOs */
|
||||
CIFR |= CIFR_RESET_F;
|
||||
/* Enable End-Of-Frame Interrupt */
|
||||
CICR0 &= ~CICR0_EOFM;
|
||||
/* Restart the Capture Interface */
|
||||
CICR0 |= CICR0_ENB;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.add = pxa_camera_add_device,
|
||||
.remove = pxa_camera_remove_device,
|
||||
.suspend = pxa_camera_suspend,
|
||||
.resume = pxa_camera_resume,
|
||||
.set_fmt_cap = pxa_camera_set_fmt_cap,
|
||||
.try_fmt_cap = pxa_camera_try_fmt_cap,
|
||||
.init_videobuf = pxa_camera_init_videobuf,
|
||||
|
@ -1198,7 +1254,7 @@ static int __devinit pxa_camera_init(void)
|
|||
|
||||
static void __exit pxa_camera_exit(void)
|
||||
{
|
||||
return platform_driver_unregister(&pxa_camera_driver);
|
||||
platform_driver_unregister(&pxa_camera_driver);
|
||||
}
|
||||
|
||||
module_init(pxa_camera_init);
|
||||
|
|
|
@ -647,7 +647,7 @@ static int __init sh_mobile_ceu_init(void)
|
|||
|
||||
static void __exit sh_mobile_ceu_exit(void)
|
||||
{
|
||||
return platform_driver_unregister(&sh_mobile_ceu_driver);
|
||||
platform_driver_unregister(&sh_mobile_ceu_driver);
|
||||
}
|
||||
|
||||
module_init(sh_mobile_ceu_init);
|
||||
|
|
|
@ -732,10 +732,36 @@ static int soc_camera_remove(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int soc_camera_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
struct soc_camera_device *icd = to_soc_camera_dev(dev);
|
||||
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
||||
int ret = 0;
|
||||
|
||||
if (ici->ops->suspend)
|
||||
ret = ici->ops->suspend(icd, state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int soc_camera_resume(struct device *dev)
|
||||
{
|
||||
struct soc_camera_device *icd = to_soc_camera_dev(dev);
|
||||
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
||||
int ret = 0;
|
||||
|
||||
if (ici->ops->resume)
|
||||
ret = ici->ops->resume(icd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct bus_type soc_camera_bus_type = {
|
||||
.name = "soc-camera",
|
||||
.probe = soc_camera_probe,
|
||||
.remove = soc_camera_remove,
|
||||
.suspend = soc_camera_suspend,
|
||||
.resume = soc_camera_resume,
|
||||
};
|
||||
|
||||
static struct device_driver ic_drv = {
|
||||
|
|
|
@ -187,7 +187,7 @@ static int __init soc_camera_platform_module_init(void)
|
|||
|
||||
static void __exit soc_camera_platform_module_exit(void)
|
||||
{
|
||||
return platform_driver_unregister(&soc_camera_platform_driver);
|
||||
platform_driver_unregister(&soc_camera_platform_driver);
|
||||
}
|
||||
|
||||
module_init(soc_camera_platform_module_init);
|
||||
|
|
|
@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
|
|||
struct uvc_control_mapping *mapping;
|
||||
struct uvc_menu_info *menu;
|
||||
unsigned int i;
|
||||
__u8 data[8];
|
||||
__u8 *data;
|
||||
int ret;
|
||||
|
||||
ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
|
||||
if (ctrl == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
data = kmalloc(8, GFP_KERNEL);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
|
||||
v4l2_ctrl->id = mapping->id;
|
||||
v4l2_ctrl->type = mapping->v4l2_type;
|
||||
|
@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
|
|||
if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
|
||||
if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id,
|
||||
video->dev->intfnum, ctrl->info->selector,
|
||||
&data, ctrl->info->size)) < 0)
|
||||
return ret;
|
||||
data, ctrl->info->size)) < 0)
|
||||
goto out;
|
||||
v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
|
||||
}
|
||||
|
||||
|
@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
||||
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||
v4l2_ctrl->minimum = 0;
|
||||
v4l2_ctrl->maximum = 1;
|
||||
v4l2_ctrl->step = 1;
|
||||
return 0;
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
|
|||
if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
|
||||
if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id,
|
||||
video->dev->intfnum, ctrl->info->selector,
|
||||
&data, ctrl->info->size)) < 0)
|
||||
return ret;
|
||||
data, ctrl->info->size)) < 0)
|
||||
goto out;
|
||||
v4l2_ctrl->minimum = uvc_get_le_value(data, mapping);
|
||||
}
|
||||
if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
|
||||
if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
|
||||
video->dev->intfnum, ctrl->info->selector,
|
||||
&data, ctrl->info->size)) < 0)
|
||||
return ret;
|
||||
data, ctrl->info->size)) < 0)
|
||||
goto out;
|
||||
v4l2_ctrl->maximum = uvc_get_le_value(data, mapping);
|
||||
}
|
||||
if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
|
||||
if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
|
||||
video->dev->intfnum, ctrl->info->selector,
|
||||
&data, ctrl->info->size)) < 0)
|
||||
return ret;
|
||||
data, ctrl->info->size)) < 0)
|
||||
goto out;
|
||||
v4l2_ctrl->step = uvc_get_le_value(data, mapping);
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
out:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1884,7 +1884,7 @@ static struct usb_device_id uvc_ids[] = {
|
|||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* Packard Bell OEM Webcam */
|
||||
/* Packard Bell OEM Webcam - Bison Electronics */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
| USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x5986,
|
||||
|
@ -1893,7 +1893,7 @@ static struct usb_device_id uvc_ids[] = {
|
|||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* Acer Crystal Eye webcam */
|
||||
/* Acer Crystal Eye webcam - Bison Electronics */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
| USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x5986,
|
||||
|
@ -1902,7 +1902,7 @@ static struct usb_device_id uvc_ids[] = {
|
|||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* Medion Akoya Mini E1210 */
|
||||
/* Medion Akoya Mini E1210 - Bison Electronics */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
| USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x5986,
|
||||
|
@ -1911,7 +1911,7 @@ static struct usb_device_id uvc_ids[] = {
|
|||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* Acer OrbiCam - Unknown vendor */
|
||||
/* Acer OrbiCam - Bison Electronics */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
| USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x5986,
|
||||
|
@ -1920,6 +1920,24 @@ static struct usb_device_id uvc_ids[] = {
|
|||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* Bison Electronics */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
| USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x5986,
|
||||
.idProduct = 0x0300,
|
||||
.bInterfaceClass = USB_CLASS_VIDEO,
|
||||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* Clevo M570TU - Bison Electronics */
|
||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
| USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x5986,
|
||||
.idProduct = 0x0303,
|
||||
.bInterfaceClass = USB_CLASS_VIDEO,
|
||||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_PROBE_MINMAX },
|
||||
/* Generic USB Video Class */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
|
||||
{}
|
||||
|
|
|
@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video,
|
|||
static int uvc_get_video_ctrl(struct uvc_video_device *video,
|
||||
struct uvc_streaming_control *ctrl, int probe, __u8 query)
|
||||
{
|
||||
__u8 data[34];
|
||||
__u8 size;
|
||||
__u8 *data;
|
||||
__u16 size;
|
||||
int ret;
|
||||
|
||||
size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
|
||||
ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
|
||||
probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size,
|
||||
UVC_CTRL_STREAMING_TIMEOUT);
|
||||
data = kmalloc(size, GFP_KERNEL);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
|
||||
probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
|
||||
UVC_CTRL_STREAMING_TIMEOUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
|
||||
ctrl->bFormatIndex = data[2];
|
||||
|
@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
|
|||
*/
|
||||
uvc_fixup_buffer_size(video, ctrl);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int uvc_set_video_ctrl(struct uvc_video_device *video,
|
||||
struct uvc_streaming_control *ctrl, int probe)
|
||||
{
|
||||
__u8 data[34];
|
||||
__u8 size;
|
||||
__u8 *data;
|
||||
__u16 size;
|
||||
int ret;
|
||||
|
||||
size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
|
||||
memset(data, 0, sizeof data);
|
||||
data = kzalloc(size, GFP_KERNEL);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
*(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint);
|
||||
data[2] = ctrl->bFormatIndex;
|
||||
|
@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
|
|||
data[33] = ctrl->bMaxVersion;
|
||||
}
|
||||
|
||||
return __uvc_query_ctrl(video->dev, SET_CUR, 0,
|
||||
ret = __uvc_query_ctrl(video->dev, SET_CUR, 0,
|
||||
video->streaming->intfnum,
|
||||
probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size,
|
||||
probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
|
||||
UVC_CTRL_STREAMING_TIMEOUT);
|
||||
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int uvc_probe_video(struct uvc_video_device *video,
|
||||
|
|
|
@ -222,11 +222,13 @@ int video_register_device(struct video_device *vfd, int type, int nr)
|
|||
EXPORT_SYMBOL(video_register_device);
|
||||
|
||||
/**
|
||||
* video_register_device - register video4linux devices
|
||||
* video_register_device_index - register video4linux devices
|
||||
* @vfd: video device structure we want to register
|
||||
* @type: type of device to register
|
||||
* @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
|
||||
* -1 == first free)
|
||||
* @index: stream number based on parent device;
|
||||
* -1 if auto assign, requested number otherwise
|
||||
*
|
||||
* The registration code assigns minor numbers based on the type
|
||||
* requested. -ENFILE is returned in all the device slots for this
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <linux/video_decoder.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/videobuf-core.h>
|
||||
#include <linux/pm.h>
|
||||
|
||||
struct soc_camera_device {
|
||||
struct list_head list;
|
||||
|
@ -63,6 +64,8 @@ struct soc_camera_host_ops {
|
|||
struct module *owner;
|
||||
int (*add)(struct soc_camera_device *);
|
||||
void (*remove)(struct soc_camera_device *);
|
||||
int (*suspend)(struct soc_camera_device *, pm_message_t state);
|
||||
int (*resume)(struct soc_camera_device *);
|
||||
int (*set_fmt_cap)(struct soc_camera_device *, __u32,
|
||||
struct v4l2_rect *);
|
||||
int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *);
|
||||
|
@ -111,6 +114,8 @@ struct soc_camera_ops {
|
|||
struct module *owner;
|
||||
int (*probe)(struct soc_camera_device *);
|
||||
void (*remove)(struct soc_camera_device *);
|
||||
int (*suspend)(struct soc_camera_device *, pm_message_t state);
|
||||
int (*resume)(struct soc_camera_device *);
|
||||
int (*init)(struct soc_camera_device *);
|
||||
int (*release)(struct soc_camera_device *);
|
||||
int (*start_capture)(struct soc_camera_device *);
|
||||
|
|
Loading…
Reference in New Issue
Block a user