aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-09-10 05:32:52 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-10 05:32:52 -0400
commite92b4fdacc6a7d8cc7895b81347671d5fcd6c5e1 (patch)
tree4f84567261682d8ec2ad4102bce1ff970a6eed1a /drivers/media
parent9fcaff0e660d886e9a766460adbe558dd25de31b (diff)
parentadee14b2e1557d0a8559f29681732d05a89dfc35 (diff)
Merge commit 'v2.6.27-rc6' into x86/iommu
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/common/saa7146_video.c4
-rw-r--r--drivers/media/common/tuners/mt2131.c2
-rw-r--r--drivers/media/common/tuners/mt2131.h2
-rw-r--r--drivers/media/common/tuners/mt2131_priv.h2
-rw-r--r--drivers/media/common/tuners/mxl5005s.c4
-rw-r--r--drivers/media/common/tuners/mxl5005s.h2
-rw-r--r--drivers/media/common/tuners/tuner-simple.c33
-rw-r--r--drivers/media/common/tuners/xc5000.c2
-rw-r--r--drivers/media/common/tuners/xc5000.h2
-rw-r--r--drivers/media/common/tuners/xc5000_priv.h2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c3
-rw-r--r--drivers/media/dvb/b2c2/flexcop-i2c.c12
-rw-r--r--drivers/media/dvb/bt8xx/dst.c4
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c8
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c9
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h1
-rw-r--r--drivers/media/dvb/frontends/au8522.c47
-rw-r--r--drivers/media/dvb/frontends/au8522.h11
-rw-r--r--drivers/media/dvb/frontends/cx22702.c2
-rw-r--r--drivers/media/dvb/frontends/cx22702.h2
-rw-r--r--drivers/media/dvb/frontends/cx24123.c6
-rw-r--r--drivers/media/dvb/frontends/cx24123.h2
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c3
-rw-r--r--drivers/media/dvb/frontends/s5h1409.h2
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c3
-rw-r--r--drivers/media/dvb/frontends/s5h1411.h2
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c3
-rw-r--r--drivers/media/dvb/frontends/tda10048.c4
-rw-r--r--drivers/media/dvb/frontends/tda10048.h2
-rw-r--r--drivers/media/dvb/siano/sms-cards.c2
-rw-r--r--drivers/media/dvb/siano/sms-cards.h2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h2
-rw-r--r--drivers/media/dvb/siano/smsdvb.c2
-rw-r--r--drivers/media/dvb/siano/smsusb.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c3
-rw-r--r--drivers/media/dvb/ttpci/budget.c3
-rw-r--r--drivers/media/radio/Makefile4
-rw-r--r--drivers/media/radio/dsbr100.c2
-rw-r--r--drivers/media/radio/miropcm20-radio.c266
-rw-r--r--drivers/media/radio/miropcm20-rds-core.c211
-rw-r--r--drivers/media/radio/miropcm20-rds-core.h19
-rw-r--r--drivers/media/radio/miropcm20-rds.c136
-rw-r--r--drivers/media/radio/radio-aimslab.c3
-rw-r--r--drivers/media/radio/radio-aztech.c3
-rw-r--r--drivers/media/radio/radio-cadet.c2
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c2
-rw-r--r--drivers/media/radio/radio-gemtek.c3
-rw-r--r--drivers/media/radio/radio-maestro.c3
-rw-r--r--drivers/media/radio/radio-maxiradio.c28
-rw-r--r--drivers/media/radio/radio-rtrack2.c3
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/radio/radio-si470x.c4
-rw-r--r--drivers/media/radio/radio-terratec.c3
-rw-r--r--drivers/media/radio/radio-trust.c3
-rw-r--r--drivers/media/radio/radio-zoltrix.c3
-rw-r--r--drivers/media/video/Makefile4
-rw-r--r--drivers/media/video/au0828/Kconfig1
-rw-r--r--drivers/media/video/au0828/au0828-cards.c9
-rw-r--r--drivers/media/video/au0828/au0828-cards.h3
-rw-r--r--drivers/media/video/au0828/au0828-core.c4
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c25
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c2
-rw-r--r--drivers/media/video/au0828/au0828-reg.h2
-rw-r--r--drivers/media/video/au0828/au0828.h2
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c73
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c3
-rw-r--r--drivers/media/video/bt8xx/bttvp.h5
-rw-r--r--drivers/media/video/btcx-risc.c4
-rw-r--r--drivers/media/video/btcx-risc.h2
-rw-r--r--drivers/media/video/bw-qcam.c3
-rw-r--r--drivers/media/video/c-qcam.c3
-rw-r--r--drivers/media/video/cpia.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c4
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c16
-rw-r--r--drivers/media/video/cx18/cx18-driver.c6
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c2
-rw-r--r--drivers/media/video/cx18/cx18-dvb.h2
-rw-r--r--drivers/media/video/cx18/cx18-irq.c2
-rw-r--r--drivers/media/video/cx18/cx18-queue.c129
-rw-r--r--drivers/media/video/cx18/cx18-queue.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c4
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-vbi.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c4
-rw-r--r--drivers/media/video/cx23885/cx23885.h2
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c2
-rw-r--r--drivers/media/video/dabusb.c1
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c1
-rw-r--r--drivers/media/video/gspca/conex.c28
-rw-r--r--drivers/media/video/gspca/etoms.c30
-rw-r--r--drivers/media/video/gspca/gspca.c119
-rw-r--r--drivers/media/video/gspca/gspca.h21
-rw-r--r--drivers/media/video/gspca/mars.c41
-rw-r--r--drivers/media/video/gspca/ov519.c1167
-rw-r--r--drivers/media/video/gspca/pac207.c87
-rw-r--r--drivers/media/video/gspca/pac7311.c1110
-rw-r--r--drivers/media/video/gspca/pac_common.h60
-rw-r--r--drivers/media/video/gspca/sonixb.c594
-rw-r--r--drivers/media/video/gspca/sonixj.c539
-rw-r--r--drivers/media/video/gspca/spca500.c20
-rw-r--r--drivers/media/video/gspca/spca501.c16
-rw-r--r--drivers/media/video/gspca/spca505.c16
-rw-r--r--drivers/media/video/gspca/spca506.c20
-rw-r--r--drivers/media/video/gspca/spca508.c21
-rw-r--r--drivers/media/video/gspca/spca561.c727
-rw-r--r--drivers/media/video/gspca/stk014.c20
-rw-r--r--drivers/media/video/gspca/sunplus.c167
-rw-r--r--drivers/media/video/gspca/t613.c41
-rw-r--r--drivers/media/video/gspca/tv8532.c20
-rw-r--r--drivers/media/video/gspca/vc032x.c31
-rw-r--r--drivers/media/video/gspca/zc3xx.c85
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c29
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h2
-rw-r--r--drivers/media/video/ks0127.c31
-rw-r--r--drivers/media/video/meye.c2
-rw-r--r--drivers/media/video/mxb.c12
-rw-r--r--drivers/media/video/ov511.c14
-rw-r--r--drivers/media/video/pms.c13
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c18
-rw-r--r--drivers/media/video/saa7115.c5
-rw-r--r--drivers/media/video/se401.c2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c1
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h21
-rw-r--r--drivers/media/video/stv680.c2
-rw-r--r--drivers/media/video/usbvideo/ibmcam.c6
-rw-r--r--drivers/media/video/usbvideo/vicam.c2
-rw-r--r--drivers/media/video/v4l2-dev.c5
-rw-r--r--drivers/media/video/v4l2-ioctl.c4
-rw-r--r--drivers/media/video/vivi.c52
-rw-r--r--drivers/media/video/w9966.c2
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c1
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h19
146 files changed, 3342 insertions, 3135 deletions
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index e8bc7abf2409..99be9e5c85f7 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1068,7 +1068,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
1068 { 1068 {
1069 v4l2_std_id *id = arg; 1069 v4l2_std_id *id = arg;
1070 int found = 0; 1070 int found = 0;
1071 int i, err; 1071 int i;
1072 1072
1073 DEB_EE(("VIDIOC_S_STD\n")); 1073 DEB_EE(("VIDIOC_S_STD\n"));
1074 1074
@@ -1116,7 +1116,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
1116 case VIDIOC_OVERLAY: 1116 case VIDIOC_OVERLAY:
1117 { 1117 {
1118 int on = *(int *)arg; 1118 int on = *(int *)arg;
1119 int err = 0;
1120 1119
1121 DEB_D(("VIDIOC_OVERLAY on:%d\n",on)); 1120 DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
1122 if (on != 0) { 1121 if (on != 0) {
@@ -1192,7 +1191,6 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
1192 case VIDIOCGMBUF: 1191 case VIDIOCGMBUF:
1193 { 1192 {
1194 struct video_mbuf *mbuf = arg; 1193 struct video_mbuf *mbuf = arg;
1195 struct videobuf_queue *q;
1196 int i; 1194 int i;
1197 1195
1198 /* fixme: number of capture buffers and sizes for v4l apps */ 1196 /* fixme: number of capture buffers and sizes for v4l apps */
diff --git a/drivers/media/common/tuners/mt2131.c b/drivers/media/common/tuners/mt2131.c
index e254bcfc2efb..e8d3c48f8605 100644
--- a/drivers/media/common/tuners/mt2131.c
+++ b/drivers/media/common/tuners/mt2131.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner" 2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/mt2131.h b/drivers/media/common/tuners/mt2131.h
index cd8376f6f7b4..6632de640df0 100644
--- a/drivers/media/common/tuners/mt2131.h
+++ b/drivers/media/common/tuners/mt2131.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner" 2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/mt2131_priv.h b/drivers/media/common/tuners/mt2131_priv.h
index e930759c2c00..4e05a67e88c1 100644
--- a/drivers/media/common/tuners/mt2131_priv.h
+++ b/drivers/media/common/tuners/mt2131_priv.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner" 2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 0dc2bef9f6a3..227642b044ae 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -2,7 +2,7 @@
2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver 2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
3 3
4 Copyright (C) 2008 MaxLinear 4 Copyright (C) 2008 MaxLinear
5 Copyright (C) 2006 Steven Toth <stoth@hauppauge.com> 5 Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
6 Functions: 6 Functions:
7 mxl5005s_reset() 7 mxl5005s_reset()
8 mxl5005s_writereg() 8 mxl5005s_writereg()
@@ -3837,7 +3837,7 @@ static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
3837/* ---------------------------------------------------------------- 3837/* ----------------------------------------------------------------
3838 * Begin: Everything after here is new code to adapt the 3838 * Begin: Everything after here is new code to adapt the
3839 * proprietary Realtek driver into a Linux API tuner. 3839 * proprietary Realtek driver into a Linux API tuner.
3840 * Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 3840 * Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
3841 */ 3841 */
3842static int mxl5005s_reset(struct dvb_frontend *fe) 3842static int mxl5005s_reset(struct dvb_frontend *fe)
3843{ 3843{
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 396db150bf0c..7ac6815b30aa 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -2,7 +2,7 @@
2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver 2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
3 3
4 Copyright (C) 2008 MaxLinear 4 Copyright (C) 2008 MaxLinear
5 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 5 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 597e47f5d69c..aa773a658a2a 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -253,7 +253,7 @@ static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe,
253 253
254static int simple_config_lookup(struct dvb_frontend *fe, 254static int simple_config_lookup(struct dvb_frontend *fe,
255 struct tuner_params *t_params, 255 struct tuner_params *t_params,
256 int *frequency, u8 *config, u8 *cb) 256 unsigned *frequency, u8 *config, u8 *cb)
257{ 257{
258 struct tuner_simple_priv *priv = fe->tuner_priv; 258 struct tuner_simple_priv *priv = fe->tuner_priv;
259 int i; 259 int i;
@@ -587,45 +587,45 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
587 priv->last_div = div; 587 priv->last_div = div;
588 if (t_params->has_tda9887) { 588 if (t_params->has_tda9887) {
589 struct v4l2_priv_tun_config tda9887_cfg; 589 struct v4l2_priv_tun_config tda9887_cfg;
590 int config = 0; 590 int tda_config = 0;
591 int is_secam_l = (params->std & (V4L2_STD_SECAM_L | 591 int is_secam_l = (params->std & (V4L2_STD_SECAM_L |
592 V4L2_STD_SECAM_LC)) && 592 V4L2_STD_SECAM_LC)) &&
593 !(params->std & ~(V4L2_STD_SECAM_L | 593 !(params->std & ~(V4L2_STD_SECAM_L |
594 V4L2_STD_SECAM_LC)); 594 V4L2_STD_SECAM_LC));
595 595
596 tda9887_cfg.tuner = TUNER_TDA9887; 596 tda9887_cfg.tuner = TUNER_TDA9887;
597 tda9887_cfg.priv = &config; 597 tda9887_cfg.priv = &tda_config;
598 598
599 if (params->std == V4L2_STD_SECAM_LC) { 599 if (params->std == V4L2_STD_SECAM_LC) {
600 if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc) 600 if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
601 config |= TDA9887_PORT1_ACTIVE; 601 tda_config |= TDA9887_PORT1_ACTIVE;
602 if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc) 602 if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
603 config |= TDA9887_PORT2_ACTIVE; 603 tda_config |= TDA9887_PORT2_ACTIVE;
604 } else { 604 } else {
605 if (t_params->port1_active) 605 if (t_params->port1_active)
606 config |= TDA9887_PORT1_ACTIVE; 606 tda_config |= TDA9887_PORT1_ACTIVE;
607 if (t_params->port2_active) 607 if (t_params->port2_active)
608 config |= TDA9887_PORT2_ACTIVE; 608 tda_config |= TDA9887_PORT2_ACTIVE;
609 } 609 }
610 if (t_params->intercarrier_mode) 610 if (t_params->intercarrier_mode)
611 config |= TDA9887_INTERCARRIER; 611 tda_config |= TDA9887_INTERCARRIER;
612 if (is_secam_l) { 612 if (is_secam_l) {
613 if (i == 0 && t_params->default_top_secam_low) 613 if (i == 0 && t_params->default_top_secam_low)
614 config |= TDA9887_TOP(t_params->default_top_secam_low); 614 tda_config |= TDA9887_TOP(t_params->default_top_secam_low);
615 else if (i == 1 && t_params->default_top_secam_mid) 615 else if (i == 1 && t_params->default_top_secam_mid)
616 config |= TDA9887_TOP(t_params->default_top_secam_mid); 616 tda_config |= TDA9887_TOP(t_params->default_top_secam_mid);
617 else if (t_params->default_top_secam_high) 617 else if (t_params->default_top_secam_high)
618 config |= TDA9887_TOP(t_params->default_top_secam_high); 618 tda_config |= TDA9887_TOP(t_params->default_top_secam_high);
619 } else { 619 } else {
620 if (i == 0 && t_params->default_top_low) 620 if (i == 0 && t_params->default_top_low)
621 config |= TDA9887_TOP(t_params->default_top_low); 621 tda_config |= TDA9887_TOP(t_params->default_top_low);
622 else if (i == 1 && t_params->default_top_mid) 622 else if (i == 1 && t_params->default_top_mid)
623 config |= TDA9887_TOP(t_params->default_top_mid); 623 tda_config |= TDA9887_TOP(t_params->default_top_mid);
624 else if (t_params->default_top_high) 624 else if (t_params->default_top_high)
625 config |= TDA9887_TOP(t_params->default_top_high); 625 tda_config |= TDA9887_TOP(t_params->default_top_high);
626 } 626 }
627 if (t_params->default_pll_gating_18) 627 if (t_params->default_pll_gating_18)
628 config |= TDA9887_GATING_18; 628 tda_config |= TDA9887_GATING_18;
629 i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG, 629 i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
630 &tda9887_cfg); 630 &tda9887_cfg);
631 } 631 }
@@ -813,7 +813,8 @@ static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf,
813 static struct tuner_params *t_params; 813 static struct tuner_params *t_params;
814 u8 config, cb; 814 u8 config, cb;
815 u32 div; 815 u32 div;
816 int ret, frequency = params->frequency / 62500; 816 int ret;
817 unsigned frequency = params->frequency / 62500;
817 818
818 t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL); 819 t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL);
819 ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb); 820 ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb);
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 5f99de0ad612..dcddfa803a75 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -2,7 +2,7 @@
2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner" 2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
3 * 3 *
4 * Copyright (c) 2007 Xceive Corporation 4 * Copyright (c) 2007 Xceive Corporation
5 * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> 5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index c910715addc9..5389f740945a 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner" 2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
3 * 3 *
4 * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
index a72a9887fe7f..b2a0074c99c9 100644
--- a/drivers/media/common/tuners/xc5000_priv.h
+++ b/drivers/media/common/tuners/xc5000_priv.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner" 2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
3 * 3 *
4 * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index f9d087669d5d..4eed783f4bce 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -137,7 +137,8 @@ static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, un
137 flexcop_diseqc_send_byte(fe, 0xff); 137 flexcop_diseqc_send_byte(fe, 0xff);
138 else { 138 else {
139 flexcop_set_tone(fe, SEC_TONE_ON); 139 flexcop_set_tone(fe, SEC_TONE_ON);
140 udelay(12500); 140 mdelay(12);
141 udelay(500);
141 flexcop_set_tone(fe, SEC_TONE_OFF); 142 flexcop_set_tone(fe, SEC_TONE_OFF);
142 } 143 }
143 msleep(20); 144 msleep(20);
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
index 55973eaf3711..43a112ec6d44 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -221,12 +221,12 @@ int flexcop_i2c_init(struct flexcop_device *fc)
221 fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM; 221 fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
222 fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER; 222 fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
223 223
224 strncpy(fc->fc_i2c_adap[0].i2c_adap.name, 224 strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
225 "B2C2 FlexCop I2C to demod", I2C_NAME_SIZE); 225 sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
226 strncpy(fc->fc_i2c_adap[1].i2c_adap.name, 226 strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
227 "B2C2 FlexCop I2C to eeprom", I2C_NAME_SIZE); 227 sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
228 strncpy(fc->fc_i2c_adap[2].i2c_adap.name, 228 strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
229 "B2C2 FlexCop I2C to tuner", I2C_NAME_SIZE); 229 sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
230 230
231 i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]); 231 i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
232 i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); 232 i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index a7637562e742..aa3db57d32d9 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1244,7 +1244,7 @@ static int dst_command(struct dst_state *state, u8 *data, u8 len)
1244 goto error; 1244 goto error;
1245 } 1245 }
1246 if (state->type_flags & DST_TYPE_HAS_FW_1) 1246 if (state->type_flags & DST_TYPE_HAS_FW_1)
1247 udelay(3000); 1247 mdelay(3);
1248 if (read_dst(state, &reply, GET_ACK)) { 1248 if (read_dst(state, &reply, GET_ACK)) {
1249 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 1249 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
1250 if ((dst_error_recovery(state)) < 0) { 1250 if ((dst_error_recovery(state)) < 0) {
@@ -1260,7 +1260,7 @@ static int dst_command(struct dst_state *state, u8 *data, u8 len)
1260 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 1260 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
1261 goto error; 1261 goto error;
1262 if (state->type_flags & DST_TYPE_HAS_FW_1) 1262 if (state->type_flags & DST_TYPE_HAS_FW_1)
1263 udelay(3000); 1263 mdelay(3);
1264 else 1264 else
1265 udelay(2000); 1265 udelay(2000);
1266 if (!dst_wait_dst_ready(state, NO_DELAY)) 1266 if (!dst_wait_dst_ready(state, NO_DELAY))
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 1cf9fcb6f514..069d847ba887 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -641,7 +641,6 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
641 struct timespec timeout = { 0 }; 641 struct timespec timeout = { 0 };
642 struct dmx_pes_filter_params *para = &filter->params.pes; 642 struct dmx_pes_filter_params *para = &filter->params.pes;
643 dmx_output_t otype; 643 dmx_output_t otype;
644 int ret;
645 int ts_type; 644 int ts_type;
646 enum dmx_ts_pes ts_pes; 645 enum dmx_ts_pes ts_pes;
647 struct dmx_ts_feed **tsfeed = &filter->feed.ts; 646 struct dmx_ts_feed **tsfeed = &filter->feed.ts;
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 8e5dd7b1f034..98ee16773ff2 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1032,7 +1032,7 @@ static int dvb_ca_en50221_thread(void *data)
1032 /* we need this extra check for annoying interfaces like the budget-av */ 1032 /* we need this extra check for annoying interfaces like the budget-av */
1033 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && 1033 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1034 (ca->pub->poll_slot_status)) { 1034 (ca->pub->poll_slot_status)) {
1035 int status = ca->pub->poll_slot_status(ca->pub, slot, 0); 1035 status = ca->pub->poll_slot_status(ca->pub, slot, 0);
1036 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { 1036 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1037 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; 1037 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1038 dvb_ca_en50221_thread_update_delay(ca); 1038 dvb_ca_en50221_thread_update_delay(ca);
@@ -1089,7 +1089,7 @@ static int dvb_ca_en50221_thread(void *data)
1089 /* we need this extra check for annoying interfaces like the budget-av */ 1089 /* we need this extra check for annoying interfaces like the budget-av */
1090 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && 1090 if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) &&
1091 (ca->pub->poll_slot_status)) { 1091 (ca->pub->poll_slot_status)) {
1092 int status = ca->pub->poll_slot_status(ca->pub, slot, 0); 1092 status = ca->pub->poll_slot_status(ca->pub, slot, 0);
1093 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { 1093 if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) {
1094 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; 1094 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
1095 dvb_ca_en50221_thread_update_delay(ca); 1095 dvb_ca_en50221_thread_update_delay(ca);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 8cbdb218952f..3526e3ee9487 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -889,13 +889,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
889 * initialization, so parg is 8 bits and does not 889 * initialization, so parg is 8 bits and does not
890 * include the initialization or start bit 890 * include the initialization or start bit
891 */ 891 */
892 unsigned long cmd = ((unsigned long) parg) << 1; 892 unsigned long swcmd = ((unsigned long) parg) << 1;
893 struct timeval nexttime; 893 struct timeval nexttime;
894 struct timeval tv[10]; 894 struct timeval tv[10];
895 int i; 895 int i;
896 u8 last = 1; 896 u8 last = 1;
897 if (dvb_frontend_debug) 897 if (dvb_frontend_debug)
898 printk("%s switch command: 0x%04lx\n", __func__, cmd); 898 printk("%s switch command: 0x%04lx\n", __func__, swcmd);
899 do_gettimeofday(&nexttime); 899 do_gettimeofday(&nexttime);
900 if (dvb_frontend_debug) 900 if (dvb_frontend_debug)
901 memcpy(&tv[0], &nexttime, sizeof(struct timeval)); 901 memcpy(&tv[0], &nexttime, sizeof(struct timeval));
@@ -908,12 +908,12 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
908 for (i = 0; i < 9; i++) { 908 for (i = 0; i < 9; i++) {
909 if (dvb_frontend_debug) 909 if (dvb_frontend_debug)
910 do_gettimeofday(&tv[i + 1]); 910 do_gettimeofday(&tv[i + 1]);
911 if ((cmd & 0x01) != last) { 911 if ((swcmd & 0x01) != last) {
912 /* set voltage to (last ? 13V : 18V) */ 912 /* set voltage to (last ? 13V : 18V) */
913 fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); 913 fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
914 last = (last) ? 0 : 1; 914 last = (last) ? 0 : 1;
915 } 915 }
916 cmd = cmd >> 1; 916 swcmd = swcmd >> 1;
917 if (i != 8) 917 if (i != 8)
918 dvb_frontend_sleep_until(&nexttime, 8000); 918 dvb_frontend_sleep_until(&nexttime, 8000);
919 } 919 }
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index aaa0b6f0b521..563400277a42 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -210,7 +210,7 @@ static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
210 if (d->state == DVB_USB_STATE_INIT && 210 if (d->state == DVB_USB_STATE_INIT &&
211 usb_set_interface(d->udev, 0, 0) < 0) 211 usb_set_interface(d->udev, 0, 0) < 0)
212 err("set interface failed"); 212 err("set interface failed");
213 do; while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) && 213 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
214 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) && 214 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
215 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0); 215 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
216 if (!ret) { 216 if (!ret) {
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 3dd20bfbed32..6c0e5c5f4362 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1117,7 +1117,8 @@ struct usb_device_id dib0700_usb_id_table[] = {
1117 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, 1117 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
1118 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, 1118 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
1119 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, 1119 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1120 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, 1120/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1121 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1121 { 0 } /* Terminating entry */ 1122 { 0 } /* Terminating entry */
1122}; 1123};
1123MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1124MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1373,7 +1374,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1373 } 1374 }
1374 }, 1375 },
1375 1376
1376 .num_device_descs = 3, 1377 .num_device_descs = 4,
1377 .devices = { 1378 .devices = {
1378 { "DiBcom STK7070PD reference design", 1379 { "DiBcom STK7070PD reference design",
1379 { &dib0700_usb_id_table[17], NULL }, 1380 { &dib0700_usb_id_table[17], NULL },
@@ -1386,6 +1387,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1386 { "Hauppauge Nova-TD Stick (52009)", 1387 { "Hauppauge Nova-TD Stick (52009)",
1387 { &dib0700_usb_id_table[35], NULL }, 1388 { &dib0700_usb_id_table[35], NULL },
1388 { NULL }, 1389 { NULL },
1390 },
1391 { "Hauppauge Nova-TD-500 (84xxx)",
1392 { &dib0700_usb_id_table[36], NULL },
1393 { NULL },
1389 } 1394 }
1390 } 1395 }
1391 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 1396 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 029b437caf9a..03dfb9f2fe30 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -129,6 +129,7 @@
129#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 129#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
130#define USB_PID_HAUPPAUGE_NOVA_T_500 0x9941 130#define USB_PID_HAUPPAUGE_NOVA_T_500 0x9941
131#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950 131#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950
132#define USB_PID_HAUPPAUGE_NOVA_T_500_3 0x8400
132#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050 133#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050
133#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060 134#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060
134#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 135#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index f7b71657f0f6..0b82cc2a1e16 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Auvitek AU8522 QAM/8VSB demodulator driver 2 Auvitek AU8522 QAM/8VSB demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -304,6 +304,43 @@ static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
304 return ret; 304 return ret;
305} 305}
306 306
307static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
308{
309 struct au8522_state *state = fe->demodulator_priv;
310 u8 r0b5, r0b6, r0b7;
311 char *ifmhz;
312
313 switch (if_freq) {
314 case AU8522_IF_3_25MHZ:
315 ifmhz = "3.25";
316 r0b5 = 0x00;
317 r0b6 = 0x3d;
318 r0b7 = 0xa0;
319 break;
320 case AU8522_IF_4MHZ:
321 ifmhz = "4.00";
322 r0b5 = 0x00;
323 r0b6 = 0x4b;
324 r0b7 = 0xd9;
325 break;
326 case AU8522_IF_6MHZ:
327 ifmhz = "6.00";
328 r0b5 = 0xfb;
329 r0b6 = 0x8e;
330 r0b7 = 0x39;
331 break;
332 default:
333 dprintk("%s() IF Frequency not supported\n", __func__);
334 return -EINVAL;
335 }
336 dprintk("%s() %s MHz\n", __func__, ifmhz);
337 au8522_writereg(state, 0x80b5, r0b5);
338 au8522_writereg(state, 0x80b6, r0b6);
339 au8522_writereg(state, 0x80b7, r0b7);
340
341 return 0;
342}
343
307/* VSB Modulation table */ 344/* VSB Modulation table */
308static struct { 345static struct {
309 u16 reg; 346 u16 reg;
@@ -334,9 +371,6 @@ static struct {
334 { 0x80af, 0x66 }, 371 { 0x80af, 0x66 },
335 { 0x821b, 0xcc }, 372 { 0x821b, 0xcc },
336 { 0x821d, 0x80 }, 373 { 0x821d, 0x80 },
337 { 0x80b5, 0xfb },
338 { 0x80b6, 0x8e },
339 { 0x80b7, 0x39 },
340 { 0x80a4, 0xe8 }, 374 { 0x80a4, 0xe8 },
341 { 0x8231, 0x13 }, 375 { 0x8231, 0x13 },
342}; 376};
@@ -350,9 +384,6 @@ static struct {
350 { 0x80a4, 0x00 }, 384 { 0x80a4, 0x00 },
351 { 0x8081, 0xc4 }, 385 { 0x8081, 0xc4 },
352 { 0x80a5, 0x40 }, 386 { 0x80a5, 0x40 },
353 { 0x80b5, 0xfb },
354 { 0x80b6, 0x8e },
355 { 0x80b7, 0x39 },
356 { 0x80aa, 0x77 }, 387 { 0x80aa, 0x77 },
357 { 0x80ad, 0x77 }, 388 { 0x80ad, 0x77 },
358 { 0x80a6, 0x67 }, 389 { 0x80a6, 0x67 },
@@ -438,6 +469,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
438 au8522_writereg(state, 469 au8522_writereg(state,
439 VSB_mod_tab[i].reg, 470 VSB_mod_tab[i].reg,
440 VSB_mod_tab[i].data); 471 VSB_mod_tab[i].data);
472 au8522_set_if(fe, state->config->vsb_if);
441 break; 473 break;
442 case QAM_64: 474 case QAM_64:
443 case QAM_256: 475 case QAM_256:
@@ -446,6 +478,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
446 au8522_writereg(state, 478 au8522_writereg(state,
447 QAM_mod_tab[i].reg, 479 QAM_mod_tab[i].reg,
448 QAM_mod_tab[i].data); 480 QAM_mod_tab[i].data);
481 au8522_set_if(fe, state->config->qam_if);
449 break; 482 break;
450 default: 483 default:
451 dprintk("%s() Invalid modulation\n", __func__); 484 dprintk("%s() Invalid modulation\n", __func__);
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index d7affa3cdb27..595915ade8c3 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -1,7 +1,7 @@
1/* 1/*
2 Auvitek AU8522 QAM/8VSB demodulator driver 2 Auvitek AU8522 QAM/8VSB demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -24,6 +24,12 @@
24 24
25#include <linux/dvb/frontend.h> 25#include <linux/dvb/frontend.h>
26 26
27enum au8522_if_freq {
28 AU8522_IF_6MHZ = 0,
29 AU8522_IF_4MHZ,
30 AU8522_IF_3_25MHZ,
31};
32
27struct au8522_config { 33struct au8522_config {
28 /* the demodulator's i2c address */ 34 /* the demodulator's i2c address */
29 u8 demod_address; 35 u8 demod_address;
@@ -32,6 +38,9 @@ struct au8522_config {
32#define AU8522_TUNERLOCKING 0 38#define AU8522_TUNERLOCKING 0
33#define AU8522_DEMODLOCKING 1 39#define AU8522_DEMODLOCKING 1
34 u8 status_mode; 40 u8 status_mode;
41
42 enum au8522_if_freq vsb_if;
43 enum au8522_if_freq qam_if;
35}; 44};
36 45
37#if defined(CONFIG_DVB_AU8522) || \ 46#if defined(CONFIG_DVB_AU8522) || \
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index cc1db4e371c3..9430e03dba6c 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -7,7 +7,7 @@
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH 7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de> 8 Holger Waechtler <holger@convergence.de>
9 9
10 Copyright (C) 2004 Steven Toth <stoth@hauppauge.com> 10 Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
11 11
12 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by 13 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 8af766a31552..b1e465c6c2ce 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -7,7 +7,7 @@
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH 7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de> 8 Holger Waechtler <holger@convergence.de>
9 9
10 Copyright (C) 2004 Steven Toth <stoth@hauppauge.com> 10 Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
11 11
12 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by 13 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 7f68d78c6558..7156157cb34b 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver 2 * Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
3 * 3 *
4 * Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> 4 * Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> 6 * Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
7 * 7 *
@@ -1072,8 +1072,8 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
1072 if (config->dont_use_pll) 1072 if (config->dont_use_pll)
1073 cx24123_repeater_mode(state, 1, 0); 1073 cx24123_repeater_mode(state, 1, 0);
1074 1074
1075 strncpy(state->tuner_i2c_adapter.name, 1075 strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
1076 "CX24123 tuner I2C bus", I2C_NAME_SIZE); 1076 sizeof(state->tuner_i2c_adapter.name));
1077 state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, 1077 state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL,
1078 state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; 1078 state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo;
1079 state->tuner_i2c_adapter.algo_data = NULL; 1079 state->tuner_i2c_adapter.algo_data = NULL;
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index 81ebc3d2f19f..cc6b411d6d20 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -1,7 +1,7 @@
1/* 1/*
2 Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver 2 Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
3 3
4 Copyright (C) 2005 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index 5ddb2dca305c..7500a1c53e68 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Samsung S5H1409 VSB/QAM demodulator driver 2 Samsung S5H1409 VSB/QAM demodulator driver
3 3
4 Copyright (C) 2006 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -404,6 +404,7 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
404 break; 404 break;
405 case QAM_64: 405 case QAM_64:
406 case QAM_256: 406 case QAM_256:
407 case QAM_AUTO:
407 dprintk("%s() QAM_AUTO (64/256)\n", __func__); 408 dprintk("%s() QAM_AUTO (64/256)\n", __func__);
408 if (state->if_freq != S5H1409_QAM_IF_FREQ) 409 if (state->if_freq != S5H1409_QAM_IF_FREQ)
409 s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ); 410 s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
index 59f4335964c6..d1a1d2eb8e11 100644
--- a/drivers/media/dvb/frontends/s5h1409.h
+++ b/drivers/media/dvb/frontends/s5h1409.h
@@ -1,7 +1,7 @@
1/* 1/*
2 Samsung S5H1409 VSB/QAM demodulator driver 2 Samsung S5H1409 VSB/QAM demodulator driver
3 3
4 Copyright (C) 2006 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index cff360ce1ba3..2da1a3763de9 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Samsung S5H1411 VSB/QAM demodulator driver 2 Samsung S5H1411 VSB/QAM demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -488,6 +488,7 @@ static int s5h1411_enable_modulation(struct dvb_frontend *fe,
488 break; 488 break;
489 case QAM_64: 489 case QAM_64:
490 case QAM_256: 490 case QAM_256:
491 case QAM_AUTO:
491 dprintk("%s() QAM_AUTO (64/256)\n", __func__); 492 dprintk("%s() QAM_AUTO (64/256)\n", __func__);
492 s5h1411_set_if_freq(fe, state->config->qam_if); 493 s5h1411_set_if_freq(fe, state->config->qam_if);
493 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171); 494 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h
index 1855f64ed4d8..7d542bc00c48 100644
--- a/drivers/media/dvb/frontends/s5h1411.h
+++ b/drivers/media/dvb/frontends/s5h1411.h
@@ -1,7 +1,7 @@
1/* 1/*
2 Samsung S5H1411 VSB/QAM demodulator driver 2 Samsung S5H1411 VSB/QAM demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 720ed9ff7c5f..747d3fa2e5e5 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -915,7 +915,8 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
915 state->frontend.demodulator_priv = state; 915 state->frontend.demodulator_priv = state;
916 916
917 /* create tuner i2c adapter */ 917 /* create tuner i2c adapter */
918 strncpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", I2C_NAME_SIZE); 918 strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
919 sizeof(state->tuner_i2c_adapter.name));
919 state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, 920 state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL,
920 state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; 921 state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo;
921 state->tuner_i2c_adapter.algo_data = NULL; 922 state->tuner_i2c_adapter.algo_data = NULL;
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
index 0ab8d86b3ae3..04e7f1cc1403 100644
--- a/drivers/media/dvb/frontends/tda10048.c
+++ b/drivers/media/dvb/frontends/tda10048.c
@@ -1,7 +1,7 @@
1/* 1/*
2 NXP TDA10048HN DVB OFDM demodulator driver 2 NXP TDA10048HN DVB OFDM demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
@@ -303,7 +303,7 @@ static int tda10048_firmware_upload(struct dvb_frontend *fe)
303 303
304 if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) { 304 if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) {
305 printk(KERN_ERR "%s: firmware incorrect size\n", __func__); 305 printk(KERN_ERR "%s: firmware incorrect size\n", __func__);
306 return -EIO; 306 ret = -EIO;
307 } else { 307 } else {
308 printk(KERN_INFO "%s: firmware uploading\n", __func__); 308 printk(KERN_INFO "%s: firmware uploading\n", __func__);
309 309
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h
index 2b5c78e62c86..0457b24601fa 100644
--- a/drivers/media/dvb/frontends/tda10048.h
+++ b/drivers/media/dvb/frontends/tda10048.h
@@ -1,7 +1,7 @@
1/* 1/*
2 NXP TDA10048HN DVB OFDM demodulator driver 2 NXP TDA10048HN DVB OFDM demodulator driver
3 3
4 Copyright (C) 2008 Steven Toth <stoth@hauppauge.com> 4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index e7a8ac0c4049..cc5efb643f33 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -4,7 +4,7 @@
4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> 4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 3 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation; 8 * published by the Free Software Foundation;
9 * 9 *
10 * Software distributed under the License is distributed on an "AS IS" 10 * Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 83b39bc203fe..c8f3da6f9bc1 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -4,7 +4,7 @@
4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> 4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 3 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation; 8 * published by the Free Software Foundation;
9 * 9 *
10 * Software distributed under the License is distributed on an "AS IS" 10 * Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index c5f45fed69dc..6576fbb40fc6 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -8,7 +8,7 @@
8 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 8 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 3 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation; 12 * published by the Free Software Foundation;
13 * 13 *
14 * Software distributed under the License is distributed on an "AS IS" 14 * Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index c1f8f1dccb11..8d973f726fb8 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -6,7 +6,7 @@
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 3 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation; 10 * published by the Free Software Foundation;
11 * 11 *
12 * Software distributed under the License is distributed on an "AS IS" 12 * Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 229274a14110..8d490e133f35 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -6,7 +6,7 @@
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 3 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation; 10 * published by the Free Software Foundation;
11 * 11 *
12 * Software distributed under the License is distributed on an "AS IS" 12 * Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index c10b1849c6a3..87a3c24454b9 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -6,7 +6,7 @@
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 3 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation; 10 * published by the Free Software Foundation;
11 * 11 *
12 * Software distributed under the License is distributed on an "AS IS" 12 * Software distributed under the License is distributed on an "AS IS"
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 39bd0a20f53a..aa5ed4ef19f2 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -116,7 +116,8 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long
116 DiseqcSendByte(budget, 0xff); 116 DiseqcSendByte(budget, 0xff);
117 else { 117 else {
118 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); 118 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
119 udelay(12500); 119 mdelay(12);
120 udelay(500);
120 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 121 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
121 } 122 }
122 msleep(20); 123 msleep(20);
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 2293d80c6e51..f0068996ac07 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -108,7 +108,8 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long
108 DiseqcSendByte(budget, 0xff); 108 DiseqcSendByte(budget, 0xff);
109 else { 109 else {
110 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); 110 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
111 udelay(12500); 111 mdelay(12);
112 udelay(500);
112 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 113 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
113 } 114 }
114 msleep(20); 115 msleep(20);
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index a30159f6fa42..7ca71ab96b43 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -2,8 +2,6 @@
2# Makefile for the kernel character device drivers. 2# Makefile for the kernel character device drivers.
3# 3#
4 4
5miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o
6
7obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o 5obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
8obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o 6obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
9obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o 7obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o
@@ -14,8 +12,6 @@ obj-$(CONFIG_RADIO_TERRATEC) += radio-terratec.o
14obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o 12obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o
15obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o 13obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o
16obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o 14obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
17obj-$(CONFIG_RADIO_MIROPCM20) += miropcm20.o
18obj-$(CONFIG_RADIO_MIROPCM20_RDS) += miropcm20-rds.o
19obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o 15obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
20obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o 16obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
21obj-$(CONFIG_RADIO_TRUST) += radio-trust.o 17obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 1ed88f3abe61..70c65a745923 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -493,7 +493,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
493 radio->usbdev = interface_to_usbdev(intf); 493 radio->usbdev = interface_to_usbdev(intf);
494 radio->curfreq = FREQ_MIN*FREQ_MUL; 494 radio->curfreq = FREQ_MIN*FREQ_MUL;
495 video_set_drvdata(radio->videodev, radio); 495 video_set_drvdata(radio->videodev, radio);
496 if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) { 496 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
497 warn("Could not register video device"); 497 warn("Could not register video device");
498 video_device_release(radio->videodev); 498 video_device_release(radio->videodev);
499 kfree(radio->transfer_buffer); 499 kfree(radio->transfer_buffer);
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
deleted file mode 100644
index 7fd7ee2d32c1..000000000000
--- a/drivers/media/radio/miropcm20-radio.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/* Miro PCM20 radio driver for Linux radio support
2 * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
3 * Thanks to Norberto Pellici for the ACI device interface specification
4 * The API part is based on the radiotrack driver by M. Kirkwood
5 * This driver relies on the aci mixer (drivers/sound/aci.c)
6 * Look there for further info...
7 */
8
9/* Revision history:
10 *
11 * 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
12 * 2000-09-05 Robert Siemer <Robert.Siemer@gmx.de>
13 * removed unfinished volume control (maybe adding it later again)
14 * use OSS-mixer; added stereo control
15 */
16
17/* What ever you think about the ACI, version 0x07 is not very well!
18 * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
19 * conditions... Robert
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/videodev.h>
25#include <media/v4l2-common.h>
26#include <media/v4l2-ioctl.h>
27#include "oss/aci.h"
28#include "miropcm20-rds-core.h"
29
30static int radio_nr = -1;
31module_param(radio_nr, int, 0);
32
33struct pcm20_device {
34 unsigned long freq;
35 int muted;
36 int stereo;
37};
38
39
40static int pcm20_mute(struct pcm20_device *dev, unsigned char mute)
41{
42 dev->muted = mute;
43 return aci_write_cmd(ACI_SET_TUNERMUTE, mute);
44}
45
46static int pcm20_stereo(struct pcm20_device *dev, unsigned char stereo)
47{
48 dev->stereo = stereo;
49 return aci_write_cmd(ACI_SET_TUNERMONO, !stereo);
50}
51
52static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
53{
54 unsigned char freql;
55 unsigned char freqh;
56
57 dev->freq=freq;
58
59 freq /= 160;
60 if (!(aci_version==0x07 || aci_version>=0xb0))
61 freq /= 10; /* I don't know exactly which version
62 * needs this hack */
63 freql = freq & 0xff;
64 freqh = freq >> 8;
65
66 aci_rds_cmd(RDS_RESET, NULL, 0);
67 pcm20_stereo(dev, 1);
68
69 return aci_rw_cmd(ACI_WRITE_TUNE, freql, freqh);
70}
71
72static int pcm20_getflags(struct pcm20_device *dev, __u32 *flags, __u16 *signal)
73{
74 /* okay, check for signal, stereo and rds here... */
75 int i;
76 unsigned char buf;
77
78 if ((i=aci_rw_cmd(ACI_READ_TUNERSTATION, -1, -1))<0)
79 return i;
80 pr_debug("check_sig: 0x%x\n", i);
81 if (i & 0x80) {
82 /* no signal from tuner */
83 *flags=0;
84 *signal=0;
85 return 0;
86 } else
87 *signal=0xffff;
88
89 if ((i=aci_rw_cmd(ACI_READ_TUNERSTEREO, -1, -1))<0)
90 return i;
91 if (i & 0x40) {
92 *flags=0;
93 } else {
94 /* stereo */
95 *flags=VIDEO_TUNER_STEREO_ON;
96 /* I can't see stereo, when forced to mono */
97 dev->stereo=1;
98 }
99
100 if ((i=aci_rds_cmd(RDS_STATUS, &buf, 1))<0)
101 return i;
102 if (buf & 1)
103 /* RDS available */
104 *flags|=VIDEO_TUNER_RDS_ON;
105 else
106 return 0;
107
108 if ((i=aci_rds_cmd(RDS_RXVALUE, &buf, 1))<0)
109 return i;
110 pr_debug("rds-signal: %d\n", buf);
111 if (buf > 15) {
112 printk("miropcm20-radio: RX strengths unexpected high...\n");
113 buf=15;
114 }
115 /* refine signal */
116 if ((*signal=SCALE(15, 0xffff, buf))==0)
117 *signal = 1;
118
119 return 0;
120}
121
122static int pcm20_do_ioctl(struct inode *inode, struct file *file,
123 unsigned int cmd, void *arg)
124{
125 struct video_device *dev = video_devdata(file);
126 struct pcm20_device *pcm20 = dev->priv;
127 int i;
128
129 switch(cmd)
130 {
131 case VIDIOCGCAP:
132 {
133 struct video_capability *v = arg;
134 memset(v,0,sizeof(*v));
135 v->type=VID_TYPE_TUNER;
136 strcpy(v->name, "Miro PCM20");
137 v->channels=1;
138 v->audios=1;
139 return 0;
140 }
141 case VIDIOCGTUNER:
142 {
143 struct video_tuner *v = arg;
144 if(v->tuner) /* Only 1 tuner */
145 return -EINVAL;
146 v->rangelow=87*16000;
147 v->rangehigh=108*16000;
148 pcm20_getflags(pcm20, &v->flags, &v->signal);
149 v->flags|=VIDEO_TUNER_LOW;
150 v->mode=VIDEO_MODE_AUTO;
151 strcpy(v->name, "FM");
152 return 0;
153 }
154 case VIDIOCSTUNER:
155 {
156 struct video_tuner *v = arg;
157 if(v->tuner!=0)
158 return -EINVAL;
159 /* Only 1 tuner so no setting needed ! */
160 return 0;
161 }
162 case VIDIOCGFREQ:
163 {
164 unsigned long *freq = arg;
165 *freq = pcm20->freq;
166 return 0;
167 }
168 case VIDIOCSFREQ:
169 {
170 unsigned long *freq = arg;
171 pcm20->freq = *freq;
172 i=pcm20_setfreq(pcm20, pcm20->freq);
173 pr_debug("First view (setfreq): 0x%x\n", i);
174 return i;
175 }
176 case VIDIOCGAUDIO:
177 {
178 struct video_audio *v = arg;
179 memset(v,0, sizeof(*v));
180 v->flags=VIDEO_AUDIO_MUTABLE;
181 if (pcm20->muted)
182 v->flags|=VIDEO_AUDIO_MUTE;
183 v->mode=VIDEO_SOUND_STEREO;
184 if (pcm20->stereo)
185 v->mode|=VIDEO_SOUND_MONO;
186 /* v->step=2048; */
187 strcpy(v->name, "Radio");
188 return 0;
189 }
190 case VIDIOCSAUDIO:
191 {
192 struct video_audio *v = arg;
193 if(v->audio)
194 return -EINVAL;
195
196 pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE));
197 if(v->flags&VIDEO_SOUND_MONO)
198 pcm20_stereo(pcm20, 0);
199 if(v->flags&VIDEO_SOUND_STEREO)
200 pcm20_stereo(pcm20, 1);
201
202 return 0;
203 }
204 default:
205 return -ENOIOCTLCMD;
206 }
207}
208
209static int pcm20_ioctl(struct inode *inode, struct file *file,
210 unsigned int cmd, unsigned long arg)
211{
212 return video_usercopy(inode, file, cmd, arg, pcm20_do_ioctl);
213}
214
215static struct pcm20_device pcm20_unit = {
216 .freq = 87*16000,
217 .muted = 1,
218};
219
220static const struct file_operations pcm20_fops = {
221 .owner = THIS_MODULE,
222 .open = video_exclusive_open,
223 .release = video_exclusive_release,
224 .ioctl = pcm20_ioctl,
225#ifdef CONFIG_COMPAT
226 .compat_ioctl = v4l_compat_ioctl32,
227#endif
228 .llseek = no_llseek,
229};
230
231static struct video_device pcm20_radio = {
232 .name = "Miro PCM 20 radio",
233 .fops = &pcm20_fops,
234 .priv = &pcm20_unit
235};
236
237static int __init pcm20_init(void)
238{
239 if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
240 goto video_register_device;
241
242 if(attach_aci_rds()<0)
243 goto attach_aci_rds;
244
245 printk(KERN_INFO "Miro PCM20 radio card driver.\n");
246
247 return 0;
248
249 attach_aci_rds:
250 video_unregister_device(&pcm20_radio);
251 video_register_device:
252 return -EINVAL;
253}
254
255MODULE_AUTHOR("Ruurd Reitsma");
256MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
257MODULE_LICENSE("GPL");
258
259static void __exit pcm20_cleanup(void)
260{
261 unload_aci_rds();
262 video_unregister_device(&pcm20_radio);
263}
264
265module_init(pcm20_init);
266module_exit(pcm20_cleanup);
diff --git a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c
deleted file mode 100644
index 9428d8b2642c..000000000000
--- a/drivers/media/radio/miropcm20-rds-core.c
+++ /dev/null
@@ -1,211 +0,0 @@
1/*
2 * Many thanks to Fred Seidel <seidel@metabox.de>, the
3 * designer of the RDS decoder hardware. With his help
4 * I was able to code this driver.
5 * Thanks also to Norberto Pellicci, Dominic Mounteney
6 * <DMounteney@pinnaclesys.com> and www.teleauskunft.de
7 * for good hints on finding Fred. It was somewhat hard
8 * to locate him here in Germany... [:
9 *
10 * Revision history:
11 *
12 * 2000-08-09 Robert Siemer <Robert.Siemer@gmx.de>
13 * RDS support for MiroSound PCM20 radio
14 */
15
16#include <linux/module.h>
17#include <linux/errno.h>
18#include <linux/string.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/mutex.h>
22
23#include <asm/io.h>
24#include "oss/aci.h"
25#include "miropcm20-rds-core.h"
26
27#define DEBUG 0
28
29static struct mutex aci_rds_mutex;
30
31#define RDS_DATASHIFT 2 /* Bit 2 */
32#define RDS_DATAMASK (1 << RDS_DATASHIFT)
33#define RDS_BUSYMASK 0x10 /* Bit 4 */
34#define RDS_CLOCKMASK 0x08 /* Bit 3 */
35
36#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1)
37
38
39#if DEBUG
40static void print_matrix(char array[], unsigned int length)
41{
42 int i, j;
43
44 for (i=0; i<length; i++) {
45 printk(KERN_DEBUG "aci-rds: ");
46 for (j=7; j>=0; j--) {
47 printk("%d", (array[i] >> j) & 0x1);
48 }
49 if (i%8 == 0)
50 printk(" byte-border\n");
51 else
52 printk("\n");
53 }
54}
55#endif /* DEBUG */
56
57static int byte2trans(unsigned char byte, unsigned char sendbuffer[], int size)
58{
59 int i;
60
61 if (size != 8)
62 return -1;
63 for (i = 7; i >= 0; i--)
64 sendbuffer[7-i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
65 sendbuffer[0] |= RDS_CLOCKMASK;
66
67 return 0;
68}
69
70static int rds_waitread(void)
71{
72 unsigned char byte;
73 int i=2000;
74
75 do {
76 byte=inb(RDS_REGISTER);
77 i--;
78 }
79 while ((byte & RDS_BUSYMASK) && i);
80
81 if (i) {
82 #if DEBUG
83 printk(KERN_DEBUG "rds_waitread()");
84 print_matrix(&byte, 1);
85 #endif
86 return (byte);
87 } else {
88 printk(KERN_WARNING "aci-rds: rds_waitread() timeout...\n");
89 return -1;
90 }
91}
92
93/* don't use any ..._nowait() function if you are not sure what you do... */
94
95static inline void rds_rawwrite_nowait(unsigned char byte)
96{
97 #if DEBUG
98 printk(KERN_DEBUG "rds_rawwrite()");
99 print_matrix(&byte, 1);
100 #endif
101 outb(byte, RDS_REGISTER);
102}
103
104static int rds_rawwrite(unsigned char byte)
105{
106 if (rds_waitread() >= 0) {
107 rds_rawwrite_nowait(byte);
108 return 0;
109 } else
110 return -1;
111}
112
113static int rds_write(unsigned char cmd)
114{
115 unsigned char sendbuffer[8];
116 int i;
117
118 if (byte2trans(cmd, sendbuffer, 8) != 0){
119 return -1;
120 } else {
121 for (i=0; i<8; i++) {
122 rds_rawwrite(sendbuffer[i]);
123 }
124 }
125 return 0;
126}
127
128static int rds_readcycle_nowait(void)
129{
130 rds_rawwrite_nowait(0);
131 return rds_waitread();
132}
133
134static int rds_readcycle(void)
135{
136 if (rds_rawwrite(0) < 0)
137 return -1;
138 return rds_waitread();
139}
140
141static int rds_read(unsigned char databuffer[], int datasize)
142{
143 #define READSIZE (8*datasize)
144
145 int i,j;
146
147 if (datasize < 1) /* nothing to read */
148 return 0;
149
150 /* to be able to use rds_readcycle_nowait()
151 I have to waitread() here */
152 if (rds_waitread() < 0)
153 return -1;
154
155 memset(databuffer, 0, datasize);
156
157 for (i=0; i< READSIZE; i++)
158 if((j=rds_readcycle_nowait()) < 0) {
159 return -1;
160 } else {
161 databuffer[i/8]|=(RDS_DATA(j) << (7-(i%8)));
162 }
163
164 return 0;
165}
166
167static int rds_ack(void)
168{
169 int i=rds_readcycle();
170
171 if (i < 0)
172 return -1;
173 if (i & RDS_DATAMASK) {
174 return 0; /* ACK */
175 } else {
176 printk(KERN_DEBUG "aci-rds: NACK\n");
177 return 1; /* NACK */
178 }
179}
180
181int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize)
182{
183 int ret;
184
185 if (mutex_lock_interruptible(&aci_rds_mutex))
186 return -EINTR;
187
188 rds_write(cmd);
189
190 /* RDS_RESET doesn't need further processing */
191 if (cmd!=RDS_RESET && (rds_ack() || rds_read(databuffer, datasize)))
192 ret = -1;
193 else
194 ret = 0;
195
196 mutex_unlock(&aci_rds_mutex);
197
198 return ret;
199}
200EXPORT_SYMBOL(aci_rds_cmd);
201
202int __init attach_aci_rds(void)
203{
204 mutex_init(&aci_rds_mutex);
205 return 0;
206}
207
208void __exit unload_aci_rds(void)
209{
210}
211MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/miropcm20-rds-core.h b/drivers/media/radio/miropcm20-rds-core.h
deleted file mode 100644
index aeb5761f0469..000000000000
--- a/drivers/media/radio/miropcm20-rds-core.h
+++ /dev/null
@@ -1,19 +0,0 @@
1#ifndef _MIROPCM20_RDS_CORE_H_
2#define _MIROPCM20_RDS_CORE_H_
3
4extern int aci_rds_cmd(unsigned char cmd, unsigned char databuffer[], int datasize);
5
6#define RDS_STATUS 0x01
7#define RDS_STATIONNAME 0x02
8#define RDS_TEXT 0x03
9#define RDS_ALTFREQ 0x04
10#define RDS_TIMEDATE 0x05
11#define RDS_PI_CODE 0x06
12#define RDS_PTYTATP 0x07
13#define RDS_RESET 0x08
14#define RDS_RXVALUE 0x09
15
16extern void __exit unload_aci_rds(void);
17extern int __init attach_aci_rds(void);
18
19#endif /* _MIROPCM20_RDS_CORE_H_ */
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
deleted file mode 100644
index 3e840f74d45c..000000000000
--- a/drivers/media/radio/miropcm20-rds.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/* MiroSOUND PCM20 radio rds interface driver
2 * (c) 2001 Robert Siemer <Robert.Siemer@gmx.de>
3 * Thanks to Fred Seidel. See miropcm20-rds-core.c for further information.
4 */
5
6/* Revision history:
7 *
8 * 2001-04-18 Robert Siemer <Robert.Siemer@gmx.de>
9 * separate file for user interface driver
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/slab.h>
15#include <linux/smp_lock.h>
16#include <linux/fs.h>
17#include <linux/miscdevice.h>
18#include <linux/delay.h>
19#include <asm/uaccess.h>
20#include "miropcm20-rds-core.h"
21
22static char * text_buffer;
23static int rds_users;
24
25
26static int rds_f_open(struct inode *in, struct file *fi)
27{
28 if (rds_users)
29 return -EBUSY;
30
31 lock_kernel();
32 rds_users++;
33 if ((text_buffer=kmalloc(66, GFP_KERNEL)) == 0) {
34 rds_users--;
35 printk(KERN_NOTICE "aci-rds: Out of memory by open()...\n");
36 unlock_kernel();
37 return -ENOMEM;
38 }
39
40 unlock_kernel();
41 return 0;
42}
43
44static int rds_f_release(struct inode *in, struct file *fi)
45{
46 kfree(text_buffer);
47
48 rds_users--;
49 return 0;
50}
51
52static void print_matrix(char *ch, char out[])
53{
54 int j;
55
56 for (j=7; j>=0; j--) {
57 out[7-j] = ((*ch >> j) & 0x1) + '0';
58 }
59}
60
61static ssize_t rds_f_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
62{
63// i = sprintf(text_buffer, "length: %d, offset: %d\n", length, *offset);
64
65 char c;
66 char bits[8];
67
68 msleep(2000);
69 aci_rds_cmd(RDS_STATUS, &c, 1);
70 print_matrix(&c, bits);
71 if (copy_to_user(buffer, bits, 8))
72 return -EFAULT;
73
74/* if ((c >> 3) & 1) {
75 aci_rds_cmd(RDS_STATIONNAME, text_buffer+1, 8);
76 text_buffer[0] = ' ' ;
77 text_buffer[9] = '\n';
78 return copy_to_user(buffer+8, text_buffer, 10) ? -EFAULT: 18;
79 }
80*/
81/* if ((c >> 6) & 1) {
82 aci_rds_cmd(RDS_PTYTATP, &c, 1);
83 if ( c & 1)
84 sprintf(text_buffer, " M");
85 else
86 sprintf(text_buffer, " S");
87 if ((c >> 1) & 1)
88 sprintf(text_buffer+2, " TA");
89 else
90 sprintf(text_buffer+2, " --");
91 if ((c >> 7) & 1)
92 sprintf(text_buffer+5, " TP");
93 else
94 sprintf(text_buffer+5, " --");
95 sprintf(text_buffer+8, " %2d\n", (c >> 2) & 0x1f);
96 return copy_to_user(buffer+8, text_buffer, 12) ? -EFAULT: 20;
97 }
98*/
99
100 if ((c >> 4) & 1) {
101 aci_rds_cmd(RDS_TEXT, text_buffer, 65);
102 text_buffer[0] = ' ' ;
103 text_buffer[65] = '\n';
104 return copy_to_user(buffer+8, text_buffer,66) ? -EFAULT : 66+8;
105 } else {
106 put_user('\n', buffer+8);
107 return 9;
108 }
109}
110
111static const struct file_operations rds_fops = {
112 .owner = THIS_MODULE,
113 .read = rds_f_read,
114 .open = rds_f_open,
115 .release = rds_f_release
116};
117
118static struct miscdevice rds_miscdev = {
119 .minor = MISC_DYNAMIC_MINOR,
120 .name = "radiotext",
121 .fops = &rds_fops,
122};
123
124static int __init miropcm20_rds_init(void)
125{
126 return misc_register(&rds_miscdev);
127}
128
129static void __exit miropcm20_rds_cleanup(void)
130{
131 misc_deregister(&rds_miscdev);
132}
133
134module_init(miropcm20_rds_init);
135module_exit(miropcm20_rds_cleanup);
136MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index eba9209b3024..1f064f4b32df 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -426,8 +426,7 @@ static int __init rtrack_init(void)
426 426
427 rtrack_radio.priv=&rtrack_unit; 427 rtrack_radio.priv=&rtrack_unit;
428 428
429 if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1) 429 if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
430 {
431 release_region(io, 2); 430 release_region(io, 2);
432 return -EINVAL; 431 return -EINVAL;
433 } 432 }
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 3fe5504428c5..628c689e3ffe 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -394,8 +394,7 @@ static int __init aztech_init(void)
394 mutex_init(&lock); 394 mutex_init(&lock);
395 aztech_radio.priv=&aztech_unit; 395 aztech_radio.priv=&aztech_unit;
396 396
397 if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1) 397 if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
398 {
399 release_region(io,2); 398 release_region(io,2);
400 return -EINVAL; 399 return -EINVAL;
401 } 400 }
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 6166e726ed72..04c3698d32e4 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -682,7 +682,7 @@ static int __init cadet_init(void)
682 } 682 }
683 if (!request_region(io,2,"cadet")) 683 if (!request_region(io,2,"cadet"))
684 goto fail; 684 goto fail;
685 if(video_register_device(&cadet_radio,VFL_TYPE_RADIO,radio_nr)==-1) { 685 if (video_register_device(&cadet_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
686 release_region(io,2); 686 release_region(io,2);
687 goto fail; 687 goto fail;
688 } 688 }
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 36e754e3ffb2..5cd7f032298d 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -425,7 +425,7 @@ static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci
425 } 425 }
426 *devradio = vdev_template; 426 *devradio = vdev_template;
427 427
428 if ( video_register_device( devradio, VFL_TYPE_RADIO , nr_radio) == -1 ) { 428 if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) {
429 kfree( devradio ); 429 kfree( devradio );
430 goto err_video; 430 goto err_video;
431 } 431 }
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 2b1a6221de6d..0a0f956bb308 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -612,8 +612,7 @@ static int __init gemtek_init(void)
612 612
613 gemtek_radio.priv = &gemtek_unit; 613 gemtek_radio.priv = &gemtek_unit;
614 614
615 if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, 615 if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
616 radio_nr) == -1) {
617 release_region(io, 1); 616 release_region(io, 1);
618 return -EBUSY; 617 return -EBUSY;
619 } 618 }
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 0ada1c697e8a..9ef0a763eeb7 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -409,8 +409,7 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
409 video_set_drvdata(maestro_radio_inst, radio_unit); 409 video_set_drvdata(maestro_radio_inst, radio_unit);
410 pci_set_drvdata(pdev, maestro_radio_inst); 410 pci_set_drvdata(pdev, maestro_radio_inst);
411 411
412 retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, 412 retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, radio_nr);
413 radio_nr);
414 if (retval) { 413 if (retval) {
415 printk(KERN_ERR "can't register video device!\n"); 414 printk(KERN_ERR "can't register video device!\n");
416 goto errfr1; 415 goto errfr1;
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 43c75497dc49..0cc6fcb041fd 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -156,28 +156,28 @@ static void set_freq(__u16 io, __u32 freq)
156{ 156{
157 unsigned long int si; 157 unsigned long int si;
158 int bl; 158 int bl;
159 int data = FREQ2BITS(freq); 159 int val = FREQ2BITS(freq);
160 160
161 /* TEA5757 shift register bits (see pdf) */ 161 /* TEA5757 shift register bits (see pdf) */
162 162
163 outbit(0,io); // 24 search 163 outbit(0, io); /* 24 search */
164 outbit(1,io); // 23 search up/down 164 outbit(1, io); /* 23 search up/down */
165 165
166 outbit(0,io); // 22 stereo/mono 166 outbit(0, io); /* 22 stereo/mono */
167 167
168 outbit(0,io); // 21 band 168 outbit(0, io); /* 21 band */
169 outbit(0,io); // 20 band (only 00=FM works I think) 169 outbit(0, io); /* 20 band (only 00=FM works I think) */
170 170
171 outbit(0,io); // 19 port ? 171 outbit(0, io); /* 19 port ? */
172 outbit(0,io); // 18 port ? 172 outbit(0, io); /* 18 port ? */
173 173
174 outbit(0,io); // 17 search level 174 outbit(0, io); /* 17 search level */
175 outbit(0,io); // 16 search level 175 outbit(0, io); /* 16 search level */
176 176
177 si = 0x8000; 177 si = 0x8000;
178 for (bl = 1; bl <= 16 ; bl++) { 178 for (bl = 1; bl <= 16; bl++) {
179 outbit(data & si,io); 179 outbit(val & si, io);
180 si >>=1; 180 si >>= 1;
181 } 181 }
182 182
183 dprintk(1, "Radio freq set to %d.%02d MHz\n", 183 dprintk(1, "Radio freq set to %d.%02d MHz\n",
@@ -410,7 +410,7 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d
410 mutex_init(&radio_unit.lock); 410 mutex_init(&radio_unit.lock);
411 maxiradio_radio.priv = &radio_unit; 411 maxiradio_radio.priv = &radio_unit;
412 412
413 if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) { 413 if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
414 printk("radio-maxiradio: can't register device!"); 414 printk("radio-maxiradio: can't register device!");
415 goto err_out_free_region; 415 goto err_out_free_region;
416 } 416 }
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index e2dde0807268..6d820e2481e7 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -332,8 +332,7 @@ static int __init rtrack2_init(void)
332 rtrack2_radio.priv=&rtrack2_unit; 332 rtrack2_radio.priv=&rtrack2_unit;
333 333
334 spin_lock_init(&lock); 334 spin_lock_init(&lock);
335 if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1) 335 if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
336 {
337 release_region(io, 4); 336 release_region(io, 4);
338 return -EINVAL; 337 return -EINVAL;
339 } 338 }
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index bb5d92f104af..0d478f54a907 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -377,7 +377,7 @@ static int __init fmi_init(void)
377 377
378 mutex_init(&lock); 378 mutex_init(&lock);
379 379
380 if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { 380 if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
381 release_region(io, 2); 381 release_region(io, 2);
382 return -EINVAL; 382 return -EINVAL;
383 } 383 }
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index a4984ff87c9c..16c7ef20265c 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1694,8 +1694,8 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
1694 INIT_DELAYED_WORK(&radio->work, si470x_work); 1694 INIT_DELAYED_WORK(&radio->work, si470x_work);
1695 1695
1696 /* register video device */ 1696 /* register video device */
1697 if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { 1697 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
1698 retval = -EIO; 1698 if (retval) {
1699 printk(KERN_WARNING DRIVER_NAME 1699 printk(KERN_WARNING DRIVER_NAME
1700 ": Could not register video device\n"); 1700 ": Could not register video device\n");
1701 goto err_all; 1701 goto err_all;
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index cefa44fc5aed..0876fecc5f27 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -405,8 +405,7 @@ static int __init terratec_init(void)
405 405
406 spin_lock_init(&lock); 406 spin_lock_init(&lock);
407 407
408 if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1) 408 if (video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
409 {
410 release_region(io,2); 409 release_region(io,2);
411 return -EINVAL; 410 return -EINVAL;
412 } 411 }
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index d70172d23edb..193161956253 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -378,8 +378,7 @@ static int __init trust_init(void)
378 printk(KERN_ERR "trust: port 0x%x already in use\n", io); 378 printk(KERN_ERR "trust: port 0x%x already in use\n", io);
379 return -EBUSY; 379 return -EBUSY;
380 } 380 }
381 if(video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr)==-1) 381 if (video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
382 {
383 release_region(io, 2); 382 release_region(io, 2);
384 return -EINVAL; 383 return -EINVAL;
385 } 384 }
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 9f17a332fa11..51d57ed3b3e1 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -446,8 +446,7 @@ static int __init zoltrix_init(void)
446 return -EBUSY; 446 return -EBUSY;
447 } 447 }
448 448
449 if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) == -1) 449 if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
450 {
451 release_region(io, 2); 450 release_region(io, 2);
452 return -EINVAL; 451 return -EINVAL;
453 } 452 }
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index bbc6f8b82297..ef7c8d3ffb18 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -20,6 +20,8 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
20 obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o 20 obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
21endif 21endif
22 22
23obj-$(CONFIG_VIDEO_TUNER) += tuner.o
24
23obj-$(CONFIG_VIDEO_BT848) += bt8xx/ 25obj-$(CONFIG_VIDEO_BT848) += bt8xx/
24obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o 26obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
25obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o 27obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
@@ -85,8 +87,6 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
85obj-$(CONFIG_VIDEO_DPC) += dpc7146.o 87obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
86obj-$(CONFIG_TUNER_3036) += tuner-3036.o 88obj-$(CONFIG_TUNER_3036) += tuner-3036.o
87 89
88obj-$(CONFIG_VIDEO_TUNER) += tuner.o
89
90obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o 90obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
91obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o 91obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
92obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o 92obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index ed9a50f189fc..018f72b8e3e2 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -7,6 +7,7 @@ config VIDEO_AU0828
7 select DVB_AU8522 if !DVB_FE_CUSTOMIZE 7 select DVB_AU8522 if !DVB_FE_CUSTOMIZE
8 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE 8 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
9 select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE 9 select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
10 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
10 ---help--- 11 ---help---
11 This is a video4linux driver for Auvitek's USB device. 12 This is a video4linux driver for Auvitek's USB device.
12 13
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 443e59009762..ed48908a9034 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Auvitek USB bridge 2 * Driver for the Auvitek USB bridge
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -38,6 +38,9 @@ struct au0828_board au0828_boards[] = {
38 [AU0828_BOARD_DVICO_FUSIONHDTV7] = { 38 [AU0828_BOARD_DVICO_FUSIONHDTV7] = {
39 .name = "DViCO FusionHDTV USB", 39 .name = "DViCO FusionHDTV USB",
40 }, 40 },
41 [AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
42 .name = "Hauppauge Woodbury",
43 },
41}; 44};
42 45
43/* Tuner callback function for au0828 boards. Currently only needed 46/* Tuner callback function for au0828 boards. Currently only needed
@@ -115,6 +118,7 @@ void au0828_card_setup(struct au0828_dev *dev)
115 case AU0828_BOARD_HAUPPAUGE_HVR850: 118 case AU0828_BOARD_HAUPPAUGE_HVR850:
116 case AU0828_BOARD_HAUPPAUGE_HVR950Q: 119 case AU0828_BOARD_HAUPPAUGE_HVR950Q:
117 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: 120 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
121 case AU0828_BOARD_HAUPPAUGE_WOODBURY:
118 if (dev->i2c_rc == 0) 122 if (dev->i2c_rc == 0)
119 hauppauge_eeprom(dev, eeprom+0xa0); 123 hauppauge_eeprom(dev, eeprom+0xa0);
120 break; 124 break;
@@ -134,6 +138,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
134 case AU0828_BOARD_HAUPPAUGE_HVR850: 138 case AU0828_BOARD_HAUPPAUGE_HVR850:
135 case AU0828_BOARD_HAUPPAUGE_HVR950Q: 139 case AU0828_BOARD_HAUPPAUGE_HVR950Q:
136 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: 140 case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
141 case AU0828_BOARD_HAUPPAUGE_WOODBURY:
137 /* GPIO's 142 /* GPIO's
138 * 4 - CS5340 143 * 4 - CS5340
139 * 5 - AU8522 Demodulator 144 * 5 - AU8522 Demodulator
@@ -205,6 +210,8 @@ struct usb_device_id au0828_usb_id_table [] = {
205 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, 210 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
206 { USB_DEVICE(0x2040, 0x7281), 211 { USB_DEVICE(0x2040, 0x7281),
207 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, 212 .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
213 { USB_DEVICE(0x2040, 0x8200),
214 .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
208 { }, 215 { },
209}; 216};
210 217
diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/video/au0828/au0828-cards.h
index c37f5fd0fa80..48a1882c2b6b 100644
--- a/drivers/media/video/au0828/au0828-cards.h
+++ b/drivers/media/video/au0828/au0828-cards.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Auvitek USB bridge 2 * Driver for the Auvitek USB bridge
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -24,3 +24,4 @@
24#define AU0828_BOARD_HAUPPAUGE_HVR850 2 24#define AU0828_BOARD_HAUPPAUGE_HVR850 2
25#define AU0828_BOARD_DVICO_FUSIONHDTV7 3 25#define AU0828_BOARD_DVICO_FUSIONHDTV7 3
26#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4 26#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4
27#define AU0828_BOARD_HAUPPAUGE_WOODBURY 5
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 54bfc0f05295..d856de9f742f 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Auvitek USB bridge 2 * Driver for the Auvitek USB bridge
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -252,5 +252,5 @@ module_init(au0828_init);
252module_exit(au0828_exit); 252module_exit(au0828_exit);
253 253
254MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products"); 254MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products");
255MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); 255MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
256MODULE_LICENSE("GPL"); 256MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 584a83a94a2a..ba94be7e0ac1 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Auvitek USB bridge 2 * Driver for the Auvitek USB bridge
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
29#include "au8522.h" 29#include "au8522.h"
30#include "xc5000.h" 30#include "xc5000.h"
31#include "mxl5007t.h" 31#include "mxl5007t.h"
32#include "tda18271.h"
32 33
33DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 34DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
34 35
@@ -38,6 +39,15 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
38static struct au8522_config hauppauge_hvr950q_config = { 39static struct au8522_config hauppauge_hvr950q_config = {
39 .demod_address = 0x8e >> 1, 40 .demod_address = 0x8e >> 1,
40 .status_mode = AU8522_DEMODLOCKING, 41 .status_mode = AU8522_DEMODLOCKING,
42 .qam_if = AU8522_IF_6MHZ,
43 .vsb_if = AU8522_IF_6MHZ,
44};
45
46static struct au8522_config hauppauge_woodbury_config = {
47 .demod_address = 0x8e >> 1,
48 .status_mode = AU8522_DEMODLOCKING,
49 .qam_if = AU8522_IF_4MHZ,
50 .vsb_if = AU8522_IF_3_25MHZ,
41}; 51};
42 52
43static struct xc5000_config hauppauge_hvr950q_tunerconfig = { 53static struct xc5000_config hauppauge_hvr950q_tunerconfig = {
@@ -51,6 +61,10 @@ static struct mxl5007t_config mxl5007t_hvr950q_config = {
51 .if_freq_hz = MxL_IF_6_MHZ, 61 .if_freq_hz = MxL_IF_6_MHZ,
52}; 62};
53 63
64static struct tda18271_config hauppauge_woodbury_tunerconfig = {
65 .gate = TDA18271_GATE_DIGITAL,
66};
67
54/*-------------------------------------------------------------------*/ 68/*-------------------------------------------------------------------*/
55static void urb_completion(struct urb *purb) 69static void urb_completion(struct urb *purb)
56{ 70{
@@ -357,6 +371,15 @@ int au0828_dvb_register(struct au0828_dev *dev)
357 &dev->i2c_adap, 0x60, 371 &dev->i2c_adap, 0x60,
358 &mxl5007t_hvr950q_config); 372 &mxl5007t_hvr950q_config);
359 break; 373 break;
374 case AU0828_BOARD_HAUPPAUGE_WOODBURY:
375 dvb->frontend = dvb_attach(au8522_attach,
376 &hauppauge_woodbury_config,
377 &dev->i2c_adap);
378 if (dvb->frontend != NULL)
379 dvb_attach(tda18271_attach, dvb->frontend,
380 0x60, &dev->i2c_adap,
381 &hauppauge_woodbury_tunerconfig);
382 break;
360 default: 383 default:
361 printk(KERN_WARNING "The frontend of your DVB/ATSC card " 384 printk(KERN_WARNING "The frontend of your DVB/ATSC card "
362 "isn't supported yet\n"); 385 "isn't supported yet\n");
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index 741a4937b050..d618fbaade1b 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Auvitek AU0828 USB bridge 2 * Driver for the Auvitek AU0828 USB bridge
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h
index 39827550891c..1e87fa0c6842 100644
--- a/drivers/media/video/au0828/au0828-reg.h
+++ b/drivers/media/video/au0828/au0828-reg.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Auvitek USB bridge 2 * Driver for the Auvitek USB bridge
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 7beb571798e5..4f10ff300135 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Auvitek AU0828 USB bridge 2 * Driver for the Auvitek AU0828 USB bridge
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 1c56ae92ce74..6081edc362df 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3144,8 +3144,9 @@ static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
3144 3144
3145static void flyvideo_gpio(struct bttv *btv) 3145static void flyvideo_gpio(struct bttv *btv)
3146{ 3146{
3147 int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821; 3147 int gpio, has_remote, has_radio, is_capture_only;
3148 int tuner=UNSET,ttype; 3148 int is_lr90, has_tda9820_tda9821;
3149 int tuner_type = UNSET, ttype;
3149 3150
3150 gpio_inout(0xffffff, 0); 3151 gpio_inout(0xffffff, 0);
3151 udelay(8); /* without this we would see the 0x1800 mask */ 3152 udelay(8); /* without this we would see the 0x1800 mask */
@@ -3163,20 +3164,26 @@ static void flyvideo_gpio(struct bttv *btv)
3163 * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered 3164 * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
3164 * Note: Some bits are Audio_Mask ! 3165 * Note: Some bits are Audio_Mask !
3165 */ 3166 */
3166 ttype=(gpio&0x0f0000)>>16; 3167 ttype = (gpio & 0x0f0000) >> 16;
3167 switch(ttype) { 3168 switch (ttype) {
3168 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ 3169 case 0x0:
3170 tuner_type = 2; /* NTSC, e.g. TPI8NSR11P */
3169 break; 3171 break;
3170 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ 3172 case 0x2:
3173 tuner_type = 39; /* LG NTSC (newer TAPC series) TAPC-H701P */
3171 break; 3174 break;
3172 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ 3175 case 0x4:
3176 tuner_type = 5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
3173 break; 3177 break;
3174 case 0x6: tuner=37;/* LG PAL (newer TAPC series) TAPC-G702P */ 3178 case 0x6:
3179 tuner_type = 37; /* LG PAL (newer TAPC series) TAPC-G702P */
3175 break; 3180 break;
3176 case 0xC: tuner=3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */ 3181 case 0xC:
3182 tuner_type = 3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
3177 break; 3183 break;
3178 default: 3184 default:
3179 printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr); 3185 printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
3186 break;
3180 } 3187 }
3181 3188
3182 has_remote = gpio & 0x800000; 3189 has_remote = gpio & 0x800000;
@@ -3189,23 +3196,26 @@ static void flyvideo_gpio(struct bttv *btv)
3189 /* 3196 /*
3190 * gpio & 0x001000 output bit for audio routing */ 3197 * gpio & 0x001000 output bit for audio routing */
3191 3198
3192 if(is_capture_only) 3199 if (is_capture_only)
3193 tuner = TUNER_ABSENT; /* No tuner present */ 3200 tuner_type = TUNER_ABSENT; /* No tuner present */
3194 3201
3195 printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", 3202 printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
3196 btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); 3203 btv->c.nr, has_radio ? "yes" : "no ",
3204 has_remote ? "yes" : "no ", tuner_type, gpio);
3197 printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n", 3205 printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n",
3198 btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ", 3206 btv->c.nr, is_lr90 ? "yes" : "no ",
3199 is_capture_only?"yes":"no "); 3207 has_tda9820_tda9821 ? "yes" : "no ",
3208 is_capture_only ? "yes" : "no ");
3200 3209
3201 if (tuner != UNSET) /* only set if known tuner autodetected, else let insmod option through */ 3210 if (tuner_type != UNSET) /* only set if known tuner autodetected, else let insmod option through */
3202 btv->tuner_type = tuner; 3211 btv->tuner_type = tuner_type;
3203 btv->has_radio = has_radio; 3212 btv->has_radio = has_radio;
3204 3213
3205 /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80 3214 /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
3206 * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00 3215 * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
3207 * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */ 3216 * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
3208 if(has_tda9820_tda9821) btv->audio_mode_gpio = lt9415_audio; 3217 if (has_tda9820_tda9821)
3218 btv->audio_mode_gpio = lt9415_audio;
3209 /* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */ 3219 /* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */
3210} 3220}
3211 3221
@@ -3962,7 +3972,7 @@ static int tuner_1_table[] = {
3962 3972
3963static void __devinit avermedia_eeprom(struct bttv *btv) 3973static void __devinit avermedia_eeprom(struct bttv *btv)
3964{ 3974{
3965 int tuner_make,tuner_tv_fm,tuner_format,tuner=0; 3975 int tuner_make, tuner_tv_fm, tuner_format, tuner_type = 0;
3966 3976
3967 tuner_make = (eeprom_data[0x41] & 0x7); 3977 tuner_make = (eeprom_data[0x41] & 0x7);
3968 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; 3978 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
@@ -3970,24 +3980,24 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
3970 btv->has_remote = (eeprom_data[0x42] & 0x01); 3980 btv->has_remote = (eeprom_data[0x42] & 0x01);
3971 3981
3972 if (tuner_make == 0 || tuner_make == 2) 3982 if (tuner_make == 0 || tuner_make == 2)
3973 if(tuner_format <=0x0a) 3983 if (tuner_format <= 0x0a)
3974 tuner = tuner_0_table[tuner_format]; 3984 tuner_type = tuner_0_table[tuner_format];
3975 if (tuner_make == 1) 3985 if (tuner_make == 1)
3976 if(tuner_format <=9) 3986 if (tuner_format <= 9)
3977 tuner = tuner_1_table[tuner_format]; 3987 tuner_type = tuner_1_table[tuner_format];
3978 3988
3979 if (tuner_make == 4) 3989 if (tuner_make == 4)
3980 if(tuner_format == 0x09) 3990 if (tuner_format == 0x09)
3981 tuner = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */ 3991 tuner_type = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
3982 3992
3983 printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=", 3993 printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
3984 btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]); 3994 btv->c.nr, eeprom_data[0x41], eeprom_data[0x42]);
3985 if(tuner) { 3995 if (tuner_type) {
3986 btv->tuner_type=tuner; 3996 btv->tuner_type = tuner_type;
3987 printk("%d",tuner); 3997 printk(KERN_CONT "%d", tuner_type);
3988 } else 3998 } else
3989 printk("Unknown type"); 3999 printk(KERN_CONT "Unknown type");
3990 printk(" radio:%s remote control:%s\n", 4000 printk(KERN_CONT " radio:%s remote control:%s\n",
3991 tuner_tv_fm ? "yes" : "no", 4001 tuner_tv_fm ? "yes" : "no",
3992 btv->has_remote ? "yes" : "no"); 4002 btv->has_remote ? "yes" : "no");
3993} 4003}
@@ -4029,7 +4039,8 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
4029 4039
4030 gpio_inout(mask,mask); 4040 gpio_inout(mask,mask);
4031 gpio_bits(mask,0); 4041 gpio_bits(mask,0);
4032 udelay(2500); 4042 mdelay(2);
4043 udelay(500);
4033 gpio_bits(mask,mask); 4044 gpio_bits(mask,mask);
4034 4045
4035 if (bttv_gpio) 4046 if (bttv_gpio)
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 85bf31ab8789..6ae4cc860efe 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -96,7 +96,6 @@ static unsigned int irq_iswitch;
96static unsigned int uv_ratio = 50; 96static unsigned int uv_ratio = 50;
97static unsigned int full_luma_range; 97static unsigned int full_luma_range;
98static unsigned int coring; 98static unsigned int coring;
99extern int no_overlay;
100 99
101/* API features (turn on/off stuff for testing) */ 100/* API features (turn on/off stuff for testing) */
102static unsigned int v4l2 = 1; 101static unsigned int v4l2 = 1;
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 649682aac1ac..5b1b8e4c78ba 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -244,7 +244,8 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
244 const struct bttv_format *fmt, struct bttv_overlay *ov, 244 const struct bttv_format *fmt, struct bttv_overlay *ov,
245 int skip_even, int skip_odd) 245 int skip_even, int skip_odd)
246{ 246{
247 int dwords,rc,line,maxy,start,end,skip,nskips; 247 int dwords, rc, line, maxy, start, end;
248 unsigned skip, nskips;
248 struct btcx_skiplist *skips; 249 struct btcx_skiplist *skips;
249 __le32 *rp; 250 __le32 *rp;
250 u32 ri,ra; 251 u32 ri,ra;
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 08ef54a22c9e..b4d940b2e447 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -267,6 +267,11 @@ int bttv_sub_add_device(struct bttv_core *core, char *name);
267int bttv_sub_del_devices(struct bttv_core *core); 267int bttv_sub_del_devices(struct bttv_core *core);
268 268
269/* ---------------------------------------------------------- */ 269/* ---------------------------------------------------------- */
270/* bttv-cards.c */
271
272extern int no_overlay;
273
274/* ---------------------------------------------------------- */
270/* bttv-driver.c */ 275/* bttv-driver.c */
271 276
272/* insmod options */ 277/* insmod options */
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
index f42701f82e7f..3324ab38f58c 100644
--- a/drivers/media/video/btcx-risc.c
+++ b/drivers/media/video/btcx-risc.c
@@ -184,12 +184,12 @@ btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
184} 184}
185 185
186void 186void
187btcx_calc_skips(int line, int width, unsigned int *maxy, 187btcx_calc_skips(int line, int width, int *maxy,
188 struct btcx_skiplist *skips, unsigned int *nskips, 188 struct btcx_skiplist *skips, unsigned int *nskips,
189 const struct v4l2_clip *clips, unsigned int nclips) 189 const struct v4l2_clip *clips, unsigned int nclips)
190{ 190{
191 unsigned int clip,skip; 191 unsigned int clip,skip;
192 int end,maxline; 192 int end, maxline;
193 193
194 skip=0; 194 skip=0;
195 maxline = 9999; 195 maxline = 9999;
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h
index 861bc8112824..f8bc6e8e7b51 100644
--- a/drivers/media/video/btcx-risc.h
+++ b/drivers/media/video/btcx-risc.h
@@ -23,7 +23,7 @@ int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
23int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, 23int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
24 unsigned int n, int mask); 24 unsigned int n, int mask);
25void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips); 25void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
26void btcx_calc_skips(int line, int width, unsigned int *maxy, 26void btcx_calc_skips(int line, int width, int *maxy,
27 struct btcx_skiplist *skips, unsigned int *nskips, 27 struct btcx_skiplist *skips, unsigned int *nskips,
28 const struct v4l2_clip *clips, unsigned int nclips); 28 const struct v4l2_clip *clips, unsigned int nclips);
29 29
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index d3b3268bace8..6e39e253ce53 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -946,8 +946,7 @@ static int init_bwqcam(struct parport *port)
946 946
947 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); 947 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
948 948
949 if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1) 949 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
950 {
951 parport_unregister_device(qcam->pdev); 950 parport_unregister_device(qcam->pdev);
952 kfree(qcam); 951 kfree(qcam);
953 return -ENODEV; 952 return -ENODEV;
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index fe9379b282d3..7f6c6b4bec10 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -787,8 +787,7 @@ static int init_cqcam(struct parport *port)
787 787
788 parport_release(qcam->pdev); 788 parport_release(qcam->pdev);
789 789
790 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1) 790 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
791 {
792 printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", 791 printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
793 qcam->pport->name); 792 qcam->pport->name);
794 parport_unregister_device(qcam->pdev); 793 parport_unregister_device(qcam->pdev);
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index dc8cc6115e2f..a661800b0e69 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3955,7 +3955,7 @@ struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowleve
3955 camera->lowlevel_data = lowlevel; 3955 camera->lowlevel_data = lowlevel;
3956 3956
3957 /* register v4l device */ 3957 /* register v4l device */
3958 if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { 3958 if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
3959 kfree(camera); 3959 kfree(camera);
3960 printk(KERN_DEBUG "video_register_device failed\n"); 3960 printk(KERN_DEBUG "video_register_device failed\n");
3961 return NULL; 3961 return NULL;
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 515c8b57a60d..eb9f15cd4c45 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1024,7 +1024,6 @@ static int ioctl_queryctrl(void *arg,struct camera_data *cam)
1024 if(cam->params.pnp_id.device_type == DEVICE_STV_672 && 1024 if(cam->params.pnp_id.device_type == DEVICE_STV_672 &&
1025 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){ 1025 cam->params.version.sensor_flags==CPIA2_VP_SENSOR_FLAGS_500){
1026 // Maximum 15fps 1026 // Maximum 15fps
1027 int i;
1028 for(i=0; i<c->maximum; ++i) { 1027 for(i=0; i<c->maximum; ++i) {
1029 if(framerate_controls[i].value == 1028 if(framerate_controls[i].value ==
1030 CPIA2_VP_FRAMERATE_15) { 1029 CPIA2_VP_FRAMERATE_15) {
@@ -1959,8 +1958,7 @@ int cpia2_register_camera(struct camera_data *cam)
1959 reset_camera_struct_v4l(cam); 1958 reset_camera_struct_v4l(cam);
1960 1959
1961 /* register v4l device */ 1960 /* register v4l device */
1962 if (video_register_device 1961 if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1963 (cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1964 ERR("video_register_device failed\n"); 1962 ERR("video_register_device failed\n");
1965 video_device_release(cam->vdev); 1963 video_device_release(cam->vdev);
1966 return -ENODEV; 1964 return -ENODEV;
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 834b9248242e..e996a4e3123a 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -32,7 +32,7 @@ int cx18_av_loadfw(struct cx18 *cx)
32 u32 v; 32 u32 v;
33 const u8 *ptr; 33 const u8 *ptr;
34 int i; 34 int i;
35 int retries = 0; 35 int retries1 = 0;
36 36
37 if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { 37 if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
38 CX18_ERR("unable to open firmware %s\n", FWFILE); 38 CX18_ERR("unable to open firmware %s\n", FWFILE);
@@ -41,7 +41,7 @@ int cx18_av_loadfw(struct cx18 *cx)
41 41
42 /* The firmware load often has byte errors, so allow for several 42 /* The firmware load often has byte errors, so allow for several
43 retries, both at byte level and at the firmware load level. */ 43 retries, both at byte level and at the firmware load level. */
44 while (retries < 5) { 44 while (retries1 < 5) {
45 cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); 45 cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
46 cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); 46 cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6);
47 47
@@ -57,9 +57,9 @@ int cx18_av_loadfw(struct cx18 *cx)
57 for (i = 0; i < size; i++) { 57 for (i = 0; i < size; i++) {
58 u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); 58 u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
59 u32 value = 0; 59 u32 value = 0;
60 int retries; 60 int retries2;
61 61
62 for (retries = 0; retries < 5; retries++) { 62 for (retries2 = 0; retries2 < 5; retries2++) {
63 cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); 63 cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
64 udelay(10); 64 udelay(10);
65 value = cx18_av_read4(cx, CXADEC_DL_CTL); 65 value = cx18_av_read4(cx, CXADEC_DL_CTL);
@@ -69,18 +69,18 @@ int cx18_av_loadfw(struct cx18 *cx)
69 the address. We can only write the lower 69 the address. We can only write the lower
70 address byte of the address. */ 70 address byte of the address. */
71 if ((value & 0x3F00) != (dl_control & 0x3F00)) { 71 if ((value & 0x3F00) != (dl_control & 0x3F00)) {
72 retries = 5; 72 retries2 = 5;
73 break; 73 break;
74 } 74 }
75 } 75 }
76 if (retries >= 5) 76 if (retries2 >= 5)
77 break; 77 break;
78 } 78 }
79 if (i == size) 79 if (i == size)
80 break; 80 break;
81 retries++; 81 retries1++;
82 } 82 }
83 if (retries >= 5) { 83 if (retries1 >= 5) {
84 CX18_ERR("unable to load firmware %s\n", FWFILE); 84 CX18_ERR("unable to load firmware %s\n", FWFILE);
85 release_firmware(fw); 85 release_firmware(fw);
86 return -EIO; 86 return -EIO;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 22434aadde31..bd18afebbf86 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -74,9 +74,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
74 -1, -1, -1, -1, -1, -1, -1, -1, 74 -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1 }; 75 -1, -1, -1, -1, -1, -1, -1, -1 };
76 76
77static int cardtype_c = 1; 77static unsigned cardtype_c = 1;
78static int tuner_c = 1; 78static unsigned tuner_c = 1;
79static int radio_c = 1; 79static unsigned radio_c = 1;
80static char pal[] = "--"; 80static char pal[] = "--";
81static char secam[] = "--"; 81static char secam[] = "--";
82static char ntsc[] = "-"; 82static char ntsc[] = "-";
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index cae38985b131..1e420a804fc9 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * cx18 functions for DVB support 2 * cx18 functions for DVB support
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
index d6a6ccda79a9..bf8d8f6f5455 100644
--- a/drivers/media/video/cx18/cx18-dvb.h
+++ b/drivers/media/video/cx18/cx18-dvb.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * cx18 functions for DVB support 2 * cx18 functions for DVB support
3 * 3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index 25114a5cbd57..ab218315c84b 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
61 CX18_WARN("Ack struct = %d for %s\n", 61 CX18_WARN("Ack struct = %d for %s\n",
62 mb->args[2], s->name); 62 mb->args[2], s->name);
63 id = read_enc(off); 63 id = read_enc(off);
64 buf = cx18_queue_find_buf(s, id, read_enc(off + 4)); 64 buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4));
65 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); 65 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
66 if (buf) { 66 if (buf) {
67 cx18_buf_sync_for_cpu(s, buf); 67 cx18_buf_sync_for_cpu(s, buf);
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 6990b77c6200..dbe792ac3001 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
78 return buf; 78 return buf;
79} 79}
80 80
81struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, 81struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
82 u32 bytesused) 82 u32 bytesused)
83{ 83{
84 struct cx18 *cx = s->cx; 84 struct cx18 *cx = s->cx;
85 struct list_head *p; 85 struct list_head *p;
86 86
87 spin_lock(&s->qlock);
87 list_for_each(p, &s->q_free.list) { 88 list_for_each(p, &s->q_free.list) {
88 struct cx18_buffer *buf = 89 struct cx18_buffer *buf =
89 list_entry(p, struct cx18_buffer, list); 90 list_entry(p, struct cx18_buffer, list);
@@ -92,114 +93,48 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
92 continue; 93 continue;
93 buf->bytesused = bytesused; 94 buf->bytesused = bytesused;
94 /* the transport buffers are handled differently, 95 /* the transport buffers are handled differently,
95 so there is no need to move them to the full queue */ 96 they are not moved to the full queue */
96 if (s->type == CX18_ENC_STREAM_TYPE_TS) 97 if (s->type != CX18_ENC_STREAM_TYPE_TS) {
97 return buf; 98 s->q_free.buffers--;
98 s->q_free.buffers--; 99 s->q_free.length -= s->buf_size;
99 s->q_free.length -= s->buf_size; 100 s->q_full.buffers++;
100 s->q_full.buffers++; 101 s->q_full.length += s->buf_size;
101 s->q_full.length += s->buf_size; 102 s->q_full.bytesused += buf->bytesused;
102 s->q_full.bytesused += buf->bytesused; 103 list_move_tail(&buf->list, &s->q_full.list);
103 list_move_tail(&buf->list, &s->q_full.list); 104 }
105 spin_unlock(&s->qlock);
104 return buf; 106 return buf;
105 } 107 }
108 spin_unlock(&s->qlock);
106 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); 109 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
107 return NULL; 110 return NULL;
108} 111}
109 112
110static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from, 113/* Move all buffers of a queue to q_free, while flushing the buffers */
111 struct cx18_queue *to, int clear, int full) 114static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q)
112{
113 struct cx18_buffer *buf =
114 list_entry(from->list.next, struct cx18_buffer, list);
115
116 list_move_tail(from->list.next, &to->list);
117 from->buffers--;
118 from->length -= s->buf_size;
119 from->bytesused -= buf->bytesused - buf->readpos;
120 /* special handling for q_free */
121 if (clear)
122 buf->bytesused = buf->readpos = buf->b_flags = 0;
123 else if (full) {
124 /* special handling for stolen buffers, assume
125 all bytes are used. */
126 buf->bytesused = s->buf_size;
127 buf->readpos = buf->b_flags = 0;
128 }
129 to->buffers++;
130 to->length += s->buf_size;
131 to->bytesused += buf->bytesused - buf->readpos;
132}
133
134/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
135 If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
136 If 'steal' != NULL, then buffers may also taken from that queue if
137 needed.
138
139 The buffer is automatically cleared if it goes to the free queue. It is
140 also cleared if buffers need to be taken from the 'steal' queue and
141 the 'from' queue is the free queue.
142
143 When 'from' is q_free, then needed_bytes is compared to the total
144 available buffer length, otherwise needed_bytes is compared to the
145 bytesused value. For the 'steal' queue the total available buffer
146 length is always used.
147
148 -ENOMEM is returned if the buffers could not be obtained, 0 if all
149 buffers where obtained from the 'from' list and if non-zero then
150 the number of stolen buffers is returned. */
151static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
152 struct cx18_queue *steal, struct cx18_queue *to,
153 int needed_bytes)
154{ 115{
155 unsigned long flags; 116 unsigned long flags;
156 int rc = 0; 117 struct cx18_buffer *buf;
157 int from_free = from == &s->q_free;
158 int to_free = to == &s->q_free;
159 int bytes_available;
160
161 spin_lock_irqsave(&s->qlock, flags);
162 if (needed_bytes == 0) {
163 from_free = 1;
164 needed_bytes = from->length;
165 }
166
167 bytes_available = from_free ? from->length : from->bytesused;
168 bytes_available += steal ? steal->length : 0;
169 118
170 if (bytes_available < needed_bytes) { 119 if (q == &s->q_free)
171 spin_unlock_irqrestore(&s->qlock, flags); 120 return;
172 return -ENOMEM;
173 }
174 if (from_free) {
175 u32 old_length = to->length;
176 121
177 while (to->length - old_length < needed_bytes) { 122 spin_lock_irqsave(&s->qlock, flags);
178 if (list_empty(&from->list)) 123 while (!list_empty(&q->list)) {
179 from = steal; 124 buf = list_entry(q->list.next, struct cx18_buffer, list);
180 if (from == steal) 125 list_move_tail(q->list.next, &s->q_free.list);
181 rc++; /* keep track of 'stolen' buffers */ 126 buf->bytesused = buf->readpos = buf->b_flags = 0;
182 cx18_queue_move_buf(s, from, to, 1, 0); 127 s->q_free.buffers++;
183 } 128 s->q_free.length += s->buf_size;
184 } else {
185 u32 old_bytesused = to->bytesused;
186
187 while (to->bytesused - old_bytesused < needed_bytes) {
188 if (list_empty(&from->list))
189 from = steal;
190 if (from == steal)
191 rc++; /* keep track of 'stolen' buffers */
192 cx18_queue_move_buf(s, from, to, to_free, rc);
193 }
194 } 129 }
130 cx18_queue_init(q);
195 spin_unlock_irqrestore(&s->qlock, flags); 131 spin_unlock_irqrestore(&s->qlock, flags);
196 return rc;
197} 132}
198 133
199void cx18_flush_queues(struct cx18_stream *s) 134void cx18_flush_queues(struct cx18_stream *s)
200{ 135{
201 cx18_queue_move(s, &s->q_io, NULL, &s->q_free, 0); 136 cx18_queue_flush(s, &s->q_io);
202 cx18_queue_move(s, &s->q_full, NULL, &s->q_free, 0); 137 cx18_queue_flush(s, &s->q_full);
203} 138}
204 139
205int cx18_stream_alloc(struct cx18_stream *s) 140int cx18_stream_alloc(struct cx18_stream *s)
@@ -214,10 +149,10 @@ int cx18_stream_alloc(struct cx18_stream *s)
214 s->name, s->buffers, s->buf_size, 149 s->name, s->buffers, s->buf_size,
215 s->buffers * s->buf_size / 1024); 150 s->buffers * s->buf_size / 1024);
216 151
217 if (((char *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - 152 if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
218 (char *)cx->scb) > SCB_RESERVED_SIZE) { 153 (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
219 unsigned bufsz = (((char *)cx->scb) + SCB_RESERVED_SIZE - 154 unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE -
220 ((char *)cx->scb->cpu_mdl)); 155 ((char __iomem *)cx->scb->cpu_mdl));
221 156
222 CX18_ERR("Too many buffers, cannot fit in SCB area\n"); 157 CX18_ERR("Too many buffers, cannot fit in SCB area\n");
223 CX18_ERR("Max buffers = %zd\n", 158 CX18_ERR("Max buffers = %zd\n",
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 91423b9863a4..7f93bb13c09f 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q);
46void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, 46void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
47 struct cx18_queue *q); 47 struct cx18_queue *q);
48struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); 48struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
49struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, 49struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
50 u32 bytesused); 50 u32 bytesused);
51void cx18_flush_queues(struct cx18_stream *s); 51void cx18_flush_queues(struct cx18_stream *s);
52 52
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 8118091568fc..7b0e8c01692e 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -4,7 +4,7 @@
4 * 4 *
5 * (c) 2004 Jelle Foks <jelle@foks.8m.com> 5 * (c) 2004 Jelle Foks <jelle@foks.8m.com>
6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> 6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
7 * (c) 2008 Steven Toth <stoth@hauppauge.com> 7 * (c) 2008 Steven Toth <stoth@linuxtv.org>
8 * - CX23885/7/8 support 8 * - CX23885/7/8 support
9 * 9 *
10 * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/), 10 * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index a19de850955d..c36d3f632104 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 6286a9cf957e..25fb09938744 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
33#include "cx23885.h" 33#include "cx23885.h"
34 34
35MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); 35MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
36MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); 36MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39static unsigned int debug; 39static unsigned int debug;
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 0a2e6558cd66..291b9d008da8 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index c6bb0a05bc1c..f98e476e9617 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index bdd11bc513ad..20b68a236260 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c
index e36e3fcae2fb..35e61cd112fc 100644
--- a/drivers/media/video/cx23885/cx23885-vbi.c
+++ b/drivers/media/video/cx23885/cx23885-vbi.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index ad2235dab5b1..6047c78d84bf 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@
41#endif 41#endif
42 42
43MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); 43MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
44MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); 44MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
45MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
46 46
47/* ------------------------------------------------------------------ */ 47/* ------------------------------------------------------------------ */
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 00dfdc89d641..e23d97c071e0 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 209d3bcb5dbb..4da8cd74f00e 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -13,7 +13,7 @@
13 * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca> 13 * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
14 * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>. 14 * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
15 * 15 *
16 * CX23885 support by Steven Toth <stoth@hauppauge.com>. 16 * CX23885 support by Steven Toth <stoth@linuxtv.org>.
17 * 17 *
18 * This program is free software; you can redistribute it and/or 18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License 19 * modify it under the terms of the GNU General Public License
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 48f4b92a8f8b..79faedf58521 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -403,6 +403,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
403 ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev); 403 ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
404 if (ret) { 404 if (ret) {
405 err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret); 405 err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
406 kfree(b);
406 return ret; 407 return ret;
407 } 408 }
408 409
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 2d170d101c21..8db2a05bf9c5 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -2588,6 +2588,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2588 cam->v4ldev->fops = &et61x251_fops; 2588 cam->v4ldev->fops = &et61x251_fops;
2589 cam->v4ldev->minor = video_nr[dev_nr]; 2589 cam->v4ldev->minor = video_nr[dev_nr];
2590 cam->v4ldev->release = video_device_release; 2590 cam->v4ldev->release = video_device_release;
2591 cam->v4ldev->parent = &udev->dev;
2591 video_set_drvdata(cam->v4ldev, cam); 2592 video_set_drvdata(cam->v4ldev, cam);
2592 2593
2593 init_completion(&cam->probe); 2594 init_completion(&cam->probe);
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index cd3a3f5829b2..4d9f4cc255a9 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -124,7 +124,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
124 struct usb_device *dev = gspca_dev->dev; 124 struct usb_device *dev = gspca_dev->dev;
125 125
126#ifdef GSPCA_DEBUG 126#ifdef GSPCA_DEBUG
127 if (len > sizeof gspca_dev->usb_buf) { 127 if (len > USB_BUF_SZ) {
128 err("reg_r: buffer overflow"); 128 err("reg_r: buffer overflow");
129 return; 129 return;
130 } 130 }
@@ -164,7 +164,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
164 struct usb_device *dev = gspca_dev->dev; 164 struct usb_device *dev = gspca_dev->dev;
165 165
166#ifdef GSPCA_DEBUG 166#ifdef GSPCA_DEBUG
167 if (len > sizeof gspca_dev->usb_buf) { 167 if (len > USB_BUF_SZ) {
168 err("reg_w: buffer overflow"); 168 err("reg_w: buffer overflow");
169 return; 169 return;
170 } 170 }
@@ -731,13 +731,13 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev)
731 reg_w_val(gspca_dev, 0x0000, 0x00); 731 reg_w_val(gspca_dev, 0x0000, 0x00);
732 /* wait for completion */ 732 /* wait for completion */
733 retry = 50; 733 retry = 50;
734 while (retry--) { 734 do {
735 reg_r(gspca_dev, 0x0002, 1); 735 reg_r(gspca_dev, 0x0002, 1);
736 /* 0x07 until 0x00 */ 736 /* 0x07 until 0x00 */
737 if (gspca_dev->usb_buf[0] == 0x00) 737 if (gspca_dev->usb_buf[0] == 0x00)
738 break; 738 break;
739 reg_w_val(gspca_dev, 0x0053, 0x00); 739 reg_w_val(gspca_dev, 0x0053, 0x00);
740 } 740 } while (--retry);
741 if (retry == 0) 741 if (retry == 0)
742 PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); 742 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
743 /* send the qtable now */ 743 /* send the qtable now */
@@ -826,8 +826,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
826 return 0; 826 return 0;
827} 827}
828 828
829/* this function is called at open time */ 829/* this function is called at probe and resume time */
830static int sd_open(struct gspca_dev *gspca_dev) 830static int sd_init(struct gspca_dev *gspca_dev)
831{ 831{
832 cx11646_init1(gspca_dev); 832 cx11646_init1(gspca_dev);
833 cx11646_initsize(gspca_dev); 833 cx11646_initsize(gspca_dev);
@@ -845,10 +845,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
845 cx11646_jpeg(gspca_dev); 845 cx11646_jpeg(gspca_dev);
846} 846}
847 847
848static void sd_stopN(struct gspca_dev *gspca_dev)
849{
850}
851
852static void sd_stop0(struct gspca_dev *gspca_dev) 848static void sd_stop0(struct gspca_dev *gspca_dev)
853{ 849{
854 int retry = 50; 850 int retry = 50;
@@ -871,10 +867,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
871 reg_w_val(gspca_dev, 0x00fc, 0xe0); 867 reg_w_val(gspca_dev, 0x00fc, 0xe0);
872} 868}
873 869
874static void sd_close(struct gspca_dev *gspca_dev)
875{
876}
877
878static void sd_pkt_scan(struct gspca_dev *gspca_dev, 870static void sd_pkt_scan(struct gspca_dev *gspca_dev,
879 struct gspca_frame *frame, /* target */ 871 struct gspca_frame *frame, /* target */
880 __u8 *data, /* isoc packet */ 872 __u8 *data, /* isoc packet */
@@ -998,11 +990,9 @@ static struct sd_desc sd_desc = {
998 .ctrls = sd_ctrls, 990 .ctrls = sd_ctrls,
999 .nctrls = ARRAY_SIZE(sd_ctrls), 991 .nctrls = ARRAY_SIZE(sd_ctrls),
1000 .config = sd_config, 992 .config = sd_config,
1001 .open = sd_open, 993 .init = sd_init,
1002 .start = sd_start, 994 .start = sd_start,
1003 .stopN = sd_stopN,
1004 .stop0 = sd_stop0, 995 .stop0 = sd_stop0,
1005 .close = sd_close,
1006 .pkt_scan = sd_pkt_scan, 996 .pkt_scan = sd_pkt_scan,
1007}; 997};
1008 998
@@ -1026,6 +1016,10 @@ static struct usb_driver sd_driver = {
1026 .id_table = device_table, 1016 .id_table = device_table,
1027 .probe = sd_probe, 1017 .probe = sd_probe,
1028 .disconnect = gspca_disconnect, 1018 .disconnect = gspca_disconnect,
1019#ifdef CONFIG_PM
1020 .suspend = gspca_suspend,
1021 .resume = gspca_resume,
1022#endif
1029}; 1023};
1030 1024
1031/* -- module insert / remove -- */ 1025/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 1dbe92d01e6a..4ff0e386914b 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -81,6 +81,7 @@ static struct ctrl sd_ctrls[] = {
81 .set = sd_setcontrast, 81 .set = sd_setcontrast,
82 .get = sd_getcontrast, 82 .get = sd_getcontrast,
83 }, 83 },
84#define COLOR_IDX 2
84 { 85 {
85 { 86 {
86 .id = V4L2_CID_SATURATION, 87 .id = V4L2_CID_SATURATION,
@@ -234,7 +235,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
234 struct usb_device *dev = gspca_dev->dev; 235 struct usb_device *dev = gspca_dev->dev;
235 236
236#ifdef GSPCA_DEBUG 237#ifdef GSPCA_DEBUG
237 if (len > sizeof gspca_dev->usb_buf) { 238 if (len > USB_BUF_SZ) {
238 err("reg_r: buffer overflow"); 239 err("reg_r: buffer overflow");
239 return; 240 return;
240 } 241 }
@@ -272,7 +273,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
272 struct usb_device *dev = gspca_dev->dev; 273 struct usb_device *dev = gspca_dev->dev;
273 274
274#ifdef GSPCA_DEBUG 275#ifdef GSPCA_DEBUG
275 if (len > sizeof gspca_dev->usb_buf) { 276 if (len > USB_BUF_SZ) {
276 err("reg_w: buffer overflow"); 277 err("reg_w: buffer overflow");
277 return; 278 return;
278 } 279 }
@@ -665,6 +666,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
665 } else { 666 } else {
666 cam->cam_mode = vga_mode; 667 cam->cam_mode = vga_mode;
667 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 668 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
669 gspca_dev->ctrl_dis = (1 << COLOR_IDX);
668 } 670 }
669 sd->brightness = BRIGHTNESS_DEF; 671 sd->brightness = BRIGHTNESS_DEF;
670 sd->contrast = CONTRAST_DEF; 672 sd->contrast = CONTRAST_DEF;
@@ -674,8 +676,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
674 return 0; 676 return 0;
675} 677}
676 678
677/* this function is called at open time */ 679/* this function is called at probe and resume time */
678static int sd_open(struct gspca_dev *gspca_dev) 680static int sd_init(struct gspca_dev *gspca_dev)
679{ 681{
680 struct sd *sd = (struct sd *) gspca_dev; 682 struct sd *sd = (struct sd *) gspca_dev;
681 683
@@ -709,14 +711,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
709 et_video(gspca_dev, 0); /* video off */ 711 et_video(gspca_dev, 0); /* video off */
710} 712}
711 713
712static void sd_stop0(struct gspca_dev *gspca_dev)
713{
714}
715
716static void sd_close(struct gspca_dev *gspca_dev)
717{
718}
719
720static __u8 Et_getgainG(struct gspca_dev *gspca_dev) 714static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
721{ 715{
722 struct sd *sd = (struct sd *) gspca_dev; 716 struct sd *sd = (struct sd *) gspca_dev;
@@ -893,21 +887,19 @@ static struct sd_desc sd_desc = {
893 .ctrls = sd_ctrls, 887 .ctrls = sd_ctrls,
894 .nctrls = ARRAY_SIZE(sd_ctrls), 888 .nctrls = ARRAY_SIZE(sd_ctrls),
895 .config = sd_config, 889 .config = sd_config,
896 .open = sd_open, 890 .init = sd_init,
897 .start = sd_start, 891 .start = sd_start,
898 .stopN = sd_stopN, 892 .stopN = sd_stopN,
899 .stop0 = sd_stop0,
900 .close = sd_close,
901 .pkt_scan = sd_pkt_scan, 893 .pkt_scan = sd_pkt_scan,
902 .dq_callback = do_autogain, 894 .dq_callback = do_autogain,
903}; 895};
904 896
905/* -- module initialisation -- */ 897/* -- module initialisation -- */
906static __devinitdata struct usb_device_id device_table[] = { 898static __devinitdata struct usb_device_id device_table[] = {
907#ifndef CONFIG_USB_ET61X251
908 {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, 899 {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
909#endif 900#if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE
910 {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, 901 {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
902#endif
911 {} 903 {}
912}; 904};
913 905
@@ -926,6 +918,10 @@ static struct usb_driver sd_driver = {
926 .id_table = device_table, 918 .id_table = device_table,
927 .probe = sd_probe, 919 .probe = sd_probe,
928 .disconnect = gspca_disconnect, 920 .disconnect = gspca_disconnect,
921#ifdef CONFIG_PM
922 .suspend = gspca_suspend,
923 .resume = gspca_resume,
924#endif
929}; 925};
930 926
931/* -- module insert / remove -- */ 927/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 15d302b28b79..7be69284da03 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -114,7 +114,10 @@ static void fill_frame(struct gspca_dev *gspca_dev,
114 cam_pkt_op pkt_scan; 114 cam_pkt_op pkt_scan;
115 115
116 if (urb->status != 0) { 116 if (urb->status != 0) {
117 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); 117#ifdef CONFIG_PM
118 if (!gspca_dev->frozen)
119#endif
120 PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
118 return; /* disconnection ? */ 121 return; /* disconnection ? */
119 } 122 }
120 pkt_scan = gspca_dev->sd_desc->pkt_scan; 123 pkt_scan = gspca_dev->sd_desc->pkt_scan;
@@ -555,10 +558,12 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
555 gspca_dev->streaming = 0; 558 gspca_dev->streaming = 0;
556 atomic_set(&gspca_dev->nevent, 0); 559 atomic_set(&gspca_dev->nevent, 0);
557 if (gspca_dev->present) { 560 if (gspca_dev->present) {
558 gspca_dev->sd_desc->stopN(gspca_dev); 561 if (gspca_dev->sd_desc->stopN)
562 gspca_dev->sd_desc->stopN(gspca_dev);
559 destroy_urbs(gspca_dev); 563 destroy_urbs(gspca_dev);
560 gspca_set_alt0(gspca_dev); 564 gspca_set_alt0(gspca_dev);
561 gspca_dev->sd_desc->stop0(gspca_dev); 565 if (gspca_dev->sd_desc->stop0)
566 gspca_dev->sd_desc->stop0(gspca_dev);
562 PDEBUG(D_STREAM, "stream off OK"); 567 PDEBUG(D_STREAM, "stream off OK");
563 } 568 }
564} 569}
@@ -767,19 +772,7 @@ static int dev_open(struct inode *inode, struct file *file)
767 goto out; 772 goto out;
768 } 773 }
769 774
770 /* if not done yet, initialize the sensor */ 775 if (gspca_dev->users > 4) { /* (arbitrary value) */
771 if (gspca_dev->users == 0) {
772 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
773 ret = -ERESTARTSYS;
774 goto out;
775 }
776 ret = gspca_dev->sd_desc->open(gspca_dev);
777 mutex_unlock(&gspca_dev->usb_lock);
778 if (ret != 0) {
779 PDEBUG(D_ERR|D_CONF, "init device failed %d", ret);
780 goto out;
781 }
782 } else if (gspca_dev->users > 4) { /* (arbitrary value) */
783 ret = -EBUSY; 776 ret = -EBUSY;
784 goto out; 777 goto out;
785 } 778 }
@@ -792,6 +785,7 @@ static int dev_open(struct inode *inode, struct file *file)
792 else 785 else
793 gspca_dev->vdev.debug &= ~3; 786 gspca_dev->vdev.debug &= ~3;
794#endif 787#endif
788 ret = 0;
795out: 789out:
796 mutex_unlock(&gspca_dev->queue_lock); 790 mutex_unlock(&gspca_dev->queue_lock);
797 if (ret != 0) 791 if (ret != 0)
@@ -812,11 +806,11 @@ static int dev_close(struct inode *inode, struct file *file)
812 806
813 /* if the file did the capture, free the streaming resources */ 807 /* if the file did the capture, free the streaming resources */
814 if (gspca_dev->capt_file == file) { 808 if (gspca_dev->capt_file == file) {
815 mutex_lock(&gspca_dev->usb_lock); 809 if (gspca_dev->streaming) {
816 if (gspca_dev->streaming) 810 mutex_lock(&gspca_dev->usb_lock);
817 gspca_stream_off(gspca_dev); 811 gspca_stream_off(gspca_dev);
818 gspca_dev->sd_desc->close(gspca_dev); 812 mutex_unlock(&gspca_dev->usb_lock);
819 mutex_unlock(&gspca_dev->usb_lock); 813 }
820 frame_free(gspca_dev); 814 frame_free(gspca_dev);
821 gspca_dev->capt_file = NULL; 815 gspca_dev->capt_file = NULL;
822 gspca_dev->memory = GSPCA_MEMORY_NO; 816 gspca_dev->memory = GSPCA_MEMORY_NO;
@@ -853,42 +847,44 @@ static int vidioc_querycap(struct file *file, void *priv,
853 return 0; 847 return 0;
854} 848}
855 849
856/* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */
857static int vidioc_queryctrl(struct file *file, void *priv, 850static int vidioc_queryctrl(struct file *file, void *priv,
858 struct v4l2_queryctrl *q_ctrl) 851 struct v4l2_queryctrl *q_ctrl)
859{ 852{
860 struct gspca_dev *gspca_dev = priv; 853 struct gspca_dev *gspca_dev = priv;
861 int i; 854 int i, ix;
862 u32 id; 855 u32 id;
863 856
857 ix = -1;
864 id = q_ctrl->id; 858 id = q_ctrl->id;
865 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { 859 if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
866 id &= V4L2_CTRL_ID_MASK; 860 id &= V4L2_CTRL_ID_MASK;
867 id++; 861 id++;
868 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 862 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
869 if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { 863 if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
870 memcpy(q_ctrl, 864 continue;
871 &gspca_dev->sd_desc->ctrls[i].qctrl, 865 if (ix < 0) {
872 sizeof *q_ctrl); 866 ix = i;
873 return 0; 867 continue;
874 } 868 }
869 if (gspca_dev->sd_desc->ctrls[i].qctrl.id
870 > gspca_dev->sd_desc->ctrls[ix].qctrl.id)
871 continue;
872 ix = i;
875 } 873 }
876 return -EINVAL;
877 } 874 }
878 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { 875 for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
879 if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { 876 if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
880 memcpy(q_ctrl, 877 ix = i;
881 &gspca_dev->sd_desc->ctrls[i].qctrl, 878 break;
882 sizeof *q_ctrl);
883 return 0;
884 } 879 }
885 } 880 }
886 if (id >= V4L2_CID_BASE 881 if (ix < 0)
887 && id <= V4L2_CID_LASTP1) { 882 return -EINVAL;
883 memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[ix].qctrl,
884 sizeof *q_ctrl);
885 if (gspca_dev->ctrl_dis & (1 << ix))
888 q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; 886 q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
889 return 0; 887 return 0;
890 }
891 return -EINVAL;
892} 888}
893 889
894static int vidioc_s_ctrl(struct file *file, void *priv, 890static int vidioc_s_ctrl(struct file *file, void *priv,
@@ -903,6 +899,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
903 i++, ctrls++) { 899 i++, ctrls++) {
904 if (ctrl->id != ctrls->qctrl.id) 900 if (ctrl->id != ctrls->qctrl.id)
905 continue; 901 continue;
902 if (gspca_dev->ctrl_dis & (1 << i))
903 return -EINVAL;
906 if (ctrl->value < ctrls->qctrl.minimum 904 if (ctrl->value < ctrls->qctrl.minimum
907 || ctrl->value > ctrls->qctrl.maximum) 905 || ctrl->value > ctrls->qctrl.maximum)
908 return -ERANGE; 906 return -ERANGE;
@@ -929,6 +927,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
929 i++, ctrls++) { 927 i++, ctrls++) {
930 if (ctrl->id != ctrls->qctrl.id) 928 if (ctrl->id != ctrls->qctrl.id)
931 continue; 929 continue;
930 if (gspca_dev->ctrl_dis & (1 << i))
931 return -EINVAL;
932 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 932 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
933 return -ERESTARTSYS; 933 return -ERESTARTSYS;
934 ret = ctrls->get(gspca_dev, &ctrl->value); 934 ret = ctrls->get(gspca_dev, &ctrl->value);
@@ -1403,7 +1403,7 @@ static int vidioc_dqbuf(struct file *file, void *priv,
1403 i = ret; /* frame index */ 1403 i = ret; /* frame index */
1404 frame = &gspca_dev->frame[i]; 1404 frame = &gspca_dev->frame[i];
1405 if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { 1405 if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
1406 if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr, 1406 if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
1407 frame->data, 1407 frame->data,
1408 frame->v4l2_buf.bytesused)) { 1408 frame->v4l2_buf.bytesused)) {
1409 PDEBUG(D_ERR|D_STREAM, 1409 PDEBUG(D_ERR|D_STREAM,
@@ -1731,6 +1731,12 @@ int gspca_dev_probe(struct usb_interface *intf,
1731 err("couldn't kzalloc gspca struct"); 1731 err("couldn't kzalloc gspca struct");
1732 return -EIO; 1732 return -EIO;
1733 } 1733 }
1734 gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
1735 if (!gspca_dev->usb_buf) {
1736 err("out of memory");
1737 ret = -EIO;
1738 goto out;
1739 }
1734 gspca_dev->dev = dev; 1740 gspca_dev->dev = dev;
1735 gspca_dev->iface = interface->bInterfaceNumber; 1741 gspca_dev->iface = interface->bInterfaceNumber;
1736 gspca_dev->nbalt = intf->num_altsetting; 1742 gspca_dev->nbalt = intf->num_altsetting;
@@ -1738,10 +1744,13 @@ int gspca_dev_probe(struct usb_interface *intf,
1738/* gspca_dev->users = 0; (done by kzalloc) */ 1744/* gspca_dev->users = 0; (done by kzalloc) */
1739 gspca_dev->nbufread = 2; 1745 gspca_dev->nbufread = 2;
1740 1746
1741 /* configure the subdriver */ 1747 /* configure the subdriver and initialize the USB device */
1742 ret = gspca_dev->sd_desc->config(gspca_dev, id); 1748 ret = gspca_dev->sd_desc->config(gspca_dev, id);
1743 if (ret < 0) 1749 if (ret < 0)
1744 goto out; 1750 goto out;
1751 ret = gspca_dev->sd_desc->init(gspca_dev);
1752 if (ret < 0)
1753 goto out;
1745 ret = gspca_set_alt0(gspca_dev); 1754 ret = gspca_set_alt0(gspca_dev);
1746 if (ret < 0) 1755 if (ret < 0)
1747 goto out; 1756 goto out;
@@ -1771,6 +1780,7 @@ int gspca_dev_probe(struct usb_interface *intf,
1771 PDEBUG(D_PROBE, "probe ok"); 1780 PDEBUG(D_PROBE, "probe ok");
1772 return 0; 1781 return 0;
1773out: 1782out:
1783 kfree(gspca_dev->usb_buf);
1774 kfree(gspca_dev); 1784 kfree(gspca_dev);
1775 return ret; 1785 return ret;
1776} 1786}
@@ -1803,11 +1813,42 @@ void gspca_disconnect(struct usb_interface *intf)
1803/* We don't want people trying to open up the device */ 1813/* We don't want people trying to open up the device */
1804 video_unregister_device(&gspca_dev->vdev); 1814 video_unregister_device(&gspca_dev->vdev);
1805/* Free the memory */ 1815/* Free the memory */
1816 kfree(gspca_dev->usb_buf);
1806 kfree(gspca_dev); 1817 kfree(gspca_dev);
1807 PDEBUG(D_PROBE, "disconnect complete"); 1818 PDEBUG(D_PROBE, "disconnect complete");
1808} 1819}
1809EXPORT_SYMBOL(gspca_disconnect); 1820EXPORT_SYMBOL(gspca_disconnect);
1810 1821
1822#ifdef CONFIG_PM
1823int gspca_suspend(struct usb_interface *intf, pm_message_t message)
1824{
1825 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1826
1827 if (!gspca_dev->streaming)
1828 return 0;
1829 gspca_dev->frozen = 1; /* avoid urb error messages */
1830 if (gspca_dev->sd_desc->stopN)
1831 gspca_dev->sd_desc->stopN(gspca_dev);
1832 destroy_urbs(gspca_dev);
1833 gspca_set_alt0(gspca_dev);
1834 if (gspca_dev->sd_desc->stop0)
1835 gspca_dev->sd_desc->stop0(gspca_dev);
1836 return 0;
1837}
1838EXPORT_SYMBOL(gspca_suspend);
1839
1840int gspca_resume(struct usb_interface *intf)
1841{
1842 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
1843
1844 gspca_dev->frozen = 0;
1845 gspca_dev->sd_desc->init(gspca_dev);
1846 if (gspca_dev->streaming)
1847 return gspca_init_transfer(gspca_dev);
1848 return 0;
1849}
1850EXPORT_SYMBOL(gspca_resume);
1851#endif
1811/* -- cam driver utility functions -- */ 1852/* -- cam driver utility functions -- */
1812 1853
1813/* auto gain and exposure algorithm based on the knee algorithm described here: 1854/* auto gain and exposure algorithm based on the knee algorithm described here:
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 67e448940eaa..c17625cff9ba 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -56,7 +56,6 @@ extern int gspca_debug;
56 56
57/* device information - set at probe time */ 57/* device information - set at probe time */
58struct cam { 58struct cam {
59 char *dev_name;
60 struct v4l2_pix_format *cam_mode; /* size nmodes */ 59 struct v4l2_pix_format *cam_mode; /* size nmodes */
61 char nmodes; 60 char nmodes;
62 __u8 epaddr; 61 __u8 epaddr;
@@ -91,15 +90,14 @@ struct sd_desc {
91/* controls */ 90/* controls */
92 const struct ctrl *ctrls; 91 const struct ctrl *ctrls;
93 int nctrls; 92 int nctrls;
94/* operations */ 93/* mandatory operations */
95 cam_cf_op config; /* called on probe */ 94 cam_cf_op config; /* called on probe */
96 cam_op open; /* called on open */ 95 cam_op init; /* called on probe and resume */
97 cam_v_op start; /* called on stream on */ 96 cam_v_op start; /* called on stream on */
98 cam_v_op stopN; /* called on stream off - main alt */
99 cam_v_op stop0; /* called on stream off - alt 0 */
100 cam_v_op close; /* called on close */
101 cam_pkt_op pkt_scan; 97 cam_pkt_op pkt_scan;
102/* optional operations */ 98/* optional operations */
99 cam_v_op stopN; /* called on stream off - main alt */
100 cam_v_op stop0; /* called on stream off - alt 0 */
103 cam_v_op dq_callback; /* called when a frame has been dequeued */ 101 cam_v_op dq_callback; /* called when a frame has been dequeued */
104 cam_jpg_op get_jcomp; 102 cam_jpg_op get_jcomp;
105 cam_jpg_op set_jcomp; 103 cam_jpg_op set_jcomp;
@@ -127,8 +125,10 @@ struct gspca_dev {
127 125
128 struct cam cam; /* device information */ 126 struct cam cam; /* device information */
129 const struct sd_desc *sd_desc; /* subdriver description */ 127 const struct sd_desc *sd_desc; /* subdriver description */
128 unsigned ctrl_dis; /* disabled controls (bit map) */
130 129
131 __u8 usb_buf[8]; /* buffer for USB exchanges */ 130#define USB_BUF_SZ 64
131 __u8 *usb_buf; /* buffer for USB exchanges */
132 struct urb *urb[MAX_NURBS]; 132 struct urb *urb[MAX_NURBS];
133 133
134 __u8 *frbuf; /* buffer for nframes */ 134 __u8 *frbuf; /* buffer for nframes */
@@ -155,6 +155,9 @@ struct gspca_dev {
155 struct mutex queue_lock; /* ISOC queue protection */ 155 struct mutex queue_lock; /* ISOC queue protection */
156 __u32 sequence; /* frame sequence number */ 156 __u32 sequence; /* frame sequence number */
157 char streaming; 157 char streaming;
158#ifdef CONFIG_PM
159 char frozen; /* suspend - resume */
160#endif
158 char users; /* number of opens */ 161 char users; /* number of opens */
159 char present; /* device connected */ 162 char present; /* device connected */
160 char nbufread; /* number of buffers for read() */ 163 char nbufread; /* number of buffers for read() */
@@ -174,6 +177,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
174 struct gspca_frame *frame, 177 struct gspca_frame *frame,
175 const __u8 *data, 178 const __u8 *data,
176 int len); 179 int len);
180#ifdef CONFIG_PM
181int gspca_suspend(struct usb_interface *intf, pm_message_t message);
182int gspca_resume(struct usb_interface *intf);
183#endif
177int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, 184int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
178 int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); 185 int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
179#endif /* GSPCAV2_H */ 186#endif /* GSPCAV2_H */
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 21c4ee56a10a..4d5db47ba8cb 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -100,22 +100,6 @@ static int reg_w(struct gspca_dev *gspca_dev,
100 return rc; 100 return rc;
101} 101}
102 102
103static int reg_w_buf(struct gspca_dev *gspca_dev,
104 __u16 index, __u8 *buf, int len)
105{
106 int rc;
107
108 rc = usb_control_msg(gspca_dev->dev,
109 usb_sndbulkpipe(gspca_dev->dev, 4),
110 0x12,
111 0xc8, /* ?? */
112 0, /* value */
113 index, buf, len, 500);
114 if (rc < 0)
115 PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
116 return rc;
117}
118
119static void bulk_w(struct gspca_dev *gspca_dev, 103static void bulk_w(struct gspca_dev *gspca_dev,
120 __u16 *pch, 104 __u16 *pch,
121 __u16 Address) 105 __u16 Address)
@@ -144,8 +128,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
144 return 0; 128 return 0;
145} 129}
146 130
147/* this function is called at open time */ 131/* this function is called at probe and resume time */
148static int sd_open(struct gspca_dev *gspca_dev) 132static int sd_init(struct gspca_dev *gspca_dev)
149{ 133{
150 return 0; 134 return 0;
151} 135}
@@ -175,7 +159,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
175 /* 159 /*
176 Initialize the MR97113 chip register 160 Initialize the MR97113 chip register
177 */ 161 */
178 data = kmalloc(16, GFP_KERNEL);
179 data[0] = 0x00; /* address */ 162 data[0] = 0x00; /* address */
180 data[1] = 0x0c | 0x01; /* reg 0 */ 163 data[1] = 0x0c | 0x01; /* reg 0 */
181 data[2] = 0x01; /* reg 1 */ 164 data[2] = 0x01; /* reg 1 */
@@ -195,12 +178,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
195 data[10] = 0x5d; /* reg 9, I2C device address 178 data[10] = 0x5d; /* reg 9, I2C device address
196 * [for PAS5101 (0x40)] [for MI (0x5d)] */ 179 * [for PAS5101 (0x40)] [for MI (0x5d)] */
197 180
198 err_code = reg_w_buf(gspca_dev, data[0], data, 11); 181 err_code = reg_w(gspca_dev, data[0], 11);
199 kfree(data);
200 if (err_code < 0) 182 if (err_code < 0)
201 return; 183 return;
202 184
203 data = gspca_dev->usb_buf;
204 data[0] = 0x23; /* address */ 185 data[0] = 0x23; /* address */
205 data[1] = 0x09; /* reg 35, append frame header */ 186 data[1] = 0x09; /* reg 35, append frame header */
206 187
@@ -358,14 +339,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
358 PDEBUG(D_ERR, "Camera Stop failed"); 339 PDEBUG(D_ERR, "Camera Stop failed");
359} 340}
360 341
361static void sd_stop0(struct gspca_dev *gspca_dev)
362{
363}
364
365static void sd_close(struct gspca_dev *gspca_dev)
366{
367}
368
369static void sd_pkt_scan(struct gspca_dev *gspca_dev, 342static void sd_pkt_scan(struct gspca_dev *gspca_dev,
370 struct gspca_frame *frame, /* target */ 343 struct gspca_frame *frame, /* target */
371 __u8 *data, /* isoc packet */ 344 __u8 *data, /* isoc packet */
@@ -411,11 +384,9 @@ static const struct sd_desc sd_desc = {
411 .ctrls = sd_ctrls, 384 .ctrls = sd_ctrls,
412 .nctrls = ARRAY_SIZE(sd_ctrls), 385 .nctrls = ARRAY_SIZE(sd_ctrls),
413 .config = sd_config, 386 .config = sd_config,
414 .open = sd_open, 387 .init = sd_init,
415 .start = sd_start, 388 .start = sd_start,
416 .stopN = sd_stopN, 389 .stopN = sd_stopN,
417 .stop0 = sd_stop0,
418 .close = sd_close,
419 .pkt_scan = sd_pkt_scan, 390 .pkt_scan = sd_pkt_scan,
420}; 391};
421 392
@@ -439,6 +410,10 @@ static struct usb_driver sd_driver = {
439 .id_table = device_table, 410 .id_table = device_table,
440 .probe = sd_probe, 411 .probe = sd_probe,
441 .disconnect = gspca_disconnect, 412 .disconnect = gspca_disconnect,
413#ifdef CONFIG_PM
414 .suspend = gspca_suspend,
415 .resume = gspca_resume,
416#endif
442}; 417};
443 418
444/* -- module insert / remove -- */ 419/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index b4f00ec0885c..4df4eec9f7e7 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -63,11 +63,10 @@ struct sd {
63#define SEN_OV6630 2 63#define SEN_OV6630 2
64#define SEN_OV7610 3 64#define SEN_OV7610 3
65#define SEN_OV7620 4 65#define SEN_OV7620 4
66#define SEN_OV7630 5 66#define SEN_OV7640 5
67#define SEN_OV7640 6 67#define SEN_OV7670 6
68#define SEN_OV7670 7 68#define SEN_OV76BE 7
69#define SEN_OV76BE 8 69#define SEN_OV8610 8
70#define SEN_OV8610 9
71 70
72}; 71};
73 72
@@ -127,6 +126,7 @@ static struct ctrl sd_ctrls[] = {
127 .get = sd_getcolors, 126 .get = sd_getcolors,
128 }, 127 },
129/* next controls work with ov7670 only */ 128/* next controls work with ov7670 only */
129#define HFLIP_IDX 3
130 { 130 {
131 { 131 {
132 .id = V4L2_CID_HFLIP, 132 .id = V4L2_CID_HFLIP,
@@ -141,6 +141,7 @@ static struct ctrl sd_ctrls[] = {
141 .set = sd_sethflip, 141 .set = sd_sethflip,
142 .get = sd_gethflip, 142 .get = sd_gethflip,
143 }, 143 },
144#define VFLIP_IDX 4
144 { 145 {
145 { 146 {
146 .id = V4L2_CID_VFLIP, 147 .id = V4L2_CID_VFLIP,
@@ -293,6 +294,541 @@ static struct v4l2_pix_format sif_mode[] = {
293#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ 294#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
294#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ 295#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
295 296
297struct ov_regvals {
298 __u8 reg;
299 __u8 val;
300};
301struct ov_i2c_regvals {
302 __u8 reg;
303 __u8 val;
304};
305
306static const struct ov_i2c_regvals norm_6x20[] = {
307 { 0x12, 0x80 }, /* reset */
308 { 0x11, 0x01 },
309 { 0x03, 0x60 },
310 { 0x05, 0x7f }, /* For when autoadjust is off */
311 { 0x07, 0xa8 },
312 /* The ratio of 0x0c and 0x0d controls the white point */
313 { 0x0c, 0x24 },
314 { 0x0d, 0x24 },
315 { 0x0f, 0x15 }, /* COMS */
316 { 0x10, 0x75 }, /* AEC Exposure time */
317 { 0x12, 0x24 }, /* Enable AGC */
318 { 0x14, 0x04 },
319 /* 0x16: 0x06 helps frame stability with moving objects */
320 { 0x16, 0x06 },
321/* { 0x20, 0x30 }, * Aperture correction enable */
322 { 0x26, 0xb2 }, /* BLC enable */
323 /* 0x28: 0x05 Selects RGB format if RGB on */
324 { 0x28, 0x05 },
325 { 0x2a, 0x04 }, /* Disable framerate adjust */
326/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
327 { 0x2d, 0x99 },
328 { 0x33, 0xa0 }, /* Color Processing Parameter */
329 { 0x34, 0xd2 }, /* Max A/D range */
330 { 0x38, 0x8b },
331 { 0x39, 0x40 },
332
333 { 0x3c, 0x39 }, /* Enable AEC mode changing */
334 { 0x3c, 0x3c }, /* Change AEC mode */
335 { 0x3c, 0x24 }, /* Disable AEC mode changing */
336
337 { 0x3d, 0x80 },
338 /* These next two registers (0x4a, 0x4b) are undocumented.
339 * They control the color balance */
340 { 0x4a, 0x80 },
341 { 0x4b, 0x80 },
342 { 0x4d, 0xd2 }, /* This reduces noise a bit */
343 { 0x4e, 0xc1 },
344 { 0x4f, 0x04 },
345/* Do 50-53 have any effect? */
346/* Toggle 0x12[2] off and on here? */
347};
348
349static const struct ov_i2c_regvals norm_6x30[] = {
350 { 0x12, 0x80 }, /* Reset */
351 { 0x00, 0x1f }, /* Gain */
352 { 0x01, 0x99 }, /* Blue gain */
353 { 0x02, 0x7c }, /* Red gain */
354 { 0x03, 0xc0 }, /* Saturation */
355 { 0x05, 0x0a }, /* Contrast */
356 { 0x06, 0x95 }, /* Brightness */
357 { 0x07, 0x2d }, /* Sharpness */
358 { 0x0c, 0x20 },
359 { 0x0d, 0x20 },
360 { 0x0e, 0x20 },
361 { 0x0f, 0x05 },
362 { 0x10, 0x9a },
363 { 0x11, 0x00 }, /* Pixel clock = fastest */
364 { 0x12, 0x24 }, /* Enable AGC and AWB */
365 { 0x13, 0x21 },
366 { 0x14, 0x80 },
367 { 0x15, 0x01 },
368 { 0x16, 0x03 },
369 { 0x17, 0x38 },
370 { 0x18, 0xea },
371 { 0x19, 0x04 },
372 { 0x1a, 0x93 },
373 { 0x1b, 0x00 },
374 { 0x1e, 0xc4 },
375 { 0x1f, 0x04 },
376 { 0x20, 0x20 },
377 { 0x21, 0x10 },
378 { 0x22, 0x88 },
379 { 0x23, 0xc0 }, /* Crystal circuit power level */
380 { 0x25, 0x9a }, /* Increase AEC black ratio */
381 { 0x26, 0xb2 }, /* BLC enable */
382 { 0x27, 0xa2 },
383 { 0x28, 0x00 },
384 { 0x29, 0x00 },
385 { 0x2a, 0x84 }, /* 60 Hz power */
386 { 0x2b, 0xa8 }, /* 60 Hz power */
387 { 0x2c, 0xa0 },
388 { 0x2d, 0x95 }, /* Enable auto-brightness */
389 { 0x2e, 0x88 },
390 { 0x33, 0x26 },
391 { 0x34, 0x03 },
392 { 0x36, 0x8f },
393 { 0x37, 0x80 },
394 { 0x38, 0x83 },
395 { 0x39, 0x80 },
396 { 0x3a, 0x0f },
397 { 0x3b, 0x3c },
398 { 0x3c, 0x1a },
399 { 0x3d, 0x80 },
400 { 0x3e, 0x80 },
401 { 0x3f, 0x0e },
402 { 0x40, 0x00 }, /* White bal */
403 { 0x41, 0x00 }, /* White bal */
404 { 0x42, 0x80 },
405 { 0x43, 0x3f }, /* White bal */
406 { 0x44, 0x80 },
407 { 0x45, 0x20 },
408 { 0x46, 0x20 },
409 { 0x47, 0x80 },
410 { 0x48, 0x7f },
411 { 0x49, 0x00 },
412 { 0x4a, 0x00 },
413 { 0x4b, 0x80 },
414 { 0x4c, 0xd0 },
415 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
416 { 0x4e, 0x40 },
417 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
418 { 0x50, 0xff },
419 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
420 { 0x55, 0xff },
421 { 0x56, 0x12 },
422 { 0x57, 0x81 },
423 { 0x58, 0x75 },
424 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
425 { 0x5a, 0x2c },
426 { 0x5b, 0x0f }, /* AWB chrominance levels */
427 { 0x5c, 0x10 },
428 { 0x3d, 0x80 },
429 { 0x27, 0xa6 },
430 { 0x12, 0x20 }, /* Toggle AWB */
431 { 0x12, 0x24 },
432};
433
434/* Lawrence Glaister <lg@jfm.bc.ca> reports:
435 *
436 * Register 0x0f in the 7610 has the following effects:
437 *
438 * 0x85 (AEC method 1): Best overall, good contrast range
439 * 0x45 (AEC method 2): Very overexposed
440 * 0xa5 (spec sheet default): Ok, but the black level is
441 * shifted resulting in loss of contrast
442 * 0x05 (old driver setting): very overexposed, too much
443 * contrast
444 */
445static const struct ov_i2c_regvals norm_7610[] = {
446 { 0x10, 0xff },
447 { 0x16, 0x06 },
448 { 0x28, 0x24 },
449 { 0x2b, 0xac },
450 { 0x12, 0x00 },
451 { 0x38, 0x81 },
452 { 0x28, 0x24 }, /* 0c */
453 { 0x0f, 0x85 }, /* lg's setting */
454 { 0x15, 0x01 },
455 { 0x20, 0x1c },
456 { 0x23, 0x2a },
457 { 0x24, 0x10 },
458 { 0x25, 0x8a },
459 { 0x26, 0xa2 },
460 { 0x27, 0xc2 },
461 { 0x2a, 0x04 },
462 { 0x2c, 0xfe },
463 { 0x2d, 0x93 },
464 { 0x30, 0x71 },
465 { 0x31, 0x60 },
466 { 0x32, 0x26 },
467 { 0x33, 0x20 },
468 { 0x34, 0x48 },
469 { 0x12, 0x24 },
470 { 0x11, 0x01 },
471 { 0x0c, 0x24 },
472 { 0x0d, 0x24 },
473};
474
475static const struct ov_i2c_regvals norm_7620[] = {
476 { 0x00, 0x00 }, /* gain */
477 { 0x01, 0x80 }, /* blue gain */
478 { 0x02, 0x80 }, /* red gain */
479 { 0x03, 0xc0 }, /* OV7670_REG_VREF */
480 { 0x06, 0x60 },
481 { 0x07, 0x00 },
482 { 0x0c, 0x24 },
483 { 0x0c, 0x24 },
484 { 0x0d, 0x24 },
485 { 0x11, 0x01 },
486 { 0x12, 0x24 },
487 { 0x13, 0x01 },
488 { 0x14, 0x84 },
489 { 0x15, 0x01 },
490 { 0x16, 0x03 },
491 { 0x17, 0x2f },
492 { 0x18, 0xcf },
493 { 0x19, 0x06 },
494 { 0x1a, 0xf5 },
495 { 0x1b, 0x00 },
496 { 0x20, 0x18 },
497 { 0x21, 0x80 },
498 { 0x22, 0x80 },
499 { 0x23, 0x00 },
500 { 0x26, 0xa2 },
501 { 0x27, 0xea },
502 { 0x28, 0x20 },
503 { 0x29, 0x00 },
504 { 0x2a, 0x10 },
505 { 0x2b, 0x00 },
506 { 0x2c, 0x88 },
507 { 0x2d, 0x91 },
508 { 0x2e, 0x80 },
509 { 0x2f, 0x44 },
510 { 0x60, 0x27 },
511 { 0x61, 0x02 },
512 { 0x62, 0x5f },
513 { 0x63, 0xd5 },
514 { 0x64, 0x57 },
515 { 0x65, 0x83 },
516 { 0x66, 0x55 },
517 { 0x67, 0x92 },
518 { 0x68, 0xcf },
519 { 0x69, 0x76 },
520 { 0x6a, 0x22 },
521 { 0x6b, 0x00 },
522 { 0x6c, 0x02 },
523 { 0x6d, 0x44 },
524 { 0x6e, 0x80 },
525 { 0x6f, 0x1d },
526 { 0x70, 0x8b },
527 { 0x71, 0x00 },
528 { 0x72, 0x14 },
529 { 0x73, 0x54 },
530 { 0x74, 0x00 },
531 { 0x75, 0x8e },
532 { 0x76, 0x00 },
533 { 0x77, 0xff },
534 { 0x78, 0x80 },
535 { 0x79, 0x80 },
536 { 0x7a, 0x80 },
537 { 0x7b, 0xe2 },
538 { 0x7c, 0x00 },
539};
540
541/* 7640 and 7648. The defaults should be OK for most registers. */
542static const struct ov_i2c_regvals norm_7640[] = {
543 { 0x12, 0x80 },
544 { 0x12, 0x14 },
545};
546
547/* 7670. Defaults taken from OmniVision provided data,
548* as provided by Jonathan Corbet of OLPC */
549static const struct ov_i2c_regvals norm_7670[] = {
550 { OV7670_REG_COM7, OV7670_COM7_RESET },
551 { OV7670_REG_TSLB, 0x04 }, /* OV */
552 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
553 { OV7670_REG_CLKRC, 0x01 },
554/*
555 * Set the hardware window. These values from OV don't entirely
556 * make sense - hstop is less than hstart. But they work...
557 */
558 { OV7670_REG_HSTART, 0x13 },
559 { OV7670_REG_HSTOP, 0x01 },
560 { OV7670_REG_HREF, 0xb6 },
561 { OV7670_REG_VSTART, 0x02 },
562 { OV7670_REG_VSTOP, 0x7a },
563 { OV7670_REG_VREF, 0x0a },
564
565 { OV7670_REG_COM3, 0 },
566 { OV7670_REG_COM14, 0 },
567/* Mystery scaling numbers */
568 { 0x70, 0x3a },
569 { 0x71, 0x35 },
570 { 0x72, 0x11 },
571 { 0x73, 0xf0 },
572 { 0xa2, 0x02 },
573/* { OV7670_REG_COM10, 0x0 }, */
574
575/* Gamma curve values */
576 { 0x7a, 0x20 },
577 { 0x7b, 0x10 },
578 { 0x7c, 0x1e },
579 { 0x7d, 0x35 },
580 { 0x7e, 0x5a },
581 { 0x7f, 0x69 },
582 { 0x80, 0x76 },
583 { 0x81, 0x80 },
584 { 0x82, 0x88 },
585 { 0x83, 0x8f },
586 { 0x84, 0x96 },
587 { 0x85, 0xa3 },
588 { 0x86, 0xaf },
589 { 0x87, 0xc4 },
590 { 0x88, 0xd7 },
591 { 0x89, 0xe8 },
592
593/* AGC and AEC parameters. Note we start by disabling those features,
594 then turn them only after tweaking the values. */
595 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
596 | OV7670_COM8_AECSTEP
597 | OV7670_COM8_BFILT },
598 { OV7670_REG_GAIN, 0 },
599 { OV7670_REG_AECH, 0 },
600 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
601 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
602 { OV7670_REG_BD50MAX, 0x05 },
603 { OV7670_REG_BD60MAX, 0x07 },
604 { OV7670_REG_AEW, 0x95 },
605 { OV7670_REG_AEB, 0x33 },
606 { OV7670_REG_VPT, 0xe3 },
607 { OV7670_REG_HAECC1, 0x78 },
608 { OV7670_REG_HAECC2, 0x68 },
609 { 0xa1, 0x03 }, /* magic */
610 { OV7670_REG_HAECC3, 0xd8 },
611 { OV7670_REG_HAECC4, 0xd8 },
612 { OV7670_REG_HAECC5, 0xf0 },
613 { OV7670_REG_HAECC6, 0x90 },
614 { OV7670_REG_HAECC7, 0x94 },
615 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
616 | OV7670_COM8_AECSTEP
617 | OV7670_COM8_BFILT
618 | OV7670_COM8_AGC
619 | OV7670_COM8_AEC },
620
621/* Almost all of these are magic "reserved" values. */
622 { OV7670_REG_COM5, 0x61 },
623 { OV7670_REG_COM6, 0x4b },
624 { 0x16, 0x02 },
625 { OV7670_REG_MVFP, 0x07 },
626 { 0x21, 0x02 },
627 { 0x22, 0x91 },
628 { 0x29, 0x07 },
629 { 0x33, 0x0b },
630 { 0x35, 0x0b },
631 { 0x37, 0x1d },
632 { 0x38, 0x71 },
633 { 0x39, 0x2a },
634 { OV7670_REG_COM12, 0x78 },
635 { 0x4d, 0x40 },
636 { 0x4e, 0x20 },
637 { OV7670_REG_GFIX, 0 },
638 { 0x6b, 0x4a },
639 { 0x74, 0x10 },
640 { 0x8d, 0x4f },
641 { 0x8e, 0 },
642 { 0x8f, 0 },
643 { 0x90, 0 },
644 { 0x91, 0 },
645 { 0x96, 0 },
646 { 0x9a, 0 },
647 { 0xb0, 0x84 },
648 { 0xb1, 0x0c },
649 { 0xb2, 0x0e },
650 { 0xb3, 0x82 },
651 { 0xb8, 0x0a },
652
653/* More reserved magic, some of which tweaks white balance */
654 { 0x43, 0x0a },
655 { 0x44, 0xf0 },
656 { 0x45, 0x34 },
657 { 0x46, 0x58 },
658 { 0x47, 0x28 },
659 { 0x48, 0x3a },
660 { 0x59, 0x88 },
661 { 0x5a, 0x88 },
662 { 0x5b, 0x44 },
663 { 0x5c, 0x67 },
664 { 0x5d, 0x49 },
665 { 0x5e, 0x0e },
666 { 0x6c, 0x0a },
667 { 0x6d, 0x55 },
668 { 0x6e, 0x11 },
669 { 0x6f, 0x9f },
670 /* "9e for advance AWB" */
671 { 0x6a, 0x40 },
672 { OV7670_REG_BLUE, 0x40 },
673 { OV7670_REG_RED, 0x60 },
674 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
675 | OV7670_COM8_AECSTEP
676 | OV7670_COM8_BFILT
677 | OV7670_COM8_AGC
678 | OV7670_COM8_AEC
679 | OV7670_COM8_AWB },
680
681/* Matrix coefficients */
682 { 0x4f, 0x80 },
683 { 0x50, 0x80 },
684 { 0x51, 0 },
685 { 0x52, 0x22 },
686 { 0x53, 0x5e },
687 { 0x54, 0x80 },
688 { 0x58, 0x9e },
689
690 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
691 { OV7670_REG_EDGE, 0 },
692 { 0x75, 0x05 },
693 { 0x76, 0xe1 },
694 { 0x4c, 0 },
695 { 0x77, 0x01 },
696 { OV7670_REG_COM13, OV7670_COM13_GAMMA
697 | OV7670_COM13_UVSAT
698 | 2}, /* was 3 */
699 { 0x4b, 0x09 },
700 { 0xc9, 0x60 },
701 { OV7670_REG_COM16, 0x38 },
702 { 0x56, 0x40 },
703
704 { 0x34, 0x11 },
705 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
706 { 0xa4, 0x88 },
707 { 0x96, 0 },
708 { 0x97, 0x30 },
709 { 0x98, 0x20 },
710 { 0x99, 0x30 },
711 { 0x9a, 0x84 },
712 { 0x9b, 0x29 },
713 { 0x9c, 0x03 },
714 { 0x9d, 0x4c },
715 { 0x9e, 0x3f },
716 { 0x78, 0x04 },
717
718/* Extra-weird stuff. Some sort of multiplexor register */
719 { 0x79, 0x01 },
720 { 0xc8, 0xf0 },
721 { 0x79, 0x0f },
722 { 0xc8, 0x00 },
723 { 0x79, 0x10 },
724 { 0xc8, 0x7e },
725 { 0x79, 0x0a },
726 { 0xc8, 0x80 },
727 { 0x79, 0x0b },
728 { 0xc8, 0x01 },
729 { 0x79, 0x0c },
730 { 0xc8, 0x0f },
731 { 0x79, 0x0d },
732 { 0xc8, 0x20 },
733 { 0x79, 0x09 },
734 { 0xc8, 0x80 },
735 { 0x79, 0x02 },
736 { 0xc8, 0xc0 },
737 { 0x79, 0x03 },
738 { 0xc8, 0x40 },
739 { 0x79, 0x05 },
740 { 0xc8, 0x30 },
741 { 0x79, 0x26 },
742};
743
744static const struct ov_i2c_regvals norm_8610[] = {
745 { 0x12, 0x80 },
746 { 0x00, 0x00 },
747 { 0x01, 0x80 },
748 { 0x02, 0x80 },
749 { 0x03, 0xc0 },
750 { 0x04, 0x30 },
751 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
752 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
753 { 0x0a, 0x86 },
754 { 0x0b, 0xb0 },
755 { 0x0c, 0x20 },
756 { 0x0d, 0x20 },
757 { 0x11, 0x01 },
758 { 0x12, 0x25 },
759 { 0x13, 0x01 },
760 { 0x14, 0x04 },
761 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
762 { 0x16, 0x03 },
763 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
764 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
765 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
766 { 0x1a, 0xf5 },
767 { 0x1b, 0x00 },
768 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
769 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
770 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
771 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
772 { 0x26, 0xa2 },
773 { 0x27, 0xea },
774 { 0x28, 0x00 },
775 { 0x29, 0x00 },
776 { 0x2a, 0x80 },
777 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
778 { 0x2c, 0xac },
779 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
780 { 0x2e, 0x80 },
781 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
782 { 0x4c, 0x00 },
783 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
784 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
785 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
786 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
787 { 0x63, 0xff },
788 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
789 * maybe thats wrong */
790 { 0x65, 0x00 },
791 { 0x66, 0x55 },
792 { 0x67, 0xb0 },
793 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
794 { 0x69, 0x02 },
795 { 0x6a, 0x22 },
796 { 0x6b, 0x00 },
797 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
798 * deleting bit7 colors the first images red */
799 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
800 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
801 { 0x6f, 0x01 },
802 { 0x70, 0x8b },
803 { 0x71, 0x00 },
804 { 0x72, 0x14 },
805 { 0x73, 0x54 },
806 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
807 { 0x75, 0x0e },
808 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
809 { 0x77, 0xff },
810 { 0x78, 0x80 },
811 { 0x79, 0x80 },
812 { 0x7a, 0x80 },
813 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
814 { 0x7c, 0x00 },
815 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
816 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
817 { 0x7f, 0xfb },
818 { 0x80, 0x28 },
819 { 0x81, 0x00 },
820 { 0x82, 0x23 },
821 { 0x83, 0x0b },
822 { 0x84, 0x00 },
823 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
824 { 0x86, 0xc9 },
825 { 0x87, 0x00 },
826 { 0x88, 0x00 },
827 { 0x89, 0x01 },
828 { 0x12, 0x20 },
829 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
830};
831
296static unsigned char ov7670_abs_to_sm(unsigned char v) 832static unsigned char ov7670_abs_to_sm(unsigned char v)
297{ 833{
298 if (v > 127) 834 if (v > 127)
@@ -537,18 +1073,10 @@ static int ov51x_set_slave_ids(struct sd *sd,
537 rc = reg_w(sd, R51x_I2C_W_SID, slave); 1073 rc = reg_w(sd, R51x_I2C_W_SID, slave);
538 if (rc < 0) 1074 if (rc < 0)
539 return rc; 1075 return rc;
1076 sd->primary_i2c_slave = slave;
540 return reg_w(sd, R51x_I2C_R_SID, slave + 1); 1077 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
541} 1078}
542 1079
543struct ov_regvals {
544 __u8 reg;
545 __u8 val;
546};
547struct ov_i2c_regvals {
548 __u8 reg;
549 __u8 val;
550};
551
552static int write_regvals(struct sd *sd, 1080static int write_regvals(struct sd *sd,
553 const struct ov_regvals *regvals, 1081 const struct ov_regvals *regvals,
554 int n) 1082 int n)
@@ -591,101 +1119,9 @@ static int write_i2c_regvals(struct sd *sd,
591static int ov8xx0_configure(struct sd *sd) 1119static int ov8xx0_configure(struct sd *sd)
592{ 1120{
593 int rc; 1121 int rc;
594 static const struct ov_i2c_regvals norm_8610[] = {
595 { 0x12, 0x80 },
596 { 0x00, 0x00 },
597 { 0x01, 0x80 },
598 { 0x02, 0x80 },
599 { 0x03, 0xc0 },
600 { 0x04, 0x30 },
601 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
602 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
603 { 0x0a, 0x86 },
604 { 0x0b, 0xb0 },
605 { 0x0c, 0x20 },
606 { 0x0d, 0x20 },
607 { 0x11, 0x01 },
608 { 0x12, 0x25 },
609 { 0x13, 0x01 },
610 { 0x14, 0x04 },
611 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
612 { 0x16, 0x03 },
613 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
614 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
615 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
616 { 0x1a, 0xf5 },
617 { 0x1b, 0x00 },
618 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
619 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
620 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
621 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
622 { 0x26, 0xa2 },
623 { 0x27, 0xea },
624 { 0x28, 0x00 },
625 { 0x29, 0x00 },
626 { 0x2a, 0x80 },
627 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
628 { 0x2c, 0xac },
629 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
630 { 0x2e, 0x80 },
631 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
632 { 0x4c, 0x00 },
633 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
634 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
635 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
636 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
637 { 0x63, 0xff },
638 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
639 * maybe thats wrong */
640 { 0x65, 0x00 },
641 { 0x66, 0x55 },
642 { 0x67, 0xb0 },
643 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
644 { 0x69, 0x02 },
645 { 0x6a, 0x22 },
646 { 0x6b, 0x00 },
647 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
648 deleting bit7 colors the first images red */
649 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
650 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
651 { 0x6f, 0x01 },
652 { 0x70, 0x8b },
653 { 0x71, 0x00 },
654 { 0x72, 0x14 },
655 { 0x73, 0x54 },
656 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
657 { 0x75, 0x0e },
658 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
659 { 0x77, 0xff },
660 { 0x78, 0x80 },
661 { 0x79, 0x80 },
662 { 0x7a, 0x80 },
663 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
664 { 0x7c, 0x00 },
665 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
666 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
667 { 0x7f, 0xfb },
668 { 0x80, 0x28 },
669 { 0x81, 0x00 },
670 { 0x82, 0x23 },
671 { 0x83, 0x0b },
672 { 0x84, 0x00 },
673 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
674 { 0x86, 0xc9 },
675 { 0x87, 0x00 },
676 { 0x88, 0x00 },
677 { 0x89, 0x01 },
678 { 0x12, 0x20 },
679 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
680 };
681 1122
682 PDEBUG(D_PROBE, "starting ov8xx0 configuration"); 1123 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
683 1124
684 if (init_ov_sensor(sd) < 0)
685 PDEBUG(D_ERR|D_PROBE, "Failed to read sensor ID");
686 else
687 PDEBUG(D_PROBE, "OV86x0 initialized");
688
689 /* Detect sensor (sub)type */ 1125 /* Detect sensor (sub)type */
690 rc = i2c_r(sd, OV7610_REG_COM_I); 1126 rc = i2c_r(sd, OV7610_REG_COM_I);
691 if (rc < 0) { 1127 if (rc < 0) {
@@ -698,9 +1134,6 @@ static int ov8xx0_configure(struct sd *sd)
698 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); 1134 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
699 return -1; 1135 return -1;
700 } 1136 }
701 PDEBUG(D_PROBE, "Writing 8610 registers");
702 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
703 return -1;
704 1137
705 /* Set sensor-specific vars */ 1138 /* Set sensor-specific vars */
706/* sd->sif = 0; already done */ 1139/* sd->sif = 0; already done */
@@ -714,252 +1147,6 @@ static int ov7xx0_configure(struct sd *sd)
714{ 1147{
715 int rc, high, low; 1148 int rc, high, low;
716 1149
717 /* Lawrence Glaister <lg@jfm.bc.ca> reports:
718 *
719 * Register 0x0f in the 7610 has the following effects:
720 *
721 * 0x85 (AEC method 1): Best overall, good contrast range
722 * 0x45 (AEC method 2): Very overexposed
723 * 0xa5 (spec sheet default): Ok, but the black level is
724 * shifted resulting in loss of contrast
725 * 0x05 (old driver setting): very overexposed, too much
726 * contrast
727 */
728 static const struct ov_i2c_regvals norm_7610[] = {
729 { 0x10, 0xff },
730 { 0x16, 0x06 },
731 { 0x28, 0x24 },
732 { 0x2b, 0xac },
733 { 0x12, 0x00 },
734 { 0x38, 0x81 },
735 { 0x28, 0x24 }, /* 0c */
736 { 0x0f, 0x85 }, /* lg's setting */
737 { 0x15, 0x01 },
738 { 0x20, 0x1c },
739 { 0x23, 0x2a },
740 { 0x24, 0x10 },
741 { 0x25, 0x8a },
742 { 0x26, 0xa2 },
743 { 0x27, 0xc2 },
744 { 0x2a, 0x04 },
745 { 0x2c, 0xfe },
746 { 0x2d, 0x93 },
747 { 0x30, 0x71 },
748 { 0x31, 0x60 },
749 { 0x32, 0x26 },
750 { 0x33, 0x20 },
751 { 0x34, 0x48 },
752 { 0x12, 0x24 },
753 { 0x11, 0x01 },
754 { 0x0c, 0x24 },
755 { 0x0d, 0x24 },
756 };
757
758 static const struct ov_i2c_regvals norm_7620[] = {
759 { 0x00, 0x00 }, /* gain */
760 { 0x01, 0x80 }, /* blue gain */
761 { 0x02, 0x80 }, /* red gain */
762 { 0x03, 0xc0 }, /* OV7670_REG_VREF */
763 { 0x06, 0x60 },
764 { 0x07, 0x00 },
765 { 0x0c, 0x24 },
766 { 0x0c, 0x24 },
767 { 0x0d, 0x24 },
768 { 0x11, 0x01 },
769 { 0x12, 0x24 },
770 { 0x13, 0x01 },
771 { 0x14, 0x84 },
772 { 0x15, 0x01 },
773 { 0x16, 0x03 },
774 { 0x17, 0x2f },
775 { 0x18, 0xcf },
776 { 0x19, 0x06 },
777 { 0x1a, 0xf5 },
778 { 0x1b, 0x00 },
779 { 0x20, 0x18 },
780 { 0x21, 0x80 },
781 { 0x22, 0x80 },
782 { 0x23, 0x00 },
783 { 0x26, 0xa2 },
784 { 0x27, 0xea },
785 { 0x28, 0x20 },
786 { 0x29, 0x00 },
787 { 0x2a, 0x10 },
788 { 0x2b, 0x00 },
789 { 0x2c, 0x88 },
790 { 0x2d, 0x91 },
791 { 0x2e, 0x80 },
792 { 0x2f, 0x44 },
793 { 0x60, 0x27 },
794 { 0x61, 0x02 },
795 { 0x62, 0x5f },
796 { 0x63, 0xd5 },
797 { 0x64, 0x57 },
798 { 0x65, 0x83 },
799 { 0x66, 0x55 },
800 { 0x67, 0x92 },
801 { 0x68, 0xcf },
802 { 0x69, 0x76 },
803 { 0x6a, 0x22 },
804 { 0x6b, 0x00 },
805 { 0x6c, 0x02 },
806 { 0x6d, 0x44 },
807 { 0x6e, 0x80 },
808 { 0x6f, 0x1d },
809 { 0x70, 0x8b },
810 { 0x71, 0x00 },
811 { 0x72, 0x14 },
812 { 0x73, 0x54 },
813 { 0x74, 0x00 },
814 { 0x75, 0x8e },
815 { 0x76, 0x00 },
816 { 0x77, 0xff },
817 { 0x78, 0x80 },
818 { 0x79, 0x80 },
819 { 0x7a, 0x80 },
820 { 0x7b, 0xe2 },
821 { 0x7c, 0x00 },
822 };
823
824 /* 7640 and 7648. The defaults should be OK for most registers. */
825 static const struct ov_i2c_regvals norm_7640[] = {
826 { 0x12, 0x80 },
827 { 0x12, 0x14 },
828 };
829
830 /* 7670. Defaults taken from OmniVision provided data,
831 * as provided by Jonathan Corbet of OLPC */
832 static const struct ov_i2c_regvals norm_7670[] = {
833 { OV7670_REG_COM7, OV7670_COM7_RESET },
834 { OV7670_REG_TSLB, 0x04 }, /* OV */
835 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
836 { OV7670_REG_CLKRC, 0x01 },
837 /*
838 * Set the hardware window. These values from OV don't entirely
839 * make sense - hstop is less than hstart. But they work...
840 */
841 { OV7670_REG_HSTART, 0x13 }, { OV7670_REG_HSTOP, 0x01 },
842 { OV7670_REG_HREF, 0xb6 }, { OV7670_REG_VSTART, 0x02 },
843 { OV7670_REG_VSTOP, 0x7a }, { OV7670_REG_VREF, 0x0a },
844
845 { OV7670_REG_COM3, 0 }, { OV7670_REG_COM14, 0 },
846 /* Mystery scaling numbers */
847 { 0x70, 0x3a }, { 0x71, 0x35 },
848 { 0x72, 0x11 }, { 0x73, 0xf0 },
849 { 0xa2, 0x02 },
850/* { OV7670_REG_COM10, 0x0 }, */
851
852 /* Gamma curve values */
853 { 0x7a, 0x20 },
854 { 0x7b, 0x10 },
855 { 0x7c, 0x1e },
856 { 0x7d, 0x35 },
857 { 0x7e, 0x5a }, { 0x7f, 0x69 },
858 { 0x80, 0x76 }, { 0x81, 0x80 },
859 { 0x82, 0x88 }, { 0x83, 0x8f },
860 { 0x84, 0x96 }, { 0x85, 0xa3 },
861 { 0x86, 0xaf }, { 0x87, 0xc4 },
862 { 0x88, 0xd7 }, { 0x89, 0xe8 },
863
864 /* AGC and AEC parameters. Note we start by disabling those features,
865 then turn them only after tweaking the values. */
866 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
867 | OV7670_COM8_AECSTEP
868 | OV7670_COM8_BFILT },
869 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 },
870 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
871 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
872 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 },
873 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 },
874 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 },
875 { OV7670_REG_HAECC2, 0x68 },
876 { 0xa1, 0x03 }, /* magic */
877 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 },
878 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 },
879 { OV7670_REG_HAECC7, 0x94 },
880 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
881 | OV7670_COM8_AECSTEP
882 | OV7670_COM8_BFILT
883 | OV7670_COM8_AGC
884 | OV7670_COM8_AEC },
885
886 /* Almost all of these are magic "reserved" values. */
887 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b },
888 { 0x16, 0x02 },
889 { OV7670_REG_MVFP, 0x07 },
890 { 0x21, 0x02 }, { 0x22, 0x91 },
891 { 0x29, 0x07 }, { 0x33, 0x0b },
892 { 0x35, 0x0b }, { 0x37, 0x1d },
893 { 0x38, 0x71 }, { 0x39, 0x2a },
894 { OV7670_REG_COM12, 0x78 }, { 0x4d, 0x40 },
895 { 0x4e, 0x20 }, { OV7670_REG_GFIX, 0 },
896 { 0x6b, 0x4a }, { 0x74, 0x10 },
897 { 0x8d, 0x4f }, { 0x8e, 0 },
898 { 0x8f, 0 }, { 0x90, 0 },
899 { 0x91, 0 }, { 0x96, 0 },
900 { 0x9a, 0 }, { 0xb0, 0x84 },
901 { 0xb1, 0x0c }, { 0xb2, 0x0e },
902 { 0xb3, 0x82 }, { 0xb8, 0x0a },
903
904 /* More reserved magic, some of which tweaks white balance */
905 { 0x43, 0x0a }, { 0x44, 0xf0 },
906 { 0x45, 0x34 }, { 0x46, 0x58 },
907 { 0x47, 0x28 }, { 0x48, 0x3a },
908 { 0x59, 0x88 }, { 0x5a, 0x88 },
909 { 0x5b, 0x44 }, { 0x5c, 0x67 },
910 { 0x5d, 0x49 }, { 0x5e, 0x0e },
911 { 0x6c, 0x0a }, { 0x6d, 0x55 },
912 { 0x6e, 0x11 }, { 0x6f, 0x9f },
913 /* "9e for advance AWB" */
914 { 0x6a, 0x40 }, { OV7670_REG_BLUE, 0x40 },
915 { OV7670_REG_RED, 0x60 },
916 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
917 | OV7670_COM8_AECSTEP
918 | OV7670_COM8_BFILT
919 | OV7670_COM8_AGC
920 | OV7670_COM8_AEC
921 | OV7670_COM8_AWB },
922
923 /* Matrix coefficients */
924 { 0x4f, 0x80 }, { 0x50, 0x80 },
925 { 0x51, 0 }, { 0x52, 0x22 },
926 { 0x53, 0x5e }, { 0x54, 0x80 },
927 { 0x58, 0x9e },
928
929 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
930 { OV7670_REG_EDGE, 0 },
931 { 0x75, 0x05 }, { 0x76, 0xe1 },
932 { 0x4c, 0 }, { 0x77, 0x01 },
933 { OV7670_REG_COM13, OV7670_COM13_GAMMA
934 | OV7670_COM13_UVSAT
935 | 2}, /* was 3 */
936 { 0x4b, 0x09 },
937 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
938 { 0x56, 0x40 },
939
940 { 0x34, 0x11 },
941 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
942 { 0xa4, 0x88 }, { 0x96, 0 },
943 { 0x97, 0x30 }, { 0x98, 0x20 },
944 { 0x99, 0x30 }, { 0x9a, 0x84 },
945 { 0x9b, 0x29 }, { 0x9c, 0x03 },
946 { 0x9d, 0x4c }, { 0x9e, 0x3f },
947 { 0x78, 0x04 },
948
949 /* Extra-weird stuff. Some sort of multiplexor register */
950 { 0x79, 0x01 }, { 0xc8, 0xf0 },
951 { 0x79, 0x0f }, { 0xc8, 0x00 },
952 { 0x79, 0x10 }, { 0xc8, 0x7e },
953 { 0x79, 0x0a }, { 0xc8, 0x80 },
954 { 0x79, 0x0b }, { 0xc8, 0x01 },
955 { 0x79, 0x0c }, { 0xc8, 0x0f },
956 { 0x79, 0x0d }, { 0xc8, 0x20 },
957 { 0x79, 0x09 }, { 0xc8, 0x80 },
958 { 0x79, 0x02 }, { 0xc8, 0xc0 },
959 { 0x79, 0x03 }, { 0xc8, 0x40 },
960 { 0x79, 0x05 }, { 0xc8, 0x30 },
961 { 0x79, 0x26 },
962 };
963 1150
964 PDEBUG(D_PROBE, "starting OV7xx0 configuration"); 1151 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
965 1152
@@ -1011,8 +1198,9 @@ static int ov7xx0_configure(struct sd *sd)
1011 switch (low) { 1198 switch (low) {
1012 case 0x30: 1199 case 0x30:
1013 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); 1200 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
1014 sd->sensor = SEN_OV7630; 1201 PDEBUG(D_ERR,
1015 break; 1202 "7630 is not supported by this driver");
1203 return -1;
1016 case 0x40: 1204 case 0x40:
1017 PDEBUG(D_PROBE, "Sensor is an OV7645"); 1205 PDEBUG(D_PROBE, "Sensor is an OV7645");
1018 sd->sensor = SEN_OV7640; /* FIXME */ 1206 sd->sensor = SEN_OV7640; /* FIXME */
@@ -1038,32 +1226,6 @@ static int ov7xx0_configure(struct sd *sd)
1038 return -1; 1226 return -1;
1039 } 1227 }
1040 1228
1041 switch (sd->sensor) {
1042 case SEN_OV7620:
1043 PDEBUG(D_PROBE, "Writing 7620 registers");
1044 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
1045 return -1;
1046 break;
1047 case SEN_OV7630:
1048 PDEBUG(D_ERR, "7630 is not supported by this driver version");
1049 return -1;
1050 case SEN_OV7640:
1051 PDEBUG(D_PROBE, "Writing 7640 registers");
1052 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
1053 return -1;
1054 break;
1055 case SEN_OV7670:
1056 PDEBUG(D_PROBE, "Writing 7670 registers");
1057 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
1058 return -1;
1059 break;
1060 default:
1061 PDEBUG(D_PROBE, "Writing 7610 registers");
1062 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
1063 return -1;
1064 break;
1065 }
1066
1067 /* Set sensor-specific vars */ 1229 /* Set sensor-specific vars */
1068/* sd->sif = 0; already done */ 1230/* sd->sif = 0; already done */
1069 return 0; 1231 return 0;
@@ -1073,141 +1235,7 @@ static int ov7xx0_configure(struct sd *sd)
1073static int ov6xx0_configure(struct sd *sd) 1235static int ov6xx0_configure(struct sd *sd)
1074{ 1236{
1075 int rc; 1237 int rc;
1076 static const struct ov_i2c_regvals norm_6x20[] = { 1238 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
1077 { 0x12, 0x80 }, /* reset */
1078 { 0x11, 0x01 },
1079 { 0x03, 0x60 },
1080 { 0x05, 0x7f }, /* For when autoadjust is off */
1081 { 0x07, 0xa8 },
1082 /* The ratio of 0x0c and 0x0d controls the white point */
1083 { 0x0c, 0x24 },
1084 { 0x0d, 0x24 },
1085 { 0x0f, 0x15 }, /* COMS */
1086 { 0x10, 0x75 }, /* AEC Exposure time */
1087 { 0x12, 0x24 }, /* Enable AGC */
1088 { 0x14, 0x04 },
1089 /* 0x16: 0x06 helps frame stability with moving objects */
1090 { 0x16, 0x06 },
1091/* { 0x20, 0x30 }, * Aperture correction enable */
1092 { 0x26, 0xb2 }, /* BLC enable */
1093 /* 0x28: 0x05 Selects RGB format if RGB on */
1094 { 0x28, 0x05 },
1095 { 0x2a, 0x04 }, /* Disable framerate adjust */
1096/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
1097 { 0x2d, 0x99 },
1098 { 0x33, 0xa0 }, /* Color Processing Parameter */
1099 { 0x34, 0xd2 }, /* Max A/D range */
1100 { 0x38, 0x8b },
1101 { 0x39, 0x40 },
1102
1103 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1104 { 0x3c, 0x3c }, /* Change AEC mode */
1105 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1106
1107 { 0x3d, 0x80 },
1108 /* These next two registers (0x4a, 0x4b) are undocumented.
1109 * They control the color balance */
1110 { 0x4a, 0x80 },
1111 { 0x4b, 0x80 },
1112 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1113 { 0x4e, 0xc1 },
1114 { 0x4f, 0x04 },
1115/* Do 50-53 have any effect? */
1116/* Toggle 0x12[2] off and on here? */
1117 };
1118
1119 static const struct ov_i2c_regvals norm_6x30[] = {
1120 { 0x12, 0x80 }, /* Reset */
1121 { 0x00, 0x1f }, /* Gain */
1122 { 0x01, 0x99 }, /* Blue gain */
1123 { 0x02, 0x7c }, /* Red gain */
1124 { 0x03, 0xc0 }, /* Saturation */
1125 { 0x05, 0x0a }, /* Contrast */
1126 { 0x06, 0x95 }, /* Brightness */
1127 { 0x07, 0x2d }, /* Sharpness */
1128 { 0x0c, 0x20 },
1129 { 0x0d, 0x20 },
1130 { 0x0e, 0x20 },
1131 { 0x0f, 0x05 },
1132 { 0x10, 0x9a },
1133 { 0x11, 0x00 }, /* Pixel clock = fastest */
1134 { 0x12, 0x24 }, /* Enable AGC and AWB */
1135 { 0x13, 0x21 },
1136 { 0x14, 0x80 },
1137 { 0x15, 0x01 },
1138 { 0x16, 0x03 },
1139 { 0x17, 0x38 },
1140 { 0x18, 0xea },
1141 { 0x19, 0x04 },
1142 { 0x1a, 0x93 },
1143 { 0x1b, 0x00 },
1144 { 0x1e, 0xc4 },
1145 { 0x1f, 0x04 },
1146 { 0x20, 0x20 },
1147 { 0x21, 0x10 },
1148 { 0x22, 0x88 },
1149 { 0x23, 0xc0 }, /* Crystal circuit power level */
1150 { 0x25, 0x9a }, /* Increase AEC black ratio */
1151 { 0x26, 0xb2 }, /* BLC enable */
1152 { 0x27, 0xa2 },
1153 { 0x28, 0x00 },
1154 { 0x29, 0x00 },
1155 { 0x2a, 0x84 }, /* 60 Hz power */
1156 { 0x2b, 0xa8 }, /* 60 Hz power */
1157 { 0x2c, 0xa0 },
1158 { 0x2d, 0x95 }, /* Enable auto-brightness */
1159 { 0x2e, 0x88 },
1160 { 0x33, 0x26 },
1161 { 0x34, 0x03 },
1162 { 0x36, 0x8f },
1163 { 0x37, 0x80 },
1164 { 0x38, 0x83 },
1165 { 0x39, 0x80 },
1166 { 0x3a, 0x0f },
1167 { 0x3b, 0x3c },
1168 { 0x3c, 0x1a },
1169 { 0x3d, 0x80 },
1170 { 0x3e, 0x80 },
1171 { 0x3f, 0x0e },
1172 { 0x40, 0x00 }, /* White bal */
1173 { 0x41, 0x00 }, /* White bal */
1174 { 0x42, 0x80 },
1175 { 0x43, 0x3f }, /* White bal */
1176 { 0x44, 0x80 },
1177 { 0x45, 0x20 },
1178 { 0x46, 0x20 },
1179 { 0x47, 0x80 },
1180 { 0x48, 0x7f },
1181 { 0x49, 0x00 },
1182 { 0x4a, 0x00 },
1183 { 0x4b, 0x80 },
1184 { 0x4c, 0xd0 },
1185 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1186 { 0x4e, 0x40 },
1187 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1188 { 0x50, 0xff },
1189 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1190 { 0x55, 0xff },
1191 { 0x56, 0x12 },
1192 { 0x57, 0x81 },
1193 { 0x58, 0x75 },
1194 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1195 { 0x5a, 0x2c },
1196 { 0x5b, 0x0f }, /* AWB chrominance levels */
1197 { 0x5c, 0x10 },
1198 { 0x3d, 0x80 },
1199 { 0x27, 0xa6 },
1200 { 0x12, 0x20 }, /* Toggle AWB */
1201 { 0x12, 0x24 },
1202 };
1203
1204 PDEBUG(D_PROBE, "starting sensor configuration");
1205
1206 if (init_ov_sensor(sd) < 0) {
1207 PDEBUG(D_ERR, "Failed to read sensor ID.");
1208 return -1;
1209 }
1210 PDEBUG(D_PROBE, "OV6xx0 sensor detected");
1211 1239
1212 /* Detect sensor (sub)type */ 1240 /* Detect sensor (sub)type */
1213 rc = i2c_r(sd, OV7610_REG_COM_I); 1241 rc = i2c_r(sd, OV7610_REG_COM_I);
@@ -1251,15 +1279,6 @@ static int ov6xx0_configure(struct sd *sd)
1251 /* Set sensor-specific vars */ 1279 /* Set sensor-specific vars */
1252 sd->sif = 1; 1280 sd->sif = 1;
1253 1281
1254 if (sd->sensor == SEN_OV6620) {
1255 PDEBUG(D_PROBE, "Writing 6x20 registers");
1256 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
1257 return -1;
1258 } else {
1259 PDEBUG(D_PROBE, "Writing 6x30 registers");
1260 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
1261 return -1;
1262 }
1263 return 0; 1282 return 0;
1264} 1283}
1265 1284
@@ -1298,22 +1317,31 @@ static int sd_config(struct gspca_dev *gspca_dev,
1298 ov51x_led_control(sd, 0); /* turn LED off */ 1317 ov51x_led_control(sd, 0); /* turn LED off */
1299 1318
1300 /* Test for 76xx */ 1319 /* Test for 76xx */
1301 sd->primary_i2c_slave = OV7xx0_SID;
1302 if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0) 1320 if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
1303 goto error; 1321 goto error;
1304 1322
1305 /* The OV519 must be more aggressive about sensor detection since 1323 /* The OV519 must be more aggressive about sensor detection since
1306 * I2C write will never fail if the sensor is not present. We have 1324 * I2C write will never fail if the sensor is not present. We have
1307 * to try to initialize the sensor to detect its presence */ 1325 * to try to initialize the sensor to detect its presence */
1308 if (init_ov_sensor(sd) < 0) { 1326 if (init_ov_sensor(sd) >= 0) {
1327 if (ov7xx0_configure(sd) < 0) {
1328 PDEBUG(D_ERR, "Failed to configure OV7xx0");
1329 goto error;
1330 }
1331 } else {
1332
1309 /* Test for 6xx0 */ 1333 /* Test for 6xx0 */
1310 sd->primary_i2c_slave = OV6xx0_SID;
1311 if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) 1334 if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0)
1312 goto error; 1335 goto error;
1313 1336
1314 if (init_ov_sensor(sd) < 0) { 1337 if (init_ov_sensor(sd) >= 0) {
1338 if (ov6xx0_configure(sd) < 0) {
1339 PDEBUG(D_ERR, "Failed to configure OV6xx0");
1340 goto error;
1341 }
1342 } else {
1343
1315 /* Test for 8xx0 */ 1344 /* Test for 8xx0 */
1316 sd->primary_i2c_slave = OV8xx0_SID;
1317 if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0) 1345 if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
1318 goto error; 1346 goto error;
1319 1347
@@ -1321,24 +1349,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
1321 PDEBUG(D_ERR, 1349 PDEBUG(D_ERR,
1322 "Can't determine sensor slave IDs"); 1350 "Can't determine sensor slave IDs");
1323 goto error; 1351 goto error;
1324 } else {
1325 if (ov8xx0_configure(sd) < 0) {
1326 PDEBUG(D_ERR,
1327 "Failed to configure OV8xx0 sensor");
1328 goto error;
1329 }
1330 } 1352 }
1331 } else { 1353 if (ov8xx0_configure(sd) < 0) {
1332 if (ov6xx0_configure(sd) < 0) { 1354 PDEBUG(D_ERR,
1333 PDEBUG(D_ERR, "Failed to configure OV6xx0"); 1355 "Failed to configure OV8xx0 sensor");
1334 goto error; 1356 goto error;
1335 } 1357 }
1336 } 1358 }
1337 } else {
1338 if (ov7xx0_configure(sd) < 0) {
1339 PDEBUG(D_ERR, "Failed to configure OV7xx0");
1340 goto error;
1341 }
1342 } 1359 }
1343 1360
1344 cam = &gspca_dev->cam; 1361 cam = &gspca_dev->cam;
@@ -1355,15 +1372,53 @@ static int sd_config(struct gspca_dev *gspca_dev,
1355 sd->colors = COLOR_DEF; 1372 sd->colors = COLOR_DEF;
1356 sd->hflip = HFLIP_DEF; 1373 sd->hflip = HFLIP_DEF;
1357 sd->vflip = VFLIP_DEF; 1374 sd->vflip = VFLIP_DEF;
1375 if (sd->sensor != SEN_OV7670)
1376 gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
1377 | (1 << VFLIP_IDX);
1358 return 0; 1378 return 0;
1359error: 1379error:
1360 PDEBUG(D_ERR, "OV519 Config failed"); 1380 PDEBUG(D_ERR, "OV519 Config failed");
1361 return -EBUSY; 1381 return -EBUSY;
1362} 1382}
1363 1383
1364/* this function is called at open time */ 1384/* this function is called at probe and resume time */
1365static int sd_open(struct gspca_dev *gspca_dev) 1385static int sd_init(struct gspca_dev *gspca_dev)
1366{ 1386{
1387 struct sd *sd = (struct sd *) gspca_dev;
1388
1389 /* initialize the sensor */
1390 switch (sd->sensor) {
1391 case SEN_OV6620:
1392 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
1393 return -EIO;
1394 break;
1395 case SEN_OV6630:
1396 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
1397 return -EIO;
1398 break;
1399 default:
1400/* case SEN_OV7610: */
1401/* case SEN_OV76BE: */
1402 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
1403 return -EIO;
1404 break;
1405 case SEN_OV7620:
1406 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
1407 return -EIO;
1408 break;
1409 case SEN_OV7640:
1410 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
1411 return -EIO;
1412 break;
1413 case SEN_OV7670:
1414 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
1415 return -EIO;
1416 break;
1417 case SEN_OV8610:
1418 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
1419 return -EIO;
1420 break;
1421 }
1367 return 0; 1422 return 0;
1368} 1423}
1369 1424
@@ -1827,14 +1882,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1827 ov51x_led_control((struct sd *) gspca_dev, 0); 1882 ov51x_led_control((struct sd *) gspca_dev, 0);
1828} 1883}
1829 1884
1830static void sd_stop0(struct gspca_dev *gspca_dev)
1831{
1832}
1833
1834static void sd_close(struct gspca_dev *gspca_dev)
1835{
1836}
1837
1838static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1885static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1839 struct gspca_frame *frame, /* target */ 1886 struct gspca_frame *frame, /* target */
1840 __u8 *data, /* isoc packet */ 1887 __u8 *data, /* isoc packet */
@@ -2091,11 +2138,9 @@ static const struct sd_desc sd_desc = {
2091 .ctrls = sd_ctrls, 2138 .ctrls = sd_ctrls,
2092 .nctrls = ARRAY_SIZE(sd_ctrls), 2139 .nctrls = ARRAY_SIZE(sd_ctrls),
2093 .config = sd_config, 2140 .config = sd_config,
2094 .open = sd_open, 2141 .init = sd_init,
2095 .start = sd_start, 2142 .start = sd_start,
2096 .stopN = sd_stopN, 2143 .stopN = sd_stopN,
2097 .stop0 = sd_stop0,
2098 .close = sd_close,
2099 .pkt_scan = sd_pkt_scan, 2144 .pkt_scan = sd_pkt_scan,
2100}; 2145};
2101 2146
@@ -2132,6 +2177,10 @@ static struct usb_driver sd_driver = {
2132 .id_table = device_table, 2177 .id_table = device_table,
2133 .probe = sd_probe, 2178 .probe = sd_probe,
2134 .disconnect = gspca_disconnect, 2179 .disconnect = gspca_disconnect,
2180#ifdef CONFIG_PM
2181 .suspend = gspca_suspend,
2182 .resume = gspca_resume,
2183#endif
2135}; 2184};
2136 2185
2137/* -- module insert / remove -- */ 2186/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 7ef18d578811..83b5f740c947 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -56,12 +56,6 @@ MODULE_LICENSE("GPL");
56#define PAC207_GAIN_KNEE 20 56#define PAC207_GAIN_KNEE 20
57 57
58#define PAC207_AUTOGAIN_DEADZONE 30 58#define PAC207_AUTOGAIN_DEADZONE 30
59/* We calculating the autogain at the end of the transfer of a frame, at this
60 moment a frame with the old settings is being transmitted, and a frame is
61 being captured with the old settings. So if we adjust the autogain we must
62 ignore atleast the 2 next frames for the new settings to come into effect
63 before doing any other adjustments */
64#define PAC207_AUTOGAIN_IGNORE_FRAMES 3
65 59
66/* specific webcam descriptor */ 60/* specific webcam descriptor */
67struct sd { 61struct sd {
@@ -131,7 +125,8 @@ static struct ctrl sd_ctrls[] = {
131 .minimum = 0, 125 .minimum = 0,
132 .maximum = 1, 126 .maximum = 1,
133 .step = 1, 127 .step = 1,
134 .default_value = 1, 128#define AUTOGAIN_DEF 1
129 .default_value = AUTOGAIN_DEF,
135 .flags = 0, 130 .flags = 0,
136 }, 131 },
137 .set = sd_setautogain, 132 .set = sd_setautogain,
@@ -181,9 +176,6 @@ static const __u8 pac207_sensor_init[][8] = {
181 /* 48 reg_72 Rate Control end BalSize_4a =0x36 */ 176 /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
182static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; 177static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
183 178
184static const unsigned char pac207_sof_marker[5] =
185 { 0xff, 0xff, 0x00, 0xff, 0x96 };
186
187static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, 179static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
188 const u8 *buffer, u16 length) 180 const u8 *buffer, u16 length)
189{ 181{
@@ -259,35 +251,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
259 return -ENODEV; 251 return -ENODEV;
260 } 252 }
261 253
262 pac207_write_reg(gspca_dev, 0x41, 0x00);
263 /* Bit_0=Image Format,
264 * Bit_1=LED,
265 * Bit_2=Compression test mode enable */
266 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
267 pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
268
269 PDEBUG(D_PROBE, 254 PDEBUG(D_PROBE,
270 "Pixart PAC207BCA Image Processor and Control Chip detected" 255 "Pixart PAC207BCA Image Processor and Control Chip detected"
271 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); 256 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
272 257
273 cam = &gspca_dev->cam; 258 cam = &gspca_dev->cam;
274 cam->dev_name = (char *) id->driver_info;
275 cam->epaddr = 0x05; 259 cam->epaddr = 0x05;
276 cam->cam_mode = sif_mode; 260 cam->cam_mode = sif_mode;
277 cam->nmodes = ARRAY_SIZE(sif_mode); 261 cam->nmodes = ARRAY_SIZE(sif_mode);
278 sd->brightness = PAC207_BRIGHTNESS_DEFAULT; 262 sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
279 sd->exposure = PAC207_EXPOSURE_DEFAULT; 263 sd->exposure = PAC207_EXPOSURE_DEFAULT;
280 sd->gain = PAC207_GAIN_DEFAULT; 264 sd->gain = PAC207_GAIN_DEFAULT;
265 sd->autogain = AUTOGAIN_DEF;
281 266
282 return 0; 267 return 0;
283} 268}
284 269
285/* this function is called at open time */ 270/* this function is called at probe and resume time */
286static int sd_open(struct gspca_dev *gspca_dev) 271static int sd_init(struct gspca_dev *gspca_dev)
287{ 272{
288 struct sd *sd = (struct sd *) gspca_dev; 273 pac207_write_reg(gspca_dev, 0x41, 0x00);
274 /* Bit_0=Image Format,
275 * Bit_1=LED,
276 * Bit_2=Compression test mode enable */
277 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
278 pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
289 279
290 sd->autogain = 1;
291 return 0; 280 return 0;
292} 281}
293 282
@@ -343,14 +332,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
343 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ 332 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
344} 333}
345 334
346static void sd_stop0(struct gspca_dev *gspca_dev) 335/* Include pac common sof detection functions */
347{ 336#include "pac_common.h"
348}
349
350/* this function is called at close time */
351static void sd_close(struct gspca_dev *gspca_dev)
352{
353}
354 337
355static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) 338static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
356{ 339{
@@ -365,33 +348,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
365 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 348 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
366 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE, 349 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
367 PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) 350 PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
368 sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; 351 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
369}
370
371static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
372 unsigned char *m, int len)
373{
374 struct sd *sd = (struct sd *) gspca_dev;
375 int i;
376
377 /* Search for the SOF marker (fixed part) in the header */
378 for (i = 0; i < len; i++) {
379 if (m[i] == pac207_sof_marker[sd->sof_read]) {
380 sd->sof_read++;
381 if (sd->sof_read == sizeof(pac207_sof_marker)) {
382 PDEBUG(D_STREAM,
383 "SOF found, bytes to analyze: %u."
384 " Frame starts at byte #%u",
385 len, i + 1);
386 sd->sof_read = 0;
387 return m + i + 1;
388 }
389 } else {
390 sd->sof_read = 0;
391 }
392 }
393
394 return NULL;
395} 352}
396 353
397static void sd_pkt_scan(struct gspca_dev *gspca_dev, 354static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -402,14 +359,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
402 struct sd *sd = (struct sd *) gspca_dev; 359 struct sd *sd = (struct sd *) gspca_dev;
403 unsigned char *sof; 360 unsigned char *sof;
404 361
405 sof = pac207_find_sof(gspca_dev, data, len); 362 sof = pac_find_sof(gspca_dev, data, len);
406 if (sof) { 363 if (sof) {
407 int n; 364 int n;
408 365
409 /* finish decoding current frame */ 366 /* finish decoding current frame */
410 n = sof - data; 367 n = sof - data;
411 if (n > sizeof pac207_sof_marker) 368 if (n > sizeof pac_sof_marker)
412 n -= sizeof pac207_sof_marker; 369 n -= sizeof pac_sof_marker;
413 else 370 else
414 n = 0; 371 n = 0;
415 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 372 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -537,7 +494,7 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
537 sd->gain = PAC207_GAIN_DEFAULT; 494 sd->gain = PAC207_GAIN_DEFAULT;
538 if (gspca_dev->streaming) { 495 if (gspca_dev->streaming) {
539 sd->autogain_ignore_frames = 496 sd->autogain_ignore_frames =
540 PAC207_AUTOGAIN_IGNORE_FRAMES; 497 PAC_AUTOGAIN_IGNORE_FRAMES;
541 setexposure(gspca_dev); 498 setexposure(gspca_dev);
542 setgain(gspca_dev); 499 setgain(gspca_dev);
543 } 500 }
@@ -560,11 +517,9 @@ static const struct sd_desc sd_desc = {
560 .ctrls = sd_ctrls, 517 .ctrls = sd_ctrls,
561 .nctrls = ARRAY_SIZE(sd_ctrls), 518 .nctrls = ARRAY_SIZE(sd_ctrls),
562 .config = sd_config, 519 .config = sd_config,
563 .open = sd_open, 520 .init = sd_init,
564 .start = sd_start, 521 .start = sd_start,
565 .stopN = sd_stopN, 522 .stopN = sd_stopN,
566 .stop0 = sd_stop0,
567 .close = sd_close,
568 .dq_callback = pac207_do_auto_gain, 523 .dq_callback = pac207_do_auto_gain,
569 .pkt_scan = sd_pkt_scan, 524 .pkt_scan = sd_pkt_scan,
570}; 525};
@@ -597,6 +552,10 @@ static struct usb_driver sd_driver = {
597 .id_table = device_table, 552 .id_table = device_table,
598 .probe = sd_probe, 553 .probe = sd_probe,
599 .disconnect = gspca_disconnect, 554 .disconnect = gspca_disconnect,
555#ifdef CONFIG_PM
556 .suspend = gspca_suspend,
557 .resume = gspca_resume,
558#endif
600}; 559};
601 560
602/* -- module insert / remove -- */ 561/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 815bea6edc44..d4be51843286 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -19,6 +19,36 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22/* Some documentation about various registers as determined by trial and error.
23 When the register addresses differ between the 7202 and the 7311 the 2
24 different addresses are written as 7302addr/7311addr, when one of the 2
25 addresses is a - sign that register description is not valid for the
26 matching IC.
27
28 Register page 1:
29
30 Address Description
31 -/0x08 Unknown compressor related, must always be 8 except when not
32 in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
33 -/0x1b Auto white balance related, bit 0 is AWB enable (inverted)
34 bits 345 seem to toggle per color gains on/off (inverted)
35 0x78 Global control, bit 6 controls the LED (inverted)
36 -/0x80 JPEG compression ratio ? Best not touched
37
38 Register page 3/4:
39
40 Address Description
41 0x02 Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
42 the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
43 -/0x0f Master gain 1-245, low value = high gain
44 0x10/- Master gain 0-31
45 -/0x10 Another gain 0-15, limited influence (1-2x gain I guess)
46 0x21 Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47 -/0x27 Seems to toggle various gains on / off, Setting bit 7 seems to
48 completely disable the analog amplification block. Set to 0x68
49 for max gain, 0x14 for minimal gain.
50*/
51
22#define MODULE_NAME "pac7311" 52#define MODULE_NAME "pac7311"
23 53
24#include "gspca.h" 54#include "gspca.h"
@@ -31,18 +61,23 @@ MODULE_LICENSE("GPL");
31struct sd { 61struct sd {
32 struct gspca_dev gspca_dev; /* !! must be the first item */ 62 struct gspca_dev gspca_dev; /* !! must be the first item */
33 63
34 int lum_sum;
35 atomic_t avg_lum;
36 atomic_t do_gain;
37
38 unsigned char brightness; 64 unsigned char brightness;
39 unsigned char contrast; 65 unsigned char contrast;
40 unsigned char colors; 66 unsigned char colors;
67 unsigned char gain;
68 unsigned char exposure;
41 unsigned char autogain; 69 unsigned char autogain;
70 __u8 hflip;
71 __u8 vflip;
72
73 __u8 sensor;
74#define SENSOR_PAC7302 0
75#define SENSOR_PAC7311 1
42 76
43 char ffseq; 77 u8 sof_read;
44 signed char ag_cnt; 78 u8 autogain_ignore_frames;
45#define AG_CNT_START 13 79
80 atomic_t avg_lum;
46}; 81};
47 82
48/* V4L2 controls supported by the driver */ 83/* V4L2 controls supported by the driver */
@@ -54,8 +89,18 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 89static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
55static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 90static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
56static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 91static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
98static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
57 100
58static struct ctrl sd_ctrls[] = { 101static struct ctrl sd_ctrls[] = {
102/* This control is pac7302 only */
103#define BRIGHTNESS_IDX 0
59 { 104 {
60 { 105 {
61 .id = V4L2_CID_BRIGHTNESS, 106 .id = V4L2_CID_BRIGHTNESS,
@@ -71,13 +116,15 @@ static struct ctrl sd_ctrls[] = {
71 .set = sd_setbrightness, 116 .set = sd_setbrightness,
72 .get = sd_getbrightness, 117 .get = sd_getbrightness,
73 }, 118 },
119/* This control is for both the 7302 and the 7311 */
74 { 120 {
75 { 121 {
76 .id = V4L2_CID_CONTRAST, 122 .id = V4L2_CID_CONTRAST,
77 .type = V4L2_CTRL_TYPE_INTEGER, 123 .type = V4L2_CTRL_TYPE_INTEGER,
78 .name = "Contrast", 124 .name = "Contrast",
79 .minimum = 0, 125 .minimum = 0,
80 .maximum = 255, 126#define CONTRAST_MAX 255
127 .maximum = CONTRAST_MAX,
81 .step = 1, 128 .step = 1,
82#define CONTRAST_DEF 127 129#define CONTRAST_DEF 127
83 .default_value = CONTRAST_DEF, 130 .default_value = CONTRAST_DEF,
@@ -85,13 +132,16 @@ static struct ctrl sd_ctrls[] = {
85 .set = sd_setcontrast, 132 .set = sd_setcontrast,
86 .get = sd_getcontrast, 133 .get = sd_getcontrast,
87 }, 134 },
135/* This control is pac7302 only */
136#define SATURATION_IDX 2
88 { 137 {
89 { 138 {
90 .id = V4L2_CID_SATURATION, 139 .id = V4L2_CID_SATURATION,
91 .type = V4L2_CTRL_TYPE_INTEGER, 140 .type = V4L2_CTRL_TYPE_INTEGER,
92 .name = "Color", 141 .name = "Saturation",
93 .minimum = 0, 142 .minimum = 0,
94 .maximum = 255, 143#define COLOR_MAX 255
144 .maximum = COLOR_MAX,
95 .step = 1, 145 .step = 1,
96#define COLOR_DEF 127 146#define COLOR_DEF 127
97 .default_value = COLOR_DEF, 147 .default_value = COLOR_DEF,
@@ -99,6 +149,39 @@ static struct ctrl sd_ctrls[] = {
99 .set = sd_setcolors, 149 .set = sd_setcolors,
100 .get = sd_getcolors, 150 .get = sd_getcolors,
101 }, 151 },
152/* All controls below are for both the 7302 and the 7311 */
153 {
154 {
155 .id = V4L2_CID_GAIN,
156 .type = V4L2_CTRL_TYPE_INTEGER,
157 .name = "Gain",
158 .minimum = 0,
159#define GAIN_MAX 255
160 .maximum = GAIN_MAX,
161 .step = 1,
162#define GAIN_DEF 127
163#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
164 .default_value = GAIN_DEF,
165 },
166 .set = sd_setgain,
167 .get = sd_getgain,
168 },
169 {
170 {
171 .id = V4L2_CID_EXPOSURE,
172 .type = V4L2_CTRL_TYPE_INTEGER,
173 .name = "Exposure",
174 .minimum = 0,
175#define EXPOSURE_MAX 255
176 .maximum = EXPOSURE_MAX,
177 .step = 1,
178#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
179#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
180 .default_value = EXPOSURE_DEF,
181 },
182 .set = sd_setexposure,
183 .get = sd_getexposure,
184 },
102 { 185 {
103 { 186 {
104 .id = V4L2_CID_AUTOGAIN, 187 .id = V4L2_CID_AUTOGAIN,
@@ -113,101 +196,207 @@ static struct ctrl sd_ctrls[] = {
113 .set = sd_setautogain, 196 .set = sd_setautogain,
114 .get = sd_getautogain, 197 .get = sd_getautogain,
115 }, 198 },
199 {
200 {
201 .id = V4L2_CID_HFLIP,
202 .type = V4L2_CTRL_TYPE_BOOLEAN,
203 .name = "Mirror",
204 .minimum = 0,
205 .maximum = 1,
206 .step = 1,
207#define HFLIP_DEF 0
208 .default_value = HFLIP_DEF,
209 },
210 .set = sd_sethflip,
211 .get = sd_gethflip,
212 },
213 {
214 {
215 .id = V4L2_CID_VFLIP,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
217 .name = "Vflip",
218 .minimum = 0,
219 .maximum = 1,
220 .step = 1,
221#define VFLIP_DEF 0
222 .default_value = VFLIP_DEF,
223 },
224 .set = sd_setvflip,
225 .get = sd_getvflip,
226 },
116}; 227};
117 228
118static struct v4l2_pix_format vga_mode[] = { 229static struct v4l2_pix_format vga_mode[] = {
119 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 230 {160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
120 .bytesperline = 160, 231 .bytesperline = 160,
121 .sizeimage = 160 * 120 * 3 / 8 + 590, 232 .sizeimage = 160 * 120 * 3 / 8 + 590,
122 .colorspace = V4L2_COLORSPACE_JPEG, 233 .colorspace = V4L2_COLORSPACE_JPEG,
123 .priv = 2}, 234 .priv = 2},
124 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 235 {320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
125 .bytesperline = 320, 236 .bytesperline = 320,
126 .sizeimage = 320 * 240 * 3 / 8 + 590, 237 .sizeimage = 320 * 240 * 3 / 8 + 590,
127 .colorspace = V4L2_COLORSPACE_JPEG, 238 .colorspace = V4L2_COLORSPACE_JPEG,
128 .priv = 1}, 239 .priv = 1},
129 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 240 {640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
130 .bytesperline = 640, 241 .bytesperline = 640,
131 .sizeimage = 640 * 480 * 3 / 8 + 590, 242 .sizeimage = 640 * 480 * 3 / 8 + 590,
132 .colorspace = V4L2_COLORSPACE_JPEG, 243 .colorspace = V4L2_COLORSPACE_JPEG,
133 .priv = 0}, 244 .priv = 0},
134}; 245};
135 246
136#define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ 247/* pac 7302 */
137 248static const __u8 init_7302[] = {
138static const __u8 pac7311_jpeg_header[] = { 249/* index,value */
139 0xff, 0xd8, 250 0xff, 0x01, /* page 1 */
140 0xff, 0xe0, 0x00, 0x03, 0x20, 251 0x78, 0x00, /* deactivate */
141 0xff, 0xc0, 0x00, 0x11, 0x08, 252 0xff, 0x01,
142 0x01, 0xe0, /* 12: height */ 253 0x78, 0x40, /* led off */
143 0x02, 0x80, /* 14: width */ 254};
144 0x03, /* 16 */ 255static const __u8 start_7302[] = {
145 0x01, 0x21, 0x00, 256/* index, len, [value]* */
146 0x02, 0x11, 0x01, 257 0xff, 1, 0x00, /* page 0 */
147 0x03, 0x11, 0x01, 258 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
148 0xff, 0xdb, 0x00, 0x84, 259 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, 260 0x0d, 24, 0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
150 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, 261 0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
151 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 262 0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
152 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 263 0x26, 2, 0xaa, 0xaa,
153 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f, 264 0x2e, 1, 0x31,
154 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64, 265 0x38, 1, 0x01,
155 0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18, 266 0x3a, 3, 0x14, 0xff, 0x5a,
156 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 267 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
157 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 268 0x00, 0x54, 0x11,
158 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 269 0x55, 1, 0x00,
159 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 270 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
160 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 271 0x6b, 1, 0x00,
161 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 272 0x6e, 3, 0x08, 0x06, 0x00,
162 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 273 0x72, 3, 0x00, 0xff, 0x00,
163 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 274 0x7d, 23, 0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
164 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 275 0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
165 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 276 0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
166 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 277 0xa2, 10, 0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
167 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 278 0xd2, 0xeb,
168 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 279 0xaf, 1, 0x02,
169 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 280 0xb5, 2, 0x08, 0x08,
170 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 281 0xb8, 2, 0x08, 0x88,
171 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 282 0xc4, 4, 0xae, 0x01, 0x04, 0x01,
172 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 283 0xcc, 1, 0x00,
173 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 284 0xd1, 11, 0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
174 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 285 0xc1, 0xd7, 0xec,
175 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 286 0xdc, 1, 0x01,
176 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 287 0xff, 1, 0x01, /* page 1 */
177 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 288 0x12, 3, 0x02, 0x00, 0x01,
178 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 289 0x3e, 2, 0x00, 0x00,
179 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 290 0x76, 5, 0x01, 0x20, 0x40, 0x00, 0xf2,
180 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 291 0x7c, 1, 0x00,
181 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 292 0x7f, 10, 0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
182 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 293 0x02, 0x00,
183 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 294 0x96, 5, 0x01, 0x10, 0x04, 0x01, 0x04,
184 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 295 0xc8, 14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
185 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 296 0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
186 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 297 0xd8, 1, 0x01,
187 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 298 0xdb, 2, 0x00, 0x01,
188 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 299 0xde, 7, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
189 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 300 0xe6, 4, 0x00, 0x00, 0x00, 0x01,
190 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 301 0xeb, 1, 0x00,
191 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 302 0xff, 1, 0x02, /* page 2 */
192 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 303 0x22, 1, 0x00,
193 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 304 0xff, 1, 0x03, /* page 3 */
194 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 305 0x00, 255, /* load the page 3 */
195 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 306 0x11, 1, 0x01,
196 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 307 0xff, 1, 0x02, /* page 2 */
197 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 308 0x13, 1, 0x00,
198 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 309 0x22, 4, 0x1f, 0xa4, 0xf0, 0x96,
199 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 310 0x27, 2, 0x14, 0x0c,
200 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 311 0x2a, 5, 0xc8, 0x00, 0x18, 0x12, 0x22,
201 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 312 0x64, 8, 0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
202 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 313 0x6e, 1, 0x08,
203 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 314 0xff, 1, 0x01, /* page 1 */
204 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 315 0x78, 1, 0x00,
205 0x11, 0x00, 0x3f, 0x00 316 0, 0 /* end of sequence */
317};
318
319/* page 3 - the value 0xaa says skip the index - see reg_w_page() */
320static const __u8 page3_7302[] = {
321 0x90, 0x40, 0x03, 0x50, 0xc2, 0x01, 0x14, 0x16,
322 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
323 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
325 0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
326 0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
327 0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
328 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
331 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
335 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
336 0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
337 0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
340 0x00
341};
342
343/* pac 7311 */
344static const __u8 init_7311[] = {
345 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
346 0x78, 0x40, /* Bit_0=start stream, Bit_6=LED */
347 0x78, 0x44, /* Bit_0=start stream, Bit_6=LED */
348 0xff, 0x04,
349 0x27, 0x80,
350 0x28, 0xca,
351 0x29, 0x53,
352 0x2a, 0x0e,
353 0xff, 0x01,
354 0x3e, 0x20,
355};
356
357static const __u8 start_7311[] = {
358/* index, len, [value]* */
359 0xff, 1, 0x01, /* page 1 */
360 0x02, 43, 0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
361 0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
362 0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
363 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00,
366 0x3e, 42, 0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
367 0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
368 0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
369 0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
370 0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
371 0xd0, 0xff,
372 0x78, 6, 0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
373 0x7f, 18, 0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
374 0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
375 0x18, 0x20,
376 0x96, 3, 0x01, 0x08, 0x04,
377 0xa0, 4, 0x44, 0x44, 0x44, 0x04,
378 0xf0, 13, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
379 0x3f, 0x00, 0x0a, 0x01, 0x00,
380 0xff, 1, 0x04, /* page 4 */
381 0x00, 254, /* load the page 4 */
382 0x11, 1, 0x01,
383 0, 0 /* end of sequence */
384};
385
386/* page 4 - the value 0xaa says skip the index - see reg_w_page() */
387static const __u8 page4_7311[] = {
388 0xaa, 0xaa, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
389 0x09, 0x00, 0xaa, 0xaa, 0x07, 0x00, 0x00, 0x62,
390 0x08, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, 0xaa,
392 0xaa, 0x00, 0x08, 0xaa, 0x03, 0xaa, 0x00, 0x68,
393 0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
394 0x23, 0x28, 0x04, 0x11, 0x00, 0x00
206}; 395};
207 396
208static void reg_w_buf(struct gspca_dev *gspca_dev, 397static void reg_w_buf(struct gspca_dev *gspca_dev,
209 __u16 index, 398 __u8 index,
210 const char *buffer, __u16 len) 399 const char *buffer, int len)
211{ 400{
212 memcpy(gspca_dev->usb_buf, buffer, len); 401 memcpy(gspca_dev->usb_buf, buffer, len);
213 usb_control_msg(gspca_dev->dev, 402 usb_control_msg(gspca_dev->dev,
@@ -219,21 +408,9 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
219 500); 408 500);
220} 409}
221 410
222static __u8 reg_r(struct gspca_dev *gspca_dev,
223 __u16 index)
224{
225 usb_control_msg(gspca_dev->dev,
226 usb_rcvctrlpipe(gspca_dev->dev, 0),
227 0, /* request */
228 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
229 0, /* value */
230 index, gspca_dev->usb_buf, 1,
231 500);
232 return gspca_dev->usb_buf[0];
233}
234 411
235static void reg_w(struct gspca_dev *gspca_dev, 412static void reg_w(struct gspca_dev *gspca_dev,
236 __u16 index, 413 __u8 index,
237 __u8 value) 414 __u8 value)
238{ 415{
239 gspca_dev->usb_buf[0] = value; 416 gspca_dev->usb_buf[0] = value;
@@ -241,10 +418,78 @@ static void reg_w(struct gspca_dev *gspca_dev,
241 usb_sndctrlpipe(gspca_dev->dev, 0), 418 usb_sndctrlpipe(gspca_dev->dev, 0),
242 0, /* request */ 419 0, /* request */
243 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 420 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
244 value, index, gspca_dev->usb_buf, 1, 421 0, index, gspca_dev->usb_buf, 1,
245 500); 422 500);
246} 423}
247 424
425static void reg_w_seq(struct gspca_dev *gspca_dev,
426 const __u8 *seq, int len)
427{
428 while (--len >= 0) {
429 reg_w(gspca_dev, seq[0], seq[1]);
430 seq += 2;
431 }
432}
433
434/* load the beginning of a page */
435static void reg_w_page(struct gspca_dev *gspca_dev,
436 const __u8 *page, int len)
437{
438 int index;
439
440 for (index = 0; index < len; index++) {
441 if (page[index] == 0xaa) /* skip this index */
442 continue;
443 gspca_dev->usb_buf[0] = page[index];
444 usb_control_msg(gspca_dev->dev,
445 usb_sndctrlpipe(gspca_dev->dev, 0),
446 0, /* request */
447 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
448 0, index, gspca_dev->usb_buf, 1,
449 500);
450 }
451}
452
453/* output a variable sequence */
454static void reg_w_var(struct gspca_dev *gspca_dev,
455 const __u8 *seq)
456{
457 int index, len;
458
459 for (;;) {
460 index = *seq++;
461 len = *seq++;
462 switch (len) {
463 case 0:
464 return;
465 case 254:
466 reg_w_page(gspca_dev, page4_7311, sizeof page4_7311);
467 break;
468 case 255:
469 reg_w_page(gspca_dev, page3_7302, sizeof page3_7302);
470 break;
471 default:
472 if (len > 64) {
473 PDEBUG(D_ERR|D_STREAM,
474 "Incorrect variable sequence");
475 return;
476 }
477 while (len > 0) {
478 if (len < 8) {
479 reg_w_buf(gspca_dev, index, seq, len);
480 seq += len;
481 break;
482 }
483 reg_w_buf(gspca_dev, index, seq, 8);
484 seq += 8;
485 index += 8;
486 len -= 8;
487 }
488 }
489 }
490 /* not reached */
491}
492
248/* this function is called at probe time */ 493/* this function is called at probe time */
249static int sd_config(struct gspca_dev *gspca_dev, 494static int sd_config(struct gspca_dev *gspca_dev,
250 const struct usb_device_id *id) 495 const struct usb_device_id *id)
@@ -252,203 +497,245 @@ static int sd_config(struct gspca_dev *gspca_dev,
252 struct sd *sd = (struct sd *) gspca_dev; 497 struct sd *sd = (struct sd *) gspca_dev;
253 struct cam *cam; 498 struct cam *cam;
254 499
255 PDEBUG(D_CONF, "Find Sensor PAC7311");
256 reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
257 reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
258 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
259 reg_w(gspca_dev, 0xff, 0x04);
260 reg_w(gspca_dev, 0x27, 0x80);
261 reg_w(gspca_dev, 0x28, 0xca);
262 reg_w(gspca_dev, 0x29, 0x53);
263 reg_w(gspca_dev, 0x2a, 0x0e);
264 reg_w(gspca_dev, 0xff, 0x01);
265 reg_w(gspca_dev, 0x3e, 0x20);
266
267 cam = &gspca_dev->cam; 500 cam = &gspca_dev->cam;
268 cam->epaddr = 0x05; 501 cam->epaddr = 0x05;
269 cam->cam_mode = vga_mode; 502
270 cam->nmodes = ARRAY_SIZE(vga_mode); 503 sd->sensor = id->driver_info;
504 if (sd->sensor == SENSOR_PAC7302) {
505 PDEBUG(D_CONF, "Find Sensor PAC7302");
506 cam->cam_mode = &vga_mode[2]; /* only 640x480 */
507 cam->nmodes = 1;
508 } else {
509 PDEBUG(D_CONF, "Find Sensor PAC7311");
510 cam->cam_mode = vga_mode;
511 cam->nmodes = ARRAY_SIZE(vga_mode);
512 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX)
513 | (1 << SATURATION_IDX);
514 }
271 515
272 sd->brightness = BRIGHTNESS_DEF; 516 sd->brightness = BRIGHTNESS_DEF;
273 sd->contrast = CONTRAST_DEF; 517 sd->contrast = CONTRAST_DEF;
274 sd->colors = COLOR_DEF; 518 sd->colors = COLOR_DEF;
519 sd->gain = GAIN_DEF;
520 sd->exposure = EXPOSURE_DEF;
275 sd->autogain = AUTOGAIN_DEF; 521 sd->autogain = AUTOGAIN_DEF;
276 sd->ag_cnt = -1; 522 sd->hflip = HFLIP_DEF;
523 sd->vflip = VFLIP_DEF;
277 return 0; 524 return 0;
278} 525}
279 526
280static void setbrightness(struct gspca_dev *gspca_dev) 527/* This function is used by pac7302 only */
528static void setbrightcont(struct gspca_dev *gspca_dev)
529{
530 struct sd *sd = (struct sd *) gspca_dev;
531 int i, v;
532 static const __u8 max[10] =
533 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
534 0xd4, 0xec};
535 static const __u8 delta[10] =
536 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
537 0x11, 0x0b};
538
539 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
540 for (i = 0; i < 10; i++) {
541 v = max[i];
542 v += (sd->brightness - BRIGHTNESS_MAX)
543 * 150 / BRIGHTNESS_MAX; /* 200 ? */
544 v -= delta[i] * sd->contrast / CONTRAST_MAX;
545 if (v < 0)
546 v = 0;
547 else if (v > 0xff)
548 v = 0xff;
549 reg_w(gspca_dev, 0xa2 + i, v);
550 }
551 reg_w(gspca_dev, 0xdc, 0x01);
552}
553
554/* This function is used by pac7311 only */
555static void setcontrast(struct gspca_dev *gspca_dev)
281{ 556{
282 struct sd *sd = (struct sd *) gspca_dev; 557 struct sd *sd = (struct sd *) gspca_dev;
283 int brightness;
284 558
285/*jfm: inverted?*/
286 brightness = BRIGHTNESS_MAX - sd->brightness;
287 reg_w(gspca_dev, 0xff, 0x04); 559 reg_w(gspca_dev, 0xff, 0x04);
288/* reg_w(gspca_dev, 0x0e, 0x00); */ 560 reg_w(gspca_dev, 0x10, sd->contrast >> 4);
289 reg_w(gspca_dev, 0x0f, brightness);
290 /* load registers to sensor (Bit 0, auto clear) */ 561 /* load registers to sensor (Bit 0, auto clear) */
291 reg_w(gspca_dev, 0x11, 0x01); 562 reg_w(gspca_dev, 0x11, 0x01);
292 PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness);
293} 563}
294 564
295static void setcontrast(struct gspca_dev *gspca_dev) 565/* This function is used by pac7302 only */
566static void setcolors(struct gspca_dev *gspca_dev)
296{ 567{
297 struct sd *sd = (struct sd *) gspca_dev; 568 struct sd *sd = (struct sd *) gspca_dev;
569 int i, v;
570 static const int a[9] =
571 {217, -212, 0, -101, 170, -67, -38, -315, 355};
572 static const int b[9] =
573 {19, 106, 0, 19, 106, 1, 19, 106, 1};
298 574
299 reg_w(gspca_dev, 0xff, 0x01); 575 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
300 reg_w(gspca_dev, 0x80, sd->contrast);
301 /* load registers to sensor (Bit 0, auto clear) */
302 reg_w(gspca_dev, 0x11, 0x01); 576 reg_w(gspca_dev, 0x11, 0x01);
303 PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); 577 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
578 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
579 for (i = 0; i < 9; i++) {
580 v = a[i] * sd->colors / COLOR_MAX + b[i];
581 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
582 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
583 }
584 reg_w(gspca_dev, 0xdc, 0x01);
585 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
304} 586}
305 587
306static void setcolors(struct gspca_dev *gspca_dev) 588static void setgain(struct gspca_dev *gspca_dev)
307{ 589{
308 struct sd *sd = (struct sd *) gspca_dev; 590 struct sd *sd = (struct sd *) gspca_dev;
309 591
310 reg_w(gspca_dev, 0xff, 0x01); 592 if (sd->sensor == SENSOR_PAC7302) {
311 reg_w(gspca_dev, 0x10, sd->colors); 593 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
594 reg_w(gspca_dev, 0x10, sd->gain >> 3);
595 } else {
596 int gain = GAIN_MAX - sd->gain;
597 if (gain < 1)
598 gain = 1;
599 else if (gain > 245)
600 gain = 245;
601 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
602 reg_w(gspca_dev, 0x0e, 0x00);
603 reg_w(gspca_dev, 0x0f, gain);
604 }
312 /* load registers to sensor (Bit 0, auto clear) */ 605 /* load registers to sensor (Bit 0, auto clear) */
313 reg_w(gspca_dev, 0x11, 0x01); 606 reg_w(gspca_dev, 0x11, 0x01);
314 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
315} 607}
316 608
317static void setautogain(struct gspca_dev *gspca_dev) 609static void setexposure(struct gspca_dev *gspca_dev)
318{ 610{
319 struct sd *sd = (struct sd *) gspca_dev; 611 struct sd *sd = (struct sd *) gspca_dev;
612 __u8 reg;
613
614 /* register 2 of frame 3/4 contains the clock divider configuring the
615 no fps according to the formula: 60 / reg. sd->exposure is the
616 desired exposure time in ms. */
617 reg = 120 * sd->exposure / 1000;
618 if (reg < 2)
619 reg = 2;
620 else if (reg > 63)
621 reg = 63;
622
623 if (sd->sensor == SENSOR_PAC7302) {
624 /* On the pac7302 reg2 MUST be a multiple of 3, so round it to
625 the nearest multiple of 3, except when between 6 and 12? */
626 if (reg < 6 || reg > 12)
627 reg = ((reg + 1) / 3) * 3;
628 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
629 reg_w(gspca_dev, 0x02, reg);
630 } else {
631 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
632 reg_w(gspca_dev, 0x02, reg);
633 /* Page 1 register 8 must always be 0x08 except when not in
634 640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
635 reg_w(gspca_dev, 0xff, 0x01);
636 if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
637 reg <= 3)
638 reg_w(gspca_dev, 0x08, 0x09);
639 else
640 reg_w(gspca_dev, 0x08, 0x08);
641 }
642 /* load registers to sensor (Bit 0, auto clear) */
643 reg_w(gspca_dev, 0x11, 0x01);
644}
320 645
321 if (sd->autogain) { 646static void sethvflip(struct gspca_dev *gspca_dev)
322 sd->lum_sum = 0; 647{
323 sd->ag_cnt = AG_CNT_START; 648 struct sd *sd = (struct sd *) gspca_dev;
649 __u8 data;
650
651 if (sd->sensor == SENSOR_PAC7302) {
652 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
653 data = (sd->hflip ? 0x08 : 0x00)
654 | (sd->vflip ? 0x04 : 0x00);
324 } else { 655 } else {
325 sd->ag_cnt = -1; 656 reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
657 data = (sd->hflip ? 0x04 : 0x00)
658 | (sd->vflip ? 0x08 : 0x00);
326 } 659 }
660 reg_w(gspca_dev, 0x21, data);
661 /* load registers to sensor (Bit 0, auto clear) */
662 reg_w(gspca_dev, 0x11, 0x01);
327} 663}
328 664
329/* this function is called at open time */ 665/* this function is called at probe and resume time */
330static int sd_open(struct gspca_dev *gspca_dev) 666static int sd_init(struct gspca_dev *gspca_dev)
331{ 667{
332 reg_w(gspca_dev, 0x78, 0x00); /* Turn on LED */ 668 struct sd *sd = (struct sd *) gspca_dev;
669
670 if (sd->sensor == SENSOR_PAC7302)
671 reg_w_seq(gspca_dev, init_7302, sizeof init_7302);
672 else
673 reg_w_seq(gspca_dev, init_7311, sizeof init_7311);
674
333 return 0; 675 return 0;
334} 676}
335 677
336static void sd_start(struct gspca_dev *gspca_dev) 678static void sd_start(struct gspca_dev *gspca_dev)
337{ 679{
338 reg_w(gspca_dev, 0xff, 0x01); 680 struct sd *sd = (struct sd *) gspca_dev;
339 reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
340 reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
341 reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8);
342 reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8);
343 reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8);
344 reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3);
345 reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8);
346 reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8);
347 reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8);
348 reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8);
349 reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8);
350 reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2);
351 reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6);
352 reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8);
353 reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8);
354 reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2);
355 reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3);
356 reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4);
357 reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8);
358 reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5);
359 681
360 reg_w(gspca_dev, 0xff, 0x04); 682 sd->sof_read = 0;
361 reg_w(gspca_dev, 0x02, 0x04); 683
362 reg_w(gspca_dev, 0x03, 0x54); 684 if (sd->sensor == SENSOR_PAC7302) {
363 reg_w(gspca_dev, 0x04, 0x07); 685 reg_w_var(gspca_dev, start_7302);
364 reg_w(gspca_dev, 0x05, 0x2b); 686 setbrightcont(gspca_dev);
365 reg_w(gspca_dev, 0x06, 0x09); 687 setcolors(gspca_dev);
366 reg_w(gspca_dev, 0x07, 0x0f); 688 } else {
367 reg_w(gspca_dev, 0x08, 0x09); 689 reg_w_var(gspca_dev, start_7311);
368 reg_w(gspca_dev, 0x09, 0x00); 690 setcontrast(gspca_dev);
369 reg_w(gspca_dev, 0x0c, 0x07); 691 }
370 reg_w(gspca_dev, 0x0d, 0x00); 692 setgain(gspca_dev);
371 reg_w(gspca_dev, 0x0e, 0x00); 693 setexposure(gspca_dev);
372 reg_w(gspca_dev, 0x0f, 0x62); 694 sethvflip(gspca_dev);
373 reg_w(gspca_dev, 0x10, 0x08);
374 reg_w(gspca_dev, 0x12, 0x07);
375 reg_w(gspca_dev, 0x13, 0x00);
376 reg_w(gspca_dev, 0x14, 0x00);
377 reg_w(gspca_dev, 0x15, 0x00);
378 reg_w(gspca_dev, 0x16, 0x00);
379 reg_w(gspca_dev, 0x17, 0x00);
380 reg_w(gspca_dev, 0x18, 0x00);
381 reg_w(gspca_dev, 0x19, 0x00);
382 reg_w(gspca_dev, 0x1a, 0x00);
383 reg_w(gspca_dev, 0x1b, 0x03);
384 reg_w(gspca_dev, 0x1c, 0xa0);
385 reg_w(gspca_dev, 0x1d, 0x01);
386 reg_w(gspca_dev, 0x1e, 0xf4);
387 reg_w(gspca_dev, 0x21, 0x00);
388 reg_w(gspca_dev, 0x22, 0x08);
389 reg_w(gspca_dev, 0x24, 0x03);
390 reg_w(gspca_dev, 0x26, 0x00);
391 reg_w(gspca_dev, 0x27, 0x01);
392 reg_w(gspca_dev, 0x28, 0xca);
393 reg_w(gspca_dev, 0x29, 0x10);
394 reg_w(gspca_dev, 0x2a, 0x06);
395 reg_w(gspca_dev, 0x2b, 0x78);
396 reg_w(gspca_dev, 0x2c, 0x00);
397 reg_w(gspca_dev, 0x2d, 0x00);
398 reg_w(gspca_dev, 0x2e, 0x00);
399 reg_w(gspca_dev, 0x2f, 0x00);
400 reg_w(gspca_dev, 0x30, 0x23);
401 reg_w(gspca_dev, 0x31, 0x28);
402 reg_w(gspca_dev, 0x32, 0x04);
403 reg_w(gspca_dev, 0x33, 0x11);
404 reg_w(gspca_dev, 0x34, 0x00);
405 reg_w(gspca_dev, 0x35, 0x00);
406 reg_w(gspca_dev, 0x11, 0x01);
407 setcontrast(gspca_dev);
408 setbrightness(gspca_dev);
409 setcolors(gspca_dev);
410 setautogain(gspca_dev);
411 695
412 /* set correct resolution */ 696 /* set correct resolution */
413 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 697 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
414 case 2: /* 160x120 */ 698 case 2: /* 160x120 pac7311 */
415 reg_w(gspca_dev, 0xff, 0x04);
416 reg_w(gspca_dev, 0x02, 0x03);
417 reg_w(gspca_dev, 0xff, 0x01); 699 reg_w(gspca_dev, 0xff, 0x01);
418 reg_w(gspca_dev, 0x08, 0x09);
419 reg_w(gspca_dev, 0x17, 0x20); 700 reg_w(gspca_dev, 0x17, 0x20);
420 reg_w(gspca_dev, 0x1b, 0x00);
421/* reg_w(gspca_dev, 0x80, 0x69); */
422 reg_w(gspca_dev, 0x87, 0x10); 701 reg_w(gspca_dev, 0x87, 0x10);
423 break; 702 break;
424 case 1: /* 320x240 */ 703 case 1: /* 320x240 pac7311 */
425 reg_w(gspca_dev, 0xff, 0x04);
426 reg_w(gspca_dev, 0x02, 0x03);
427 reg_w(gspca_dev, 0xff, 0x01); 704 reg_w(gspca_dev, 0xff, 0x01);
428 reg_w(gspca_dev, 0x08, 0x09);
429 reg_w(gspca_dev, 0x17, 0x30); 705 reg_w(gspca_dev, 0x17, 0x30);
430/* reg_w(gspca_dev, 0x80, 0x3f); */
431 reg_w(gspca_dev, 0x87, 0x11); 706 reg_w(gspca_dev, 0x87, 0x11);
432 break; 707 break;
433 case 0: /* 640x480 */ 708 case 0: /* 640x480 */
434 reg_w(gspca_dev, 0xff, 0x04); 709 if (sd->sensor == SENSOR_PAC7302)
435 reg_w(gspca_dev, 0x02, 0x03); 710 break;
436 reg_w(gspca_dev, 0xff, 0x01); 711 reg_w(gspca_dev, 0xff, 0x01);
437 reg_w(gspca_dev, 0x08, 0x08);
438 reg_w(gspca_dev, 0x17, 0x00); 712 reg_w(gspca_dev, 0x17, 0x00);
439/* reg_w(gspca_dev, 0x80, 0x1c); */
440 reg_w(gspca_dev, 0x87, 0x12); 713 reg_w(gspca_dev, 0x87, 0x12);
441 break; 714 break;
442 } 715 }
443 716
717 sd->sof_read = 0;
718 sd->autogain_ignore_frames = 0;
719 atomic_set(&sd->avg_lum, -1);
720
444 /* start stream */ 721 /* start stream */
445 reg_w(gspca_dev, 0xff, 0x01); 722 reg_w(gspca_dev, 0xff, 0x01);
446 reg_w(gspca_dev, 0x78, 0x04); 723 if (sd->sensor == SENSOR_PAC7302)
447 reg_w(gspca_dev, 0x78, 0x05); 724 reg_w(gspca_dev, 0x78, 0x01);
725 else
726 reg_w(gspca_dev, 0x78, 0x05);
448} 727}
449 728
450static void sd_stopN(struct gspca_dev *gspca_dev) 729static void sd_stopN(struct gspca_dev *gspca_dev)
451{ 730{
731 struct sd *sd = (struct sd *) gspca_dev;
732
733 if (sd->sensor == SENSOR_PAC7302) {
734 reg_w(gspca_dev, 0xff, 0x01);
735 reg_w(gspca_dev, 0x78, 0x00);
736 reg_w(gspca_dev, 0x78, 0x00);
737 return;
738 }
452 reg_w(gspca_dev, 0xff, 0x04); 739 reg_w(gspca_dev, 0xff, 0x04);
453 reg_w(gspca_dev, 0x27, 0x80); 740 reg_w(gspca_dev, 0x27, 0x80);
454 reg_w(gspca_dev, 0x28, 0xca); 741 reg_w(gspca_dev, 0x28, 0xca);
@@ -456,187 +743,147 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
456 reg_w(gspca_dev, 0x2a, 0x0e); 743 reg_w(gspca_dev, 0x2a, 0x0e);
457 reg_w(gspca_dev, 0xff, 0x01); 744 reg_w(gspca_dev, 0xff, 0x01);
458 reg_w(gspca_dev, 0x3e, 0x20); 745 reg_w(gspca_dev, 0x3e, 0x20);
459 reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ 746 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
460 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ 747 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
461 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ 748 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
462} 749}
463 750
464static void sd_stop0(struct gspca_dev *gspca_dev) 751static void sd_stop0(struct gspca_dev *gspca_dev)
465{ 752{
466} 753 struct sd *sd = (struct sd *) gspca_dev;
467 754
468/* this function is called at close time */ 755 if (sd->sensor == SENSOR_PAC7302) {
469static void sd_close(struct gspca_dev *gspca_dev) 756 reg_w(gspca_dev, 0xff, 0x01);
470{ 757 reg_w(gspca_dev, 0x78, 0x40);
471 reg_w(gspca_dev, 0xff, 0x04); 758 }
472 reg_w(gspca_dev, 0x27, 0x80);
473 reg_w(gspca_dev, 0x28, 0xca);
474 reg_w(gspca_dev, 0x29, 0x53);
475 reg_w(gspca_dev, 0x2a, 0x0e);
476 reg_w(gspca_dev, 0xff, 0x01);
477 reg_w(gspca_dev, 0x3e, 0x20);
478 reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
479 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
480 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
481} 759}
482 760
761/* Include pac common sof detection functions */
762#include "pac_common.h"
763
483static void do_autogain(struct gspca_dev *gspca_dev) 764static void do_autogain(struct gspca_dev *gspca_dev)
484{ 765{
485 struct sd *sd = (struct sd *) gspca_dev; 766 struct sd *sd = (struct sd *) gspca_dev;
486 int luma; 767 int avg_lum = atomic_read(&sd->avg_lum);
487 int luma_mean = 128; 768 int desired_lum, deadzone;
488 int luma_delta = 20;
489 __u8 spring = 5;
490 int Gbright;
491 769
492 if (!atomic_read(&sd->do_gain)) 770 if (avg_lum == -1)
493 return; 771 return;
494 atomic_set(&sd->do_gain, 0); 772
495 773 if (sd->sensor == SENSOR_PAC7302) {
496 luma = atomic_read(&sd->avg_lum); 774 desired_lum = 270 + sd->brightness * 4;
497 Gbright = reg_r(gspca_dev, 0x02); 775 /* Hack hack, with the 7202 the first exposure step is
498 PDEBUG(D_FRAM, "luma mean %d", luma); 776 pretty large, so if we're about to make the first
499 if (luma < luma_mean - luma_delta || 777 exposure increase make the deadzone large to avoid
500 luma > luma_mean + luma_delta) { 778 oscilating */
501 Gbright += (luma_mean - luma) >> spring; 779 if (desired_lum > avg_lum && sd->gain == GAIN_DEF &&
502 if (Gbright > 0x1a) 780 sd->exposure > EXPOSURE_DEF &&
503 Gbright = 0x1a; 781 sd->exposure < 42)
504 else if (Gbright < 4) 782 deadzone = 90;
505 Gbright = 4; 783 else
506 PDEBUG(D_FRAM, "gbright %d", Gbright); 784 deadzone = 30;
507 reg_w(gspca_dev, 0xff, 0x04); 785 } else {
508 reg_w(gspca_dev, 0x0f, Gbright); 786 desired_lum = 200;
509 /* load registers to sensor (Bit 0, auto clear) */ 787 deadzone = 20;
510 reg_w(gspca_dev, 0x11, 0x01);
511 } 788 }
789
790 if (sd->autogain_ignore_frames > 0)
791 sd->autogain_ignore_frames--;
792 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
793 deadzone, GAIN_KNEE, EXPOSURE_KNEE))
794 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
512} 795}
513 796
797static const unsigned char pac7311_jpeg_header1[] = {
798 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08
799};
800
801static const unsigned char pac7311_jpeg_header2[] = {
802 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda,
803 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
804};
805
806/* this function is run at interrupt level */
514static void sd_pkt_scan(struct gspca_dev *gspca_dev, 807static void sd_pkt_scan(struct gspca_dev *gspca_dev,
515 struct gspca_frame *frame, /* target */ 808 struct gspca_frame *frame, /* target */
516 __u8 *data, /* isoc packet */ 809 __u8 *data, /* isoc packet */
517 int len) /* iso packet length */ 810 int len) /* iso packet length */
518{ 811{
519 struct sd *sd = (struct sd *) gspca_dev; 812 struct sd *sd = (struct sd *) gspca_dev;
520 unsigned char tmpbuf[4]; 813 unsigned char *sof;
521 int i, p, ffseq; 814
522 815 sof = pac_find_sof(gspca_dev, data, len);
523/* if (len < 5) { */ 816 if (sof) {
524 if (len < 6) { 817 unsigned char tmpbuf[4];
525/* gspca_dev->last_packet_type = DISCARD_PACKET; */ 818 int n, lum_offset, footer_length;
526 return; 819
527 } 820 if (sd->sensor == SENSOR_PAC7302) {
528 821 /* 6 bytes after the FF D9 EOF marker a number of lumination
529 ffseq = sd->ffseq; 822 bytes are send corresponding to different parts of the
530 823 image, the 14th and 15th byte after the EOF seem to
531 for (p = 0; p < len - 6; p++) { 824 correspond to the center of the image */
532 if ((data[0 + p] == 0xff) 825 lum_offset = 61 + sizeof pac_sof_marker;
533 && (data[1 + p] == 0xff) 826 footer_length = 74;
534 && (data[2 + p] == 0x00) 827 } else {
535 && (data[3 + p] == 0xff) 828 lum_offset = 24 + sizeof pac_sof_marker;
536 && (data[4 + p] == 0x96)) { 829 footer_length = 26;
537 830 }
538 /* start of frame */
539 if (sd->ag_cnt >= 0 && p > 28) {
540 sd->lum_sum += data[p - 23];
541 if (--sd->ag_cnt < 0) {
542 sd->ag_cnt = AG_CNT_START;
543 atomic_set(&sd->avg_lum,
544 sd->lum_sum / AG_CNT_START);
545 sd->lum_sum = 0;
546 atomic_set(&sd->do_gain, 1);
547 }
548 }
549 831
550 /* copy the end of data to the current frame */ 832 /* Finish decoding current frame */
833 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
834 if (n < 0) {
835 frame->data_end += n;
836 n = 0;
837 }
838 frame = gspca_frame_add(gspca_dev, INTER_PACKET, frame,
839 data, n);
840 if (gspca_dev->last_packet_type != DISCARD_PACKET &&
841 frame->data_end[-2] == 0xff &&
842 frame->data_end[-1] == 0xd9)
551 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 843 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
552 data, p); 844 NULL, 0);
553 845
554 /* put the JPEG header in the new frame */ 846 n = sof - data;
555 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 847 len -= n;
556 (unsigned char *) pac7311_jpeg_header, 848 data = sof;
557 12); 849
850 /* Get average lumination */
851 if (gspca_dev->last_packet_type == LAST_PACKET &&
852 n >= lum_offset)
853 atomic_set(&sd->avg_lum, data[-lum_offset] +
854 data[-lum_offset + 1]);
855 else
856 atomic_set(&sd->avg_lum, -1);
857
858 /* Start the new frame with the jpeg header */
859 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
860 pac7311_jpeg_header1, sizeof(pac7311_jpeg_header1));
861 if (sd->sensor == SENSOR_PAC7302) {
862 /* The PAC7302 has the image rotated 90 degrees */
863 tmpbuf[0] = gspca_dev->width >> 8;
864 tmpbuf[1] = gspca_dev->width & 0xff;
865 tmpbuf[2] = gspca_dev->height >> 8;
866 tmpbuf[3] = gspca_dev->height & 0xff;
867 } else {
558 tmpbuf[0] = gspca_dev->height >> 8; 868 tmpbuf[0] = gspca_dev->height >> 8;
559 tmpbuf[1] = gspca_dev->height & 0xff; 869 tmpbuf[1] = gspca_dev->height & 0xff;
560 tmpbuf[2] = gspca_dev->width >> 8; 870 tmpbuf[2] = gspca_dev->width >> 8;
561 tmpbuf[3] = gspca_dev->width & 0xff; 871 tmpbuf[3] = gspca_dev->width & 0xff;
562 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
563 tmpbuf, 4);
564 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
565 (unsigned char *) &pac7311_jpeg_header[16],
566 PAC7311_JPEG_HEADER_SIZE - 16);
567
568 data += p + 7;
569 len -= p + 7;
570 ffseq = 0;
571 break;
572 } 872 }
873 gspca_frame_add(gspca_dev, INTER_PACKET, frame, tmpbuf, 4);
874 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
875 pac7311_jpeg_header2, sizeof(pac7311_jpeg_header2));
573 } 876 }
574
575 /* remove the 'ff ff ff xx' sequences */
576 switch (ffseq) {
577 case 3:
578 data += 1;
579 len -= 1;
580 break;
581 case 2:
582 if (data[0] == 0xff) {
583 data += 2;
584 len -= 2;
585 frame->data_end -= 2;
586 }
587 break;
588 case 1:
589 if (data[0] == 0xff
590 && data[1] == 0xff) {
591 data += 3;
592 len -= 3;
593 frame->data_end -= 1;
594 }
595 break;
596 }
597 for (i = 0; i < len - 4; i++) {
598 if (data[i] == 0xff
599 && data[i + 1] == 0xff
600 && data[i + 2] == 0xff) {
601 memmove(&data[i], &data[i + 4], len - i - 4);
602 len -= 4;
603 }
604 }
605 ffseq = 0;
606 if (data[len - 4] == 0xff) {
607 if (data[len - 3] == 0xff
608 && data[len - 2] == 0xff) {
609 len -= 4;
610 }
611 } else if (data[len - 3] == 0xff) {
612 if (data[len - 2] == 0xff
613 && data[len - 1] == 0xff)
614 ffseq = 3;
615 } else if (data[len - 2] == 0xff) {
616 if (data[len - 1] == 0xff)
617 ffseq = 2;
618 } else if (data[len - 1] == 0xff)
619 ffseq = 1;
620 sd->ffseq = ffseq;
621 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 877 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
622} 878}
623 879
624static void getbrightness(struct gspca_dev *gspca_dev)
625{
626/* sd->brightness = reg_r(gspca_dev, 0x08);
627 return sd->brightness; */
628/* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */
629}
630
631
632
633static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 880static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
634{ 881{
635 struct sd *sd = (struct sd *) gspca_dev; 882 struct sd *sd = (struct sd *) gspca_dev;
636 883
637 sd->brightness = val; 884 sd->brightness = val;
638 if (gspca_dev->streaming) 885 if (gspca_dev->streaming)
639 setbrightness(gspca_dev); 886 setbrightcont(gspca_dev);
640 return 0; 887 return 0;
641} 888}
642 889
@@ -644,7 +891,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
644{ 891{
645 struct sd *sd = (struct sd *) gspca_dev; 892 struct sd *sd = (struct sd *) gspca_dev;
646 893
647 getbrightness(gspca_dev);
648 *val = sd->brightness; 894 *val = sd->brightness;
649 return 0; 895 return 0;
650} 896}
@@ -654,8 +900,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
654 struct sd *sd = (struct sd *) gspca_dev; 900 struct sd *sd = (struct sd *) gspca_dev;
655 901
656 sd->contrast = val; 902 sd->contrast = val;
657 if (gspca_dev->streaming) 903 if (gspca_dev->streaming) {
658 setcontrast(gspca_dev); 904 if (sd->sensor == SENSOR_PAC7302)
905 setbrightcont(gspca_dev);
906 else
907 setcontrast(gspca_dev);
908 }
659 return 0; 909 return 0;
660} 910}
661 911
@@ -663,7 +913,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
663{ 913{
664 struct sd *sd = (struct sd *) gspca_dev; 914 struct sd *sd = (struct sd *) gspca_dev;
665 915
666/* getcontrast(gspca_dev); */
667 *val = sd->contrast; 916 *val = sd->contrast;
668 return 0; 917 return 0;
669} 918}
@@ -682,18 +931,66 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
682{ 931{
683 struct sd *sd = (struct sd *) gspca_dev; 932 struct sd *sd = (struct sd *) gspca_dev;
684 933
685/* getcolors(gspca_dev); */
686 *val = sd->colors; 934 *val = sd->colors;
687 return 0; 935 return 0;
688} 936}
689 937
938static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
939{
940 struct sd *sd = (struct sd *) gspca_dev;
941
942 sd->gain = val;
943 if (gspca_dev->streaming)
944 setgain(gspca_dev);
945 return 0;
946}
947
948static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
949{
950 struct sd *sd = (struct sd *) gspca_dev;
951
952 *val = sd->gain;
953 return 0;
954}
955
956static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
957{
958 struct sd *sd = (struct sd *) gspca_dev;
959
960 sd->exposure = val;
961 if (gspca_dev->streaming)
962 setexposure(gspca_dev);
963 return 0;
964}
965
966static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
967{
968 struct sd *sd = (struct sd *) gspca_dev;
969
970 *val = sd->exposure;
971 return 0;
972}
973
690static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 974static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
691{ 975{
692 struct sd *sd = (struct sd *) gspca_dev; 976 struct sd *sd = (struct sd *) gspca_dev;
693 977
694 sd->autogain = val; 978 sd->autogain = val;
695 if (gspca_dev->streaming) 979 /* when switching to autogain set defaults to make sure
696 setautogain(gspca_dev); 980 we are on a valid point of the autogain gain /
981 exposure knee graph, and give this change time to
982 take effect before doing autogain. */
983 if (sd->autogain) {
984 sd->exposure = EXPOSURE_DEF;
985 sd->gain = GAIN_DEF;
986 if (gspca_dev->streaming) {
987 sd->autogain_ignore_frames =
988 PAC_AUTOGAIN_IGNORE_FRAMES;
989 setexposure(gspca_dev);
990 setgain(gspca_dev);
991 }
992 }
993
697 return 0; 994 return 0;
698} 995}
699 996
@@ -705,30 +1002,67 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
705 return 0; 1002 return 0;
706} 1003}
707 1004
1005static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1006{
1007 struct sd *sd = (struct sd *) gspca_dev;
1008
1009 sd->hflip = val;
1010 if (gspca_dev->streaming)
1011 sethvflip(gspca_dev);
1012 return 0;
1013}
1014
1015static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1016{
1017 struct sd *sd = (struct sd *) gspca_dev;
1018
1019 *val = sd->hflip;
1020 return 0;
1021}
1022
1023static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1024{
1025 struct sd *sd = (struct sd *) gspca_dev;
1026
1027 sd->vflip = val;
1028 if (gspca_dev->streaming)
1029 sethvflip(gspca_dev);
1030 return 0;
1031}
1032
1033static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1034{
1035 struct sd *sd = (struct sd *) gspca_dev;
1036
1037 *val = sd->vflip;
1038 return 0;
1039}
1040
708/* sub-driver description */ 1041/* sub-driver description */
709static struct sd_desc sd_desc = { 1042static struct sd_desc sd_desc = {
710 .name = MODULE_NAME, 1043 .name = MODULE_NAME,
711 .ctrls = sd_ctrls, 1044 .ctrls = sd_ctrls,
712 .nctrls = ARRAY_SIZE(sd_ctrls), 1045 .nctrls = ARRAY_SIZE(sd_ctrls),
713 .config = sd_config, 1046 .config = sd_config,
714 .open = sd_open, 1047 .init = sd_init,
715 .start = sd_start, 1048 .start = sd_start,
716 .stopN = sd_stopN, 1049 .stopN = sd_stopN,
717 .stop0 = sd_stop0, 1050 .stop0 = sd_stop0,
718 .close = sd_close,
719 .pkt_scan = sd_pkt_scan, 1051 .pkt_scan = sd_pkt_scan,
720 .dq_callback = do_autogain, 1052 .dq_callback = do_autogain,
721}; 1053};
722 1054
723/* -- module initialisation -- */ 1055/* -- module initialisation -- */
724static __devinitdata struct usb_device_id device_table[] = { 1056static __devinitdata struct usb_device_id device_table[] = {
725 {USB_DEVICE(0x093a, 0x2600)}, 1057 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
726 {USB_DEVICE(0x093a, 0x2601)}, 1058 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
727 {USB_DEVICE(0x093a, 0x2603)}, 1059 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
728 {USB_DEVICE(0x093a, 0x2608)}, 1060 {USB_DEVICE(0x093a, 0x2608), .driver_info = SENSOR_PAC7311},
729 {USB_DEVICE(0x093a, 0x260e)}, 1061 {USB_DEVICE(0x093a, 0x260e), .driver_info = SENSOR_PAC7311},
730 {USB_DEVICE(0x093a, 0x260f)}, 1062 {USB_DEVICE(0x093a, 0x260f), .driver_info = SENSOR_PAC7311},
731 {USB_DEVICE(0x093a, 0x2621)}, 1063 {USB_DEVICE(0x093a, 0x2621), .driver_info = SENSOR_PAC7302},
1064 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1065 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
732 {} 1066 {}
733}; 1067};
734MODULE_DEVICE_TABLE(usb, device_table); 1068MODULE_DEVICE_TABLE(usb, device_table);
@@ -746,6 +1080,10 @@ static struct usb_driver sd_driver = {
746 .id_table = device_table, 1080 .id_table = device_table,
747 .probe = sd_probe, 1081 .probe = sd_probe,
748 .disconnect = gspca_disconnect, 1082 .disconnect = gspca_disconnect,
1083#ifdef CONFIG_PM
1084 .suspend = gspca_suspend,
1085 .resume = gspca_resume,
1086#endif
749}; 1087};
750 1088
751/* -- module insert / remove -- */ 1089/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/pac_common.h b/drivers/media/video/gspca/pac_common.h
new file mode 100644
index 000000000000..34d4b1494cd5
--- /dev/null
+++ b/drivers/media/video/gspca/pac_common.h
@@ -0,0 +1,60 @@
1/*
2 * Pixart PAC207BCA / PAC73xx common functions
3 *
4 * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6 * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
7 *
8 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26/* We calculate the autogain at the end of the transfer of a frame, at this
27 moment a frame with the old settings is being transmitted, and a frame is
28 being captured with the old settings. So if we adjust the autogain we must
29 ignore atleast the 2 next frames for the new settings to come into effect
30 before doing any other adjustments */
31#define PAC_AUTOGAIN_IGNORE_FRAMES 3
32
33static const unsigned char pac_sof_marker[5] =
34 { 0xff, 0xff, 0x00, 0xff, 0x96 };
35
36static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev,
37 unsigned char *m, int len)
38{
39 struct sd *sd = (struct sd *) gspca_dev;
40 int i;
41
42 /* Search for the SOF marker (fixed part) in the header */
43 for (i = 0; i < len; i++) {
44 if (m[i] == pac_sof_marker[sd->sof_read]) {
45 sd->sof_read++;
46 if (sd->sof_read == sizeof(pac_sof_marker)) {
47 PDEBUG(D_FRAM,
48 "SOF found, bytes to analyze: %u."
49 " Frame starts at byte #%u",
50 len, i + 1);
51 sd->sof_read = 0;
52 return m + i + 1;
53 }
54 } else {
55 sd->sof_read = 0;
56 }
57 }
58
59 return NULL;
60}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 11210c71f66c..5dd78c6766ea 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -20,6 +20,26 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23/* Some documentation on known sonixb registers:
24
25Reg Use
260x10 high nibble red gain low nibble blue gain
270x11 low nibble green gain
280x12 hstart
290x13 vstart
300x15 hsize (hsize = register-value * 16)
310x16 vsize (vsize = register-value * 16)
320x17 bit 0 toggle compression quality (according to sn9c102 driver)
330x18 bit 7 enables compression, bit 4-5 set image down scaling:
34 00 scale 1, 01 scale 1/2, 10, scale 1/4
350x19 high-nibble is sensor clock divider, changes exposure on sensors which
36 use a clock generated by the bridge. Some sensors have their own clock.
370x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
380x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
390x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
400x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
41*/
42
23#define MODULE_NAME "sonixb" 43#define MODULE_NAME "sonixb"
24 44
25#include "gspca.h" 45#include "gspca.h"
@@ -31,10 +51,8 @@ MODULE_LICENSE("GPL");
31/* specific webcam descriptor */ 51/* specific webcam descriptor */
32struct sd { 52struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 53 struct gspca_dev gspca_dev; /* !! must be the first item */
34
35 struct sd_desc sd_desc; /* our nctrls differ dependend upon the
36 sensor, so we use a per cam copy */
37 atomic_t avg_lum; 54 atomic_t avg_lum;
55 int prev_avg_lum;
38 56
39 unsigned char gain; 57 unsigned char gain;
40 unsigned char exposure; 58 unsigned char exposure;
@@ -44,8 +62,12 @@ struct sd {
44 unsigned char frames_to_drop; 62 unsigned char frames_to_drop;
45 unsigned char freq; /* light freq filter setting */ 63 unsigned char freq; /* light freq filter setting */
46 64
47 unsigned char fr_h_sz; /* size of frame header */ 65 __u8 bridge; /* Type of bridge */
48 char sensor; /* Type of image sensor chip */ 66#define BRIDGE_101 0
67#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
68#define BRIDGE_103 1
69
70 __u8 sensor; /* Type of image sensor chip */
49#define SENSOR_HV7131R 0 71#define SENSOR_HV7131R 0
50#define SENSOR_OV6650 1 72#define SENSOR_OV6650 1
51#define SENSOR_OV7630 2 73#define SENSOR_OV7630 2
@@ -53,16 +75,35 @@ struct sd {
53#define SENSOR_PAS202 4 75#define SENSOR_PAS202 4
54#define SENSOR_TAS5110 5 76#define SENSOR_TAS5110 5
55#define SENSOR_TAS5130CXX 6 77#define SENSOR_TAS5130CXX 6
56 char sensor_has_gain;
57 __u8 sensor_addr;
58 __u8 reg11; 78 __u8 reg11;
59}; 79};
60 80
61/* flags used in the device id table */ 81typedef const __u8 sensor_init_t[8];
82
83struct sensor_data {
84 const __u8 *bridge_init[2];
85 int bridge_init_size[2];
86 sensor_init_t *sensor_init;
87 int sensor_init_size;
88 sensor_init_t *sensor_bridge_init[2];
89 int sensor_bridge_init_size[2];
90 int flags;
91 unsigned ctrl_dis;
92 __u8 sensor_addr;
93};
94
95/* sensor_data flags */
62#define F_GAIN 0x01 /* has gain */ 96#define F_GAIN 0x01 /* has gain */
63#define F_AUTO 0x02 /* has autogain */ 97#define F_SIF 0x02 /* sif or vga */
64#define F_SIF 0x04 /* sif or vga */ 98
65#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */ 99/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
100#define MODE_RAW 0x10 /* raw bayer mode */
101#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
102
103/* ctrl_dis helper macros */
104#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
105#define NO_FREQ (1 << FREQ_IDX)
106#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
66 107
67#define COMP2 0x8f 108#define COMP2 0x8f
68#define COMP 0xc7 /* 0x87 //0x07 */ 109#define COMP 0xc7 /* 0x87 //0x07 */
@@ -73,6 +114,18 @@ struct sd {
73 114
74#define SYS_CLK 0x04 115#define SYS_CLK 0x04
75 116
117#define SENS(bridge_1, bridge_3, sensor, sensor_1, \
118 sensor_3, _flags, _ctrl_dis, _sensor_addr) \
119{ \
120 .bridge_init = { bridge_1, bridge_3 }, \
121 .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
122 .sensor_init = sensor, \
123 .sensor_init_size = sizeof(sensor), \
124 .sensor_bridge_init = { sensor_1, sensor_3,}, \
125 .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
126 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
127}
128
76/* We calculate the autogain at the end of the transfer of a frame, at this 129/* We calculate the autogain at the end of the transfer of a frame, at this
77 moment a frame with the old settings is being transmitted, and a frame is 130 moment a frame with the old settings is being transmitted, and a frame is
78 being captured with the old settings. So if we adjust the autogain we must 131 being captured with the old settings. So if we adjust the autogain we must
@@ -95,6 +148,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 148static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
96 149
97static struct ctrl sd_ctrls[] = { 150static struct ctrl sd_ctrls[] = {
151#define BRIGHTNESS_IDX 0
98 { 152 {
99 { 153 {
100 .id = V4L2_CID_BRIGHTNESS, 154 .id = V4L2_CID_BRIGHTNESS,
@@ -109,6 +163,7 @@ static struct ctrl sd_ctrls[] = {
109 .set = sd_setbrightness, 163 .set = sd_setbrightness,
110 .get = sd_getbrightness, 164 .get = sd_getbrightness,
111 }, 165 },
166#define GAIN_IDX 1
112 { 167 {
113 { 168 {
114 .id = V4L2_CID_GAIN, 169 .id = V4L2_CID_GAIN,
@@ -124,6 +179,7 @@ static struct ctrl sd_ctrls[] = {
124 .set = sd_setgain, 179 .set = sd_setgain,
125 .get = sd_getgain, 180 .get = sd_getgain,
126 }, 181 },
182#define EXPOSURE_IDX 2
127 { 183 {
128 { 184 {
129 .id = V4L2_CID_EXPOSURE, 185 .id = V4L2_CID_EXPOSURE,
@@ -140,6 +196,7 @@ static struct ctrl sd_ctrls[] = {
140 .set = sd_setexposure, 196 .set = sd_setexposure,
141 .get = sd_getexposure, 197 .get = sd_getexposure,
142 }, 198 },
199#define AUTOGAIN_IDX 3
143 { 200 {
144 { 201 {
145 .id = V4L2_CID_AUTOGAIN, 202 .id = V4L2_CID_AUTOGAIN,
@@ -155,6 +212,7 @@ static struct ctrl sd_ctrls[] = {
155 .set = sd_setautogain, 212 .set = sd_setautogain,
156 .get = sd_getautogain, 213 .get = sd_getautogain,
157 }, 214 },
215#define FREQ_IDX 4
158 { 216 {
159 { 217 {
160 .id = V4L2_CID_POWER_LINE_FREQUENCY, 218 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -172,31 +230,56 @@ static struct ctrl sd_ctrls[] = {
172}; 230};
173 231
174static struct v4l2_pix_format vga_mode[] = { 232static struct v4l2_pix_format vga_mode[] = {
233 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
234 .bytesperline = 160,
235 .sizeimage = 160 * 120 * 5 / 4,
236 .colorspace = V4L2_COLORSPACE_SRGB,
237 .priv = 2 | MODE_RAW},
175 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 238 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
176 .bytesperline = 160, 239 .bytesperline = 160,
177 .sizeimage = 160 * 120, 240 .sizeimage = 160 * 120 * 5 / 4,
178 .colorspace = V4L2_COLORSPACE_SRGB, 241 .colorspace = V4L2_COLORSPACE_SRGB,
179 .priv = 2}, 242 .priv = 2},
180 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 243 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
181 .bytesperline = 320, 244 .bytesperline = 320,
182 .sizeimage = 320 * 240, 245 .sizeimage = 320 * 240 * 5 / 4,
183 .colorspace = V4L2_COLORSPACE_SRGB, 246 .colorspace = V4L2_COLORSPACE_SRGB,
184 .priv = 1}, 247 .priv = 1},
185 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 248 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
186 .bytesperline = 640, 249 .bytesperline = 640,
187 .sizeimage = 640 * 480, 250 .sizeimage = 640 * 480 * 5 / 4,
188 .colorspace = V4L2_COLORSPACE_SRGB, 251 .colorspace = V4L2_COLORSPACE_SRGB,
189 .priv = 0}, 252 .priv = 0},
190}; 253};
191static struct v4l2_pix_format sif_mode[] = { 254static struct v4l2_pix_format sif_mode[] = {
255 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
256 .bytesperline = 160,
257 .sizeimage = 160 * 120,
258 .colorspace = V4L2_COLORSPACE_SRGB,
259 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
260 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
261 .bytesperline = 160,
262 .sizeimage = 160 * 120 * 5 / 4,
263 .colorspace = V4L2_COLORSPACE_SRGB,
264 .priv = 1 | MODE_REDUCED_SIF},
265 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
266 .bytesperline = 176,
267 .sizeimage = 176 * 144 * 5 / 4,
268 .colorspace = V4L2_COLORSPACE_SRGB,
269 .priv = 1 | MODE_RAW},
192 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 270 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
193 .bytesperline = 176, 271 .bytesperline = 176,
194 .sizeimage = 176 * 144, 272 .sizeimage = 176 * 144 * 5 / 4,
195 .colorspace = V4L2_COLORSPACE_SRGB, 273 .colorspace = V4L2_COLORSPACE_SRGB,
196 .priv = 1}, 274 .priv = 1},
275 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
276 .bytesperline = 320,
277 .sizeimage = 320 * 240 * 5 / 4,
278 .colorspace = V4L2_COLORSPACE_SRGB,
279 .priv = 0 | MODE_REDUCED_SIF},
197 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, 280 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
198 .bytesperline = 352, 281 .bytesperline = 352,
199 .sizeimage = 352 * 288, 282 .sizeimage = 352 * 288 * 5 / 4,
200 .colorspace = V4L2_COLORSPACE_SRGB, 283 .colorspace = V4L2_COLORSPACE_SRGB,
201 .priv = 0}, 284 .priv = 0},
202}; 285};
@@ -204,7 +287,7 @@ static struct v4l2_pix_format sif_mode[] = {
204static const __u8 initHv7131[] = { 287static const __u8 initHv7131[] = {
205 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 288 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
206 0x00, 0x00, 289 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */ 290 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
208 0x28, 0x1e, 0x60, 0x8a, 0x20, 291 0x28, 0x1e, 0x60, 0x8a, 0x20,
209 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c 292 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
210}; 293};
@@ -218,8 +301,8 @@ static const __u8 hv7131_sensor_init[][8] = {
218static const __u8 initOv6650[] = { 301static const __u8 initOv6650[] = {
219 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 302 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
220 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 303 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b, 304 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
222 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 305 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
223}; 306};
224static const __u8 ov6650_sensor_init[][8] = 307static const __u8 ov6650_sensor_init[][8] =
225{ 308{
@@ -257,15 +340,15 @@ static const __u8 ov6650_sensor_init[][8] =
257static const __u8 initOv7630[] = { 340static const __u8 initOv7630[] = {
258 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ 341 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
259 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ 342 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
260 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ 343 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
261 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 344 0x28, 0x1e, /* H & V sizes r15 .. r16 */
262 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ 345 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
263 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ 346 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
264}; 347};
265static const __u8 initOv7630_3[] = { 348static const __u8 initOv7630_3[] = {
266 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 349 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
267 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ 350 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
268 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ 351 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
269 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 352 0x28, 0x1e, /* H & V sizes r15 .. r16 */
270 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 353 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
271 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ 354 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
@@ -294,47 +377,65 @@ static const __u8 ov7630_sensor_init[][8] = {
294 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, 377 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
295}; 378};
296 379
380static const __u8 ov7630_sensor_init_3[][8] = {
381 {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
382};
383
297static const __u8 initPas106[] = { 384static const __u8 initPas106[] = {
298 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, 385 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
299 0x00, 0x00, 386 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 387 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
301 0x16, 0x12, 0x28, COMP1, MCK_INIT1, 388 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
302 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 389 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
303}; 390};
304/* compression 0x86 mckinit1 0x2b */ 391/* compression 0x86 mckinit1 0x2b */
305static const __u8 pas106_data[][2] = { 392static const __u8 pas106_sensor_init[][8] = {
306 {0x02, 0x04}, /* Pixel Clock Divider 6 */ 393 /* Pixel Clock Divider 6 */
307 {0x03, 0x13}, /* Frame Time MSB */ 394 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
308/* {0x03, 0x12}, * Frame Time MSB */ 395 /* Frame Time MSB (also seen as 0x12) */
309 {0x04, 0x06}, /* Frame Time LSB */ 396 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
310/* {0x04, 0x05}, * Frame Time LSB */ 397 /* Frame Time LSB (also seen as 0x05) */
311 {0x05, 0x65}, /* Shutter Time Line Offset */ 398 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
312/* {0x05, 0x6d}, * Shutter Time Line Offset */ 399 /* Shutter Time Line Offset (also seen as 0x6d) */
313/* {0x06, 0xb1}, * Shutter Time Pixel Offset */ 400 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
314 {0x06, 0xcd}, /* Shutter Time Pixel Offset */ 401 /* Shutter Time Pixel Offset (also seen as 0xb1) */
315 {0x07, 0xc1}, /* Black Level Subtract Sign */ 402 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
316/* {0x07, 0x00}, * Black Level Subtract Sign */ 403 /* Black Level Subtract Sign (also seen 0x00) */
317 {0x08, 0x06}, /* Black Level Subtract Level */ 404 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
318 {0x08, 0x06}, /* Black Level Subtract Level */ 405 /* Black Level Subtract Level (also seen 0x01) */
319/* {0x08, 0x01}, * Black Level Subtract Level */ 406 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
320 {0x09, 0x05}, /* Color Gain B Pixel 5 a */ 407 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
321 {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */ 408 /* Color Gain B Pixel 5 a */
322 {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */ 409 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
323 {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */ 410 /* Color Gain G1 Pixel 1 5 */
324 {0x0d, 0x00}, /* Color GainH Pixel */ 411 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
325 {0x0e, 0x0e}, /* Global Gain */ 412 /* Color Gain G2 Pixel 1 0 5 */
326 {0x0f, 0x00}, /* Contrast */ 413 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
327 {0x10, 0x06}, /* H&V synchro polarity */ 414 /* Color Gain R Pixel 3 1 */
328 {0x11, 0x06}, /* ?default */ 415 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
329 {0x12, 0x06}, /* DAC scale */ 416 /* Color GainH Pixel */
330 {0x14, 0x02}, /* ?default */ 417 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
331 {0x13, 0x01}, /* Validate Settings */ 418 /* Global Gain */
419 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
420 /* Contrast */
421 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
422 /* H&V synchro polarity */
423 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
424 /* ?default */
425 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
426 /* DAC scale */
427 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
428 /* ?default */
429 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
430 /* Validate Settings */
431 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
332}; 432};
433
333static const __u8 initPas202[] = { 434static const __u8 initPas202[] = {
334 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 435 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
335 0x00, 0x00, 436 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ 437 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
337 0x28, 0x1e, 0x28, 0x89, 0x30, 438 0x28, 0x1e, 0x28, 0x89, 0x20,
338 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c 439 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
339}; 440};
340static const __u8 pas202_sensor_init[][8] = { 441static const __u8 pas202_sensor_init[][8] = {
@@ -364,7 +465,7 @@ static const __u8 pas202_sensor_init[][8] = {
364static const __u8 initTas5110[] = { 465static const __u8 initTas5110[] = {
365 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 466 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
366 0x00, 0x00, 467 0x00, 0x00,
367 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */ 468 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
368 0x16, 0x12, 0x60, 0x86, 0x2b, 469 0x16, 0x12, 0x60, 0x86, 0x2b,
369 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 470 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
370}; 471};
@@ -377,7 +478,7 @@ static const __u8 tas5110_sensor_init[][8] = {
377static const __u8 initTas5130[] = { 478static const __u8 initTas5130[] = {
378 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, 479 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
379 0x00, 0x00, 480 0x00, 0x00,
380 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a, 481 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
381 0x28, 0x1e, 0x60, COMP, MCK_INIT, 482 0x28, 0x1e, 0x60, COMP, MCK_INIT,
382 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c 483 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
383}; 484};
@@ -389,6 +490,21 @@ static const __u8 tas5130_sensor_init[][8] = {
389 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, 490 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
390}; 491};
391 492
493struct sensor_data sensor_data[] = {
494SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
495SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
496SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
497 F_GAIN, 0, 0x21),
498SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
499 0),
500SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
501 NO_EXPO|NO_FREQ, 0),
502SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
503 NO_BRIGHTNESS|NO_FREQ, 0),
504SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
505 0),
506};
507
392/* get one byte in gspca_dev->usb_buf */ 508/* get one byte in gspca_dev->usb_buf */
393static void reg_r(struct gspca_dev *gspca_dev, 509static void reg_r(struct gspca_dev *gspca_dev,
394 __u16 value) 510 __u16 value)
@@ -409,7 +525,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
409 int len) 525 int len)
410{ 526{
411#ifdef GSPCA_DEBUG 527#ifdef GSPCA_DEBUG
412 if (len > sizeof gspca_dev->usb_buf) { 528 if (len > USB_BUF_SZ) {
413 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); 529 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
414 return; 530 return;
415 } 531 }
@@ -425,26 +541,6 @@ static void reg_w(struct gspca_dev *gspca_dev,
425 500); 541 500);
426} 542}
427 543
428static void reg_w_big(struct gspca_dev *gspca_dev,
429 __u16 value,
430 const __u8 *buffer,
431 int len)
432{
433 __u8 *tmpbuf;
434
435 tmpbuf = kmalloc(len, GFP_KERNEL);
436 memcpy(tmpbuf, buffer, len);
437 usb_control_msg(gspca_dev->dev,
438 usb_sndctrlpipe(gspca_dev->dev, 0),
439 0x08, /* request */
440 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
441 value,
442 0, /* index */
443 tmpbuf, len,
444 500);
445 kfree(tmpbuf);
446}
447
448static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) 544static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
449{ 545{
450 int retry = 60; 546 int retry = 60;
@@ -487,7 +583,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
487 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; 583 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
488 584
489 /* change reg 0x06 */ 585 /* change reg 0x06 */
490 i2cOV[1] = sd->sensor_addr; 586 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
491 i2cOV[3] = sd->brightness; 587 i2cOV[3] = sd->brightness;
492 if (i2c_w(gspca_dev, i2cOV) < 0) 588 if (i2c_w(gspca_dev, i2cOV) < 0)
493 goto err; 589 goto err;
@@ -545,9 +641,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
545 goto err; 641 goto err;
546 break; 642 break;
547 } 643 }
548 case SENSOR_TAS5110:
549 /* FIXME figure out howto control brightness on TAS5110 */
550 break;
551 } 644 }
552 return; 645 return;
553err: 646err:
@@ -577,7 +670,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
577 case SENSOR_OV7630: { 670 case SENSOR_OV7630: {
578 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 671 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
579 672
580 i2c[1] = sd->sensor_addr; 673 i2c[1] = sensor_data[sd->sensor].sensor_addr;
581 i2c[3] = gain >> 2; 674 i2c[3] = gain >> 2;
582 if (i2c_w(gspca_dev, i2c) < 0) 675 if (i2c_w(gspca_dev, i2c) < 0)
583 goto err; 676 goto err;
@@ -604,7 +697,7 @@ static void setgain(struct gspca_dev *gspca_dev)
604 rgb_value = gain; 697 rgb_value = gain;
605 reg_w(gspca_dev, 0x11, &rgb_value, 1); 698 reg_w(gspca_dev, 0x11, &rgb_value, 1);
606 699
607 if (sd->sensor_has_gain) 700 if (sensor_data[sd->sensor].flags & F_GAIN)
608 setsensorgain(gspca_dev); 701 setsensorgain(gspca_dev);
609} 702}
610 703
@@ -665,6 +758,11 @@ static void setexposure(struct gspca_dev *gspca_dev)
665 else if (reg11 > 16) 758 else if (reg11 > 16)
666 reg11 = 16; 759 reg11 = 16;
667 760
761 /* In 640x480, if the reg11 has less than 3, the image is
762 unstable (not enough bandwidth). */
763 if (gspca_dev->width == 640 && reg11 < 3)
764 reg11 = 3;
765
668 /* frame exposure time in ms = 1000 * reg11 / 30 -> 766 /* frame exposure time in ms = 1000 * reg11 / 30 ->
669 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ 767 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
670 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); 768 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
@@ -678,13 +776,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
678 else if (reg10 > reg10_max) 776 else if (reg10 > reg10_max)
679 reg10 = reg10_max; 777 reg10 = reg10_max;
680 778
681 /* In 640x480, if the reg11 has less than 3, the image is
682 unstable (not enough bandwidth). */
683 if (gspca_dev->width == 640 && reg11 < 3)
684 reg11 = 3;
685
686 /* Write reg 10 and reg11 low nibble */ 779 /* Write reg 10 and reg11 low nibble */
687 i2c[1] = sd->sensor_addr; 780 i2c[1] = sensor_data[sd->sensor].sensor_addr;
688 i2c[3] = reg10; 781 i2c[3] = reg10;
689 i2c[4] |= reg11 - 1; 782 i2c[4] |= reg11 - 1;
690 783
@@ -724,7 +817,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
724 ? 0x4f : 0x8a; 817 ? 0x4f : 0x8a;
725 break; 818 break;
726 } 819 }
727 i2c[1] = sd->sensor_addr; 820 i2c[1] = sensor_data[sd->sensor].sensor_addr;
728 if (i2c_w(gspca_dev, i2c) < 0) 821 if (i2c_w(gspca_dev, i2c) < 0)
729 PDEBUG(D_ERR, "i2c error setfreq"); 822 PDEBUG(D_ERR, "i2c error setfreq");
730 break; 823 break;
@@ -757,30 +850,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
757{ 850{
758 struct sd *sd = (struct sd *) gspca_dev; 851 struct sd *sd = (struct sd *) gspca_dev;
759 struct cam *cam; 852 struct cam *cam;
760 int sif = 0;
761 853
762 /* nctrls depends upon the sensor, so we use a per cam copy */ 854 reg_r(gspca_dev, 0x00);
763 memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); 855 if (gspca_dev->usb_buf[0] != 0x10)
764 gspca_dev->sd_desc = &sd->sd_desc; 856 return -ENODEV;
765 857
766 /* copy the webcam info from the device id */ 858 /* copy the webcam info from the device id */
767 sd->sensor = (id->driver_info >> 24) & 0xff; 859 sd->sensor = id->driver_info >> 8;
768 if (id->driver_info & (F_GAIN << 16)) 860 sd->bridge = id->driver_info & 0xff;
769 sd->sensor_has_gain = 1; 861 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
770 if (id->driver_info & (F_AUTO << 16))
771 sd->sd_desc.dq_callback = do_autogain;
772 if (id->driver_info & (F_SIF << 16))
773 sif = 1;
774 if (id->driver_info & (F_H18 << 16))
775 sd->fr_h_sz = 18; /* size of frame header */
776 else
777 sd->fr_h_sz = 12;
778 sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff;
779 sd->sensor_addr = id->driver_info & 0xff;
780 862
781 cam = &gspca_dev->cam; 863 cam = &gspca_dev->cam;
782 cam->epaddr = 0x01; 864 cam->epaddr = 0x01;
783 if (!sif) { 865 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
784 cam->cam_mode = vga_mode; 866 cam->cam_mode = vga_mode;
785 cam->nmodes = ARRAY_SIZE(vga_mode); 867 cam->nmodes = ARRAY_SIZE(vga_mode);
786 } else { 868 } else {
@@ -790,157 +872,98 @@ static int sd_config(struct gspca_dev *gspca_dev,
790 sd->brightness = BRIGHTNESS_DEF; 872 sd->brightness = BRIGHTNESS_DEF;
791 sd->gain = GAIN_DEF; 873 sd->gain = GAIN_DEF;
792 sd->exposure = EXPOSURE_DEF; 874 sd->exposure = EXPOSURE_DEF;
793 sd->autogain = AUTOGAIN_DEF; 875 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
876 sd->autogain = 0; /* Disable do_autogain callback */
877 else
878 sd->autogain = AUTOGAIN_DEF;
794 sd->freq = FREQ_DEF; 879 sd->freq = FREQ_DEF;
795 880
796 return 0; 881 return 0;
797} 882}
798 883
799/* this function is called at open time */ 884/* this function is called at probe and resume time */
800static int sd_open(struct gspca_dev *gspca_dev) 885static int sd_init(struct gspca_dev *gspca_dev)
801{ 886{
802 reg_r(gspca_dev, 0x00); 887 const __u8 stop = 0x09; /* Disable stream turn of LED */
803 if (gspca_dev->usb_buf[0] != 0x10)
804 return -ENODEV;
805 return 0;
806}
807 888
808static void pas106_i2cinit(struct gspca_dev *gspca_dev) 889 reg_w(gspca_dev, 0x01, &stop, 1);
809{ 890
810 int i; 891 return 0;
811 const __u8 *data;
812 __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
813
814 i = ARRAY_SIZE(pas106_data);
815 data = pas106_data[0];
816 while (--i >= 0) {
817 memcpy(&i2c1[2], data, 2);
818 /* copy 2 bytes from the template */
819 if (i2c_w(gspca_dev, i2c1) < 0)
820 PDEBUG(D_ERR, "i2c error pas106");
821 data += 2;
822 }
823} 892}
824 893
825/* -- start the camera -- */ 894/* -- start the camera -- */
826static void sd_start(struct gspca_dev *gspca_dev) 895static void sd_start(struct gspca_dev *gspca_dev)
827{ 896{
828 struct sd *sd = (struct sd *) gspca_dev; 897 struct sd *sd = (struct sd *) gspca_dev;
829 int mode, l = 0x1f; 898 struct cam *cam = &gspca_dev->cam;
899 int mode, l;
830 const __u8 *sn9c10x; 900 const __u8 *sn9c10x;
831 __u8 reg17_19[3]; 901 __u8 reg12_19[8];
832 902
833 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 903 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
904 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
905 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
906 memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
907 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
908 /* Special cases where reg 17 and or 19 value depends on mode */
834 switch (sd->sensor) { 909 switch (sd->sensor) {
835 case SENSOR_HV7131R:
836 sn9c10x = initHv7131;
837 reg17_19[0] = 0x60;
838 reg17_19[1] = (mode << 4) | 0x8a;
839 reg17_19[2] = 0x20;
840 break;
841 case SENSOR_OV6650:
842 sn9c10x = initOv6650;
843 reg17_19[0] = 0x68;
844 reg17_19[1] = (mode << 4) | 0x8b;
845 reg17_19[2] = 0x20;
846 break;
847 case SENSOR_OV7630:
848 if (sd->fr_h_sz == 18) { /* SN9C103 */
849 sn9c10x = initOv7630_3;
850 l = sizeof initOv7630_3;
851 } else
852 sn9c10x = initOv7630;
853 reg17_19[0] = 0x68;
854 reg17_19[1] = (mode << 4) | COMP2;
855 reg17_19[2] = MCK_INIT1;
856 break;
857 case SENSOR_PAS106:
858 sn9c10x = initPas106;
859 reg17_19[0] = 0x24; /* 0x28 */
860 reg17_19[1] = (mode << 4) | COMP1;
861 reg17_19[2] = MCK_INIT1;
862 break;
863 case SENSOR_PAS202: 910 case SENSOR_PAS202:
864 sn9c10x = initPas202; 911 reg12_19[5] = mode ? 0x24 : 0x20;
865 reg17_19[0] = mode ? 0x24 : 0x20;
866 reg17_19[1] = (mode << 4) | 0x89;
867 reg17_19[2] = 0x20;
868 break; 912 break;
869 case SENSOR_TAS5110: 913 case SENSOR_TAS5130CXX:
870 sn9c10x = initTas5110; 914 /* probably not mode specific at all most likely the upper
871 reg17_19[0] = 0x60; 915 nibble of 0x19 is exposure (clock divider) just as with
872 reg17_19[1] = (mode << 4) | 0x86; 916 the tas5110, we need someone to test this. */
873 reg17_19[2] = 0x2b; /* 0xf3; */ 917 reg12_19[7] = mode ? 0x23 : 0x43;
874 break;
875 default:
876/* case SENSOR_TAS5130CXX: */
877 sn9c10x = initTas5130;
878 reg17_19[0] = 0x60;
879 reg17_19[1] = (mode << 4) | COMP;
880 reg17_19[2] = mode ? 0x23 : 0x43;
881 break; 918 break;
882 } 919 }
920 /* Disable compression when the raw bayer format has been selected */
921 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
922 reg12_19[6] &= ~0x80;
923
924 /* Vga mode emulation on SIF sensor? */
925 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
926 reg12_19[0] += 16; /* 0x12: hstart adjust */
927 reg12_19[1] += 24; /* 0x13: vstart adjust */
928 reg12_19[3] = 320 / 16; /* 0x15: hsize */
929 reg12_19[4] = 240 / 16; /* 0x16: vsize */
930 }
883 931
884 /* reg 0x01 bit 2 video transfert on */ 932 /* reg 0x01 bit 2 video transfert on */
885 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); 933 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
886 /* reg 0x17 SensorClk enable inv Clk 0x60 */ 934 /* reg 0x17 SensorClk enable inv Clk 0x60 */
887 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); 935 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
888 /* Set the registers from the template */ 936 /* Set the registers from the template */
889 reg_w_big(gspca_dev, 0x01, sn9c10x, l); 937 reg_w(gspca_dev, 0x01, sn9c10x, l);
890 switch (sd->sensor) { 938
891 case SENSOR_HV7131R: 939 /* Init the sensor */
892 i2c_w_vector(gspca_dev, hv7131_sensor_init, 940 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
893 sizeof hv7131_sensor_init); 941 sensor_data[sd->sensor].sensor_init_size);
894 break; 942 if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
895 case SENSOR_OV6650: 943 i2c_w_vector(gspca_dev,
896 i2c_w_vector(gspca_dev, ov6650_sensor_init, 944 sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
897 sizeof ov6650_sensor_init); 945 sensor_data[sd->sensor].sensor_bridge_init_size[
898 break; 946 sd->bridge]);
899 case SENSOR_OV7630: 947
900 i2c_w_vector(gspca_dev, ov7630_sensor_init,
901 sizeof ov7630_sensor_init);
902 if (sd->fr_h_sz == 18) { /* SN9C103 */
903 const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
904 0x00, 0x00, 0x10 };
905 i2c_w(gspca_dev, i2c);
906 }
907 break;
908 case SENSOR_PAS106:
909 pas106_i2cinit(gspca_dev);
910 break;
911 case SENSOR_PAS202:
912 i2c_w_vector(gspca_dev, pas202_sensor_init,
913 sizeof pas202_sensor_init);
914 break;
915 case SENSOR_TAS5110:
916 i2c_w_vector(gspca_dev, tas5110_sensor_init,
917 sizeof tas5110_sensor_init);
918 break;
919 default:
920/* case SENSOR_TAS5130CXX: */
921 i2c_w_vector(gspca_dev, tas5130_sensor_init,
922 sizeof tas5130_sensor_init);
923 break;
924 }
925 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ 948 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
926 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); 949 reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
927 /* compression register */ 950 /* compression register */
928 reg_w(gspca_dev, 0x18, &reg17_19[1], 1); 951 reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
929 /* H_start */ 952 /* H_start */
930 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); 953 reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
931 /* V_START */ 954 /* V_START */
932 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); 955 reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
933 /* reset 0x17 SensorClk enable inv Clk 0x60 */ 956 /* reset 0x17 SensorClk enable inv Clk 0x60 */
934 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ 957 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
935 reg_w(gspca_dev, 0x17, &reg17_19[0], 1); 958 reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
936 /*MCKSIZE ->3 */ /*fixme: not ov7630*/ 959 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
937 reg_w(gspca_dev, 0x19, &reg17_19[2], 1); 960 reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
938 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ 961 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
939 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); 962 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
940 /* Enable video transfert */ 963 /* Enable video transfert */
941 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); 964 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
942 /* Compression */ 965 /* Compression */
943 reg_w(gspca_dev, 0x18, &reg17_19[1], 2); 966 reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
944 msleep(20); 967 msleep(20);
945 968
946 sd->reg11 = -1; 969 sd->reg11 = -1;
@@ -957,18 +980,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
957 980
958static void sd_stopN(struct gspca_dev *gspca_dev) 981static void sd_stopN(struct gspca_dev *gspca_dev)
959{ 982{
960 __u8 ByteSend; 983 sd_init(gspca_dev);
961
962 ByteSend = 0x09; /* 0X00 */
963 reg_w(gspca_dev, 0x01, &ByteSend, 1);
964}
965
966static void sd_stop0(struct gspca_dev *gspca_dev)
967{
968}
969
970static void sd_close(struct gspca_dev *gspca_dev)
971{
972} 984}
973 985
974static void sd_pkt_scan(struct gspca_dev *gspca_dev, 986static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -978,6 +990,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
978{ 990{
979 int i; 991 int i;
980 struct sd *sd = (struct sd *) gspca_dev; 992 struct sd *sd = (struct sd *) gspca_dev;
993 struct cam *cam = &gspca_dev->cam;
981 994
982 /* frames start with: 995 /* frames start with:
983 * ff ff 00 c4 c4 96 synchro 996 * ff ff 00 c4 c4 96 synchro
@@ -998,20 +1011,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
998 && data[5 + i] == 0x96) { /* start of frame */ 1011 && data[5 + i] == 0x96) { /* start of frame */
999 int lum = -1; 1012 int lum = -1;
1000 int pkt_type = LAST_PACKET; 1013 int pkt_type = LAST_PACKET;
1014 int fr_h_sz = (sd->bridge == BRIDGE_103) ?
1015 18 : 12;
1001 1016
1002 if (len - i < sd->fr_h_sz) { 1017 if (len - i < fr_h_sz) {
1003 PDEBUG(D_STREAM, "packet too short to" 1018 PDEBUG(D_STREAM, "packet too short to"
1004 " get avg brightness"); 1019 " get avg brightness");
1005 } else if (sd->fr_h_sz == 12) { 1020 } else if (sd->bridge == BRIDGE_103) {
1006 lum = data[i + 8] + (data[i + 9] << 8);
1007 } else {
1008 lum = data[i + 9] + 1021 lum = data[i + 9] +
1009 (data[i + 10] << 8); 1022 (data[i + 10] << 8);
1023 } else {
1024 lum = data[i + 8] + (data[i + 9] << 8);
1010 } 1025 }
1011 if (lum == 0) { 1026 /* When exposure changes midway a frame we
1027 get a lum of 0 in this case drop 2 frames
1028 as the frames directly after an exposure
1029 change have an unstable image. Sometimes lum
1030 *really* is 0 (cam used in low light with
1031 low exposure setting), so do not drop frames
1032 if the previous lum was 0 too. */
1033 if (lum == 0 && sd->prev_avg_lum != 0) {
1012 lum = -1; 1034 lum = -1;
1013 sd->frames_to_drop = 2; 1035 sd->frames_to_drop = 2;
1014 } 1036 sd->prev_avg_lum = 0;
1037 } else
1038 sd->prev_avg_lum = lum;
1015 atomic_set(&sd->avg_lum, lum); 1039 atomic_set(&sd->avg_lum, lum);
1016 1040
1017 if (sd->frames_to_drop) { 1041 if (sd->frames_to_drop) {
@@ -1021,14 +1045,25 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1021 1045
1022 frame = gspca_frame_add(gspca_dev, pkt_type, 1046 frame = gspca_frame_add(gspca_dev, pkt_type,
1023 frame, data, 0); 1047 frame, data, 0);
1024 data += i + sd->fr_h_sz; 1048 data += i + fr_h_sz;
1025 len -= i + sd->fr_h_sz; 1049 len -= i + fr_h_sz;
1026 gspca_frame_add(gspca_dev, FIRST_PACKET, 1050 gspca_frame_add(gspca_dev, FIRST_PACKET,
1027 frame, data, len); 1051 frame, data, len);
1028 return; 1052 return;
1029 } 1053 }
1030 } 1054 }
1031 } 1055 }
1056
1057 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1058 /* In raw mode we sometimes get some garbage after the frame
1059 ignore this */
1060 int used = frame->data_end - frame->data;
1061 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1062
1063 if (used + len > size)
1064 len = size - used;
1065 }
1066
1032 gspca_frame_add(gspca_dev, INTER_PACKET, 1067 gspca_frame_add(gspca_dev, INTER_PACKET,
1033 frame, data, len); 1068 frame, data, len);
1034} 1069}
@@ -1162,58 +1197,45 @@ static const struct sd_desc sd_desc = {
1162 .ctrls = sd_ctrls, 1197 .ctrls = sd_ctrls,
1163 .nctrls = ARRAY_SIZE(sd_ctrls), 1198 .nctrls = ARRAY_SIZE(sd_ctrls),
1164 .config = sd_config, 1199 .config = sd_config,
1165 .open = sd_open, 1200 .init = sd_init,
1166 .start = sd_start, 1201 .start = sd_start,
1167 .stopN = sd_stopN, 1202 .stopN = sd_stopN,
1168 .stop0 = sd_stop0,
1169 .close = sd_close,
1170 .pkt_scan = sd_pkt_scan, 1203 .pkt_scan = sd_pkt_scan,
1171 .querymenu = sd_querymenu, 1204 .querymenu = sd_querymenu,
1205 .dq_callback = do_autogain,
1172}; 1206};
1173 1207
1174/* -- module initialisation -- */ 1208/* -- module initialisation -- */
1175#define SFCI(sensor, flags, nctrls, i2c_addr) \ 1209#define SB(sensor, bridge) \
1176 .driver_info = (SENSOR_ ## sensor << 24) \ 1210 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1177 | ((flags) << 16) \ 1211
1178 | ((nctrls) << 8) \ 1212
1179 | (i2c_addr)
1180static __devinitdata struct usb_device_id device_table[] = { 1213static __devinitdata struct usb_device_id device_table[] = {
1181#ifndef CONFIG_USB_SN9C102 1214 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
1182 {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ 1215 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
1183 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, 1216#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1184 {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ 1217 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */
1185 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, 1218 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1186 {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */ 1219 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1187 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1188 {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */
1189 SFCI(PAS106, F_SIF, 2, 0)},
1190 {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */
1191 SFCI(PAS106, F_SIF, 2, 0)},
1192#endif 1220#endif
1193 {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ 1221 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1194 SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)}, 1222#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1195#ifndef CONFIG_USB_SN9C102 1223 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1196 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ 1224 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1197 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, 1225 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1198 {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ 1226 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1199 SFCI(TAS5130CXX, 0, 2, 0)}, 1227 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1200 {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ 1228 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1201 SFCI(TAS5130CXX, 0, 2, 0)},
1202 {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */
1203 SFCI(PAS202, 0, 2, 0)},
1204 {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */
1205 SFCI(PAS106, F_SIF, 2, 0)},
1206 {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */
1207 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
1208 {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */
1209 SFCI(HV7131R, 0, 2, 0)},
1210 {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */
1211 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
1212 {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */
1213 SFCI(PAS202, F_H18, 2, 0)},
1214 {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */
1215 SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
1216#endif 1229#endif
1230 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1231#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1232 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1233#endif
1234 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1235#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1236 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1237#endif
1238 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1217 {} 1239 {}
1218}; 1240};
1219MODULE_DEVICE_TABLE(usb, device_table); 1241MODULE_DEVICE_TABLE(usb, device_table);
@@ -1231,6 +1253,10 @@ static struct usb_driver sd_driver = {
1231 .id_table = device_table, 1253 .id_table = device_table,
1232 .probe = sd_probe, 1254 .probe = sd_probe,
1233 .disconnect = gspca_disconnect, 1255 .disconnect = gspca_disconnect,
1256#ifdef CONFIG_PM
1257 .suspend = gspca_suspend,
1258 .resume = gspca_resume,
1259#endif
1234}; 1260};
1235 1261
1236/* -- module insert / remove -- */ 1262/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 245a30ec5fb1..d75b1d20b318 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -54,8 +54,10 @@ struct sd {
54#define SENSOR_HV7131R 0 54#define SENSOR_HV7131R 0
55#define SENSOR_MI0360 1 55#define SENSOR_MI0360 1
56#define SENSOR_MO4000 2 56#define SENSOR_MO4000 2
57#define SENSOR_OV7648 3 57#define SENSOR_OM6802 3
58#define SENSOR_OV7660 4 58#define SENSOR_OV7630 4
59#define SENSOR_OV7648 5
60#define SENSOR_OV7660 6
59 unsigned char i2c_base; 61 unsigned char i2c_base;
60}; 62};
61 63
@@ -76,7 +78,8 @@ static struct ctrl sd_ctrls[] = {
76 .type = V4L2_CTRL_TYPE_INTEGER, 78 .type = V4L2_CTRL_TYPE_INTEGER,
77 .name = "Brightness", 79 .name = "Brightness",
78 .minimum = 0, 80 .minimum = 0,
79 .maximum = 0xffff, 81#define BRIGHTNESS_MAX 0xffff
82 .maximum = BRIGHTNESS_MAX,
80 .step = 1, 83 .step = 1,
81#define BRIGHTNESS_DEF 0x7fff 84#define BRIGHTNESS_DEF 0x7fff
82 .default_value = BRIGHTNESS_DEF, 85 .default_value = BRIGHTNESS_DEF,
@@ -90,7 +93,8 @@ static struct ctrl sd_ctrls[] = {
90 .type = V4L2_CTRL_TYPE_INTEGER, 93 .type = V4L2_CTRL_TYPE_INTEGER,
91 .name = "Contrast", 94 .name = "Contrast",
92 .minimum = 0, 95 .minimum = 0,
93 .maximum = 127, 96#define CONTRAST_MAX 127
97 .maximum = CONTRAST_MAX,
94 .step = 1, 98 .step = 1,
95#define CONTRAST_DEF 63 99#define CONTRAST_DEF 63
96 .default_value = CONTRAST_DEF, 100 .default_value = CONTRAST_DEF,
@@ -104,14 +108,15 @@ static struct ctrl sd_ctrls[] = {
104 .type = V4L2_CTRL_TYPE_INTEGER, 108 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Color", 109 .name = "Color",
106 .minimum = 0, 110 .minimum = 0,
107 .maximum = 255, 111 .maximum = 64,
108 .step = 1, 112 .step = 1,
109#define COLOR_DEF 127 113#define COLOR_DEF 32
110 .default_value = COLOR_DEF, 114 .default_value = COLOR_DEF,
111 }, 115 },
112 .set = sd_setcolors, 116 .set = sd_setcolors,
113 .get = sd_getcolors, 117 .get = sd_getcolors,
114 }, 118 },
119#define AUTOGAIN_IDX 3
115 { 120 {
116 { 121 {
117 .id = V4L2_CID_AUTOGAIN, 122 .id = V4L2_CID_AUTOGAIN,
@@ -131,7 +136,7 @@ static struct ctrl sd_ctrls[] = {
131static struct v4l2_pix_format vga_mode[] = { 136static struct v4l2_pix_format vga_mode[] = {
132 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 137 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133 .bytesperline = 160, 138 .bytesperline = 160,
134 .sizeimage = 160 * 120 * 3 / 8 + 590, 139 .sizeimage = 160 * 120 * 4 / 8 + 590,
135 .colorspace = V4L2_COLORSPACE_JPEG, 140 .colorspace = V4L2_COLORSPACE_JPEG,
136 .priv = 2}, 141 .priv = 2},
137 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 142 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -180,6 +185,31 @@ static const __u8 sn_mo4000[] = {
180 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 185 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
181}; 186};
182 187
188static const __u8 sn_om6802[] = {
189/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
190 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
191/* reg8 reg9 rega regb regc regd rege regf */
192 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
194 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
195/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
196 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
198 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
199 0xf7
200};
201
202static const __u8 sn_ov7630[] = {
203/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
204 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
205/* reg8 reg9 rega regb regc regd rege regf */
206 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
207/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
208 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
209/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
210 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
211};
212
183static const __u8 sn_ov7648[] = { 213static const __u8 sn_ov7648[] = {
184/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 214/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
185 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 215 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
@@ -207,31 +237,22 @@ static const __u8 *sn_tb[] = {
207 sn_hv7131, 237 sn_hv7131,
208 sn_mi0360, 238 sn_mi0360,
209 sn_mo4000, 239 sn_mo4000,
240 sn_om6802,
241 sn_ov7630,
210 sn_ov7648, 242 sn_ov7648,
211 sn_ov7660 243 sn_ov7660
212}; 244};
213 245
214static const __u8 regsn20[] = { 246static const __u8 gamma_def[] = {
215 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 247 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
216 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 248 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
217}; 249};
218static const __u8 regsn20_sn9c325[] = {
219 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
220 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
221};
222 250
223static const __u8 reg84[] = { 251static const __u8 reg84[] = {
224 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, 252 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
225 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, 253 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
226/* 0x00, 0x00, 0x00, 0x00, 0x00 */ 254 0xf7, 0x0f, 0x00, 0x00, 0x00
227 0xf7, 0x0f, 0x0a, 0x00, 0x00
228};
229static const __u8 reg84_sn9c325[] = {
230 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
231 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
232 0xf8, 0x0f, 0x00, 0x00, 0x00
233}; 255};
234
235static const __u8 hv7131r_sensor_init[][8] = { 256static const __u8 hv7131r_sensor_init[][8] = {
236 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 257 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
237 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, 258 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
@@ -340,6 +361,92 @@ static const __u8 mo4000_sensor_init[][8] = {
340 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, 361 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
341 {} 362 {}
342}; 363};
364static __u8 om6802_sensor_init[][8] = {
365 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
366 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
367 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
368 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
369/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
370 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
371 /* white balance & auto-exposure */
372/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
373 * set color mode */
374/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
375 * max AGC value in AE */
376/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
377 * preset AGC */
378/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
379 * preset brightness */
380/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
381 * preset contrast */
382/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
383 * preset gamma */
384 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
385 /* luminance mode (0x4f = AE) */
386 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
387 /* preset shutter */
388/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
389 * auto frame rate */
390/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
391
392/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
393/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
394/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
395/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
396 {}
397};
398static const __u8 ov7630_sensor_init[][8] = {
399 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
400 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
401/* win: delay 20ms */
402 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
403 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
404/* win: delay 20ms */
405 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
406/* win: i2c_r from 00 to 80 */
407 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
408 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
409 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
410 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
411 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
412 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
413 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
414 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
415 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
416 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
417 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
418 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
420 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
422 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
424 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
425 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
426 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
427 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
428 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
429 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
430 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
431 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
432 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
433/* */
434 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
435 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
436/*fixme: + 0x12, 0x04*/
437 {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
441/* */
442 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
444 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
445/* */
446 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
447/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
448 {}
449};
343static const __u8 ov7660_sensor_init[][8] = { 450static const __u8 ov7660_sensor_init[][8] = {
344 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 451 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
345/* (delay 20ms) */ 452/* (delay 20ms) */
@@ -506,10 +613,16 @@ static const __u8 qtable4[] = {
506 0x29, 0x29, 0x29, 0x29 613 0x29, 0x29, 0x29, 0x29
507}; 614};
508 615
509/* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */ 616/* read <len> bytes to gspca_dev->usb_buf */
510static void reg_r(struct gspca_dev *gspca_dev, 617static void reg_r(struct gspca_dev *gspca_dev,
511 __u16 value, int len) 618 __u16 value, int len)
512{ 619{
620#ifdef GSPCA_DEBUG
621 if (len > USB_BUF_SZ) {
622 err("reg_r: buffer overflow");
623 return;
624 }
625#endif
513 usb_control_msg(gspca_dev->dev, 626 usb_control_msg(gspca_dev->dev,
514 usb_rcvctrlpipe(gspca_dev->dev, 0), 627 usb_rcvctrlpipe(gspca_dev->dev, 0),
515 0, 628 0,
@@ -542,29 +655,20 @@ static void reg_w(struct gspca_dev *gspca_dev,
542{ 655{
543 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", 656 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
544 value, buffer[0], buffer[1]); 657 value, buffer[0], buffer[1]);
545 if (len <= sizeof gspca_dev->usb_buf) { 658#ifdef GSPCA_DEBUG
546 memcpy(gspca_dev->usb_buf, buffer, len); 659 if (len > USB_BUF_SZ) {
547 usb_control_msg(gspca_dev->dev, 660 err("reg_w: buffer overflow");
548 usb_sndctrlpipe(gspca_dev->dev, 0), 661 return;
549 0x08,
550 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
551 value, 0,
552 gspca_dev->usb_buf, len,
553 500);
554 } else {
555 __u8 *tmpbuf;
556
557 tmpbuf = kmalloc(len, GFP_KERNEL);
558 memcpy(tmpbuf, buffer, len);
559 usb_control_msg(gspca_dev->dev,
560 usb_sndctrlpipe(gspca_dev->dev, 0),
561 0x08,
562 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
563 value, 0,
564 tmpbuf, len,
565 500);
566 kfree(tmpbuf);
567 } 662 }
663#endif
664 memcpy(gspca_dev->usb_buf, buffer, len);
665 usb_control_msg(gspca_dev->dev,
666 usb_sndctrlpipe(gspca_dev->dev, 0),
667 0x08,
668 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
669 value, 0,
670 gspca_dev->usb_buf, len,
671 500);
568} 672}
569 673
570/* I2C write 1 byte */ 674/* I2C write 1 byte */
@@ -665,7 +769,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
665 static const __u8 regd4[] = {0x60, 0x00, 0x00}; 769 static const __u8 regd4[] = {0x60, 0x00, 0x00};
666 770
667 reg_w1(gspca_dev, 0xf1, 0x00); 771 reg_w1(gspca_dev, 0xf1, 0x00);
668 reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ 772 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
669 773
670 /* configure gpio */ 774 /* configure gpio */
671 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 775 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
@@ -685,21 +789,41 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
685 789
686 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 790 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
687 791
688 switch (sd->bridge) { 792 switch (sd->sensor) {
689 case BRIDGE_SN9C325: 793 case SENSOR_OM6802:
794 reg_w1(gspca_dev, 0x02, 0x71);
795 reg_w1(gspca_dev, 0x01, 0x42);
796 reg_w1(gspca_dev, 0x17, 0x64);
797 reg_w1(gspca_dev, 0x01, 0x42);
798 break;
799/*jfm: from win trace */
800 case SENSOR_OV7630:
801 reg_w1(gspca_dev, 0x01, 0x61);
802 reg_w1(gspca_dev, 0x17, 0xe2);
803 reg_w1(gspca_dev, 0x01, 0x60);
804 reg_w1(gspca_dev, 0x01, 0x40);
805 break;
806 case SENSOR_OV7648:
690 reg_w1(gspca_dev, 0x01, 0x43); 807 reg_w1(gspca_dev, 0x01, 0x43);
691 reg_w1(gspca_dev, 0x17, 0xae); 808 reg_w1(gspca_dev, 0x17, 0xae);
692 reg_w1(gspca_dev, 0x01, 0x42); 809 reg_w1(gspca_dev, 0x01, 0x42);
693 break; 810 break;
811/*jfm: from win trace */
812 case SENSOR_OV7660:
813 reg_w1(gspca_dev, 0x01, 0x61);
814 reg_w1(gspca_dev, 0x17, 0x20);
815 reg_w1(gspca_dev, 0x01, 0x60);
816 reg_w1(gspca_dev, 0x01, 0x40);
817 break;
694 default: 818 default:
695 reg_w1(gspca_dev, 0x01, 0x43); 819 reg_w1(gspca_dev, 0x01, 0x43);
696 reg_w1(gspca_dev, 0x17, 0x61); 820 reg_w1(gspca_dev, 0x17, 0x61);
697 reg_w1(gspca_dev, 0x01, 0x42); 821 reg_w1(gspca_dev, 0x01, 0x42);
698 } 822 if (sd->sensor == SENSOR_HV7131R) {
699 823 if (probesensor(gspca_dev) < 0)
700 if (sd->sensor == SENSOR_HV7131R) { 824 return -ENODEV;
701 if (probesensor(gspca_dev) < 0) 825 }
702 return -ENODEV; 826 break;
703 } 827 }
704 return 0; 828 return 0;
705} 829}
@@ -737,6 +861,40 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
737 } 861 }
738} 862}
739 863
864static void om6802_InitSensor(struct gspca_dev *gspca_dev)
865{
866 int i = 0;
867
868 while (om6802_sensor_init[i][0]) {
869 i2c_w8(gspca_dev, om6802_sensor_init[i]);
870 i++;
871 }
872}
873
874static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
875{
876 int i = 0;
877
878 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
879 i++;
880 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
881 i++;
882 msleep(20);
883 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
884 i++;
885 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
886 i++;
887 msleep(20);
888 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
889 i++;
890/*jfm:win i2c_r from 00 to 80*/
891
892 while (ov7630_sensor_init[i][0]) {
893 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
894 i++;
895 }
896}
897
740static void ov7648_InitSensor(struct gspca_dev *gspca_dev) 898static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
741{ 899{
742 int i = 0; 900 int i = 0;
@@ -783,11 +941,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
783 sd->autogain = AUTOGAIN_DEF; 941 sd->autogain = AUTOGAIN_DEF;
784 sd->ag_cnt = -1; 942 sd->ag_cnt = -1;
785 943
944 switch (sd->sensor) {
945 case SENSOR_OV7630:
946 case SENSOR_OV7648:
947 case SENSOR_OV7660:
948 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
949 break;
950 }
951
786 return 0; 952 return 0;
787} 953}
788 954
789/* this function is called at open time */ 955/* this function is called at probe and resume time */
790static int sd_open(struct gspca_dev *gspca_dev) 956static int sd_init(struct gspca_dev *gspca_dev)
791{ 957{
792 struct sd *sd = (struct sd *) gspca_dev; 958 struct sd *sd = (struct sd *) gspca_dev;
793/* const __u8 *sn9c1xx; */ 959/* const __u8 *sn9c1xx; */
@@ -891,16 +1057,53 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
891 | ((expoMo10[3] & 0x30) >> 4)); 1057 | ((expoMo10[3] & 0x30) >> 4));
892 break; 1058 break;
893 } 1059 }
1060 case SENSOR_OM6802: {
1061 __u8 gainOm[] =
1062 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1063
1064 if (expo > 0x03ff)
1065 expo = 0x03ff;
1066 if (expo < 0x0001)
1067 expo = 0x0001;
1068 gainOm[3] = expo >> 2;
1069 i2c_w8(gspca_dev, gainOm);
1070 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1071 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1072 break;
1073 }
894 } 1074 }
895 return expo; 1075 return expo;
896} 1076}
897 1077
1078/* this function is used for sensors o76xx only */
1079static void setbrightcont(struct gspca_dev *gspca_dev)
1080{
1081 struct sd *sd = (struct sd *) gspca_dev;
1082 unsigned val;
1083 __u8 reg84_full[0x15];
1084
1085 memset(reg84_full, 0, sizeof reg84_full);
1086 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */
1087 reg84_full[2] = val;
1088 reg84_full[0] = (val + 1) / 2;
1089 reg84_full[4] = (val + 1) / 5;
1090 if (val > BRIGHTNESS_DEF)
1091 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1092 / BRIGHTNESS_MAX;
1093 else
1094 val = 0;
1095 reg84_full[0x12] = val; /* 00..1f */
1096 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1097}
1098
1099/* sensor != ov76xx */
898static void setbrightness(struct gspca_dev *gspca_dev) 1100static void setbrightness(struct gspca_dev *gspca_dev)
899{ 1101{
900 struct sd *sd = (struct sd *) gspca_dev; 1102 struct sd *sd = (struct sd *) gspca_dev;
901 unsigned int expo; 1103 unsigned int expo;
902 __u8 k2; 1104 __u8 k2;
903 1105
1106 k2 = sd->brightness >> 10;
904 switch (sd->sensor) { 1107 switch (sd->sensor) {
905 case SENSOR_HV7131R: 1108 case SENSOR_HV7131R:
906 expo = sd->brightness << 4; 1109 expo = sd->brightness << 4;
@@ -915,12 +1118,17 @@ static void setbrightness(struct gspca_dev *gspca_dev)
915 expo = sd->brightness >> 4; 1118 expo = sd->brightness >> 4;
916 sd->exposure = setexposure(gspca_dev, expo); 1119 sd->exposure = setexposure(gspca_dev, expo);
917 break; 1120 break;
1121 case SENSOR_OM6802:
1122 expo = sd->brightness >> 6;
1123 sd->exposure = setexposure(gspca_dev, expo);
1124 k2 = sd->brightness >> 11;
1125 break;
918 } 1126 }
919 1127
920 k2 = sd->brightness >> 10;
921 reg_w1(gspca_dev, 0x96, k2); 1128 reg_w1(gspca_dev, 0x96, k2);
922} 1129}
923 1130
1131/* sensor != ov76xx */
924static void setcontrast(struct gspca_dev *gspca_dev) 1132static void setcontrast(struct gspca_dev *gspca_dev)
925{ 1133{
926 struct sd *sd = (struct sd *) gspca_dev; 1134 struct sd *sd = (struct sd *) gspca_dev;
@@ -937,31 +1145,30 @@ static void setcontrast(struct gspca_dev *gspca_dev)
937static void setcolors(struct gspca_dev *gspca_dev) 1145static void setcolors(struct gspca_dev *gspca_dev)
938{ 1146{
939 struct sd *sd = (struct sd *) gspca_dev; 1147 struct sd *sd = (struct sd *) gspca_dev;
940 __u8 data; 1148 __u8 blue, red;
941 int colour;
942 1149
943 colour = sd->colors - 128; 1150 if (sd->colors >= 32) {
944 if (colour > 0) 1151 red = 32 + (sd->colors - 32) / 2;
945 data = (colour + 32) & 0x7f; /* blue */ 1152 blue = 64 - sd->colors;
946 else 1153 } else {
947 data = (-colour + 32) & 0x7f; /* red */ 1154 red = sd->colors;
948 reg_w1(gspca_dev, 0x05, data); 1155 blue = 32 + (32 - sd->colors) / 2;
1156 }
1157 reg_w1(gspca_dev, 0x05, red);
1158/* reg_w1(gspca_dev, 0x07, 32); */
1159 reg_w1(gspca_dev, 0x06, blue);
949} 1160}
950 1161
951static void setautogain(struct gspca_dev *gspca_dev) 1162static void setautogain(struct gspca_dev *gspca_dev)
952{ 1163{
953 struct sd *sd = (struct sd *) gspca_dev; 1164 struct sd *sd = (struct sd *) gspca_dev;
954 1165
955 switch (sd->sensor) { 1166 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
956 case SENSOR_HV7131R: 1167 return;
957 case SENSOR_MO4000: 1168 if (sd->autogain)
958 case SENSOR_MI0360: 1169 sd->ag_cnt = AG_CNT_START;
959 if (sd->autogain) 1170 else
960 sd->ag_cnt = AG_CNT_START; 1171 sd->ag_cnt = -1;
961 else
962 sd->ag_cnt = -1;
963 break;
964 }
965} 1172}
966 1173
967/* -- start the camera -- */ 1174/* -- start the camera -- */
@@ -975,13 +1182,12 @@ static void sd_start(struct gspca_dev *gspca_dev)
975 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 1182 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
976 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 1183 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
977 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 1184 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
978 static const __u8 CE_sn9c325[] = 1185 static const __u8 CE_ov76xx[] =
979 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ 1186 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7630/48 */
980 1187
981 sn9c1xx = sn_tb[(int) sd->sensor]; 1188 sn9c1xx = sn_tb[(int) sd->sensor];
982 configure_gpio(gspca_dev, sn9c1xx); 1189 configure_gpio(gspca_dev, sn9c1xx);
983 1190
984/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
985 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); 1191 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
986 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); 1192 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
987 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); 1193 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
@@ -994,10 +1200,17 @@ static void sd_start(struct gspca_dev *gspca_dev)
994 reg_w1(gspca_dev, 0xc8, 0x50); 1200 reg_w1(gspca_dev, 0xc8, 0x50);
995 reg_w1(gspca_dev, 0xc9, 0x3c); 1201 reg_w1(gspca_dev, 0xc9, 0x3c);
996 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 1202 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
997 switch (sd->bridge) { 1203 switch (sd->sensor) {
998 case BRIDGE_SN9C325: 1204 case SENSOR_OV7630:
1205 reg17 = 0xe2;
1206 break;
1207 case SENSOR_OV7648:
999 reg17 = 0xae; 1208 reg17 = 0xae;
1000 break; 1209 break;
1210/*jfm: from win trace */
1211 case SENSOR_OV7660:
1212 reg17 = 0xa0;
1213 break;
1001 default: 1214 default:
1002 reg17 = 0x60; 1215 reg17 = 0x60;
1003 break; 1216 break;
@@ -1007,24 +1220,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
1007 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1220 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1008 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1221 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1009 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 1222 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1010 switch (sd->bridge) { 1223 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1011 case BRIDGE_SN9C325: 1224 for (i = 0; i < 8; i++)
1012 reg_w(gspca_dev, 0x20, regsn20_sn9c325, 1225 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1013 sizeof regsn20_sn9c325);
1014 for (i = 0; i < 8; i++)
1015 reg_w(gspca_dev, 0x84, reg84_sn9c325,
1016 sizeof reg84_sn9c325);
1017 reg_w1(gspca_dev, 0x9a, 0x0a);
1018 reg_w1(gspca_dev, 0x99, 0x60);
1019 break;
1020 default:
1021 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1022 for (i = 0; i < 8; i++)
1023 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1024 reg_w1(gspca_dev, 0x9a, 0x08); 1226 reg_w1(gspca_dev, 0x9a, 0x08);
1025 reg_w1(gspca_dev, 0x99, 0x59); 1227 reg_w1(gspca_dev, 0x99, 0x59);
1026 break;
1027 }
1028 1228
1029 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1229 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1030 if (mode) 1230 if (mode)
@@ -1049,6 +1249,15 @@ static void sd_start(struct gspca_dev *gspca_dev)
1049/* reg1 = 0x06; * 640 clk 24Mz (done) */ 1249/* reg1 = 0x06; * 640 clk 24Mz (done) */
1050 } 1250 }
1051 break; 1251 break;
1252 case SENSOR_OM6802:
1253 om6802_InitSensor(gspca_dev);
1254 reg17 = 0x64; /* 640 MCKSIZE */
1255 break;
1256 case SENSOR_OV7630:
1257 ov7630_InitSensor(gspca_dev);
1258 reg17 = 0xe2;
1259 reg1 = 0x44;
1260 break;
1052 case SENSOR_OV7648: 1261 case SENSOR_OV7648:
1053 ov7648_InitSensor(gspca_dev); 1262 ov7648_InitSensor(gspca_dev);
1054 reg17 = 0xa2; 1263 reg17 = 0xa2;
@@ -1073,9 +1282,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
1073 } 1282 }
1074 reg_w(gspca_dev, 0xc0, C0, 6); 1283 reg_w(gspca_dev, 0xc0, C0, 6);
1075 reg_w(gspca_dev, 0xca, CA, 4); 1284 reg_w(gspca_dev, 0xca, CA, 4);
1076 switch (sd->bridge) { 1285 switch (sd->sensor) {
1077 case BRIDGE_SN9C325: 1286 case SENSOR_OV7630:
1078 reg_w(gspca_dev, 0xce, CE_sn9c325, 4); 1287 case SENSOR_OV7648:
1288 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1079 break; 1289 break;
1080 default: 1290 default:
1081 reg_w(gspca_dev, 0xce, CE, 4); 1291 reg_w(gspca_dev, 0xce, CE, 4);
@@ -1093,10 +1303,20 @@ static void sd_start(struct gspca_dev *gspca_dev)
1093 reg_w1(gspca_dev, 0x18, reg18); 1303 reg_w1(gspca_dev, 0x18, reg18);
1094 1304
1095 reg_w1(gspca_dev, 0x17, reg17); 1305 reg_w1(gspca_dev, 0x17, reg17);
1096 reg_w1(gspca_dev, 0x01, reg1); 1306 switch (sd->sensor) {
1097 setbrightness(gspca_dev); 1307 case SENSOR_HV7131R:
1098 setcontrast(gspca_dev); 1308 case SENSOR_MI0360:
1309 case SENSOR_MO4000:
1310 case SENSOR_OM6802:
1311 setbrightness(gspca_dev);
1312 setcontrast(gspca_dev);
1313 break;
1314 default: /* OV76xx */
1315 setbrightcont(gspca_dev);
1316 break;
1317 }
1099 setautogain(gspca_dev); 1318 setautogain(gspca_dev);
1319 reg_w1(gspca_dev, 0x01, reg1);
1100} 1320}
1101 1321
1102static void sd_stopN(struct gspca_dev *gspca_dev) 1322static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1119,6 +1339,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1119 i2c_w8(gspca_dev, stopmi0360); 1339 i2c_w8(gspca_dev, stopmi0360);
1120 data = 0x29; 1340 data = 0x29;
1121 break; 1341 break;
1342 case SENSOR_OV7630:
1122 case SENSOR_OV7648: 1343 case SENSOR_OV7648:
1123 data = 0x29; 1344 data = 0x29;
1124 break; 1345 break;
@@ -1132,15 +1353,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1132 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 1353 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1133 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 1354 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1134 reg_w1(gspca_dev, 0x01, data); 1355 reg_w1(gspca_dev, 0x01, data);
1135 reg_w1(gspca_dev, 0xf1, 0x01); 1356 reg_w1(gspca_dev, 0xf1, 0x00);
1136}
1137
1138static void sd_stop0(struct gspca_dev *gspca_dev)
1139{
1140}
1141
1142static void sd_close(struct gspca_dev *gspca_dev)
1143{
1144} 1357}
1145 1358
1146static void do_autogain(struct gspca_dev *gspca_dev) 1359static void do_autogain(struct gspca_dev *gspca_dev)
@@ -1174,6 +1387,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1174 default: 1387 default:
1175/* case SENSOR_MO4000: */ 1388/* case SENSOR_MO4000: */
1176/* case SENSOR_MI0360: */ 1389/* case SENSOR_MI0360: */
1390/* case SENSOR_OM6802: */
1177 expotimes = sd->exposure; 1391 expotimes = sd->exposure;
1178 expotimes += (luma_mean - delta) >> 6; 1392 expotimes += (luma_mean - delta) >> 6;
1179 if (expotimes < 0) 1393 if (expotimes < 0)
@@ -1229,69 +1443,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1229 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1443 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1230} 1444}
1231 1445
1232static unsigned int getexposure(struct gspca_dev *gspca_dev)
1233{
1234 struct sd *sd = (struct sd *) gspca_dev;
1235 __u8 hexpo, mexpo, lexpo;
1236
1237 switch (sd->sensor) {
1238 case SENSOR_HV7131R:
1239 /* read sensor exposure */
1240 i2c_r5(gspca_dev, 0x25);
1241 return (gspca_dev->usb_buf[0] << 16)
1242 | (gspca_dev->usb_buf[1] << 8)
1243 | gspca_dev->usb_buf[2];
1244 case SENSOR_MI0360:
1245 /* read sensor exposure */
1246 i2c_r5(gspca_dev, 0x09);
1247 return (gspca_dev->usb_buf[0] << 8)
1248 | gspca_dev->usb_buf[1];
1249 case SENSOR_MO4000:
1250 i2c_r5(gspca_dev, 0x0e);
1251 hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
1252 mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
1253 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1254 PDEBUG(D_CONF, "exposure %d",
1255 (hexpo << 10) | (mexpo << 2) | lexpo);
1256 return (hexpo << 10) | (mexpo << 2) | lexpo;
1257 default:
1258/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
1259/* case SENSOR_OV7660: */
1260 /* read sensor exposure */
1261 i2c_r5(gspca_dev, 0x04);
1262 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1263 lexpo = gspca_dev->usb_buf[0] & 0x02;
1264 i2c_r5(gspca_dev, 0x08);
1265 mexpo = gspca_dev->usb_buf[2];
1266 return (hexpo << 10) | (mexpo << 2) | lexpo;
1267 }
1268}
1269
1270static void getbrightness(struct gspca_dev *gspca_dev)
1271{
1272 struct sd *sd = (struct sd *) gspca_dev;
1273
1274 /* hardcoded registers seem not readable */
1275 switch (sd->sensor) {
1276 case SENSOR_HV7131R:
1277 sd->brightness = getexposure(gspca_dev) >> 4;
1278 break;
1279 case SENSOR_MI0360:
1280 sd->brightness = getexposure(gspca_dev) << 4;
1281 break;
1282 case SENSOR_MO4000:
1283 sd->brightness = getexposure(gspca_dev) << 4;
1284 break;
1285 }
1286}
1287
1288static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1446static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1289{ 1447{
1290 struct sd *sd = (struct sd *) gspca_dev; 1448 struct sd *sd = (struct sd *) gspca_dev;
1291 1449
1292 sd->brightness = val; 1450 sd->brightness = val;
1293 if (gspca_dev->streaming) 1451 if (gspca_dev->streaming) {
1294 setbrightness(gspca_dev); 1452 switch (sd->sensor) {
1453 case SENSOR_HV7131R:
1454 case SENSOR_MI0360:
1455 case SENSOR_MO4000:
1456 case SENSOR_OM6802:
1457 setbrightness(gspca_dev);
1458 break;
1459 default: /* OV76xx */
1460 setbrightcont(gspca_dev);
1461 break;
1462 }
1463 }
1295 return 0; 1464 return 0;
1296} 1465}
1297 1466
@@ -1299,7 +1468,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1299{ 1468{
1300 struct sd *sd = (struct sd *) gspca_dev; 1469 struct sd *sd = (struct sd *) gspca_dev;
1301 1470
1302 getbrightness(gspca_dev);
1303 *val = sd->brightness; 1471 *val = sd->brightness;
1304 return 0; 1472 return 0;
1305} 1473}
@@ -1309,8 +1477,19 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1309 struct sd *sd = (struct sd *) gspca_dev; 1477 struct sd *sd = (struct sd *) gspca_dev;
1310 1478
1311 sd->contrast = val; 1479 sd->contrast = val;
1312 if (gspca_dev->streaming) 1480 if (gspca_dev->streaming) {
1313 setcontrast(gspca_dev); 1481 switch (sd->sensor) {
1482 case SENSOR_HV7131R:
1483 case SENSOR_MI0360:
1484 case SENSOR_MO4000:
1485 case SENSOR_OM6802:
1486 setcontrast(gspca_dev);
1487 break;
1488 default: /* OV76xx */
1489 setbrightcont(gspca_dev);
1490 break;
1491 }
1492 }
1314 return 0; 1493 return 0;
1315} 1494}
1316 1495
@@ -1364,11 +1543,9 @@ static const struct sd_desc sd_desc = {
1364 .ctrls = sd_ctrls, 1543 .ctrls = sd_ctrls,
1365 .nctrls = ARRAY_SIZE(sd_ctrls), 1544 .nctrls = ARRAY_SIZE(sd_ctrls),
1366 .config = sd_config, 1545 .config = sd_config,
1367 .open = sd_open, 1546 .init = sd_init,
1368 .start = sd_start, 1547 .start = sd_start,
1369 .stopN = sd_stopN, 1548 .stopN = sd_stopN,
1370 .stop0 = sd_stop0,
1371 .close = sd_close,
1372 .pkt_scan = sd_pkt_scan, 1549 .pkt_scan = sd_pkt_scan,
1373 .dq_callback = do_autogain, 1550 .dq_callback = do_autogain,
1374}; 1551};
@@ -1379,7 +1556,7 @@ static const struct sd_desc sd_desc = {
1379 | (SENSOR_ ## sensor << 8) \ 1556 | (SENSOR_ ## sensor << 8) \
1380 | (i2c_addr) 1557 | (i2c_addr)
1381static const __devinitdata struct usb_device_id device_table[] = { 1558static const __devinitdata struct usb_device_id device_table[] = {
1382#ifndef CONFIG_USB_SN9C102 1559#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1383 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, 1560 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1384 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, 1561 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1385 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, 1562 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
@@ -1406,15 +1583,17 @@ static const __devinitdata struct usb_device_id device_table[] = {
1406/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ 1583/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1407/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ 1584/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1408/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ 1585/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1409 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)}, 1586 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1410/* bw600.inf: 1587/*bw600.inf:*/
1411 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */ 1588 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1412 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, 1589 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1413/* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ 1590 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1414/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ 1591/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1415#ifndef CONFIG_USB_SN9C102 1592#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1416 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 1593 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1594#endif
1417 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 1595 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1596#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1418/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */ 1597/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1419 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, 1598 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1420 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 1599 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
@@ -1438,6 +1617,10 @@ static struct usb_driver sd_driver = {
1438 .id_table = device_table, 1617 .id_table = device_table,
1439 .probe = sd_probe, 1618 .probe = sd_probe,
1440 .disconnect = gspca_disconnect, 1619 .disconnect = gspca_disconnect,
1620#ifdef CONFIG_PM
1621 .suspend = gspca_suspend,
1622 .resume = gspca_resume,
1623#endif
1441}; 1624};
1442 1625
1443/* -- module insert / remove -- */ 1626/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 17fe2c2a440d..6e733901fcca 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -645,8 +645,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
645 return 0; 645 return 0;
646} 646}
647 647
648/* this function is called at open time */ 648/* this function is called at probe and resume time */
649static int sd_open(struct gspca_dev *gspca_dev) 649static int sd_init(struct gspca_dev *gspca_dev)
650{ 650{
651 struct sd *sd = (struct sd *) gspca_dev; 651 struct sd *sd = (struct sd *) gspca_dev;
652 652
@@ -880,14 +880,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
880 gspca_dev->usb_buf[0]); 880 gspca_dev->usb_buf[0]);
881} 881}
882 882
883static void sd_stop0(struct gspca_dev *gspca_dev)
884{
885}
886
887static void sd_close(struct gspca_dev *gspca_dev)
888{
889}
890
891static void sd_pkt_scan(struct gspca_dev *gspca_dev, 883static void sd_pkt_scan(struct gspca_dev *gspca_dev,
892 struct gspca_frame *frame, /* target */ 884 struct gspca_frame *frame, /* target */
893 __u8 *data, /* isoc packet */ 885 __u8 *data, /* isoc packet */
@@ -1051,11 +1043,9 @@ static struct sd_desc sd_desc = {
1051 .ctrls = sd_ctrls, 1043 .ctrls = sd_ctrls,
1052 .nctrls = ARRAY_SIZE(sd_ctrls), 1044 .nctrls = ARRAY_SIZE(sd_ctrls),
1053 .config = sd_config, 1045 .config = sd_config,
1054 .open = sd_open, 1046 .init = sd_init,
1055 .start = sd_start, 1047 .start = sd_start,
1056 .stopN = sd_stopN, 1048 .stopN = sd_stopN,
1057 .stop0 = sd_stop0,
1058 .close = sd_close,
1059 .pkt_scan = sd_pkt_scan, 1049 .pkt_scan = sd_pkt_scan,
1060}; 1050};
1061 1051
@@ -1093,6 +1083,10 @@ static struct usb_driver sd_driver = {
1093 .id_table = device_table, 1083 .id_table = device_table,
1094 .probe = sd_probe, 1084 .probe = sd_probe,
1095 .disconnect = gspca_disconnect, 1085 .disconnect = gspca_disconnect,
1086#ifdef CONFIG_PM
1087 .suspend = gspca_suspend,
1088 .resume = gspca_resume,
1089#endif
1096}; 1090};
1097 1091
1098/* -- module insert / remove -- */ 1092/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 51a3c3429ef0..e9eb59bae4fb 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1953,8 +1953,8 @@ error:
1953 return -EINVAL; 1953 return -EINVAL;
1954} 1954}
1955 1955
1956/* this function is called at open time */ 1956/* this function is called at probe and resume time */
1957static int sd_open(struct gspca_dev *gspca_dev) 1957static int sd_init(struct gspca_dev *gspca_dev)
1958{ 1958{
1959 struct sd *sd = (struct sd *) gspca_dev; 1959 struct sd *sd = (struct sd *) gspca_dev;
1960 1960
@@ -2023,11 +2023,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2023 2023
2024static void sd_stop0(struct gspca_dev *gspca_dev) 2024static void sd_stop0(struct gspca_dev *gspca_dev)
2025{ 2025{
2026}
2027
2028/* this function is called at close time */
2029static void sd_close(struct gspca_dev *gspca_dev)
2030{
2031 reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); 2026 reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
2032} 2027}
2033 2028
@@ -2120,11 +2115,10 @@ static const struct sd_desc sd_desc = {
2120 .ctrls = sd_ctrls, 2115 .ctrls = sd_ctrls,
2121 .nctrls = ARRAY_SIZE(sd_ctrls), 2116 .nctrls = ARRAY_SIZE(sd_ctrls),
2122 .config = sd_config, 2117 .config = sd_config,
2123 .open = sd_open, 2118 .init = sd_init,
2124 .start = sd_start, 2119 .start = sd_start,
2125 .stopN = sd_stopN, 2120 .stopN = sd_stopN,
2126 .stop0 = sd_stop0, 2121 .stop0 = sd_stop0,
2127 .close = sd_close,
2128 .pkt_scan = sd_pkt_scan, 2122 .pkt_scan = sd_pkt_scan,
2129}; 2123};
2130 2124
@@ -2154,6 +2148,10 @@ static struct usb_driver sd_driver = {
2154 .id_table = device_table, 2148 .id_table = device_table,
2155 .probe = sd_probe, 2149 .probe = sd_probe,
2156 .disconnect = gspca_disconnect, 2150 .disconnect = gspca_disconnect,
2151#ifdef CONFIG_PM
2152 .suspend = gspca_suspend,
2153 .resume = gspca_resume,
2154#endif
2157}; 2155};
2158 2156
2159/* -- module insert / remove -- */ 2157/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index eda29d609359..f601daf19ebe 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -655,8 +655,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
655 return 0; 655 return 0;
656} 656}
657 657
658/* this function is called at open time */ 658/* this function is called at probe and resume time */
659static int sd_open(struct gspca_dev *gspca_dev) 659static int sd_init(struct gspca_dev *gspca_dev)
660{ 660{
661 struct sd *sd = (struct sd *) gspca_dev; 661 struct sd *sd = (struct sd *) gspca_dev;
662 int ret; 662 int ret;
@@ -743,11 +743,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
743 743
744static void sd_stop0(struct gspca_dev *gspca_dev) 744static void sd_stop0(struct gspca_dev *gspca_dev)
745{ 745{
746}
747
748/* this function is called at close time */
749static void sd_close(struct gspca_dev *gspca_dev)
750{
751 /* This maybe reset or power control */ 746 /* This maybe reset or power control */
752 reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); 747 reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
753 reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); 748 reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
@@ -825,11 +820,10 @@ static const struct sd_desc sd_desc = {
825 .ctrls = sd_ctrls, 820 .ctrls = sd_ctrls,
826 .nctrls = ARRAY_SIZE(sd_ctrls), 821 .nctrls = ARRAY_SIZE(sd_ctrls),
827 .config = sd_config, 822 .config = sd_config,
828 .open = sd_open, 823 .init = sd_init,
829 .start = sd_start, 824 .start = sd_start,
830 .stopN = sd_stopN, 825 .stopN = sd_stopN,
831 .stop0 = sd_stop0, 826 .stop0 = sd_stop0,
832 .close = sd_close,
833 .pkt_scan = sd_pkt_scan, 827 .pkt_scan = sd_pkt_scan,
834}; 828};
835 829
@@ -855,6 +849,10 @@ static struct usb_driver sd_driver = {
855 .id_table = device_table, 849 .id_table = device_table,
856 .probe = sd_probe, 850 .probe = sd_probe,
857 .disconnect = gspca_disconnect, 851 .disconnect = gspca_disconnect,
852#ifdef CONFIG_PM
853 .suspend = gspca_suspend,
854 .resume = gspca_resume,
855#endif
858}; 856};
859 857
860/* -- module insert / remove -- */ 858/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index f622fa75766d..195dce96ef06 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -313,8 +313,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
313 return 0; 313 return 0;
314} 314}
315 315
316/* this function is called at open time */ 316/* this function is called at probe and resume time */
317static int sd_open(struct gspca_dev *gspca_dev) 317static int sd_init(struct gspca_dev *gspca_dev)
318{ 318{
319 struct usb_device *dev = gspca_dev->dev; 319 struct usb_device *dev = gspca_dev->dev;
320 320
@@ -560,14 +560,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
560 reg_w(dev, 0x03, 0x00, 0x0003); 560 reg_w(dev, 0x03, 0x00, 0x0003);
561} 561}
562 562
563static void sd_stop0(struct gspca_dev *gspca_dev)
564{
565}
566
567static void sd_close(struct gspca_dev *gspca_dev)
568{
569}
570
571static void sd_pkt_scan(struct gspca_dev *gspca_dev, 563static void sd_pkt_scan(struct gspca_dev *gspca_dev,
572 struct gspca_frame *frame, /* target */ 564 struct gspca_frame *frame, /* target */
573 __u8 *data, /* isoc packet */ 565 __u8 *data, /* isoc packet */
@@ -740,11 +732,9 @@ static struct sd_desc sd_desc = {
740 .ctrls = sd_ctrls, 732 .ctrls = sd_ctrls,
741 .nctrls = ARRAY_SIZE(sd_ctrls), 733 .nctrls = ARRAY_SIZE(sd_ctrls),
742 .config = sd_config, 734 .config = sd_config,
743 .open = sd_open, 735 .init = sd_init,
744 .start = sd_start, 736 .start = sd_start,
745 .stopN = sd_stopN, 737 .stopN = sd_stopN,
746 .stop0 = sd_stop0,
747 .close = sd_close,
748 .pkt_scan = sd_pkt_scan, 738 .pkt_scan = sd_pkt_scan,
749}; 739};
750 740
@@ -772,6 +762,10 @@ static struct usb_driver sd_driver = {
772 .id_table = device_table, 762 .id_table = device_table,
773 .probe = sd_probe, 763 .probe = sd_probe,
774 .disconnect = gspca_disconnect, 764 .disconnect = gspca_disconnect,
765#ifdef CONFIG_PM
766 .suspend = gspca_suspend,
767 .resume = gspca_resume,
768#endif
775}; 769};
776 770
777/* -- module insert / remove -- */ 771/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 699340c17dea..281ce02103a3 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1521,8 +1521,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1521 return 0; /* success */ 1521 return 0; /* success */
1522} 1522}
1523 1523
1524/* this function is called at open time */ 1524/* this function is called at probe and resume time */
1525static int sd_open(struct gspca_dev *gspca_dev) 1525static int sd_init(struct gspca_dev *gspca_dev)
1526{ 1526{
1527/* write_vector(gspca_dev, spca508_open_data); */ 1527/* write_vector(gspca_dev, spca508_open_data); */
1528 return 0; 1528 return 0;
@@ -1554,15 +1554,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1554 reg_write(gspca_dev->dev, 0x8112, 0x20); 1554 reg_write(gspca_dev->dev, 0x8112, 0x20);
1555} 1555}
1556 1556
1557static void sd_stop0(struct gspca_dev *gspca_dev)
1558{
1559}
1560
1561/* this function is called at close time */
1562static void sd_close(struct gspca_dev *gspca_dev)
1563{
1564}
1565
1566static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1557static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1567 struct gspca_frame *frame, /* target */ 1558 struct gspca_frame *frame, /* target */
1568 __u8 *data, /* isoc packet */ 1559 __u8 *data, /* isoc packet */
@@ -1633,11 +1624,9 @@ static const struct sd_desc sd_desc = {
1633 .ctrls = sd_ctrls, 1624 .ctrls = sd_ctrls,
1634 .nctrls = ARRAY_SIZE(sd_ctrls), 1625 .nctrls = ARRAY_SIZE(sd_ctrls),
1635 .config = sd_config, 1626 .config = sd_config,
1636 .open = sd_open, 1627 .init = sd_init,
1637 .start = sd_start, 1628 .start = sd_start,
1638 .stopN = sd_stopN, 1629 .stopN = sd_stopN,
1639 .stop0 = sd_stop0,
1640 .close = sd_close,
1641 .pkt_scan = sd_pkt_scan, 1630 .pkt_scan = sd_pkt_scan,
1642}; 1631};
1643 1632
@@ -1667,6 +1656,10 @@ static struct usb_driver sd_driver = {
1667 .id_table = device_table, 1656 .id_table = device_table,
1668 .probe = sd_probe, 1657 .probe = sd_probe,
1669 .disconnect = gspca_disconnect, 1658 .disconnect = gspca_disconnect,
1659#ifdef CONFIG_PM
1660 .suspend = gspca_suspend,
1661 .resume = gspca_resume,
1662#endif
1670}; 1663};
1671 1664
1672/* -- module insert / remove -- */ 1665/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 1073ac3d2ec6..cfbc9ebc5c5d 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -32,69 +32,48 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 unsigned short contrast; 35 __u16 contrast; /* rev72a only */
36 __u8 brightness; 36#define CONTRAST_MIN 0x0000
37#define CONTRAST_DEF 0x2000
38#define CONTRAST_MAX 0x3fff
39
40 __u16 exposure; /* rev12a only */
41#define EXPOSURE_MIN 1
42#define EXPOSURE_DEF 200
43#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
44
45 __u8 brightness; /* rev72a only */
46#define BRIGHTNESS_MIN 0
47#define BRIGHTNESS_DEF 32
48#define BRIGHTNESS_MAX 63
49
50 __u8 white; /* rev12a only */
51#define WHITE_MIN 1
52#define WHITE_DEF 0x40
53#define WHITE_MAX 0x7f
54
37 __u8 autogain; 55 __u8 autogain;
56#define AUTOGAIN_MIN 0
57#define AUTOGAIN_DEF 1
58#define AUTOGAIN_MAX 1
59
60 __u8 gain; /* rev12a only */
61#define GAIN_MIN 0x0
62#define GAIN_DEF 0x24
63#define GAIN_MAX 0x24
64
65#define EXPO12A_DEF 3
66 __u8 expo12a; /* expo/gain? for rev 12a */
38 67
39 __u8 chip_revision; 68 __u8 chip_revision;
69#define Rev012A 0
70#define Rev072A 1
71
40 signed char ag_cnt; 72 signed char ag_cnt;
41#define AG_CNT_START 13 73#define AG_CNT_START 13
42}; 74};
43 75
44/* V4L2 controls supported by the driver */ 76static struct v4l2_pix_format sif_012a_mode[] = {
45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
47static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
48static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
49static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
51
52static struct ctrl sd_ctrls[] = {
53#define SD_BRIGHTNESS 0
54 {
55 {
56 .id = V4L2_CID_BRIGHTNESS,
57 .type = V4L2_CTRL_TYPE_INTEGER,
58 .name = "Brightness",
59 .minimum = 0,
60 .maximum = 63,
61 .step = 1,
62 .default_value = 32,
63 },
64 .set = sd_setbrightness,
65 .get = sd_getbrightness,
66 },
67#define SD_CONTRAST 1
68 {
69 {
70 .id = V4L2_CID_CONTRAST,
71 .type = V4L2_CTRL_TYPE_INTEGER,
72 .name = "Contrast",
73 .minimum = 0,
74 .maximum = 0x3fff,
75 .step = 1,
76 .default_value = 0x2000,
77 },
78 .set = sd_setcontrast,
79 .get = sd_getcontrast,
80 },
81#define SD_AUTOGAIN 2
82 {
83 {
84 .id = V4L2_CID_AUTOGAIN,
85 .type = V4L2_CTRL_TYPE_BOOLEAN,
86 .name = "Auto Gain",
87 .minimum = 0,
88 .maximum = 1,
89 .step = 1,
90 .default_value = 1,
91 },
92 .set = sd_setautogain,
93 .get = sd_getautogain,
94 },
95};
96
97static struct v4l2_pix_format sif_mode[] = {
98 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, 77 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
99 .bytesperline = 160, 78 .bytesperline = 160,
100 .sizeimage = 160 * 120, 79 .sizeimage = 160 * 120,
@@ -117,6 +96,29 @@ static struct v4l2_pix_format sif_mode[] = {
117 .priv = 0}, 96 .priv = 0},
118}; 97};
119 98
99static struct v4l2_pix_format sif_072a_mode[] = {
100 {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
101 .bytesperline = 160,
102 .sizeimage = 160 * 120,
103 .colorspace = V4L2_COLORSPACE_SRGB,
104 .priv = 3},
105 {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
106 .bytesperline = 176,
107 .sizeimage = 176 * 144,
108 .colorspace = V4L2_COLORSPACE_SRGB,
109 .priv = 2},
110 {320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
111 .bytesperline = 320,
112 .sizeimage = 320 * 240,
113 .colorspace = V4L2_COLORSPACE_SRGB,
114 .priv = 1},
115 {352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
116 .bytesperline = 352,
117 .sizeimage = 352 * 288,
118 .colorspace = V4L2_COLORSPACE_SRGB,
119 .priv = 0},
120};
121
120/* 122/*
121 * Initialization data 123 * Initialization data
122 * I'm not very sure how to split initialization from open data 124 * I'm not very sure how to split initialization from open data
@@ -143,12 +145,8 @@ static struct v4l2_pix_format sif_mode[] = {
143#define SPCA561_INDEX_I2C_BASE 0x8800 145#define SPCA561_INDEX_I2C_BASE 0x8800
144#define SPCA561_SNAPBIT 0x20 146#define SPCA561_SNAPBIT 0x20
145#define SPCA561_SNAPCTRL 0x40 147#define SPCA561_SNAPCTRL 0x40
146enum {
147 Rev072A = 0,
148 Rev012A,
149};
150 148
151static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) 149static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
152{ 150{
153 int ret; 151 int ret;
154 152
@@ -198,12 +196,6 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
198 index, gspca_dev->usb_buf, len, 500); 196 index, gspca_dev->usb_buf, len, 500);
199} 197}
200 198
201static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode)
202{
203 reg_w_val(gspca_dev->dev, 0x92, 0x8804);
204 reg_w_val(gspca_dev->dev, mode, 0x8802);
205}
206
207static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) 199static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
208{ 200{
209 int retry = 60; 201 int retry = 60;
@@ -212,9 +204,9 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
212 204
213 DataLow = valeur; 205 DataLow = valeur;
214 DataHight = valeur >> 8; 206 DataHight = valeur >> 8;
215 reg_w_val(gspca_dev->dev, reg, 0x8801); 207 reg_w_val(gspca_dev->dev, 0x8801, reg);
216 reg_w_val(gspca_dev->dev, DataLow, 0x8805); 208 reg_w_val(gspca_dev->dev, 0x8805, DataLow);
217 reg_w_val(gspca_dev->dev, DataHight, 0x8800); 209 reg_w_val(gspca_dev->dev, 0x8800, DataHight);
218 while (retry--) { 210 while (retry--) {
219 reg_r(gspca_dev, 0x8803, 1); 211 reg_r(gspca_dev, 0x8803, 1);
220 if (!gspca_dev->usb_buf[0]) 212 if (!gspca_dev->usb_buf[0])
@@ -228,14 +220,14 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
228 __u8 value; 220 __u8 value;
229 __u8 vallsb; 221 __u8 vallsb;
230 222
231 reg_w_val(gspca_dev->dev, 0x92, 0x8804); 223 reg_w_val(gspca_dev->dev, 0x8804, 0x92);
232 reg_w_val(gspca_dev->dev, reg, 0x8801); 224 reg_w_val(gspca_dev->dev, 0x8801, reg);
233 reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); 225 reg_w_val(gspca_dev->dev, 0x8802, (mode | 0x01));
234 while (retry--) { 226 do {
235 reg_r(gspca_dev, 0x8803, 1); 227 reg_r(gspca_dev, 0x8803, 1);
236 if (!gspca_dev->usb_buf) 228 if (!gspca_dev->usb_buf)
237 break; 229 break;
238 } 230 } while (--retry);
239 if (retry == 0) 231 if (retry == 0)
240 return -1; 232 return -1;
241 reg_r(gspca_dev, 0x8800, 1); 233 reg_r(gspca_dev, 0x8800, 1);
@@ -438,21 +430,10 @@ static const __u16 spca561_init_data[][2] = {
438 {0x0035, 0x8801}, /* 0x14 - set gain general */ 430 {0x0035, 0x8801}, /* 0x14 - set gain general */
439 {0x001f, 0x8805}, /* 0x14 */ 431 {0x001f, 0x8805}, /* 0x14 */
440 {0x0000, 0x8800}, 432 {0x0000, 0x8800},
441 {0x0030, 0x8112}, 433 {0x000e, 0x8112}, /* white balance - was 30 */
442 {} 434 {}
443}; 435};
444 436
445static void sensor_reset(struct gspca_dev *gspca_dev)
446{
447 reg_w_val(gspca_dev->dev, 0x8631, 0xc8);
448 reg_w_val(gspca_dev->dev, 0x8634, 0xc8);
449 reg_w_val(gspca_dev->dev, 0x8112, 0x00);
450 reg_w_val(gspca_dev->dev, 0x8114, 0x00);
451 reg_w_val(gspca_dev->dev, 0x8118, 0x21);
452 i2c_init(gspca_dev, 0x14);
453 i2c_write(gspca_dev, 1, 0x0d);
454 i2c_write(gspca_dev, 0, 0x0d);
455}
456 437
457/******************** QC Express etch2 stuff ********************/ 438/******************** QC Express etch2 stuff ********************/
458static const __u16 Pb100_1map8300[][2] = { 439static const __u16 Pb100_1map8300[][2] = {
@@ -462,9 +443,9 @@ static const __u16 Pb100_1map8300[][2] = {
462 {0x8303, 0x0125}, /* image area */ 443 {0x8303, 0x0125}, /* image area */
463 {0x8304, 0x0169}, 444 {0x8304, 0x0169},
464 {0x8328, 0x000b}, 445 {0x8328, 0x000b},
465 {0x833c, 0x0001}, 446 {0x833c, 0x0001}, /*fixme: win:07*/
466 447
467 {0x832f, 0x0419}, 448 {0x832f, 0x1904}, /*fixme: was 0419*/
468 {0x8307, 0x00aa}, 449 {0x8307, 0x00aa},
469 {0x8301, 0x0003}, 450 {0x8301, 0x0003},
470 {0x8302, 0x000e}, 451 {0x8302, 0x000e},
@@ -478,9 +459,10 @@ static const __u16 Pb100_2map8300[][2] = {
478}; 459};
479 460
480static const __u16 spca561_161rev12A_data1[][2] = { 461static const __u16 spca561_161rev12A_data1[][2] = {
481 {0x21, 0x8118}, 462 {0x29, 0x8118}, /* white balance - was 21 */
482 {0x01, 0x8114}, 463 {0x08, 0x8114}, /* white balance - was 01 */
483 {0x00, 0x8112}, 464 {0x0e, 0x8112}, /* white balance - was 00 */
465 {0x00, 0x8102}, /* white balance - new */
484 {0x92, 0x8804}, 466 {0x92, 0x8804},
485 {0x04, 0x8802}, /* windows uses 08 */ 467 {0x04, 0x8802}, /* windows uses 08 */
486 {} 468 {}
@@ -505,14 +487,16 @@ static const __u16 spca561_161rev12A_data2[][2] = {
505 {0xb0, 0x8603}, 487 {0xb0, 0x8603},
506 488
507 /* sensor gains */ 489 /* sensor gains */
490 {0x07, 0x8601}, /* white balance - new */
491 {0x07, 0x8602}, /* white balance - new */
508 {0x00, 0x8610}, /* *red */ 492 {0x00, 0x8610}, /* *red */
509 {0x00, 0x8611}, /* 3f *green */ 493 {0x00, 0x8611}, /* 3f *green */
510 {0x00, 0x8612}, /* green *blue */ 494 {0x00, 0x8612}, /* green *blue */
511 {0x00, 0x8613}, /* blue *green */ 495 {0x00, 0x8613}, /* blue *green */
512 {0x35, 0x8614}, /* green *red */ 496 {0x43, 0x8614}, /* green *red - white balance - was 0x35 */
513 {0x35, 0x8615}, /* 40 *green */ 497 {0x40, 0x8615}, /* 40 *green - white balance - was 0x35 */
514 {0x35, 0x8616}, /* 7a *blue */ 498 {0x71, 0x8616}, /* 7a *blue - white balance - was 0x35 */
515 {0x35, 0x8617}, /* 40 *green */ 499 {0x40, 0x8617}, /* 40 *green - white balance - was 0x35 */
516 500
517 {0x0c, 0x8620}, /* 0c */ 501 {0x0c, 0x8620}, /* 0c */
518 {0xc8, 0x8631}, /* c8 */ 502 {0xc8, 0x8631}, /* c8 */
@@ -527,6 +511,7 @@ static const __u16 spca561_161rev12A_data2[][2] = {
527 {0xdf, 0x863c}, /* df */ 511 {0xdf, 0x863c}, /* df */
528 {0xf0, 0x8505}, 512 {0xf0, 0x8505},
529 {0x32, 0x850a}, 513 {0x32, 0x850a},
514/* {0x99, 0x8700}, * - white balance - new (removed) */
530 {} 515 {}
531}; 516};
532 517
@@ -545,9 +530,10 @@ static void sensor_mapwrite(struct gspca_dev *gspca_dev,
545} 530}
546static void init_161rev12A(struct gspca_dev *gspca_dev) 531static void init_161rev12A(struct gspca_dev *gspca_dev)
547{ 532{
548 sensor_reset(gspca_dev); 533/* sensor_reset(gspca_dev); (not in win) */
549 write_vector(gspca_dev, spca561_161rev12A_data1); 534 write_vector(gspca_dev, spca561_161rev12A_data1);
550 sensor_mapwrite(gspca_dev, Pb100_1map8300); 535 sensor_mapwrite(gspca_dev, Pb100_1map8300);
536/*fixme: should be in sd_start*/
551 write_vector(gspca_dev, spca561_161rev12A_data2); 537 write_vector(gspca_dev, spca561_161rev12A_data2);
552 sensor_mapwrite(gspca_dev, Pb100_2map8300); 538 sensor_mapwrite(gspca_dev, Pb100_2map8300);
553} 539}
@@ -581,35 +567,38 @@ static int sd_config(struct gspca_dev *gspca_dev,
581 } 567 }
582 568
583 cam = &gspca_dev->cam; 569 cam = &gspca_dev->cam;
584 cam->dev_name = (char *) id->driver_info;
585 cam->epaddr = 0x01; 570 cam->epaddr = 0x01;
586 gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ 571 gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
587 cam->cam_mode = sif_mode;
588 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
589 572
590 sd->chip_revision = id->driver_info; 573 sd->chip_revision = id->driver_info;
591 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 574 if (sd->chip_revision == Rev012A) {
592 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 575 cam->cam_mode = sif_012a_mode;
593 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; 576 cam->nmodes = ARRAY_SIZE(sif_012a_mode);
577 } else {
578 cam->cam_mode = sif_072a_mode;
579 cam->nmodes = ARRAY_SIZE(sif_072a_mode);
580 }
581 sd->brightness = BRIGHTNESS_DEF;
582 sd->contrast = CONTRAST_DEF;
583 sd->white = WHITE_DEF;
584 sd->exposure = EXPOSURE_DEF;
585 sd->autogain = AUTOGAIN_DEF;
586 sd->gain = GAIN_DEF;
587 sd->expo12a = EXPO12A_DEF;
594 return 0; 588 return 0;
595} 589}
596 590
597/* this function is called at open time */ 591/* this function is called at probe and resume time */
598static int sd_open(struct gspca_dev *gspca_dev) 592static int sd_init_12a(struct gspca_dev *gspca_dev)
599{ 593{
600 struct sd *sd = (struct sd *) gspca_dev; 594 PDEBUG(D_STREAM, "Chip revision: 012a");
601 595 init_161rev12A(gspca_dev);
602 switch (sd->chip_revision) { 596 return 0;
603 case Rev072A: 597}
604 PDEBUG(D_STREAM, "Chip revision id: 072a"); 598static int sd_init_72a(struct gspca_dev *gspca_dev)
605 write_vector(gspca_dev, spca561_init_data); 599{
606 break; 600 PDEBUG(D_STREAM, "Chip revision: 072a");
607 default: 601 write_vector(gspca_dev, spca561_init_data);
608/* case Rev012A: */
609 PDEBUG(D_STREAM, "Chip revision id: 012a");
610 init_161rev12A(gspca_dev);
611 break;
612 }
613 return 0; 602 return 0;
614} 603}
615 604
@@ -618,25 +607,20 @@ static void setcontrast(struct gspca_dev *gspca_dev)
618 struct sd *sd = (struct sd *) gspca_dev; 607 struct sd *sd = (struct sd *) gspca_dev;
619 struct usb_device *dev = gspca_dev->dev; 608 struct usb_device *dev = gspca_dev->dev;
620 __u8 lowb; 609 __u8 lowb;
621 int expotimes;
622 610
623 switch (sd->chip_revision) { 611 switch (sd->chip_revision) {
624 case Rev072A: 612 case Rev072A:
625 lowb = sd->contrast >> 8; 613 lowb = sd->contrast >> 8;
626 reg_w_val(dev, lowb, 0x8651); 614 reg_w_val(dev, 0x8651, lowb);
627 reg_w_val(dev, lowb, 0x8652); 615 reg_w_val(dev, 0x8652, lowb);
628 reg_w_val(dev, lowb, 0x8653); 616 reg_w_val(dev, 0x8653, lowb);
629 reg_w_val(dev, lowb, 0x8654); 617 reg_w_val(dev, 0x8654, lowb);
630 break; 618 break;
631 case Rev012A: { 619 default: {
632 __u8 Reg8391[] = 620/* case Rev012A: { */
633 { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; 621 static const __u8 Reg8391[] =
634 622 { 0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00 };
635 /* Write camera sensor settings */ 623
636 expotimes = (sd->contrast >> 5) & 0x07ff;
637 Reg8391[0] = expotimes & 0xff; /* exposure */
638 Reg8391[1] = 0x18 | (expotimes >> 8);
639 Reg8391[2] = sd->brightness; /* gain */
640 reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); 624 reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
641 reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); 625 reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
642 break; 626 break;
@@ -644,93 +628,151 @@ static void setcontrast(struct gspca_dev *gspca_dev)
644 } 628 }
645} 629}
646 630
647static void setautogain(struct gspca_dev *gspca_dev) 631/* rev12a only */
632static void setwhite(struct gspca_dev *gspca_dev)
648{ 633{
649 struct sd *sd = (struct sd *) gspca_dev; 634 struct sd *sd = (struct sd *) gspca_dev;
635 __u16 white;
636 __u8 reg8614, reg8616;
637
638 white = sd->white;
639 /* try to emulate MS-win as possible */
640 reg8616 = 0x90 - white * 5 / 8;
641 reg_w_val(gspca_dev->dev, 0x8616, reg8616);
642 reg8614 = 0x20 + white * 3 / 8;
643 reg_w_val(gspca_dev->dev, 0x8614, reg8614);
644}
650 645
651 if (sd->chip_revision == Rev072A) { 646/* rev 12a only */
652 if (sd->autogain) 647static void setexposure(struct gspca_dev *gspca_dev)
653 sd->ag_cnt = AG_CNT_START; 648{
654 else 649 struct sd *sd = (struct sd *) gspca_dev;
655 sd->ag_cnt = -1; 650 int expo;
651 int clock_divider;
652 __u8 data[2];
653
654 /* Register 0x8309 controls exposure for the spca561,
655 the basic exposure setting goes from 1-2047, where 1 is completely
656 dark and 2047 is very bright. It not only influences exposure but
657 also the framerate (to allow for longer exposure) from 1 - 300 it
658 only raises the exposure time then from 300 - 600 it halves the
659 framerate to be able to further raise the exposure time and for every
660 300 more it halves the framerate again. This allows for a maximum
661 exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
662 Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
663 configure a divider for the base framerate which us used at the
664 exposure setting of 1-300. These bits configure the base framerate
665 according to the following formula: fps = 60 / (value + 2) */
666 if (sd->exposure < 2048) {
667 expo = sd->exposure;
668 clock_divider = 0;
669 } else {
670 /* Add 900 to make the 0 setting of the second part of the
671 exposure equal to the 2047 setting of the first part. */
672 expo = (sd->exposure - 2048) + 900;
673 clock_divider = 3;
656 } 674 }
675 expo |= clock_divider << 11;
676 data[0] = expo;
677 data[1] = expo >> 8;
678 reg_w_buf(gspca_dev, 0x8309, data, 2);
657} 679}
658 680
659static void sd_start(struct gspca_dev *gspca_dev) 681/* rev 12a only */
682static void setgain(struct gspca_dev *gspca_dev)
660{ 683{
661 struct sd *sd = (struct sd *) gspca_dev; 684 struct sd *sd = (struct sd *) gspca_dev;
685 __u8 data[2];
686
687 data[0] = sd->gain;
688 data[1] = 0;
689 reg_w_buf(gspca_dev, 0x8335, data, 2);
690}
691
692static void setautogain(struct gspca_dev *gspca_dev)
693{
694 struct sd *sd = (struct sd *) gspca_dev;
695
696 if (sd->autogain)
697 sd->ag_cnt = AG_CNT_START;
698 else
699 sd->ag_cnt = -1;
700}
701
702static void sd_start_12a(struct gspca_dev *gspca_dev)
703{
662 struct usb_device *dev = gspca_dev->dev; 704 struct usb_device *dev = gspca_dev->dev;
663 int Clck; 705 int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
664 __u8 Reg8307[] = { 0xaa, 0x00 }; 706 __u8 Reg8307[] = { 0xaa, 0x00 };
665 int mode; 707 int mode;
666 708
667 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 709 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
668 switch (sd->chip_revision) { 710 if (mode <= 1) {
669 case Rev072A: 711 /* Use compression on 320x240 and above */
670 switch (mode) { 712 reg_w_val(dev, 0x8500, 0x10 | mode);
671 default: 713 } else {
672/* case 0: 714 /* I couldn't get the compression to work below 320x240
673 case 1: */ 715 * Fortunately at these resolutions the bandwidth
674 Clck = 0x25; 716 * is sufficient to push raw frames at ~20fps */
675 break; 717 reg_w_val(dev, 0x8500, mode);
676 case 2: 718 } /* -- qq@kuku.eu.org */
677 Clck = 0x22; 719 reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
678 break; 720 reg_w_val(gspca_dev->dev, 0x8700, Clck);
679 case 3: 721 /* 0x8f 0x85 0x27 clock */
680 Clck = 0x21; 722 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
681 break; 723 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
682 } 724 setcontrast(gspca_dev);
683 reg_w_val(dev, 0x8500, mode); /* mode */ 725 setwhite(gspca_dev);
684 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ 726 setautogain(gspca_dev);
685 reg_w_val(dev, 0x8112, 0x10 | 0x20); 727 setexposure(gspca_dev);
686 setautogain(gspca_dev); 728}
687 break; 729static void sd_start_72a(struct gspca_dev *gspca_dev)
730{
731 struct usb_device *dev = gspca_dev->dev;
732 int Clck;
733 int mode;
734
735 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
736 switch (mode) {
688 default: 737 default:
689/* case Rev012A: */ 738/* case 0:
690 switch (mode) { 739 case 1: */
691 case 0: 740 Clck = 0x25;
692 case 1: 741 break;
693 Clck = 0x8a; 742 case 2:
694 break; 743 Clck = 0x22;
695 case 2: 744 break;
696 Clck = 0x85; 745 case 3:
697 break; 746 Clck = 0x21;
698 default:
699 Clck = 0x83;
700 break;
701 }
702 if (mode <= 1) {
703 /* Use compression on 320x240 and above */
704 reg_w_val(dev, 0x8500, 0x10 | mode);
705 } else {
706 /* I couldn't get the compression to work below 320x240
707 * Fortunately at these resolutions the bandwidth
708 * is sufficient to push raw frames at ~20fps */
709 reg_w_val(dev, 0x8500, mode);
710 } /* -- qq@kuku.eu.org */
711 reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
712 reg_w_val(gspca_dev->dev, 0x8700, Clck);
713 /* 0x8f 0x85 0x27 clock */
714 reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
715 reg_w_val(gspca_dev->dev, 0x850b, 0x03);
716 setcontrast(gspca_dev);
717 break; 747 break;
718 } 748 }
749 reg_w_val(dev, 0x8500, mode); /* mode */
750 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
751 reg_w_val(dev, 0x8112, 0x10 | 0x20);
752 setautogain(gspca_dev);
719} 753}
720 754
721static void sd_stopN(struct gspca_dev *gspca_dev) 755static void sd_stopN(struct gspca_dev *gspca_dev)
722{ 756{
723 reg_w_val(gspca_dev->dev, 0x8112, 0x20); 757 struct sd *sd = (struct sd *) gspca_dev;
758
759 if (sd->chip_revision == Rev012A) {
760 reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
761 } else {
762 reg_w_val(gspca_dev->dev, 0x8112, 0x20);
763/* reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
764 }
724} 765}
725 766
726static void sd_stop0(struct gspca_dev *gspca_dev) 767static void sd_stop0(struct gspca_dev *gspca_dev)
727{ 768{
728} 769 struct sd *sd = (struct sd *) gspca_dev;
729 770
730/* this function is called at close time */ 771 if (sd->chip_revision == Rev012A) {
731static void sd_close(struct gspca_dev *gspca_dev) 772 reg_w_val(gspca_dev->dev, 0x8118, 0x29);
732{ 773 reg_w_val(gspca_dev->dev, 0x8114, 0x08);
733 reg_w_val(gspca_dev->dev, 0x8114, 0); 774 }
775/* reg_w_val(gspca_dev->dev, 0x8114, 0); */
734} 776}
735 777
736static void do_autogain(struct gspca_dev *gspca_dev) 778static void do_autogain(struct gspca_dev *gspca_dev)
@@ -744,6 +786,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
744 __u8 luma_mean = 110; 786 __u8 luma_mean = 110;
745 __u8 luma_delta = 20; 787 __u8 luma_delta = 20;
746 __u8 spring = 4; 788 __u8 spring = 4;
789 __u8 reg8339[2];
747 790
748 if (sd->ag_cnt < 0) 791 if (sd->ag_cnt < 0)
749 return; 792 return;
@@ -798,13 +841,16 @@ static void do_autogain(struct gspca_dev *gspca_dev)
798 } 841 }
799 break; 842 break;
800 case Rev012A: 843 case Rev012A:
801 /* sensor registers is access and memory mapped to 0x8300 */ 844 reg_r(gspca_dev, 0x8330, 2);
802 /* readind all 0x83xx block the sensor */ 845 if (gspca_dev->usb_buf[1] > 0x08) {
803 /* 846 reg8339[0] = ++sd->expo12a;
804 * The data from the header seem wrong where is the luma 847 reg8339[1] = 0;
805 * and chroma mean value 848 reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
806 * at the moment set exposure in contrast set 849 } else if (gspca_dev->usb_buf[1] < 0x02) {
807 */ 850 reg8339[0] = --sd->expo12a;
851 reg8339[1] = 0;
852 reg_w_buf(gspca_dev, 0x8339, reg8339, 2);
853 }
808 break; 854 break;
809 } 855 }
810} 856}
@@ -814,6 +860,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
814 __u8 *data, /* isoc packet */ 860 __u8 *data, /* isoc packet */
815 int len) /* iso packet length */ 861 int len) /* iso packet length */
816{ 862{
863 struct sd *sd = (struct sd *) gspca_dev;
864
817 switch (data[0]) { 865 switch (data[0]) {
818 case 0: /* start of frame */ 866 case 0: /* start of frame */
819 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 867 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -826,8 +874,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
826 frame, data, len); 874 frame, data, len);
827 } else { 875 } else {
828 /* raw bayer (with a header, which we skip) */ 876 /* raw bayer (with a header, which we skip) */
829 data += 20; 877 if (sd->chip_revision == Rev012A) {
830 len -= 20; 878 data += 20;
879 len -= 20;
880 } else {
881 data += 16;
882 len -= 16;
883 }
831 gspca_frame_add(gspca_dev, FIRST_PACKET, 884 gspca_frame_add(gspca_dev, FIRST_PACKET,
832 frame, data, len); 885 frame, data, len);
833 } 886 }
@@ -841,24 +894,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
841 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 894 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
842} 895}
843 896
897/* rev 72a only */
844static void setbrightness(struct gspca_dev *gspca_dev) 898static void setbrightness(struct gspca_dev *gspca_dev)
845{ 899{
846 struct sd *sd = (struct sd *) gspca_dev; 900 struct sd *sd = (struct sd *) gspca_dev;
847 __u8 value; 901 __u8 value;
848 902
849 switch (sd->chip_revision) { 903 value = sd->brightness;
850 case Rev072A: 904 reg_w_val(gspca_dev->dev, 0x8611, value);
851 value = sd->brightness; 905 reg_w_val(gspca_dev->dev, 0x8612, value);
852 reg_w_val(gspca_dev->dev, value, 0x8611); 906 reg_w_val(gspca_dev->dev, 0x8613, value);
853 reg_w_val(gspca_dev->dev, value, 0x8612); 907 reg_w_val(gspca_dev->dev, 0x8614, value);
854 reg_w_val(gspca_dev->dev, value, 0x8613);
855 reg_w_val(gspca_dev->dev, value, 0x8614);
856 break;
857 default:
858/* case Rev012A: */
859 setcontrast(gspca_dev);
860 break;
861 }
862} 908}
863 909
864static void getbrightness(struct gspca_dev *gspca_dev) 910static void getbrightness(struct gspca_dev *gspca_dev)
@@ -866,52 +912,38 @@ static void getbrightness(struct gspca_dev *gspca_dev)
866 struct sd *sd = (struct sd *) gspca_dev; 912 struct sd *sd = (struct sd *) gspca_dev;
867 __u16 tot; 913 __u16 tot;
868 914
869 switch (sd->chip_revision) { 915 tot = 0;
870 case Rev072A: 916 reg_r(gspca_dev, 0x8611, 1);
871 tot = 0; 917 tot += gspca_dev->usb_buf[0];
872 reg_r(gspca_dev, 0x8611, 1); 918 reg_r(gspca_dev, 0x8612, 1);
873 tot += gspca_dev->usb_buf[0]; 919 tot += gspca_dev->usb_buf[0];
874 reg_r(gspca_dev, 0x8612, 1); 920 reg_r(gspca_dev, 0x8613, 1);
875 tot += gspca_dev->usb_buf[0]; 921 tot += gspca_dev->usb_buf[0];
876 reg_r(gspca_dev, 0x8613, 1); 922 reg_r(gspca_dev, 0x8614, 1);
877 tot += gspca_dev->usb_buf[0]; 923 tot += gspca_dev->usb_buf[0];
878 reg_r(gspca_dev, 0x8614, 1); 924 sd->brightness = tot >> 2;
879 tot += gspca_dev->usb_buf[0];
880 sd->brightness = tot >> 2;
881 break;
882 default:
883/* case Rev012A: */
884 /* no way to read sensor settings */
885 break;
886 }
887} 925}
888 926
927/* rev72a only */
889static void getcontrast(struct gspca_dev *gspca_dev) 928static void getcontrast(struct gspca_dev *gspca_dev)
890{ 929{
891 struct sd *sd = (struct sd *) gspca_dev; 930 struct sd *sd = (struct sd *) gspca_dev;
892 __u16 tot; 931 __u16 tot;
893 932
894 switch (sd->chip_revision) { 933 tot = 0;
895 case Rev072A: 934 reg_r(gspca_dev, 0x8651, 1);
896 tot = 0; 935 tot += gspca_dev->usb_buf[0];
897 reg_r(gspca_dev, 0x8651, 1); 936 reg_r(gspca_dev, 0x8652, 1);
898 tot += gspca_dev->usb_buf[0]; 937 tot += gspca_dev->usb_buf[0];
899 reg_r(gspca_dev, 0x8652, 1); 938 reg_r(gspca_dev, 0x8653, 1);
900 tot += gspca_dev->usb_buf[0]; 939 tot += gspca_dev->usb_buf[0];
901 reg_r(gspca_dev, 0x8653, 1); 940 reg_r(gspca_dev, 0x8654, 1);
902 tot += gspca_dev->usb_buf[0]; 941 tot += gspca_dev->usb_buf[0];
903 reg_r(gspca_dev, 0x8654, 1); 942 sd->contrast = tot << 6;
904 tot += gspca_dev->usb_buf[0];
905 sd->contrast = tot << 6;
906 break;
907 default:
908/* case Rev012A: */
909 /* no way to read sensor settings */
910 break;
911 }
912 PDEBUG(D_CONF, "get contrast %d", sd->contrast); 943 PDEBUG(D_CONF, "get contrast %d", sd->contrast);
913} 944}
914 945
946/* rev 72a only */
915static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 947static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
916{ 948{
917 struct sd *sd = (struct sd *) gspca_dev; 949 struct sd *sd = (struct sd *) gspca_dev;
@@ -931,6 +963,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
931 return 0; 963 return 0;
932} 964}
933 965
966/* rev 72a only */
934static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 967static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
935{ 968{
936 struct sd *sd = (struct sd *) gspca_dev; 969 struct sd *sd = (struct sd *) gspca_dev;
@@ -968,20 +1001,190 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
968 return 0; 1001 return 0;
969} 1002}
970 1003
1004/* rev12a only */
1005static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
1006{
1007 struct sd *sd = (struct sd *) gspca_dev;
1008
1009 sd->white = val;
1010 if (gspca_dev->streaming)
1011 setwhite(gspca_dev);
1012 return 0;
1013}
1014
1015static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
1016{
1017 struct sd *sd = (struct sd *) gspca_dev;
1018
1019 *val = sd->white;
1020 return 0;
1021}
1022
1023/* rev12a only */
1024static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1025{
1026 struct sd *sd = (struct sd *) gspca_dev;
1027
1028 sd->exposure = val;
1029 if (gspca_dev->streaming)
1030 setexposure(gspca_dev);
1031 return 0;
1032}
1033
1034static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1035{
1036 struct sd *sd = (struct sd *) gspca_dev;
1037
1038 *val = sd->exposure;
1039 return 0;
1040}
1041
1042/* rev12a only */
1043static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1044{
1045 struct sd *sd = (struct sd *) gspca_dev;
1046
1047 sd->gain = val;
1048 if (gspca_dev->streaming)
1049 setgain(gspca_dev);
1050 return 0;
1051}
1052
1053static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1054{
1055 struct sd *sd = (struct sd *) gspca_dev;
1056
1057 *val = sd->gain;
1058 return 0;
1059}
1060
1061/* control tables */
1062static struct ctrl sd_ctrls_12a[] = {
1063 {
1064 {
1065 .id = V4L2_CID_DO_WHITE_BALANCE,
1066 .type = V4L2_CTRL_TYPE_INTEGER,
1067 .name = "While Balance",
1068 .minimum = WHITE_MIN,
1069 .maximum = WHITE_MAX,
1070 .step = 1,
1071 .default_value = WHITE_DEF,
1072 },
1073 .set = sd_setwhite,
1074 .get = sd_getwhite,
1075 },
1076 {
1077 {
1078 .id = V4L2_CID_EXPOSURE,
1079 .type = V4L2_CTRL_TYPE_INTEGER,
1080 .name = "Exposure",
1081 .minimum = EXPOSURE_MIN,
1082 .maximum = EXPOSURE_MAX,
1083 .step = 1,
1084 .default_value = EXPOSURE_DEF,
1085 },
1086 .set = sd_setexposure,
1087 .get = sd_getexposure,
1088 },
1089 {
1090 {
1091 .id = V4L2_CID_AUTOGAIN,
1092 .type = V4L2_CTRL_TYPE_BOOLEAN,
1093 .name = "Auto Gain",
1094 .minimum = AUTOGAIN_MIN,
1095 .maximum = AUTOGAIN_MAX,
1096 .step = 1,
1097 .default_value = AUTOGAIN_DEF,
1098 },
1099 .set = sd_setautogain,
1100 .get = sd_getautogain,
1101 },
1102 {
1103 {
1104 .id = V4L2_CID_GAIN,
1105 .type = V4L2_CTRL_TYPE_INTEGER,
1106 .name = "Gain",
1107 .minimum = GAIN_MIN,
1108 .maximum = GAIN_MAX,
1109 .step = 1,
1110 .default_value = GAIN_DEF,
1111 },
1112 .set = sd_setgain,
1113 .get = sd_getgain,
1114 },
1115};
1116
1117static struct ctrl sd_ctrls_72a[] = {
1118 {
1119 {
1120 .id = V4L2_CID_BRIGHTNESS,
1121 .type = V4L2_CTRL_TYPE_INTEGER,
1122 .name = "Brightness",
1123 .minimum = BRIGHTNESS_MIN,
1124 .maximum = BRIGHTNESS_MAX,
1125 .step = 1,
1126 .default_value = BRIGHTNESS_DEF,
1127 },
1128 .set = sd_setbrightness,
1129 .get = sd_getbrightness,
1130 },
1131 {
1132 {
1133 .id = V4L2_CID_CONTRAST,
1134 .type = V4L2_CTRL_TYPE_INTEGER,
1135 .name = "Contrast",
1136 .minimum = CONTRAST_MIN,
1137 .maximum = CONTRAST_MAX,
1138 .step = 1,
1139 .default_value = CONTRAST_DEF,
1140 },
1141 .set = sd_setcontrast,
1142 .get = sd_getcontrast,
1143 },
1144 {
1145 {
1146 .id = V4L2_CID_AUTOGAIN,
1147 .type = V4L2_CTRL_TYPE_BOOLEAN,
1148 .name = "Auto Gain",
1149 .minimum = AUTOGAIN_MIN,
1150 .maximum = AUTOGAIN_MAX,
1151 .step = 1,
1152 .default_value = AUTOGAIN_DEF,
1153 },
1154 .set = sd_setautogain,
1155 .get = sd_getautogain,
1156 },
1157};
1158
971/* sub-driver description */ 1159/* sub-driver description */
972static const struct sd_desc sd_desc = { 1160static const struct sd_desc sd_desc_12a = {
1161 .name = MODULE_NAME,
1162 .ctrls = sd_ctrls_12a,
1163 .nctrls = ARRAY_SIZE(sd_ctrls_12a),
1164 .config = sd_config,
1165 .init = sd_init_12a,
1166 .start = sd_start_12a,
1167 .stopN = sd_stopN,
1168 .stop0 = sd_stop0,
1169 .pkt_scan = sd_pkt_scan,
1170/* .dq_callback = do_autogain, * fixme */
1171};
1172static const struct sd_desc sd_desc_72a = {
973 .name = MODULE_NAME, 1173 .name = MODULE_NAME,
974 .ctrls = sd_ctrls, 1174 .ctrls = sd_ctrls_72a,
975 .nctrls = ARRAY_SIZE(sd_ctrls), 1175 .nctrls = ARRAY_SIZE(sd_ctrls_72a),
976 .config = sd_config, 1176 .config = sd_config,
977 .open = sd_open, 1177 .init = sd_init_72a,
978 .start = sd_start, 1178 .start = sd_start_72a,
979 .stopN = sd_stopN, 1179 .stopN = sd_stopN,
980 .stop0 = sd_stop0, 1180 .stop0 = sd_stop0,
981 .close = sd_close,
982 .pkt_scan = sd_pkt_scan, 1181 .pkt_scan = sd_pkt_scan,
983 .dq_callback = do_autogain, 1182 .dq_callback = do_autogain,
984}; 1183};
1184static const struct sd_desc *sd_desc[2] = {
1185 &sd_desc_12a,
1186 &sd_desc_72a
1187};
985 1188
986/* -- module initialisation -- */ 1189/* -- module initialisation -- */
987static const __devinitdata struct usb_device_id device_table[] = { 1190static const __devinitdata struct usb_device_id device_table[] = {
@@ -1009,7 +1212,9 @@ MODULE_DEVICE_TABLE(usb, device_table);
1009static int sd_probe(struct usb_interface *intf, 1212static int sd_probe(struct usb_interface *intf,
1010 const struct usb_device_id *id) 1213 const struct usb_device_id *id)
1011{ 1214{
1012 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 1215 return gspca_dev_probe(intf, id,
1216 sd_desc[id->driver_info],
1217 sizeof(struct sd),
1013 THIS_MODULE); 1218 THIS_MODULE);
1014} 1219}
1015 1220
@@ -1018,6 +1223,10 @@ static struct usb_driver sd_driver = {
1018 .id_table = device_table, 1223 .id_table = device_table,
1019 .probe = sd_probe, 1224 .probe = sd_probe,
1020 .disconnect = gspca_disconnect, 1225 .disconnect = gspca_disconnect,
1226#ifdef CONFIG_PM
1227 .suspend = gspca_suspend,
1228 .resume = gspca_resume,
1229#endif
1021}; 1230};
1022 1231
1023/* -- module insert / remove -- */ 1232/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 16219cf6a6d5..2f2de429e273 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -306,8 +306,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
306 return 0; 306 return 0;
307} 307}
308 308
309/* this function is called at open time */ 309/* this function is called at probe and resume time */
310static int sd_open(struct gspca_dev *gspca_dev) 310static int sd_init(struct gspca_dev *gspca_dev)
311{ 311{
312 int ret; 312 int ret;
313 313
@@ -398,14 +398,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
398 PDEBUG(D_STREAM, "camera stopped"); 398 PDEBUG(D_STREAM, "camera stopped");
399} 399}
400 400
401static void sd_stop0(struct gspca_dev *gspca_dev)
402{
403}
404
405static void sd_close(struct gspca_dev *gspca_dev)
406{
407}
408
409static void sd_pkt_scan(struct gspca_dev *gspca_dev, 401static void sd_pkt_scan(struct gspca_dev *gspca_dev,
410 struct gspca_frame *frame, /* target */ 402 struct gspca_frame *frame, /* target */
411 __u8 *data, /* isoc packet */ 403 __u8 *data, /* isoc packet */
@@ -535,11 +527,9 @@ static const struct sd_desc sd_desc = {
535 .ctrls = sd_ctrls, 527 .ctrls = sd_ctrls,
536 .nctrls = ARRAY_SIZE(sd_ctrls), 528 .nctrls = ARRAY_SIZE(sd_ctrls),
537 .config = sd_config, 529 .config = sd_config,
538 .open = sd_open, 530 .init = sd_init,
539 .start = sd_start, 531 .start = sd_start,
540 .stopN = sd_stopN, 532 .stopN = sd_stopN,
541 .stop0 = sd_stop0,
542 .close = sd_close,
543 .pkt_scan = sd_pkt_scan, 533 .pkt_scan = sd_pkt_scan,
544 .querymenu = sd_querymenu, 534 .querymenu = sd_querymenu,
545}; 535};
@@ -564,6 +554,10 @@ static struct usb_driver sd_driver = {
564 .id_table = device_table, 554 .id_table = device_table,
565 .probe = sd_probe, 555 .probe = sd_probe,
566 .disconnect = gspca_disconnect, 556 .disconnect = gspca_disconnect,
557#ifdef CONFIG_PM
558 .suspend = gspca_suspend,
559 .resume = gspca_resume,
560#endif
567}; 561};
568 562
569/* -- module insert / remove -- */ 563/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 54efa48bee01..1cfcc6c49558 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -449,31 +449,47 @@ static const __u8 qtable_spca504_default[2][64] = {
449 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} 449 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
450}; 450};
451 451
452static void reg_r(struct usb_device *dev, 452/* read <len> bytes to gspca_dev->usb_buf */
453 __u16 req, 453static void reg_r(struct gspca_dev *gspca_dev,
454 __u16 index, 454 __u16 req,
455 __u8 *buffer, __u16 length) 455 __u16 index,
456 __u16 len)
456{ 457{
457 usb_control_msg(dev, 458#ifdef GSPCA_DEBUG
458 usb_rcvctrlpipe(dev, 0), 459 if (len > USB_BUF_SZ) {
460 err("reg_r: buffer overflow");
461 return;
462 }
463#endif
464 usb_control_msg(gspca_dev->dev,
465 usb_rcvctrlpipe(gspca_dev->dev, 0),
459 req, 466 req,
460 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 467 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
461 0, /* value */ 468 0, /* value */
462 index, buffer, length, 469 index,
470 len ? gspca_dev->usb_buf : NULL, len,
463 500); 471 500);
464} 472}
465 473
466static void reg_w(struct usb_device *dev, 474/* write <len> bytes from gspca_dev->usb_buf */
467 __u16 req, 475static void reg_w(struct gspca_dev *gspca_dev,
468 __u16 value, 476 __u16 req,
469 __u16 index, 477 __u16 value,
470 __u8 *buffer, __u16 length) 478 __u16 index,
479 __u16 len)
471{ 480{
472 usb_control_msg(dev, 481#ifdef GSPCA_DEBUG
473 usb_sndctrlpipe(dev, 0), 482 if (len > USB_BUF_SZ) {
483 err("reg_w: buffer overflow");
484 return;
485 }
486#endif
487 usb_control_msg(gspca_dev->dev,
488 usb_sndctrlpipe(gspca_dev->dev, 0),
474 req, 489 req,
475 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 490 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
476 value, index, buffer, length, 491 value, index,
492 len ? gspca_dev->usb_buf : NULL, len,
477 500); 493 500);
478} 494}
479 495
@@ -634,7 +650,7 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
634 int count = 10; 650 int count = 10;
635 651
636 while (--count > 0) { 652 while (--count > 0) {
637 reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1); 653 reg_r(gspca_dev, 0x21, 0, 1);
638 if ((gspca_dev->usb_buf[0] & 0x01) == 0) 654 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
639 break; 655 break;
640 msleep(10); 656 msleep(10);
@@ -644,15 +660,14 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
644 660
645static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) 661static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
646{ 662{
647 struct usb_device *dev = gspca_dev->dev;
648 int count = 50; 663 int count = 50;
649 664
650 while (--count > 0) { 665 while (--count > 0) {
651 reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); 666 reg_r(gspca_dev, 0x21, 1, 1);
652 if (gspca_dev->usb_buf[0] != 0) { 667 if (gspca_dev->usb_buf[0] != 0) {
653 gspca_dev->usb_buf[0] = 0; 668 gspca_dev->usb_buf[0] = 0;
654 reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1); 669 reg_w(gspca_dev, 0x21, 0, 1, 1);
655 reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); 670 reg_r(gspca_dev, 0x21, 1, 1);
656 spca504B_PollingDataReady(gspca_dev); 671 spca504B_PollingDataReady(gspca_dev);
657 break; 672 break;
658 } 673 }
@@ -662,16 +677,14 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
662 677
663static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) 678static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
664{ 679{
665 struct usb_device *dev = gspca_dev->dev;
666 __u8 *data; 680 __u8 *data;
667 681
668 data = kmalloc(64, GFP_KERNEL); 682 data = gspca_dev->usb_buf;
669 reg_r(dev, 0x20, 0, data, 5); 683 reg_r(gspca_dev, 0x20, 0, 5);
670 PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", 684 PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
671 data[0], data[1], data[2], data[3], data[4]); 685 data[0], data[1], data[2], data[3], data[4]);
672 reg_r(dev, 0x23, 0, data, 64); 686 reg_r(gspca_dev, 0x23, 0, 64);
673 reg_r(dev, 0x23, 1, data, 64); 687 reg_r(gspca_dev, 0x23, 1, 64);
674 kfree(data);
675} 688}
676 689
677static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) 690static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
@@ -686,21 +699,21 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
686 Type = 0; 699 Type = 0;
687 switch (sd->bridge) { 700 switch (sd->bridge) {
688 case BRIDGE_SPCA533: 701 case BRIDGE_SPCA533:
689 reg_w(dev, 0x31, 0, 0, NULL, 0); 702 reg_w(gspca_dev, 0x31, 0, 0, 0);
690 spca504B_WaitCmdStatus(gspca_dev); 703 spca504B_WaitCmdStatus(gspca_dev);
691 rc = spca504B_PollingDataReady(gspca_dev); 704 rc = spca504B_PollingDataReady(gspca_dev);
692 spca50x_GetFirmware(gspca_dev); 705 spca50x_GetFirmware(gspca_dev);
693 gspca_dev->usb_buf[0] = 2; /* type */ 706 gspca_dev->usb_buf[0] = 2; /* type */
694 reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1); 707 reg_w(gspca_dev, 0x24, 0, 8, 1);
695 reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1); 708 reg_r(gspca_dev, 0x24, 8, 1);
696 709
697 gspca_dev->usb_buf[0] = Size; 710 gspca_dev->usb_buf[0] = Size;
698 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); 711 reg_w(gspca_dev, 0x25, 0, 4, 1);
699 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ 712 reg_r(gspca_dev, 0x25, 4, 1); /* size */
700 rc = spca504B_PollingDataReady(gspca_dev); 713 rc = spca504B_PollingDataReady(gspca_dev);
701 714
702 /* Init the cam width height with some values get on init ? */ 715 /* Init the cam width height with some values get on init ? */
703 reg_w(dev, 0x31, 0, 4, NULL, 0); 716 reg_w(gspca_dev, 0x31, 0, 4, 0);
704 spca504B_WaitCmdStatus(gspca_dev); 717 spca504B_WaitCmdStatus(gspca_dev);
705 rc = spca504B_PollingDataReady(gspca_dev); 718 rc = spca504B_PollingDataReady(gspca_dev);
706 break; 719 break;
@@ -708,12 +721,12 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
708/* case BRIDGE_SPCA504B: */ 721/* case BRIDGE_SPCA504B: */
709/* case BRIDGE_SPCA536: */ 722/* case BRIDGE_SPCA536: */
710 gspca_dev->usb_buf[0] = Size; 723 gspca_dev->usb_buf[0] = Size;
711 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); 724 reg_w(gspca_dev, 0x25, 0, 4, 1);
712 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ 725 reg_r(gspca_dev, 0x25, 4, 1); /* size */
713 Type = 6; 726 Type = 6;
714 gspca_dev->usb_buf[0] = Type; 727 gspca_dev->usb_buf[0] = Type;
715 reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1); 728 reg_w(gspca_dev, 0x27, 0, 0, 1);
716 reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1); /* type */ 729 reg_r(gspca_dev, 0x27, 0, 1); /* type */
717 rc = spca504B_PollingDataReady(gspca_dev); 730 rc = spca504B_PollingDataReady(gspca_dev);
718 break; 731 break;
719 case BRIDGE_SPCA504: 732 case BRIDGE_SPCA504:
@@ -752,18 +765,15 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
752 765
753static void spca504B_setQtable(struct gspca_dev *gspca_dev) 766static void spca504B_setQtable(struct gspca_dev *gspca_dev)
754{ 767{
755 struct usb_device *dev = gspca_dev->dev;
756
757 gspca_dev->usb_buf[0] = 3; 768 gspca_dev->usb_buf[0] = 3;
758 reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1); 769 reg_w(gspca_dev, 0x26, 0, 0, 1);
759 reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1); 770 reg_r(gspca_dev, 0x26, 0, 1);
760 spca504B_PollingDataReady(gspca_dev); 771 spca504B_PollingDataReady(gspca_dev);
761} 772}
762 773
763static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) 774static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
764{ 775{
765 struct sd *sd = (struct sd *) gspca_dev; 776 struct sd *sd = (struct sd *) gspca_dev;
766 struct usb_device *dev = gspca_dev->dev;
767 int pollreg = 1; 777 int pollreg = 1;
768 778
769 switch (sd->bridge) { 779 switch (sd->bridge) {
@@ -774,20 +784,20 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
774 default: 784 default:
775/* case BRIDGE_SPCA533: */ 785/* case BRIDGE_SPCA533: */
776/* case BRIDGE_SPCA504B: */ 786/* case BRIDGE_SPCA504B: */
777 reg_w(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ 787 reg_w(gspca_dev, 0, 0, 0x21a7, 0); /* brightness */
778 reg_w(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ 788 reg_w(gspca_dev, 0, 0x20, 0x21a8, 0); /* contrast */
779 reg_w(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ 789 reg_w(gspca_dev, 0, 0, 0x21ad, 0); /* hue */
780 reg_w(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ 790 reg_w(gspca_dev, 0, 1, 0x21ac, 0); /* sat/hue */
781 reg_w(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ 791 reg_w(gspca_dev, 0, 0x20, 0x21ae, 0); /* saturation */
782 reg_w(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ 792 reg_w(gspca_dev, 0, 0, 0x21a3, 0); /* gamma */
783 break; 793 break;
784 case BRIDGE_SPCA536: 794 case BRIDGE_SPCA536:
785 reg_w(dev, 0, 0, 0x20f0, NULL, 0); 795 reg_w(gspca_dev, 0, 0, 0x20f0, 0);
786 reg_w(dev, 0, 0x21, 0x20f1, NULL, 0); 796 reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);
787 reg_w(dev, 0, 0x40, 0x20f5, NULL, 0); 797 reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);
788 reg_w(dev, 0, 1, 0x20f4, NULL, 0); 798 reg_w(gspca_dev, 0, 1, 0x20f4, 0);
789 reg_w(dev, 0, 0x40, 0x20f6, NULL, 0); 799 reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
790 reg_w(dev, 0, 0, 0x2089, NULL, 0); 800 reg_w(gspca_dev, 0, 0, 0x2089, 0);
791 break; 801 break;
792 } 802 }
793 if (pollreg) 803 if (pollreg)
@@ -799,7 +809,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
799 const struct usb_device_id *id) 809 const struct usb_device_id *id)
800{ 810{
801 struct sd *sd = (struct sd *) gspca_dev; 811 struct sd *sd = (struct sd *) gspca_dev;
802 struct usb_device *dev = gspca_dev->dev;
803 struct cam *cam; 812 struct cam *cam;
804 813
805 cam = &gspca_dev->cam; 814 cam = &gspca_dev->cam;
@@ -811,7 +820,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
811 if (sd->subtype == AiptekMiniPenCam13) { 820 if (sd->subtype == AiptekMiniPenCam13) {
812/* try to get the firmware as some cam answer 2.0.1.2.2 821/* try to get the firmware as some cam answer 2.0.1.2.2
813 * and should be a spca504b then overwrite that setting */ 822 * and should be a spca504b then overwrite that setting */
814 reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); 823 reg_r(gspca_dev, 0x20, 0, 1);
815 switch (gspca_dev->usb_buf[0]) { 824 switch (gspca_dev->usb_buf[0]) {
816 case 1: 825 case 1:
817 break; /* (right bridge/subtype) */ 826 break; /* (right bridge/subtype) */
@@ -848,8 +857,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
848 return 0; 857 return 0;
849} 858}
850 859
851/* this function is called at open time */ 860/* this function is called at probe and resume time */
852static int sd_open(struct gspca_dev *gspca_dev) 861static int sd_init(struct gspca_dev *gspca_dev)
853{ 862{
854 struct sd *sd = (struct sd *) gspca_dev; 863 struct sd *sd = (struct sd *) gspca_dev;
855 struct usb_device *dev = gspca_dev->dev; 864 struct usb_device *dev = gspca_dev->dev;
@@ -860,12 +869,12 @@ static int sd_open(struct gspca_dev *gspca_dev)
860 869
861 switch (sd->bridge) { 870 switch (sd->bridge) {
862 case BRIDGE_SPCA504B: 871 case BRIDGE_SPCA504B:
863 reg_w(dev, 0x1d, 0, 0, NULL, 0); 872 reg_w(gspca_dev, 0x1d, 0, 0, 0);
864 reg_w(dev, 0, 1, 0x2306, NULL, 0); 873 reg_w(gspca_dev, 0, 1, 0x2306, 0);
865 reg_w(dev, 0, 0, 0x0d04, NULL, 0); 874 reg_w(gspca_dev, 0, 0, 0x0d04, 0);
866 reg_w(dev, 0, 0, 0x2000, NULL, 0); 875 reg_w(gspca_dev, 0, 0, 0x2000, 0);
867 reg_w(dev, 0, 0x13, 0x2301, NULL, 0); 876 reg_w(gspca_dev, 0, 0x13, 0x2301, 0);
868 reg_w(dev, 0, 0, 0x2306, NULL, 0); 877 reg_w(gspca_dev, 0, 0, 0x2306, 0);
869 /* fall thru */ 878 /* fall thru */
870 case BRIDGE_SPCA533: 879 case BRIDGE_SPCA533:
871 rc = spca504B_PollingDataReady(gspca_dev); 880 rc = spca504B_PollingDataReady(gspca_dev);
@@ -873,12 +882,12 @@ static int sd_open(struct gspca_dev *gspca_dev)
873 break; 882 break;
874 case BRIDGE_SPCA536: 883 case BRIDGE_SPCA536:
875 spca50x_GetFirmware(gspca_dev); 884 spca50x_GetFirmware(gspca_dev);
876 reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1); 885 reg_r(gspca_dev, 0x00, 0x5002, 1);
877 gspca_dev->usb_buf[0] = 0; 886 gspca_dev->usb_buf[0] = 0;
878 reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1); 887 reg_w(gspca_dev, 0x24, 0, 0, 1);
879 reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1); 888 reg_r(gspca_dev, 0x24, 0, 1);
880 rc = spca504B_PollingDataReady(gspca_dev); 889 rc = spca504B_PollingDataReady(gspca_dev);
881 reg_w(dev, 0x34, 0, 0, NULL, 0); 890 reg_w(gspca_dev, 0x34, 0, 0, 0);
882 spca504B_WaitCmdStatus(gspca_dev); 891 spca504B_WaitCmdStatus(gspca_dev);
883 break; 892 break;
884 case BRIDGE_SPCA504C: /* pccam600 */ 893 case BRIDGE_SPCA504C: /* pccam600 */
@@ -971,12 +980,12 @@ static void sd_start(struct gspca_dev *gspca_dev)
971/* case BRIDGE_SPCA536: */ 980/* case BRIDGE_SPCA536: */
972 if (sd->subtype == MegapixV4 || 981 if (sd->subtype == MegapixV4 ||
973 sd->subtype == LogitechClickSmart820) { 982 sd->subtype == LogitechClickSmart820) {
974 reg_w(dev, 0xf0, 0, 0, NULL, 0); 983 reg_w(gspca_dev, 0xf0, 0, 0, 0);
975 spca504B_WaitCmdStatus(gspca_dev); 984 spca504B_WaitCmdStatus(gspca_dev);
976 reg_r(dev, 0xf0, 4, NULL, 0); 985 reg_r(gspca_dev, 0xf0, 4, 0);
977 spca504B_WaitCmdStatus(gspca_dev); 986 spca504B_WaitCmdStatus(gspca_dev);
978 } else { 987 } else {
979 reg_w(dev, 0x31, 0, 4, NULL, 0); 988 reg_w(gspca_dev, 0x31, 0, 4, 0);
980 spca504B_WaitCmdStatus(gspca_dev); 989 spca504B_WaitCmdStatus(gspca_dev);
981 rc = spca504B_PollingDataReady(gspca_dev); 990 rc = spca504B_PollingDataReady(gspca_dev);
982 } 991 }
@@ -1045,7 +1054,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1045/* case BRIDGE_SPCA533: */ 1054/* case BRIDGE_SPCA533: */
1046/* case BRIDGE_SPCA536: */ 1055/* case BRIDGE_SPCA536: */
1047/* case BRIDGE_SPCA504B: */ 1056/* case BRIDGE_SPCA504B: */
1048 reg_w(dev, 0x31, 0, 0, NULL, 0); 1057 reg_w(gspca_dev, 0x31, 0, 0, 0);
1049 spca504B_WaitCmdStatus(gspca_dev); 1058 spca504B_WaitCmdStatus(gspca_dev);
1050 spca504B_PollingDataReady(gspca_dev); 1059 spca504B_PollingDataReady(gspca_dev);
1051 break; 1060 break;
@@ -1069,14 +1078,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1069 } 1078 }
1070} 1079}
1071 1080
1072static void sd_stop0(struct gspca_dev *gspca_dev)
1073{
1074}
1075
1076static void sd_close(struct gspca_dev *gspca_dev)
1077{
1078}
1079
1080static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1081static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1081 struct gspca_frame *frame, /* target */ 1082 struct gspca_frame *frame, /* target */
1082 __u8 *data, /* isoc packet */ 1083 __u8 *data, /* isoc packet */
@@ -1369,11 +1370,9 @@ static const struct sd_desc sd_desc = {
1369 .ctrls = sd_ctrls, 1370 .ctrls = sd_ctrls,
1370 .nctrls = ARRAY_SIZE(sd_ctrls), 1371 .nctrls = ARRAY_SIZE(sd_ctrls),
1371 .config = sd_config, 1372 .config = sd_config,
1372 .open = sd_open, 1373 .init = sd_init,
1373 .start = sd_start, 1374 .start = sd_start,
1374 .stopN = sd_stopN, 1375 .stopN = sd_stopN,
1375 .stop0 = sd_stop0,
1376 .close = sd_close,
1377 .pkt_scan = sd_pkt_scan, 1376 .pkt_scan = sd_pkt_scan,
1378}; 1377};
1379 1378
@@ -1456,6 +1455,10 @@ static struct usb_driver sd_driver = {
1456 .id_table = device_table, 1455 .id_table = device_table,
1457 .probe = sd_probe, 1456 .probe = sd_probe,
1458 .disconnect = gspca_disconnect, 1457 .disconnect = gspca_disconnect,
1458#ifdef CONFIG_PM
1459 .suspend = gspca_suspend,
1460 .resume = gspca_resume,
1461#endif
1459}; 1462};
1460 1463
1461/* -- module insert / remove -- */ 1464/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 91b555c34c68..f034c748fc7e 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -30,7 +30,7 @@
30 30
31#define MAX_GAMMA 0x10 /* 0 to 15 */ 31#define MAX_GAMMA 0x10 /* 0 to 15 */
32 32
33#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3) 33#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
34 34
35MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); 35MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
36MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); 36MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
@@ -233,7 +233,7 @@ static char *effects_control[] = {
233static struct v4l2_pix_format vga_mode_t16[] = { 233static struct v4l2_pix_format vga_mode_t16[] = {
234 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 234 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
235 .bytesperline = 160, 235 .bytesperline = 160,
236 .sizeimage = 160 * 120 * 3 / 8 + 590, 236 .sizeimage = 160 * 120 * 4 / 8 + 590,
237 .colorspace = V4L2_COLORSPACE_JPEG, 237 .colorspace = V4L2_COLORSPACE_JPEG,
238 .priv = 4}, 238 .priv = 4},
239 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 239 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -391,7 +391,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
391 NULL, 0, 500); 391 NULL, 0, 500);
392 return; 392 return;
393 } 393 }
394 if (len <= sizeof gspca_dev->usb_buf) { 394 if (len <= USB_BUF_SZ) {
395 memcpy(gspca_dev->usb_buf, buffer, len); 395 memcpy(gspca_dev->usb_buf, buffer, len);
396 usb_control_msg(gspca_dev->dev, 396 usb_control_msg(gspca_dev->dev,
397 usb_sndctrlpipe(gspca_dev->dev, 0), 397 usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -552,6 +552,13 @@ static int init_default_parameters(struct gspca_dev *gspca_dev)
552 return 0; 552 return 0;
553} 553}
554 554
555/* this function is called at probe and resume time */
556static int sd_init(struct gspca_dev *gspca_dev)
557{
558 init_default_parameters(gspca_dev);
559 return 0;
560}
561
555static void setbrightness(struct gspca_dev *gspca_dev) 562static void setbrightness(struct gspca_dev *gspca_dev)
556{ 563{
557 struct sd *sd = (struct sd *) gspca_dev; 564 struct sd *sd = (struct sd *) gspca_dev;
@@ -893,18 +900,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
893 setcolors(gspca_dev); 900 setcolors(gspca_dev);
894} 901}
895 902
896static void sd_stopN(struct gspca_dev *gspca_dev)
897{
898}
899
900static void sd_stop0(struct gspca_dev *gspca_dev)
901{
902}
903
904static void sd_close(struct gspca_dev *gspca_dev)
905{
906}
907
908static void sd_pkt_scan(struct gspca_dev *gspca_dev, 903static void sd_pkt_scan(struct gspca_dev *gspca_dev,
909 struct gspca_frame *frame, /* target */ 904 struct gspca_frame *frame, /* target */
910 __u8 *data, /* isoc packet */ 905 __u8 *data, /* isoc packet */
@@ -972,24 +967,14 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
972 return -EINVAL; 967 return -EINVAL;
973} 968}
974 969
975/* this function is called at open time */
976static int sd_open(struct gspca_dev *gspca_dev)
977{
978 init_default_parameters(gspca_dev);
979 return 0;
980}
981
982/* sub-driver description */ 970/* sub-driver description */
983static const struct sd_desc sd_desc = { 971static const struct sd_desc sd_desc = {
984 .name = MODULE_NAME, 972 .name = MODULE_NAME,
985 .ctrls = sd_ctrls, 973 .ctrls = sd_ctrls,
986 .nctrls = ARRAY_SIZE(sd_ctrls), 974 .nctrls = ARRAY_SIZE(sd_ctrls),
987 .config = sd_config, 975 .config = sd_config,
988 .open = sd_open, 976 .init = sd_init,
989 .start = sd_start, 977 .start = sd_start,
990 .stopN = sd_stopN,
991 .stop0 = sd_stop0,
992 .close = sd_close,
993 .pkt_scan = sd_pkt_scan, 978 .pkt_scan = sd_pkt_scan,
994 .querymenu = sd_querymenu, 979 .querymenu = sd_querymenu,
995}; 980};
@@ -1014,6 +999,10 @@ static struct usb_driver sd_driver = {
1014 .id_table = device_table, 999 .id_table = device_table,
1015 .probe = sd_probe, 1000 .probe = sd_probe,
1016 .disconnect = gspca_disconnect, 1001 .disconnect = gspca_disconnect,
1002#ifdef CONFIG_PM
1003 .suspend = gspca_suspend,
1004 .resume = gspca_resume,
1005#endif
1017}; 1006};
1018 1007
1019/* -- module insert / remove -- */ 1008/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 1ff8ba2f7fe5..084af05302a0 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -331,8 +331,8 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
331 } 331 }
332} 332}
333 333
334/* this function is called at open time */ 334/* this function is called at probe and resume time */
335static int sd_open(struct gspca_dev *gspca_dev) 335static int sd_init(struct gspca_dev *gspca_dev)
336{ 336{
337 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); 337 reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
338 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); 338 reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
@@ -450,14 +450,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
450 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); 450 reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
451} 451}
452 452
453static void sd_stop0(struct gspca_dev *gspca_dev)
454{
455}
456
457static void sd_close(struct gspca_dev *gspca_dev)
458{
459}
460
461static void tv8532_preprocess(struct gspca_dev *gspca_dev) 453static void tv8532_preprocess(struct gspca_dev *gspca_dev)
462{ 454{
463 struct sd *sd = (struct sd *) gspca_dev; 455 struct sd *sd = (struct sd *) gspca_dev;
@@ -611,11 +603,9 @@ static const struct sd_desc sd_desc = {
611 .ctrls = sd_ctrls, 603 .ctrls = sd_ctrls,
612 .nctrls = ARRAY_SIZE(sd_ctrls), 604 .nctrls = ARRAY_SIZE(sd_ctrls),
613 .config = sd_config, 605 .config = sd_config,
614 .open = sd_open, 606 .init = sd_init,
615 .start = sd_start, 607 .start = sd_start,
616 .stopN = sd_stopN, 608 .stopN = sd_stopN,
617 .stop0 = sd_stop0,
618 .close = sd_close,
619 .pkt_scan = sd_pkt_scan, 609 .pkt_scan = sd_pkt_scan,
620}; 610};
621 611
@@ -644,6 +634,10 @@ static struct usb_driver sd_driver = {
644 .id_table = device_table, 634 .id_table = device_table,
645 .probe = sd_probe, 635 .probe = sd_probe,
646 .disconnect = gspca_disconnect, 636 .disconnect = gspca_disconnect,
637#ifdef CONFIG_PM
638 .suspend = gspca_suspend,
639 .resume = gspca_resume,
640#endif
647}; 641};
648 642
649/* -- module insert / remove -- */ 643/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index f4a52956e0d9..bd4c226c9a07 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -69,6 +69,7 @@ static struct ctrl sd_ctrls[] = {
69 .set = sd_setautogain, 69 .set = sd_setautogain,
70 .get = sd_getautogain, 70 .get = sd_getautogain,
71 }, 71 },
72#define LIGHTFREQ_IDX 1
72 { 73 {
73 { 74 {
74 .id = V4L2_CID_POWER_LINE_FREQUENCY, 75 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -87,12 +88,12 @@ static struct ctrl sd_ctrls[] = {
87}; 88};
88 89
89static struct v4l2_pix_format vc0321_mode[] = { 90static struct v4l2_pix_format vc0321_mode[] = {
90 {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 91 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
91 .bytesperline = 320, 92 .bytesperline = 320,
92 .sizeimage = 320 * 240 * 2, 93 .sizeimage = 320 * 240 * 2,
93 .colorspace = V4L2_COLORSPACE_SRGB, 94 .colorspace = V4L2_COLORSPACE_SRGB,
94 .priv = 1}, 95 .priv = 1},
95 {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 96 {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
96 .bytesperline = 640, 97 .bytesperline = 640,
97 .sizeimage = 640 * 480 * 2, 98 .sizeimage = 640 * 480 * 2,
98 .colorspace = V4L2_COLORSPACE_SRGB, 99 .colorspace = V4L2_COLORSPACE_SRGB,
@@ -1463,6 +1464,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1463 sd->qindex = 7; 1464 sd->qindex = 7;
1464 sd->autogain = AUTOGAIN_DEF; 1465 sd->autogain = AUTOGAIN_DEF;
1465 sd->lightfreq = FREQ_DEF; 1466 sd->lightfreq = FREQ_DEF;
1467 if (sd->sensor != SENSOR_OV7670)
1468 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
1466 1469
1467 if (sd->bridge == BRIDGE_VC0321) { 1470 if (sd->bridge == BRIDGE_VC0321) {
1468 reg_r(gspca_dev, 0x8a, 0, 3); 1471 reg_r(gspca_dev, 0x8a, 0, 3);
@@ -1474,8 +1477,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1474 return 0; 1477 return 0;
1475} 1478}
1476 1479
1477/* this function is called at open time */ 1480/* this function is called at probe and time */
1478static int sd_open(struct gspca_dev *gspca_dev) 1481static int sd_init(struct gspca_dev *gspca_dev)
1479{ 1482{
1480 return 0; 1483 return 0;
1481} 1484}
@@ -1637,19 +1640,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
1637 reg_w(dev, 0x89, 0xffff, 0xffff); 1640 reg_w(dev, 0x89, 0xffff, 0xffff);
1638} 1641}
1639 1642
1640/* this function is called at close time */
1641static void sd_close(struct gspca_dev *gspca_dev)
1642{
1643/* struct usb_device *dev = gspca_dev->dev;
1644 __u8 buffread;
1645
1646 reg_w(dev, 0x89, 0xffff, 0xffff);
1647 reg_w(dev, 0xa0, 0x01, 0xb301);
1648 reg_w(dev, 0xa0, 0x09, 0xb303);
1649 reg_w(dev, 0x89, 0xffff, 0xffff);
1650*/
1651}
1652
1653static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1643static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1654 struct gspca_frame *frame, /* target */ 1644 struct gspca_frame *frame, /* target */
1655 __u8 *data, /* isoc packet */ 1645 __u8 *data, /* isoc packet */
@@ -1738,11 +1728,10 @@ static const struct sd_desc sd_desc = {
1738 .ctrls = sd_ctrls, 1728 .ctrls = sd_ctrls,
1739 .nctrls = ARRAY_SIZE(sd_ctrls), 1729 .nctrls = ARRAY_SIZE(sd_ctrls),
1740 .config = sd_config, 1730 .config = sd_config,
1741 .open = sd_open, 1731 .init = sd_init,
1742 .start = sd_start, 1732 .start = sd_start,
1743 .stopN = sd_stopN, 1733 .stopN = sd_stopN,
1744 .stop0 = sd_stop0, 1734 .stop0 = sd_stop0,
1745 .close = sd_close,
1746 .pkt_scan = sd_pkt_scan, 1735 .pkt_scan = sd_pkt_scan,
1747 .querymenu = sd_querymenu, 1736 .querymenu = sd_querymenu,
1748}; 1737};
@@ -1774,6 +1763,10 @@ static struct usb_driver sd_driver = {
1774 .id_table = device_table, 1763 .id_table = device_table,
1775 .probe = sd_probe, 1764 .probe = sd_probe,
1776 .disconnect = gspca_disconnect, 1765 .disconnect = gspca_disconnect,
1766#ifdef CONFIG_PM
1767 .suspend = gspca_suspend,
1768 .resume = gspca_resume,
1769#endif
1777}; 1770};
1778 1771
1779/* -- module insert / remove -- */ 1772/* -- module insert / remove -- */
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index bc7d0eedcd81..8d7c27e6ac77 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -85,6 +85,7 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 85static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
86 86
87static struct ctrl sd_ctrls[] = { 87static struct ctrl sd_ctrls[] = {
88#define BRIGHTNESS_IDX 0
88#define SD_BRIGHTNESS 0 89#define SD_BRIGHTNESS 0
89 { 90 {
90 { 91 {
@@ -141,6 +142,7 @@ static struct ctrl sd_ctrls[] = {
141 .set = sd_setautogain, 142 .set = sd_setautogain,
142 .get = sd_getautogain, 143 .get = sd_getautogain,
143 }, 144 },
145#define LIGHTFREQ_IDX 4
144#define SD_FREQ 4 146#define SD_FREQ 4
145 { 147 {
146 { 148 {
@@ -6964,8 +6966,13 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
6964 case SENSOR_MC501CB: 6966 case SENSOR_MC501CB:
6965 return -1; /* don't probe */ 6967 return -1; /* don't probe */
6966 case SENSOR_TAS5130C_VF0250: 6968 case SENSOR_TAS5130C_VF0250:
6967 /* may probe but with write in reg 0x0010 */ 6969 /* may probe but with no write in reg 0x0010 */
6968 return -1; /* don't probe */ 6970 return -1; /* don't probe */
6971 case SENSOR_PAS106:
6972 sensor = sif_probe(gspca_dev);
6973 if (sensor >= 0)
6974 return sensor;
6975 break;
6969 } 6976 }
6970 sensor = vga_2wr_probe(gspca_dev); 6977 sensor = vga_2wr_probe(gspca_dev);
6971 if (sensor >= 0) { 6978 if (sensor >= 0) {
@@ -6974,12 +6981,10 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
6974 /* next probe is needed for OmniVision ? */ 6981 /* next probe is needed for OmniVision ? */
6975 } 6982 }
6976 sensor2 = vga_3wr_probe(gspca_dev); 6983 sensor2 = vga_3wr_probe(gspca_dev);
6977 if (sensor2 >= 0) { 6984 if (sensor2 >= 0
6978 if (sensor >= 0) 6985 && sensor >= 0)
6979 return sensor; 6986 return sensor;
6980 return sensor2; 6987 return sensor2;
6981 }
6982 return sif_probe(gspca_dev);
6983} 6988}
6984 6989
6985/* this function is called at probe time */ 6990/* this function is called at probe time */
@@ -7147,13 +7152,27 @@ static int sd_config(struct gspca_dev *gspca_dev,
7147 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; 7152 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
7148 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; 7153 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
7149 7154
7155 switch (sd->sensor) {
7156 case SENSOR_GC0305:
7157 case SENSOR_OV7620:
7158 case SENSOR_PO2030:
7159 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
7160 break;
7161 case SENSOR_HDCS2020:
7162 case SENSOR_HV7131B:
7163 case SENSOR_HV7131C:
7164 case SENSOR_OV7630C:
7165 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
7166 break;
7167 }
7168
7150 /* switch the led off */ 7169 /* switch the led off */
7151 reg_w(gspca_dev->dev, 0x01, 0x0000); 7170 reg_w(gspca_dev->dev, 0x01, 0x0000);
7152 return 0; 7171 return 0;
7153} 7172}
7154 7173
7155/* this function is called at open time */ 7174/* this function is called at probe and resume time */
7156static int sd_open(struct gspca_dev *gspca_dev) 7175static int sd_init(struct gspca_dev *gspca_dev)
7157{ 7176{
7158 reg_w(gspca_dev->dev, 0x01, 0x0000); 7177 reg_w(gspca_dev->dev, 0x01, 0x0000);
7159 return 0; 7178 return 0;
@@ -7314,10 +7333,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
7314 } 7333 }
7315} 7334}
7316 7335
7317static void sd_stopN(struct gspca_dev *gspca_dev)
7318{
7319}
7320
7321static void sd_stop0(struct gspca_dev *gspca_dev) 7336static void sd_stop0(struct gspca_dev *gspca_dev)
7322{ 7337{
7323 struct sd *sd = (struct sd *) gspca_dev; 7338 struct sd *sd = (struct sd *) gspca_dev;
@@ -7325,11 +7340,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
7325 send_unknown(gspca_dev->dev, sd->sensor); 7340 send_unknown(gspca_dev->dev, sd->sensor);
7326} 7341}
7327 7342
7328/* this function is called at close time */
7329static void sd_close(struct gspca_dev *gspca_dev)
7330{
7331}
7332
7333static void sd_pkt_scan(struct gspca_dev *gspca_dev, 7343static void sd_pkt_scan(struct gspca_dev *gspca_dev,
7334 struct gspca_frame *frame, 7344 struct gspca_frame *frame,
7335 __u8 *data, 7345 __u8 *data,
@@ -7489,37 +7499,30 @@ static const struct sd_desc sd_desc = {
7489 .ctrls = sd_ctrls, 7499 .ctrls = sd_ctrls,
7490 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], 7500 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
7491 .config = sd_config, 7501 .config = sd_config,
7492 .open = sd_open, 7502 .init = sd_init,
7493 .start = sd_start, 7503 .start = sd_start,
7494 .stopN = sd_stopN,
7495 .stop0 = sd_stop0, 7504 .stop0 = sd_stop0,
7496 .close = sd_close,
7497 .pkt_scan = sd_pkt_scan, 7505 .pkt_scan = sd_pkt_scan,
7498 .querymenu = sd_querymenu, 7506 .querymenu = sd_querymenu,
7499}; 7507};
7500 7508
7501static const __devinitdata struct usb_device_id device_table[] = { 7509static const __devinitdata struct usb_device_id device_table[] = {
7502 {USB_DEVICE(0x041e, 0x041e)}, 7510 {USB_DEVICE(0x041e, 0x041e)},
7503#ifndef CONFIG_USB_ZC0301
7504 {USB_DEVICE(0x041e, 0x4017)}, 7511 {USB_DEVICE(0x041e, 0x4017)},
7505 {USB_DEVICE(0x041e, 0x401c)}, 7512 {USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106},
7506 {USB_DEVICE(0x041e, 0x401e)}, 7513 {USB_DEVICE(0x041e, 0x401e)},
7507 {USB_DEVICE(0x041e, 0x401f)}, 7514 {USB_DEVICE(0x041e, 0x401f)},
7508#endif 7515 {USB_DEVICE(0x041e, 0x4022)},
7509 {USB_DEVICE(0x041e, 0x4029)}, 7516 {USB_DEVICE(0x041e, 0x4029)},
7510#ifndef CONFIG_USB_ZC0301 7517 {USB_DEVICE(0x041e, 0x4034), .driver_info = SENSOR_PAS106},
7511 {USB_DEVICE(0x041e, 0x4034)}, 7518 {USB_DEVICE(0x041e, 0x4035), .driver_info = SENSOR_PAS106},
7512 {USB_DEVICE(0x041e, 0x4035)},
7513 {USB_DEVICE(0x041e, 0x4036)}, 7519 {USB_DEVICE(0x041e, 0x4036)},
7514 {USB_DEVICE(0x041e, 0x403a)}, 7520 {USB_DEVICE(0x041e, 0x403a)},
7515#endif
7516 {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250}, 7521 {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250},
7517 {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250}, 7522 {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250},
7518#ifndef CONFIG_USB_ZC0301
7519 {USB_DEVICE(0x0458, 0x7007)}, 7523 {USB_DEVICE(0x0458, 0x7007)},
7520 {USB_DEVICE(0x0458, 0x700c)}, 7524 {USB_DEVICE(0x0458, 0x700c)},
7521 {USB_DEVICE(0x0458, 0x700f)}, 7525 {USB_DEVICE(0x0458, 0x700f)},
7522#endif
7523 {USB_DEVICE(0x0461, 0x0a00)}, 7526 {USB_DEVICE(0x0461, 0x0a00)},
7524 {USB_DEVICE(0x046d, 0x08a0)}, 7527 {USB_DEVICE(0x046d, 0x08a0)},
7525 {USB_DEVICE(0x046d, 0x08a1)}, 7528 {USB_DEVICE(0x046d, 0x08a1)},
@@ -7531,7 +7534,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
7531 {USB_DEVICE(0x046d, 0x08aa)}, 7534 {USB_DEVICE(0x046d, 0x08aa)},
7532 {USB_DEVICE(0x046d, 0x08ac)}, 7535 {USB_DEVICE(0x046d, 0x08ac)},
7533 {USB_DEVICE(0x046d, 0x08ad)}, 7536 {USB_DEVICE(0x046d, 0x08ad)},
7534#ifndef CONFIG_USB_ZC0301 7537#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
7535 {USB_DEVICE(0x046d, 0x08ae)}, 7538 {USB_DEVICE(0x046d, 0x08ae)},
7536#endif 7539#endif
7537 {USB_DEVICE(0x046d, 0x08af)}, 7540 {USB_DEVICE(0x046d, 0x08af)},
@@ -7541,27 +7544,25 @@ static const __devinitdata struct usb_device_id device_table[] = {
7541 {USB_DEVICE(0x046d, 0x08d8)}, 7544 {USB_DEVICE(0x046d, 0x08d8)},
7542 {USB_DEVICE(0x046d, 0x08da)}, 7545 {USB_DEVICE(0x046d, 0x08da)},
7543 {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, 7546 {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB},
7544 {USB_DEVICE(0x0471, 0x0325)}, 7547 {USB_DEVICE(0x0471, 0x0325), .driver_info = SENSOR_PAS106},
7545 {USB_DEVICE(0x0471, 0x0326)}, 7548 {USB_DEVICE(0x0471, 0x0326), .driver_info = SENSOR_PAS106},
7546 {USB_DEVICE(0x0471, 0x032d)}, 7549 {USB_DEVICE(0x0471, 0x032d), .driver_info = SENSOR_PAS106},
7547 {USB_DEVICE(0x0471, 0x032e)}, 7550 {USB_DEVICE(0x0471, 0x032e), .driver_info = SENSOR_PAS106},
7548 {USB_DEVICE(0x055f, 0xc005)}, 7551 {USB_DEVICE(0x055f, 0xc005)},
7549#ifndef CONFIG_USB_ZC0301
7550 {USB_DEVICE(0x055f, 0xd003)}, 7552 {USB_DEVICE(0x055f, 0xd003)},
7551 {USB_DEVICE(0x055f, 0xd004)}, 7553 {USB_DEVICE(0x055f, 0xd004)},
7552#endif
7553 {USB_DEVICE(0x0698, 0x2003)}, 7554 {USB_DEVICE(0x0698, 0x2003)},
7555 {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
7554 {USB_DEVICE(0x0ac8, 0x0302)}, 7556 {USB_DEVICE(0x0ac8, 0x0302)},
7555#ifndef CONFIG_USB_ZC0301
7556 {USB_DEVICE(0x0ac8, 0x301b)}, 7557 {USB_DEVICE(0x0ac8, 0x301b)},
7558#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
7557 {USB_DEVICE(0x0ac8, 0x303b)}, 7559 {USB_DEVICE(0x0ac8, 0x303b)},
7558#endif 7560#endif
7559 {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, 7561 {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
7560#ifndef CONFIG_USB_ZC0301
7561 {USB_DEVICE(0x0ac8, 0x307b)}, 7562 {USB_DEVICE(0x0ac8, 0x307b)},
7562 {USB_DEVICE(0x10fd, 0x0128)}, 7563 {USB_DEVICE(0x10fd, 0x0128)},
7564 {USB_DEVICE(0x10fd, 0x804d)},
7563 {USB_DEVICE(0x10fd, 0x8050)}, 7565 {USB_DEVICE(0x10fd, 0x8050)},
7564#endif
7565 {} /* end of entry */ 7566 {} /* end of entry */
7566}; 7567};
7567#undef DVNAME 7568#undef DVNAME
@@ -7581,6 +7582,10 @@ static struct usb_driver sd_driver = {
7581 .id_table = device_table, 7582 .id_table = device_table,
7582 .probe = sd_probe, 7583 .probe = sd_probe,
7583 .disconnect = gspca_disconnect, 7584 .disconnect = gspca_disconnect,
7585#ifdef CONFIG_PM
7586 .suspend = gspca_suspend,
7587 .resume = gspca_resume,
7588#endif
7584}; 7589};
7585 7590
7586static int __init sd_mod_init(void) 7591static int __init sd_mod_init(void)
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index aea1664948ce..4afc7ea07e86 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -688,7 +688,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
688 spin_lock_init(&itv->lock); 688 spin_lock_init(&itv->lock);
689 spin_lock_init(&itv->dma_reg_lock); 689 spin_lock_init(&itv->dma_reg_lock);
690 690
691 itv->irq_work_queues = create_workqueue(itv->name); 691 itv->irq_work_queues = create_singlethread_workqueue(itv->name);
692 if (itv->irq_work_queues == NULL) { 692 if (itv->irq_work_queues == NULL) {
693 IVTV_ERR("Could not create ivtv workqueue\n"); 693 IVTV_ERR("Could not create ivtv workqueue\n");
694 return -1; 694 return -1;
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index ab287b48fc2b..2ceb5227637c 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -251,6 +251,7 @@ struct ivtv_mailbox_data {
251#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ 251#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */
252#define IVTV_F_I_INITED 21 /* set after first open */ 252#define IVTV_F_I_INITED 21 /* set after first open */
253#define IVTV_F_I_FAILED 22 /* set if first open failed */ 253#define IVTV_F_I_FAILED 22 /* set if first open failed */
254#define IVTV_F_I_WORK_INITED 23 /* worker thread was initialized */
254 255
255/* Event notifications */ 256/* Event notifications */
256#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ 257#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index fba150a6cd23..34f3ab827858 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -76,6 +76,13 @@ void ivtv_irq_work_handler(struct work_struct *work)
76 76
77 DEFINE_WAIT(wait); 77 DEFINE_WAIT(wait);
78 78
79 if (test_and_clear_bit(IVTV_F_I_WORK_INITED, &itv->i_flags)) {
80 struct sched_param param = { .sched_priority = 99 };
81
82 /* This thread must use the FIFO scheduler as it
83 is realtime sensitive. */
84 sched_setscheduler(current, SCHED_FIFO, &param);
85 }
79 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags)) 86 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
80 ivtv_pio_work_handler(itv); 87 ivtv_pio_work_handler(itv);
81 88
@@ -678,34 +685,14 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
678 685
679static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) 686static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
680{ 687{
681 struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
682 u32 data[CX2341X_MBOX_MAX_DATA]; 688 u32 data[CX2341X_MBOX_MAX_DATA];
683 struct ivtv_stream *s; 689 struct ivtv_stream *s;
684 690
685 IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n"); 691 IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n");
686 s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; 692 s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
687 693
688 /* If more than two VBI buffers are pending, then 694 if (!stream_enc_dma_append(s, data))
689 clear the old ones and start with this new one.
690 This can happen during transition stages when MPEG capturing is
691 started, but the first interrupts haven't arrived yet. During
692 that period VBI requests can accumulate without being able to
693 DMA the data. Since at most four VBI DMA buffers are available,
694 we just drop the old requests when there are already three
695 requests queued. */
696 if (s->sg_pending_size > 2) {
697 struct ivtv_buffer *buf;
698 list_for_each_entry(buf, &s->q_predma.list, list)
699 ivtv_buf_sync_for_cpu(s, buf);
700 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
701 s->sg_pending_size = 0;
702 }
703 /* if we can append the data, and the MPEG stream isn't capturing,
704 then start a DMA request for just the VBI data. */
705 if (!stream_enc_dma_append(s, data) &&
706 !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
707 set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); 695 set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
708 }
709} 696}
710 697
711static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv) 698static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
index 7cfc0c9ab050..476556afd39a 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -23,7 +23,7 @@
23#define IVTV_QUEUE_H 23#define IVTV_QUEUE_H
24 24
25#define IVTV_DMA_UNMAPPED ((u32) -1) 25#define IVTV_DMA_UNMAPPED ((u32) -1)
26#define SLICED_VBI_PIO 1 26#define SLICED_VBI_PIO 0
27 27
28/* ivtv_buffer utility functions */ 28/* ivtv_buffer utility functions */
29 29
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 54d2023b26c4..730e85d86fc8 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -363,7 +363,7 @@ static void ivtv_vbi_setup(struct ivtv *itv)
363 /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */ 363 /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */
364 data[1] = 1; 364 data[1] = 1;
365 /* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */ 365 /* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */
366 data[2] = raw ? 4 : 8; 366 data[2] = raw ? 4 : 4 * (itv->vbi.raw_size / itv->vbi.enc_size);
367 /* The start/stop codes determine which VBI lines end up in the raw VBI data area. 367 /* The start/stop codes determine which VBI lines end up in the raw VBI data area.
368 The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line 368 The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line
369 is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video) 369 is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video)
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 71798f0da27f..1ce9deb1104f 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -293,6 +293,7 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8
293 u32 line_size = itv->vbi.sliced_decoder_line_size; 293 u32 line_size = itv->vbi.sliced_decoder_line_size;
294 struct v4l2_decode_vbi_line vbi; 294 struct v4l2_decode_vbi_line vbi;
295 int i; 295 int i;
296 unsigned lines = 0;
296 297
297 /* find the first valid line */ 298 /* find the first valid line */
298 for (i = 0; i < size; i++, buf++) { 299 for (i = 0; i < size; i++, buf++) {
@@ -313,7 +314,8 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8
313 } 314 }
314 vbi.p = p + 4; 315 vbi.p = p + 4;
315 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi); 316 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
316 if (vbi.type) { 317 if (vbi.type && !(lines & (1 << vbi.line))) {
318 lines |= 1 << vbi.line;
317 itv->vbi.sliced_data[line].id = vbi.type; 319 itv->vbi.sliced_data[line].id = vbi.type;
318 itv->vbi.sliced_data[line].field = vbi.is_second_field; 320 itv->vbi.sliced_data[line].field = vbi.is_second_field;
319 itv->vbi.sliced_data[line].line = vbi.line; 321 itv->vbi.sliced_data[line].line = vbi.line;
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
index 442f43f11b73..8cd753d30bf7 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -22,7 +22,7 @@
22 22
23#define IVTV_DRIVER_NAME "ivtv" 23#define IVTV_DRIVER_NAME "ivtv"
24#define IVTV_DRIVER_VERSION_MAJOR 1 24#define IVTV_DRIVER_VERSION_MAJOR 1
25#define IVTV_DRIVER_VERSION_MINOR 3 25#define IVTV_DRIVER_VERSION_MINOR 4
26#define IVTV_DRIVER_VERSION_PATCHLEVEL 0 26#define IVTV_DRIVER_VERSION_PATCHLEVEL 0
27 27
28#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) 28#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index 4895540be195..2fd4b4a44aa9 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -679,26 +679,27 @@ static int ks0127_command(struct i2c_client *client,
679 679
680 case DECODER_ENABLE_OUTPUT: 680 case DECODER_ENABLE_OUTPUT:
681 { 681 {
682 int enable;
682 683
683 int *iarg = arg; 684 iarg = arg;
684 int enable = (*iarg != 0); 685 enable = (*iarg != 0);
685 if (enable) { 686 if (enable) {
686 dprintk("ks0127: command " 687 dprintk("ks0127: command "
687 "DECODER_ENABLE_OUTPUT on " 688 "DECODER_ENABLE_OUTPUT on "
688 "(%d)\n", enable); 689 "(%d)\n", enable);
689 /* All output pins on */ 690 /* All output pins on */
690 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30); 691 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
691 /* Obey the OEN pin */ 692 /* Obey the OEN pin */
692 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00); 693 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
693 } else { 694 } else {
694 dprintk("ks0127: command " 695 dprintk("ks0127: command "
695 "DECODER_ENABLE_OUTPUT off " 696 "DECODER_ENABLE_OUTPUT off "
696 "(%d)\n", enable); 697 "(%d)\n", enable);
697 /* Video output pins off */ 698 /* Video output pins off */
698 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00); 699 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
699 /* Ignore the OEN pin */ 700 /* Ignore the OEN pin */
700 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80); 701 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
701 } 702 }
702 } 703 }
703 break; 704 break;
704 705
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 7c8ef6ac6c39..a9ef7802eb5f 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1806,6 +1806,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
1806 memcpy(meye.video_dev, &meye_template, sizeof(meye_template)); 1806 memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
1807 meye.video_dev->parent = &meye.mchip_dev->dev; 1807 meye.video_dev->parent = &meye.mchip_dev->dev;
1808 1808
1809 ret = -EIO;
1809 if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { 1810 if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) {
1810 printk(KERN_ERR "meye: unable to power on the camera\n"); 1811 printk(KERN_ERR "meye: unable to power on the camera\n");
1811 printk(KERN_ERR "meye: did you enable the camera in " 1812 printk(KERN_ERR "meye: did you enable the camera in "
@@ -1813,7 +1814,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
1813 goto outsonypienable; 1814 goto outsonypienable;
1814 } 1815 }
1815 1816
1816 ret = -EIO;
1817 if ((ret = pci_enable_device(meye.mchip_dev))) { 1817 if ((ret = pci_enable_device(meye.mchip_dev))) {
1818 printk(KERN_ERR "meye: pci_enable_device failed\n"); 1818 printk(KERN_ERR "meye: pci_enable_device failed\n");
1819 goto outenabledev; 1819 goto outenabledev;
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index f68e91fbe7fb..8ef578caba3b 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -931,27 +931,29 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
931 return 0; 931 return 0;
932} 932}
933 933
934static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) 934static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
935{ 935{
936 struct mxb* mxb = (struct mxb*)dev->ext_priv; 936 struct mxb *mxb = (struct mxb *)dev->ext_priv;
937 int zero = 0; 937 int zero = 0;
938 int one = 1; 938 int one = 1;
939 939
940 if(V4L2_STD_PAL_I == std->id ) { 940 if (V4L2_STD_PAL_I == standard->id) {
941 v4l2_std_id std = V4L2_STD_PAL_I; 941 v4l2_std_id std = V4L2_STD_PAL_I;
942
942 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); 943 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
943 /* set the 7146 gpio register -- I don't know what this does exactly */ 944 /* set the 7146 gpio register -- I don't know what this does exactly */
944 saa7146_write(dev, GPIO_CTRL, 0x00404050); 945 saa7146_write(dev, GPIO_CTRL, 0x00404050);
945 /* unset the 7111 gpio register -- I don't know what this does exactly */ 946 /* unset the 7111 gpio register -- I don't know what this does exactly */
946 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero); 947 mxb->saa7111a->driver->command(mxb->saa7111a, DECODER_SET_GPIO, &zero);
947 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); 948 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
948 } else { 949 } else {
949 v4l2_std_id std = V4L2_STD_PAL_BG; 950 v4l2_std_id std = V4L2_STD_PAL_BG;
951
950 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); 952 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
951 /* set the 7146 gpio register -- I don't know what this does exactly */ 953 /* set the 7146 gpio register -- I don't know what this does exactly */
952 saa7146_write(dev, GPIO_CTRL, 0x00404050); 954 saa7146_write(dev, GPIO_CTRL, 0x00404050);
953 /* set the 7111 gpio register -- I don't know what this does exactly */ 955 /* set the 7111 gpio register -- I don't know what this does exactly */
954 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one); 956 mxb->saa7111a->driver->command(mxb->saa7111a, DECODER_SET_GPIO, &one);
955 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); 957 mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
956 } 958 }
957 return 0; 959 return 0;
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 9edaca4371d7..3d3c48db45d9 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -626,9 +626,9 @@ ov511_i2c_write_internal(struct usb_ov511 *ov,
626 break; 626 break;
627 627
628 /* Retry until idle */ 628 /* Retry until idle */
629 do 629 do {
630 rc = reg_r(ov, R511_I2C_CTL); 630 rc = reg_r(ov, R511_I2C_CTL);
631 while (rc > 0 && ((rc&1) == 0)); 631 } while (rc > 0 && ((rc&1) == 0));
632 if (rc < 0) 632 if (rc < 0)
633 break; 633 break;
634 634
@@ -703,9 +703,9 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
703 return rc; 703 return rc;
704 704
705 /* Retry until idle */ 705 /* Retry until idle */
706 do 706 do {
707 rc = reg_r(ov, R511_I2C_CTL); 707 rc = reg_r(ov, R511_I2C_CTL);
708 while (rc > 0 && ((rc&1) == 0)); 708 } while (rc > 0 && ((rc & 1) == 0));
709 if (rc < 0) 709 if (rc < 0)
710 return rc; 710 return rc;
711 711
@@ -729,9 +729,9 @@ ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
729 return rc; 729 return rc;
730 730
731 /* Retry until idle */ 731 /* Retry until idle */
732 do 732 do {
733 rc = reg_r(ov, R511_I2C_CTL); 733 rc = reg_r(ov, R511_I2C_CTL);
734 while (rc > 0 && ((rc&1) == 0)); 734 } while (rc > 0 && ((rc&1) == 0));
735 if (rc < 0) 735 if (rc < 0)
736 return rc; 736 return rc;
737 737
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 00425d743656..7c84f795db54 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -1019,10 +1019,23 @@ static int init_mediavision(void)
1019 * Initialization and module stuff 1019 * Initialization and module stuff
1020 */ 1020 */
1021 1021
1022#ifndef MODULE
1023static int enable;
1024module_param(enable, int, 0);
1025#endif
1026
1022static int __init init_pms_cards(void) 1027static int __init init_pms_cards(void)
1023{ 1028{
1024 printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n"); 1029 printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
1025 1030
1031#ifndef MODULE
1032 if (!enable) {
1033 printk(KERN_INFO "PMS: not enabled, use pms.enable=1 to "
1034 "probe\n");
1035 return -ENODEV;
1036 }
1037#endif
1038
1026 data_port = io_port +1; 1039 data_port = io_port +1;
1027 1040
1028 if(init_mediavision()) 1041 if(init_mediavision())
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 1cccd5c77048..dbc560742553 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -1635,15 +1635,15 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1635 1635
1636 case VIDIOCPWCGVIDCMD: 1636 case VIDIOCPWCGVIDCMD:
1637 { 1637 {
1638 ARG_DEF(struct pwc_video_command, cmd); 1638 ARG_DEF(struct pwc_video_command, vcmd);
1639 1639
1640 ARGR(cmd).type = pdev->type; 1640 ARGR(vcmd).type = pdev->type;
1641 ARGR(cmd).release = pdev->release; 1641 ARGR(vcmd).release = pdev->release;
1642 ARGR(cmd).command_len = pdev->cmd_len; 1642 ARGR(vcmd).command_len = pdev->cmd_len;
1643 memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len); 1643 memcpy(&ARGR(vcmd).command_buf, pdev->cmd_buf, pdev->cmd_len);
1644 ARGR(cmd).bandlength = pdev->vbandlength; 1644 ARGR(vcmd).bandlength = pdev->vbandlength;
1645 ARGR(cmd).frame_size = pdev->frame_size; 1645 ARGR(vcmd).frame_size = pdev->frame_size;
1646 ARG_OUT(cmd) 1646 ARG_OUT(vcmd)
1647 break; 1647 break;
1648 } 1648 }
1649 /* 1649 /*
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index bcd1c8f6cf6b..ad733caec720 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1489,10 +1489,9 @@ static int saa7115_probe(struct i2c_client *client,
1489 client->addr << 1, client->adapter->name); 1489 client->addr << 1, client->adapter->name);
1490 1490
1491 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL); 1491 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1492 i2c_set_clientdata(client, state); 1492 if (state == NULL)
1493 if (state == NULL) {
1494 return -ENOMEM; 1493 return -ENOMEM;
1495 } 1494 i2c_set_clientdata(client, state);
1496 state->input = -1; 1495 state->input = -1;
1497 state->output = SAA7115_IPORT_ON; 1496 state->output = SAA7115_IPORT_ON;
1498 state->enable = 1; 1497 state->enable = 1;
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index f481277892da..acceed5d04ae 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1397,7 +1397,7 @@ static int se401_probe(struct usb_interface *intf,
1397 mutex_init(&se401->lock); 1397 mutex_init(&se401->lock);
1398 wmb(); 1398 wmb();
1399 1399
1400 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { 1400 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1401 kfree(se401); 1401 kfree(se401);
1402 err("video_register_device failed"); 1402 err("video_register_device failed");
1403 return -EIO; 1403 return -EIO;
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 23408764d0ef..2da6938718f2 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -3312,6 +3312,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3312 cam->v4ldev->fops = &sn9c102_fops; 3312 cam->v4ldev->fops = &sn9c102_fops;
3313 cam->v4ldev->minor = video_nr[dev_nr]; 3313 cam->v4ldev->minor = video_nr[dev_nr];
3314 cam->v4ldev->release = video_device_release; 3314 cam->v4ldev->release = video_device_release;
3315 cam->v4ldev->parent = &udev->dev;
3315 3316
3316 init_completion(&cam->probe); 3317 init_completion(&cam->probe);
3317 3318
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 6ff489baacf3..90a401dc3884 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -40,11 +40,14 @@ struct sn9c102_device;
40 40
41static const struct usb_device_id sn9c102_id_table[] = { 41static const struct usb_device_id sn9c102_id_table[] = {
42 /* SN9C101 and SN9C102 */ 42 /* SN9C101 and SN9C102 */
43#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
43 { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), }, 44 { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), },
44 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, 45 { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
46#endif
45 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, 47 { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
46 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, 48 { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
47 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, 49 { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
50/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
48 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, 51 { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
49 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, 52 { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
50 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), }, 53 { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
@@ -53,29 +56,33 @@ static const struct usb_device_id sn9c102_id_table[] = {
53 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, 56 { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
54 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, 57 { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), },
55 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, 58 { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
56 { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, 59/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
57 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, 60 { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
58 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, 61 { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
59 /* SN9C103 */ 62 /* SN9C103 */
60 { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, 63 { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), },
61 { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), }, 64 { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), },
62 { SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), }, 65/* { SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), }, HY7131D/E */
63 { SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), }, 66 { SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), },
64 { SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), }, 67 { SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), },
65 { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, 68 { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), },
66 { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), }, 69 { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), },
67 { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, 70/* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */
71#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
68 { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), }, 72 { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), },
73#endif
69 { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, 74 { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), },
70 { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), }, 75 { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), },
71 { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, 76 { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), },
72 { SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, 77/* { SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, PAS106 */
73 { SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, 78/* { SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, TAS5130 */
74 { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, 79/* { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5130 */
75 { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, 80 { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), },
76 { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, 81 { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), },
77 { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), }, 82 { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), },
83#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
78 { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), }, 84 { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), },
85#endif
79 { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, 86 { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), },
80 { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), }, 87 { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), },
81 { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), }, 88 { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), },
@@ -105,7 +112,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
105 { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, 112 { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
106 { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, 113 { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
107 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, 114 { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
108 { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, 115/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */
109 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, 116 { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
110 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, 117 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
111 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, 118 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 56dc3d6b5b29..dce947439459 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1462,7 +1462,7 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id
1462 mutex_init (&stv680->lock); 1462 mutex_init (&stv680->lock);
1463 wmb (); 1463 wmb ();
1464 1464
1465 if (video_register_device (stv680->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { 1465 if (video_register_device(stv680->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1466 PDEBUG (0, "STV(e): video_register_device failed"); 1466 PDEBUG (0, "STV(e): video_register_device failed");
1467 retval = -EIO; 1467 retval = -EIO;
1468 goto error_vdev; 1468 goto error_vdev;
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c
index 59166b760104..cc27efe121dd 100644
--- a/drivers/media/video/usbvideo/ibmcam.c
+++ b/drivers/media/video/usbvideo/ibmcam.c
@@ -736,12 +736,12 @@ static enum ParseState ibmcam_model2_320x240_parse_lines(
736 * make black color and quit the horizontal scanning loop. 736 * make black color and quit the horizontal scanning loop.
737 */ 737 */
738 if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) { 738 if (((frame->curline + 2) >= scanHeight) || (i >= scanLength)) {
739 const int j = i * V4L_BYTES_PER_PIXEL; 739 const int offset = i * V4L_BYTES_PER_PIXEL;
740#if USES_IBMCAM_PUTPIXEL 740#if USES_IBMCAM_PUTPIXEL
741 /* Refresh 'f' because we don't use it much with PUTPIXEL */ 741 /* Refresh 'f' because we don't use it much with PUTPIXEL */
742 f = frame->data + (v4l_linesize * frame->curline) + j; 742 f = frame->data + (v4l_linesize * frame->curline) + offset;
743#endif 743#endif
744 memset(f, 0, v4l_linesize - j); 744 memset(f, 0, v4l_linesize - offset);
745 break; 745 break;
746 } 746 }
747 747
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index b7792451a299..2eb45829791c 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -866,7 +866,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id)
866 cam->udev = dev; 866 cam->udev = dev;
867 cam->bulkEndpoint = bulkEndpoint; 867 cam->bulkEndpoint = bulkEndpoint;
868 868
869 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) == -1) { 869 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) < 0) {
870 kfree(cam); 870 kfree(cam);
871 printk(KERN_WARNING "video_register_device failed\n"); 871 printk(KERN_WARNING "video_register_device failed\n");
872 return -EIO; 872 return -EIO;
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 6f36006aecda..155fdec9ac7d 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -257,6 +257,9 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
257 int ret; 257 int ret;
258 char *name_base; 258 char *name_base;
259 259
260 if (vfd == NULL)
261 return -EINVAL;
262
260 switch (type) { 263 switch (type) {
261 case VFL_TYPE_GRABBER: 264 case VFL_TYPE_GRABBER:
262 base = MINOR_VFL_TYPE_GRABBER_MIN; 265 base = MINOR_VFL_TYPE_GRABBER_MIN;
@@ -281,7 +284,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
281 default: 284 default:
282 printk(KERN_ERR "%s called with unknown type: %d\n", 285 printk(KERN_ERR "%s called with unknown type: %d\n",
283 __func__, type); 286 __func__, type);
284 return -1; 287 return -EINVAL;
285 } 288 }
286 289
287 /* pick a minor number */ 290 /* pick a minor number */
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index fdfe7739c96e..140ef92c19c1 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -499,7 +499,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
499 p->timestamp.tv_sec / 3600, 499 p->timestamp.tv_sec / 3600,
500 (int)(p->timestamp.tv_sec / 60) % 60, 500 (int)(p->timestamp.tv_sec / 60) % 60,
501 (int)(p->timestamp.tv_sec % 60), 501 (int)(p->timestamp.tv_sec % 60),
502 p->timestamp.tv_usec, 502 (long)p->timestamp.tv_usec,
503 p->index, 503 p->index,
504 prt_names(p->type, v4l2_type_names), 504 prt_names(p->type, v4l2_type_names),
505 p->bytesused, p->flags, 505 p->bytesused, p->flags,
@@ -674,7 +674,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
674 __video_do_ioctl will be called again, with one or more 674 __video_do_ioctl will be called again, with one or more
675 V4L2 ioctls. 675 V4L2 ioctls.
676 ********************************************************/ 676 ********************************************************/
677 if (_IOC_TYPE(cmd) == 'v') 677 if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)
678 return v4l_compat_translate_ioctl(inode, file, cmd, arg, 678 return v4l_compat_translate_ioctl(inode, file, cmd, arg,
679 __video_do_ioctl); 679 __video_do_ioctl);
680#endif 680#endif
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 3518af071a2e..8ba8daafd7ea 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1021,13 +1021,13 @@ static int vivi_release(void)
1021 dev = list_entry(list, struct vivi_dev, vivi_devlist); 1021 dev = list_entry(list, struct vivi_dev, vivi_devlist);
1022 1022
1023 if (-1 != dev->vfd->minor) { 1023 if (-1 != dev->vfd->minor) {
1024 video_unregister_device(dev->vfd); 1024 printk(KERN_INFO "%s: unregistering /dev/video%d\n",
1025 printk(KERN_INFO "%s: /dev/video%d unregistered.\n",
1026 VIVI_MODULE_NAME, dev->vfd->minor); 1025 VIVI_MODULE_NAME, dev->vfd->minor);
1026 video_unregister_device(dev->vfd);
1027 } else { 1027 } else {
1028 video_device_release(dev->vfd); 1028 printk(KERN_INFO "%s: releasing /dev/video%d\n",
1029 printk(KERN_INFO "%s: /dev/video%d released.\n",
1030 VIVI_MODULE_NAME, dev->vfd->minor); 1029 VIVI_MODULE_NAME, dev->vfd->minor);
1030 video_device_release(dev->vfd);
1031 } 1031 }
1032 1032
1033 kfree(dev); 1033 kfree(dev);
@@ -1104,19 +1104,29 @@ static struct video_device vivi_template = {
1104 Initialization and module stuff 1104 Initialization and module stuff
1105 ------------------------------------------------------------------*/ 1105 ------------------------------------------------------------------*/
1106 1106
1107/* This routine allocates from 1 to n_devs virtual drivers.
1108
1109 The real maximum number of virtual drivers will depend on how many drivers
1110 will succeed. This is limited to the maximum number of devices that
1111 videodev supports. Since there are 64 minors for video grabbers, this is
1112 currently the theoretical maximum limit. However, a further limit does
1113 exist at videodev that forbids any driver to register more than 32 video
1114 grabbers.
1115 */
1107static int __init vivi_init(void) 1116static int __init vivi_init(void)
1108{ 1117{
1109 int ret = -ENOMEM, i; 1118 int ret = -ENOMEM, i;
1110 struct vivi_dev *dev; 1119 struct vivi_dev *dev;
1111 struct video_device *vfd; 1120 struct video_device *vfd;
1112 1121
1122 if (n_devs <= 0)
1123 n_devs = 1;
1124
1113 for (i = 0; i < n_devs; i++) { 1125 for (i = 0; i < n_devs; i++) {
1114 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1126 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1115 if (NULL == dev) 1127 if (!dev)
1116 break; 1128 break;
1117 1129
1118 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1119
1120 /* init video dma queues */ 1130 /* init video dma queues */
1121 INIT_LIST_HEAD(&dev->vidq.active); 1131 INIT_LIST_HEAD(&dev->vidq.active);
1122 init_waitqueue_head(&dev->vidq.wq); 1132 init_waitqueue_head(&dev->vidq.wq);
@@ -1126,14 +1136,27 @@ static int __init vivi_init(void)
1126 mutex_init(&dev->mutex); 1136 mutex_init(&dev->mutex);
1127 1137
1128 vfd = video_device_alloc(); 1138 vfd = video_device_alloc();
1129 if (NULL == vfd) 1139 if (!vfd) {
1140 kfree(dev);
1130 break; 1141 break;
1142 }
1131 1143
1132 *vfd = vivi_template; 1144 *vfd = vivi_template;
1133 1145
1134 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); 1146 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
1135 if (ret < 0) 1147 if (ret < 0) {
1148 video_device_release(vfd);
1149 kfree(dev);
1150
1151 /* If some registers succeeded, keep driver */
1152 if (i)
1153 ret = 0;
1154
1136 break; 1155 break;
1156 }
1157
1158 /* Now that everything is fine, let's add it to device list */
1159 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1137 1160
1138 snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", 1161 snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
1139 vivi_template.name, vfd->minor); 1162 vivi_template.name, vfd->minor);
@@ -1149,11 +1172,16 @@ static int __init vivi_init(void)
1149 if (ret < 0) { 1172 if (ret < 0) {
1150 vivi_release(); 1173 vivi_release();
1151 printk(KERN_INFO "Error %d while loading vivi driver\n", ret); 1174 printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
1152 } else 1175 } else {
1153 printk(KERN_INFO "Video Technology Magazine Virtual Video " 1176 printk(KERN_INFO "Video Technology Magazine Virtual Video "
1154 "Capture Board ver %u.%u.%u successfully loaded.\n", 1177 "Capture Board ver %u.%u.%u successfully loaded.\n",
1155 (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, 1178 (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
1156 VIVI_VERSION & 0xFF); 1179 VIVI_VERSION & 0xFF);
1180
1181 /* n_devs will reflect the actual number of allocated devices */
1182 n_devs = i;
1183 }
1184
1157 return ret; 1185 return ret;
1158} 1186}
1159 1187
@@ -1169,10 +1197,10 @@ MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
1169MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); 1197MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
1170MODULE_LICENSE("Dual BSD/GPL"); 1198MODULE_LICENSE("Dual BSD/GPL");
1171 1199
1172module_param(video_nr, int, 0); 1200module_param(video_nr, uint, 0444);
1173MODULE_PARM_DESC(video_nr, "video iminor start number"); 1201MODULE_PARM_DESC(video_nr, "video iminor start number");
1174 1202
1175module_param(n_devs, int, 0); 1203module_param(n_devs, uint, 0444);
1176MODULE_PARM_DESC(n_devs, "number of video devices to create"); 1204MODULE_PARM_DESC(n_devs, "number of video devices to create");
1177 1205
1178module_param_named(debug, vivi_template.debug, int, 0444); 1206module_param_named(debug, vivi_template.debug, int, 0444);
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 9402f40095b4..2ff00bc5ad64 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -334,7 +334,7 @@ static int w9966_init(struct w9966_dev* cam, struct parport* port)
334 memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device)); 334 memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device));
335 cam->vdev.priv = cam; 335 cam->vdev.priv = cam;
336 336
337 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1) 337 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
338 return -1; 338 return -1;
339 339
340 w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV); 340 w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 550ce7bd5c87..0c3287734c93 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1988,6 +1988,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1988 cam->v4ldev->fops = &zc0301_fops; 1988 cam->v4ldev->fops = &zc0301_fops;
1989 cam->v4ldev->minor = video_nr[dev_nr]; 1989 cam->v4ldev->minor = video_nr[dev_nr];
1990 cam->v4ldev->release = video_device_release; 1990 cam->v4ldev->release = video_device_release;
1991 cam->v4ldev->parent = &udev->dev;
1991 video_set_drvdata(cam->v4ldev, cam); 1992 video_set_drvdata(cam->v4ldev, cam);
1992 1993
1993 init_completion(&cam->probe); 1994 init_completion(&cam->probe);
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index 70fe6fc6cdd5..b0cd49c438a3 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -60,27 +60,8 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
60 60
61#define ZC0301_ID_TABLE \ 61#define ZC0301_ID_TABLE \
62static const struct usb_device_id zc0301_id_table[] = { \ 62static const struct usb_device_id zc0301_id_table[] = { \
63 { ZC0301_USB_DEVICE(0x041e, 0x4017, 0xff), }, /* ICM105 */ \
64 { ZC0301_USB_DEVICE(0x041e, 0x401c, 0xff), }, /* PAS106 */ \
65 { ZC0301_USB_DEVICE(0x041e, 0x401e, 0xff), }, /* HV7131 */ \
66 { ZC0301_USB_DEVICE(0x041e, 0x401f, 0xff), }, /* TAS5130 */ \
67 { ZC0301_USB_DEVICE(0x041e, 0x4022, 0xff), }, \
68 { ZC0301_USB_DEVICE(0x041e, 0x4034, 0xff), }, /* PAS106 */ \
69 { ZC0301_USB_DEVICE(0x041e, 0x4035, 0xff), }, /* PAS106 */ \
70 { ZC0301_USB_DEVICE(0x041e, 0x4036, 0xff), }, /* HV7131 */ \
71 { ZC0301_USB_DEVICE(0x041e, 0x403a, 0xff), }, /* HV7131 */ \
72 { ZC0301_USB_DEVICE(0x0458, 0x7007, 0xff), }, /* TAS5130 */ \
73 { ZC0301_USB_DEVICE(0x0458, 0x700c, 0xff), }, /* TAS5130 */ \
74 { ZC0301_USB_DEVICE(0x0458, 0x700f, 0xff), }, /* TAS5130 */ \
75 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ 63 { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
76 { ZC0301_USB_DEVICE(0x055f, 0xd003, 0xff), }, /* TAS5130 */ \
77 { ZC0301_USB_DEVICE(0x055f, 0xd004, 0xff), }, /* TAS5130 */ \
78 { ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \
79 { ZC0301_USB_DEVICE(0x0ac8, 0x301b, 0xff), }, /* PB-0330/HV7131 */ \
80 { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ 64 { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \
81 { ZC0301_USB_DEVICE(0x10fd, 0x0128, 0xff), }, /* TAS5130 */ \
82 { ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130 */ \
83 { ZC0301_USB_DEVICE(0x10fd, 0x804e, 0xff), }, /* TAS5130 */ \
84 { } \ 65 { } \
85}; 66};
86 67