linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 6/6] gspca - sonixj: Better handling of the bridge registers 0x01 and 0x17
@ 2010-12-13 13:04 Jean-Francois Moine
  2010-12-13 13:27 ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 5+ messages in thread
From: Jean-Francois Moine @ 2010-12-13 13:04 UTC (permalink / raw)
  To: Linux Media Mailing List, Mauro Carvalho Chehab


The initial values of the registers 0x01 and 0x17 are taken from the
senso table at capture start and updated according to the flag PDN_INV.

Their values are updated at each step of the capture initialization and
memorized for reuse in capture stop.

This patch also fixed automatically some bad hardcoded values of these
registers.

Signed-off-by: Jean-François Moine <moinejf@free.fr>

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 4c10324..880e931 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -63,6 +63,8 @@ struct sd {
 #define QUALITY_DEF 80
 	u8 jpegqual;			/* webcam quality */
 
+	u8 reg01;
+	u8 reg17;
 	u8 reg18;
 	u8 flags;
 
@@ -2306,8 +2308,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
+	u8 reg01, reg17;
 	u8 reg0102[2];
-	u8 reg1, reg17;
 	const u8 *sn9c1xx;
 	const u8 (*init)[8];
 	const u8 *reg9a;
@@ -2341,10 +2343,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	/* sensor clock already enabled in sd_init */
 	/* reg_w1(gspca_dev, 0xf1, 0x00); */
-	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
+	reg01 = sn9c1xx[1];
+	if (sd->flags & PDN_INV)
+		reg01 ^= S_PDN_INV;		/* power down inverted */
+	reg_w1(gspca_dev, 0x01, reg01);
 
 	/* configure gpio */
-	reg0102[0] = sn9c1xx[1];
+	reg0102[0] = reg01;
 	reg0102[1] = sn9c1xx[2];
 	if (gspca_dev->audio)
 		reg0102[1] |= 0x04;	/* keep the audio connection */
@@ -2370,95 +2375,49 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
+	reg17 = sn9c1xx[0x17];
 	switch (sd->sensor) {
-	case SENSOR_ADCM1700:
-		reg_w1(gspca_dev, 0x01, 0x43);
-		reg_w1(gspca_dev, 0x17, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		break;
 	case SENSOR_GC0307:
-		msleep(50);
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x22);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		msleep(50);
-		break;
-	case SENSOR_MI0360B:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		break;
-	case SENSOR_MT9V111:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x61);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
+		msleep(50);		/*fixme: is it useful? */
 		break;
 	case SENSOR_OM6802:
 		msleep(10);
 		reg_w1(gspca_dev, 0x02, 0x73);
-		reg_w1(gspca_dev, 0x17, 0x60);
+		reg17 |= SEN_CLK_EN;
+		reg_w1(gspca_dev, 0x17, reg17);
 		reg_w1(gspca_dev, 0x01, 0x22);
 		msleep(100);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x17, 0x64);
-		reg_w1(gspca_dev, 0x17, 0x64);
-		reg_w1(gspca_dev, 0x01, 0x42);
+		reg01 = SCL_SEL_OD | S_PDN_INV;
+		reg17 &= MCK_SIZE_MASK;
+		reg17 |= 0x04;		/* clock / 4 */
+		break;
+	}
+	reg01 |= SYS_SEL_48M;
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg17 |= SEN_CLK_EN;
+	reg_w1(gspca_dev, 0x17, reg17);
+	reg01 &= ~S_PWR_DN;		/* sensor power on */
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg01 &= ~SYS_SEL_48M;
+	reg_w1(gspca_dev, 0x01, reg01);
+
+	switch (sd->sensor) {
+	case SENSOR_HV7131R:
+		hv7131r_probe(gspca_dev);	/*fixme: is it useful? */
+		break;
+	case SENSOR_OM6802:
 		msleep(10);
-		reg_w1(gspca_dev, 0x01, 0x42);
+		reg_w1(gspca_dev, 0x01, reg01);
 		i2c_w8(gspca_dev, om6802_init0[0]);
 		i2c_w8(gspca_dev, om6802_init0[1]);
 		msleep(15);
 		reg_w1(gspca_dev, 0x02, 0x71);
 		msleep(150);
 		break;
-	case SENSOR_OV7630:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0xe2);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		break;
-	case SENSOR_OV7648:
-		reg_w1(gspca_dev, 0x01, 0x63);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		break;
-	case SENSOR_PO1030:
-	case SENSOR_SOI768:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		break;
-	case SENSOR_PO2030N:
-	case SENSOR_OV7660:
-		reg_w1(gspca_dev, 0x01, 0x63);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		break;
 	case SENSOR_SP80708:
-		reg_w1(gspca_dev, 0x01, 0x63);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
 		msleep(100);
 		reg_w1(gspca_dev, 0x02, 0x62);
 		break;
-	default:
-/*	case SENSOR_HV7131R: */
-/*	case SENSOR_MI0360: */
-/*	case SENSOR_MO4000: */
-		reg_w1(gspca_dev, 0x01, 0x43);
-		reg_w1(gspca_dev, 0x17, 0x61);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		if (sd->sensor == SENSOR_HV7131R)
-			hv7131r_probe(gspca_dev);
-		break;
 	}
 
 	/* initialize the sensor */
@@ -2487,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	}
 	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
 	switch (sd->sensor) {
-	case SENSOR_GC0307:
-		reg17 = 0xa2;
-		break;
-	case SENSOR_MT9V111:
-	case SENSOR_MI0360B:
-		reg17 = 0xe0;
-		break;
-	case SENSOR_ADCM1700:
-	case SENSOR_OV7630:
-		reg17 = 0xe2;
-		break;
-	case SENSOR_OV7648:
-		reg17 = 0x20;
-		break;
-	case SENSOR_OV7660:
-	case SENSOR_SOI768:
-		reg17 = 0xa0;
-		break;
-	case SENSOR_PO1030:
-	case SENSOR_PO2030N:
-		reg17 = 0xa0;
+	case SENSOR_OM6802:
+/*	case SENSOR_OV7648:		* fixme: sometimes */
 		break;
 	default:
-		reg17 = 0x60;
+		reg17 |= DEF_EN;
 		break;
 	}
 	reg_w1(gspca_dev, 0x17, reg17);
@@ -2557,95 +2497,64 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	init = NULL;
 	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+	reg01 |= V_TX_EN;
 	if (mode)
-		reg1 = 0x46;	/* 320x240: clk 48Mhz, video trf enable */
+		reg01 |= SYS_SEL_48M;	/* 320x240: clk 48Mhz */
 	else
-		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */
-	reg17 = 0x61;		/* 0x:20: enable sensor clock */
+		reg01 &= ~SYS_SEL_48M;	/* 640x480: clk 24Mhz */
+	reg17 &= ~MCK_SIZE_MASK;
+	reg17 |= 0x02;			/* clock / 2 */
 	switch (sd->sensor) {
 	case SENSOR_ADCM1700:
 		init = adcm1700_sensor_param1;
-		reg1 = 0x46;
-		reg17 = 0xe2;
+		reg01 |= SYS_SEL_48M;
 		break;
 	case SENSOR_GC0307:
 		init = gc0307_sensor_param1;
-		reg17 = 0xa2;
-		reg1 = 0x44;
+		reg01 |= SYS_SEL_48M;
 		break;
 	case SENSOR_MI0360B:
 		init = mi0360b_sensor_param1;
-		reg1 &= ~0x02;		/* don't inverse pin S_PWR_DN */
-		reg17 = 0xe2;
 		break;
 	case SENSOR_MO4000:
 		if (mode) {
-/*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
-			reg1 = 0x06;	/* clk 24Mz */
+			reg01 &= ~SYS_SEL_48M;	/* clk 24Mz */
 		} else {
-			reg17 = 0x22;	/* 640 MCKSIZE */
-/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
+			reg17 = SEN_CLK_EN | 0x02;	/* clock / 2 */
 		}
 		break;
 	case SENSOR_MT9V111:
 		init = mt9v111_sensor_param1;
-		if (mode) {
-			reg1 = 0x04;	/* 320 clk 48Mhz */
-		} else {
-/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
-			reg17 = 0xc2;
-		}
 		break;
 	case SENSOR_OM6802:
 		init = om6802_sensor_param1;
-		reg17 = 0x64;		/* 640 MCKSIZE */
 		break;
 	case SENSOR_OV7630:
 		init = ov7630_sensor_param1;
-		reg17 = 0xe2;
-		reg1 = 0x44;
+		reg01 |= SYS_SEL_48M;
 		break;
 	case SENSOR_OV7648:
 		init = ov7648_sensor_param1;
-		reg17 = 0x21;
-/*		reg1 = 0x42;		 * 42 - 46? */
+		reg17 &= ~MCK_SIZE_MASK;
+		reg17 |= 0x01;			/* clock / 1 */
 		break;
 	case SENSOR_OV7660:
 		init = ov7660_sensor_param1;
-		if (sd->bridge == BRIDGE_SN9C120) {
-			if (mode) {		/* 320x240 - 160x120 */
-				reg17 = 0xa2;
-				reg1 = 0x44;	/* 48 Mhz, video trf eneble */
-			}
-		} else {
-			reg17 = 0x22;
-			reg1 = 0x06;	/* 24 Mhz, video trf eneble
-					 * inverse power down */
-		}
 		break;
 	case SENSOR_PO1030:
 		init = po1030_sensor_param1;
-		reg17 = 0xa2;
-		reg1 = 0x44;
+		reg01 |= SYS_SEL_48M;
 		break;
 	case SENSOR_PO2030N:
 		init = po2030n_sensor_param1;
-		reg1 = 0x46;
-		reg17 = 0xa2;
+		reg01 |= SYS_SEL_48M;
 		break;
 	case SENSOR_SOI768:
 		init = soi768_sensor_param1;
-		reg1 = 0x44;
-		reg17 = 0xa2;
+		reg01 |= SYS_SEL_48M;
 		break;
 	case SENSOR_SP80708:
 		init = sp80708_sensor_param1;
-		if (mode) {
-/*??			reg1 = 0x04;	 * 320 clk 48Mhz */
-		} else {
-			reg1 = 0x46;	 /* 640 clk 48Mz */
-			reg17 = 0xa2;
-		}
 		break;
 	}
 
@@ -2695,7 +2604,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	setjpegqual(gspca_dev);
 
 	reg_w1(gspca_dev, 0x17, reg17);
-	reg_w1(gspca_dev, 0x01, reg1);
+	reg_w1(gspca_dev, 0x01, reg01);
+	sd->reg01 = reg01;
+	sd->reg17 = reg17;
 
 	sethvflip(gspca_dev);
 	setbrightness(gspca_dev);
@@ -2717,41 +2628,69 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
 	static const u8 stopsoi768[] =
 		{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
-	u8 data;
-	const u8 *sn9c1xx;
+	u8 reg01;
+	u8 reg17;
 
-	data = 0x0b;
+	reg01 = sd->reg01;
+	reg17 = sd->reg17 & ~SEN_CLK_EN;
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
+	case SENSOR_PO2030N:
+	case SENSOR_SP80708:
+		reg01 |= LED;
+		reg_w1(gspca_dev, 0x01, reg01);
+		reg01 &= ~(LED | V_TX_EN);
+		reg_w1(gspca_dev, 0x01, reg01);
+/*		reg_w1(gspca_dev, 0x02, 0x??);	 * LED off ? */
+		break;
 	case SENSOR_GC0307:
-		data = 0x29;
+		reg01 |= LED | S_PDN_INV;
+		reg_w1(gspca_dev, 0x01, reg01);
+		reg01 &= ~(LED | V_TX_EN | S_PDN_INV);
+		reg_w1(gspca_dev, 0x01, reg01);
 		break;
 	case SENSOR_HV7131R:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
 		i2c_w8(gspca_dev, stophv7131);
-		data = 0x2b;
 		break;
 	case SENSOR_MI0360:
 	case SENSOR_MI0360B:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
+/*		reg_w1(gspca_dev, 0x02, 0x40);	  * LED off ? */
 		i2c_w8(gspca_dev, stopmi0360);
-		data = 0x29;
 		break;
-	case SENSOR_OV7648:
-		i2c_w8(gspca_dev, stopov7648);
-		/* fall thru */
 	case SENSOR_MT9V111:
-	case SENSOR_OV7630:
+	case SENSOR_OM6802:
 	case SENSOR_PO1030:
-		data = 0x29;
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
+		break;
+	case SENSOR_OV7630:
+	case SENSOR_OV7648:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
+		i2c_w8(gspca_dev, stopov7648);
+		break;
+	case SENSOR_OV7660:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
 		break;
 	case SENSOR_SOI768:
 		i2c_w8(gspca_dev, stopsoi768);
-		data = 0x29;
 		break;
 	}
-	sn9c1xx = sn_tb[sd->sensor];
-	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
-	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
-	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
-	reg_w1(gspca_dev, 0x01, data);
+
+	reg01 |= SCL_SEL_OD;
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg01 |= S_PWR_DN;		/* sensor power down */
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg_w1(gspca_dev, 0x17, reg17);
+	reg01 &= ~SYS_SEL_48M;		/* clock 24MHz */
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg01 |= LED;
+	reg_w1(gspca_dev, 0x01, reg01);
 	/* Don't disable sensor clock as that disables the button on the cam */
 	/* reg_w1(gspca_dev, 0xf1, 0x01); */
 }
-- 
1.7.2.3

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 6/6] gspca - sonixj: Better handling of the bridge registers 0x01 and 0x17
  2010-12-13 13:04 Jean-Francois Moine
@ 2010-12-13 13:27 ` Mauro Carvalho Chehab
  2010-12-13 18:44   ` Hans de Goede
  2010-12-13 19:15   ` Jean-Francois Moine
  0 siblings, 2 replies; 5+ messages in thread
From: Mauro Carvalho Chehab @ 2010-12-13 13:27 UTC (permalink / raw)
  To: Jean-Francois Moine; +Cc: Linux Media Mailing List

Em 13-12-2010 11:04, Jean-Francois Moine escreveu:
> 
> The initial values of the registers 0x01 and 0x17 are taken from the
> senso table at capture start and updated according to the flag PDN_INV.
> 
> Their values are updated at each step of the capture initialization and
> memorized for reuse in capture stop.
> 
> This patch also fixed automatically some bad hardcoded values of these
> registers.
> 
> Signed-off-by: Jean-François Moine <moinejf@free.fr>
> 
> diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
> index 4c10324..880e931 100644
> --- a/drivers/media/video/gspca/sonixj.c
> +++ b/drivers/media/video/gspca/sonixj.c
> @@ -63,6 +63,8 @@ struct sd {
>  #define QUALITY_DEF 80
>  	u8 jpegqual;			/* webcam quality */
>  
> +	u8 reg01;
> +	u8 reg17;
>  	u8 reg18;
>  	u8 flags;
>  
> @@ -2306,8 +2308,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
>  {
>  	struct sd *sd = (struct sd *) gspca_dev;
>  	int i;
> +	u8 reg01, reg17;
>  	u8 reg0102[2];
> -	u8 reg1, reg17;
>  	const u8 *sn9c1xx;
>  	const u8 (*init)[8];
>  	const u8 *reg9a;
> @@ -2341,10 +2343,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
>  
>  	/* sensor clock already enabled in sd_init */
>  	/* reg_w1(gspca_dev, 0xf1, 0x00); */
> -	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
> +	reg01 = sn9c1xx[1];
> +	if (sd->flags & PDN_INV)
> +		reg01 ^= S_PDN_INV;		/* power down inverted */
> +	reg_w1(gspca_dev, 0x01, reg01);
>  
>  	/* configure gpio */
> -	reg0102[0] = sn9c1xx[1];
> +	reg0102[0] = reg01;
>  	reg0102[1] = sn9c1xx[2];
>  	if (gspca_dev->audio)
>  		reg0102[1] |= 0x04;	/* keep the audio connection */
> @@ -2370,95 +2375,49 @@ static int sd_start(struct gspca_dev *gspca_dev)
>  
>  	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
>  
> +	reg17 = sn9c1xx[0x17];
>  	switch (sd->sensor) {
> -	case SENSOR_ADCM1700:
> -		reg_w1(gspca_dev, 0x01, 0x43);
> -		reg_w1(gspca_dev, 0x17, 0x62);
> -		reg_w1(gspca_dev, 0x01, 0x42);
> -		reg_w1(gspca_dev, 0x01, 0x42);
> -		break;
>  	case SENSOR_GC0307:
> -		msleep(50);
> -		reg_w1(gspca_dev, 0x01, 0x61);
> -		reg_w1(gspca_dev, 0x17, 0x22);
> -		reg_w1(gspca_dev, 0x01, 0x60);
> -		reg_w1(gspca_dev, 0x01, 0x40);
> -		msleep(50);
> -		break;
> -	case SENSOR_MI0360B:
> -		reg_w1(gspca_dev, 0x01, 0x61);
> -		reg_w1(gspca_dev, 0x17, 0x60);
> -		reg_w1(gspca_dev, 0x01, 0x60);
> -		reg_w1(gspca_dev, 0x01, 0x40);
> -		break;
> -	case SENSOR_MT9V111:
> -		reg_w1(gspca_dev, 0x01, 0x61);
> -		reg_w1(gspca_dev, 0x17, 0x61);
> -		reg_w1(gspca_dev, 0x01, 0x60);
> -		reg_w1(gspca_dev, 0x01, 0x40);
> +		msleep(50);		/*fixme: is it useful? */
>  		break;
>  	case SENSOR_OM6802:
>  		msleep(10);
>  		reg_w1(gspca_dev, 0x02, 0x73);
> -		reg_w1(gspca_dev, 0x17, 0x60);
> +		reg17 |= SEN_CLK_EN;
> +		reg_w1(gspca_dev, 0x17, reg17);
>  		reg_w1(gspca_dev, 0x01, 0x22);
>  		msleep(100);
> -		reg_w1(gspca_dev, 0x01, 0x62);
> -		reg_w1(gspca_dev, 0x17, 0x64);
> -		reg_w1(gspca_dev, 0x17, 0x64);
> -		reg_w1(gspca_dev, 0x01, 0x42);
> +		reg01 = SCL_SEL_OD | S_PDN_INV;
> +		reg17 &= MCK_SIZE_MASK;
> +		reg17 |= 0x04;		/* clock / 4 */
> +		break;
> +	}
> +	reg01 |= SYS_SEL_48M;
> +	reg_w1(gspca_dev, 0x01, reg01);
> +	reg17 |= SEN_CLK_EN;
> +	reg_w1(gspca_dev, 0x17, reg17);
> +	reg01 &= ~S_PWR_DN;		/* sensor power on */
> +	reg_w1(gspca_dev, 0x01, reg01);
> +	reg01 &= ~SYS_SEL_48M;
> +	reg_w1(gspca_dev, 0x01, reg01);
> +
> +	switch (sd->sensor) {
> +	case SENSOR_HV7131R:
> +		hv7131r_probe(gspca_dev);	/*fixme: is it useful? */
> +		break;
> +	case SENSOR_OM6802:
>  		msleep(10);
> -		reg_w1(gspca_dev, 0x01, 0x42);
> +		reg_w1(gspca_dev, 0x01, reg01);
>  		i2c_w8(gspca_dev, om6802_init0[0]);
>  		i2c_w8(gspca_dev, om6802_init0[1]);
>  		msleep(15);
>  		reg_w1(gspca_dev, 0x02, 0x71);
>  		msleep(150);
>  		break;
> -	case SENSOR_OV7630:
> -		reg_w1(gspca_dev, 0x01, 0x61);
> -		reg_w1(gspca_dev, 0x17, 0xe2);
> -		reg_w1(gspca_dev, 0x01, 0x60);
> -		reg_w1(gspca_dev, 0x01, 0x40);
> -		break;
> -	case SENSOR_OV7648:
> -		reg_w1(gspca_dev, 0x01, 0x63);
> -		reg_w1(gspca_dev, 0x17, 0x20);
> -		reg_w1(gspca_dev, 0x01, 0x62);
> -		reg_w1(gspca_dev, 0x01, 0x42);
> -		break;
> -	case SENSOR_PO1030:
> -	case SENSOR_SOI768:
> -		reg_w1(gspca_dev, 0x01, 0x61);
> -		reg_w1(gspca_dev, 0x17, 0x20);
> -		reg_w1(gspca_dev, 0x01, 0x60);
> -		reg_w1(gspca_dev, 0x01, 0x40);
> -		break;
> -	case SENSOR_PO2030N:
> -	case SENSOR_OV7660:
> -		reg_w1(gspca_dev, 0x01, 0x63);
> -		reg_w1(gspca_dev, 0x17, 0x20);
> -		reg_w1(gspca_dev, 0x01, 0x62);
> -		reg_w1(gspca_dev, 0x01, 0x42);
> -		break;
>  	case SENSOR_SP80708:
> -		reg_w1(gspca_dev, 0x01, 0x63);
> -		reg_w1(gspca_dev, 0x17, 0x20);
> -		reg_w1(gspca_dev, 0x01, 0x62);
> -		reg_w1(gspca_dev, 0x01, 0x42);
>  		msleep(100);
>  		reg_w1(gspca_dev, 0x02, 0x62);
>  		break;
> -	default:
> -/*	case SENSOR_HV7131R: */
> -/*	case SENSOR_MI0360: */
> -/*	case SENSOR_MO4000: */
> -		reg_w1(gspca_dev, 0x01, 0x43);
> -		reg_w1(gspca_dev, 0x17, 0x61);
> -		reg_w1(gspca_dev, 0x01, 0x42);
> -		if (sd->sensor == SENSOR_HV7131R)
> -			hv7131r_probe(gspca_dev);
> -		break;
>  	}
>  
>  	/* initialize the sensor */
> @@ -2487,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
>  	}
>  	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
>  	switch (sd->sensor) {
> -	case SENSOR_GC0307:
> -		reg17 = 0xa2;
> -		break;
> -	case SENSOR_MT9V111:
> -	case SENSOR_MI0360B:
> -		reg17 = 0xe0;
> -		break;
> -	case SENSOR_ADCM1700:
> -	case SENSOR_OV7630:
> -		reg17 = 0xe2;
> -		break;
> -	case SENSOR_OV7648:
> -		reg17 = 0x20;
> -		break;
> -	case SENSOR_OV7660:
> -	case SENSOR_SOI768:
> -		reg17 = 0xa0;
> -		break;
> -	case SENSOR_PO1030:
> -	case SENSOR_PO2030N:
> -		reg17 = 0xa0;
> +	case SENSOR_OM6802:
> +/*	case SENSOR_OV7648:		* fixme: sometimes */
>  		break;
>  	default:
> -		reg17 = 0x60;
> +		reg17 |= DEF_EN;
>  		break;
>  	}
>  	reg_w1(gspca_dev, 0x17, reg17);
> @@ -2557,95 +2497,64 @@ static int sd_start(struct gspca_dev *gspca_dev)
>  
>  	init = NULL;
>  	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
> +	reg01 |= V_TX_EN;
>  	if (mode)
> -		reg1 = 0x46;	/* 320x240: clk 48Mhz, video trf enable */
> +		reg01 |= SYS_SEL_48M;	/* 320x240: clk 48Mhz */
>  	else
> -		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */
> -	reg17 = 0x61;		/* 0x:20: enable sensor clock */
> +		reg01 &= ~SYS_SEL_48M;	/* 640x480: clk 24Mhz */
> +	reg17 &= ~MCK_SIZE_MASK;
> +	reg17 |= 0x02;			/* clock / 2 */
>  	switch (sd->sensor) {
>  	case SENSOR_ADCM1700:
>  		init = adcm1700_sensor_param1;
> -		reg1 = 0x46;
> -		reg17 = 0xe2;
> +		reg01 |= SYS_SEL_48M;
>  		break;
>  	case SENSOR_GC0307:
>  		init = gc0307_sensor_param1;
> -		reg17 = 0xa2;
> -		reg1 = 0x44;
> +		reg01 |= SYS_SEL_48M;
>  		break;
>  	case SENSOR_MI0360B:
>  		init = mi0360b_sensor_param1;
> -		reg1 &= ~0x02;		/* don't inverse pin S_PWR_DN */
> -		reg17 = 0xe2;
>  		break;
>  	case SENSOR_MO4000:
>  		if (mode) {
> -/*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
> -			reg1 = 0x06;	/* clk 24Mz */
> +			reg01 &= ~SYS_SEL_48M;	/* clk 24Mz */
>  		} else {
> -			reg17 = 0x22;	/* 640 MCKSIZE */
> -/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
> +			reg17 = SEN_CLK_EN | 0x02;	/* clock / 2 */
>  		}
>  		break;
>  	case SENSOR_MT9V111:
>  		init = mt9v111_sensor_param1;
> -		if (mode) {
> -			reg1 = 0x04;	/* 320 clk 48Mhz */
> -		} else {
> -/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
> -			reg17 = 0xc2;
> -		}
>  		break;
>  	case SENSOR_OM6802:
>  		init = om6802_sensor_param1;
> -		reg17 = 0x64;		/* 640 MCKSIZE */
>  		break;
>  	case SENSOR_OV7630:
>  		init = ov7630_sensor_param1;
> -		reg17 = 0xe2;
> -		reg1 = 0x44;
> +		reg01 |= SYS_SEL_48M;
>  		break;
>  	case SENSOR_OV7648:
>  		init = ov7648_sensor_param1;
> -		reg17 = 0x21;
> -/*		reg1 = 0x42;		 * 42 - 46? */
> +		reg17 &= ~MCK_SIZE_MASK;
> +		reg17 |= 0x01;			/* clock / 1 */
>  		break;
>  	case SENSOR_OV7660:
>  		init = ov7660_sensor_param1;
> -		if (sd->bridge == BRIDGE_SN9C120) {
> -			if (mode) {		/* 320x240 - 160x120 */
> -				reg17 = 0xa2;
> -				reg1 = 0x44;	/* 48 Mhz, video trf eneble */
> -			}
> -		} else {
> -			reg17 = 0x22;
> -			reg1 = 0x06;	/* 24 Mhz, video trf eneble
> -					 * inverse power down */
> -		}

I'm not sure about this... On my tests with the two devices I have with ov7660
(sn9c105 and sn9c120), the original driver uses 48 MHz for all resolutions.

>  		break;
>  	case SENSOR_PO1030:
>  		init = po1030_sensor_param1;
> -		reg17 = 0xa2;
> -		reg1 = 0x44;
> +		reg01 |= SYS_SEL_48M;
>  		break;
>  	case SENSOR_PO2030N:
>  		init = po2030n_sensor_param1;
> -		reg1 = 0x46;
> -		reg17 = 0xa2;
> +		reg01 |= SYS_SEL_48M;
>  		break;
>  	case SENSOR_SOI768:
>  		init = soi768_sensor_param1;
> -		reg1 = 0x44;
> -		reg17 = 0xa2;
> +		reg01 |= SYS_SEL_48M;
>  		break;
>  	case SENSOR_SP80708:
>  		init = sp80708_sensor_param1;
> -		if (mode) {
> -/*??			reg1 = 0x04;	 * 320 clk 48Mhz */
> -		} else {
> -			reg1 = 0x46;	 /* 640 clk 48Mz */
> -			reg17 = 0xa2;
> -		}
>  		break;
>  	}
>  
> @@ -2695,7 +2604,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
>  	setjpegqual(gspca_dev);
>  
>  	reg_w1(gspca_dev, 0x17, reg17);
> -	reg_w1(gspca_dev, 0x01, reg1);
> +	reg_w1(gspca_dev, 0x01, reg01);
> +	sd->reg01 = reg01;
> +	sd->reg17 = reg17;
>  
>  	sethvflip(gspca_dev);
>  	setbrightness(gspca_dev);
> @@ -2717,41 +2628,69 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
>  		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
>  	static const u8 stopsoi768[] =
>  		{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
> -	u8 data;
> -	const u8 *sn9c1xx;
> +	u8 reg01;
> +	u8 reg17;
>  
> -	data = 0x0b;
> +	reg01 = sd->reg01;
> +	reg17 = sd->reg17 & ~SEN_CLK_EN;
>  	switch (sd->sensor) {
> +	case SENSOR_ADCM1700:
> +	case SENSOR_PO2030N:
> +	case SENSOR_SP80708:
> +		reg01 |= LED;
> +		reg_w1(gspca_dev, 0x01, reg01);
> +		reg01 &= ~(LED | V_TX_EN);
> +		reg_w1(gspca_dev, 0x01, reg01);
> +/*		reg_w1(gspca_dev, 0x02, 0x??);	 * LED off ? */
> +		break;
>  	case SENSOR_GC0307:
> -		data = 0x29;
> +		reg01 |= LED | S_PDN_INV;
> +		reg_w1(gspca_dev, 0x01, reg01);
> +		reg01 &= ~(LED | V_TX_EN | S_PDN_INV);

Touching at S_PDN_INV here seems wrong. sd->reg01 has already the S_PDN_INV
value stored there, for devices that require it. 

The right thing would be to use S_PWR_DN. If you got this from the original 
driver USB dump, my guess is that the developer of the original driver got 
the wrong bit by mistake. Of course, I may be wrong here.  


> +		reg_w1(gspca_dev, 0x01, reg01);
>  		break;
>  	case SENSOR_HV7131R:
> +		reg01 &= ~V_TX_EN;
> +		reg_w1(gspca_dev, 0x01, reg01);
>  		i2c_w8(gspca_dev, stophv7131);
> -		data = 0x2b;
>  		break;
>  	case SENSOR_MI0360:
>  	case SENSOR_MI0360B:
> +		reg01 &= ~V_TX_EN;
> +		reg_w1(gspca_dev, 0x01, reg01);
> +/*		reg_w1(gspca_dev, 0x02, 0x40);	  * LED off ? */
>  		i2c_w8(gspca_dev, stopmi0360);
> -		data = 0x29;
>  		break;
> -	case SENSOR_OV7648:
> -		i2c_w8(gspca_dev, stopov7648);
> -		/* fall thru */
>  	case SENSOR_MT9V111:
> -	case SENSOR_OV7630:
> +	case SENSOR_OM6802:
>  	case SENSOR_PO1030:
> -		data = 0x29;
> +		reg01 &= ~V_TX_EN;
> +		reg_w1(gspca_dev, 0x01, reg01);
> +		break;
> +	case SENSOR_OV7630:
> +	case SENSOR_OV7648:
> +		reg01 &= ~V_TX_EN;
> +		reg_w1(gspca_dev, 0x01, reg01);
> +		i2c_w8(gspca_dev, stopov7648);
> +		break;
> +	case SENSOR_OV7660:
> +		reg01 &= ~V_TX_EN;
> +		reg_w1(gspca_dev, 0x01, reg01);
>  		break;
>  	case SENSOR_SOI768:
>  		i2c_w8(gspca_dev, stopsoi768);
> -		data = 0x29;
>  		break;
>  	}
> -	sn9c1xx = sn_tb[sd->sensor];
> -	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
> -	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
> -	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
> -	reg_w1(gspca_dev, 0x01, data);
> +
> +	reg01 |= SCL_SEL_OD;
> +	reg_w1(gspca_dev, 0x01, reg01);
> +	reg01 |= S_PWR_DN;		/* sensor power down */
> +	reg_w1(gspca_dev, 0x01, reg01);
> +	reg_w1(gspca_dev, 0x17, reg17);
> +	reg01 &= ~SYS_SEL_48M;		/* clock 24MHz */
> +	reg_w1(gspca_dev, 0x01, reg01);
> +	reg01 |= LED;
> +	reg_w1(gspca_dev, 0x01, reg01);
>  	/* Don't disable sensor clock as that disables the button on the cam */
>  	/* reg_w1(gspca_dev, 0xf1, 0x01); */
>  }


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 6/6] gspca - sonixj: Better handling of the bridge registers 0x01 and 0x17
  2010-12-13 13:27 ` Mauro Carvalho Chehab
@ 2010-12-13 18:44   ` Hans de Goede
  2010-12-13 19:15   ` Jean-Francois Moine
  1 sibling, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2010-12-13 18:44 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: Jean-Francois Moine, Linux Media Mailing List

Hi,

On 12/13/2010 02:27 PM, Mauro Carvalho Chehab wrote:
> Em 13-12-2010 11:04, Jean-Francois Moine escreveu:
>>
> I'm not sure about this... On my tests with the two devices I have with ov7660
> (sn9c105 and sn9c120), the original driver uses 48 MHz for all resolutions.
>

My 2 cents:

In my experience when (windows) drivers tend to play with the clockrate / clock
dividers on the basis of the mode / resolution this is because of bandwidth
constrains. So the question is what framerate does the 48 Mhz clock give us and
(assuming the highest alt setting, here we go again) what framerate can the
bridge / usb bus handle at the highest resolution (assuming worst case
compression).

Regards,

Hans




>>   		break;
>>   	case SENSOR_PO1030:
>>   		init = po1030_sensor_param1;
>> -		reg17 = 0xa2;
>> -		reg1 = 0x44;
>> +		reg01 |= SYS_SEL_48M;
>>   		break;
>>   	case SENSOR_PO2030N:
>>   		init = po2030n_sensor_param1;
>> -		reg1 = 0x46;
>> -		reg17 = 0xa2;
>> +		reg01 |= SYS_SEL_48M;
>>   		break;
>>   	case SENSOR_SOI768:
>>   		init = soi768_sensor_param1;
>> -		reg1 = 0x44;
>> -		reg17 = 0xa2;
>> +		reg01 |= SYS_SEL_48M;
>>   		break;
>>   	case SENSOR_SP80708:
>>   		init = sp80708_sensor_param1;
>> -		if (mode) {
>> -/*??			reg1 = 0x04;	 * 320 clk 48Mhz */
>> -		} else {
>> -			reg1 = 0x46;	 /* 640 clk 48Mz */
>> -			reg17 = 0xa2;
>> -		}
>>   		break;
>>   	}
>>
>> @@ -2695,7 +2604,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
>>   	setjpegqual(gspca_dev);
>>
>>   	reg_w1(gspca_dev, 0x17, reg17);
>> -	reg_w1(gspca_dev, 0x01, reg1);
>> +	reg_w1(gspca_dev, 0x01, reg01);
>> +	sd->reg01 = reg01;
>> +	sd->reg17 = reg17;
>>
>>   	sethvflip(gspca_dev);
>>   	setbrightness(gspca_dev);
>> @@ -2717,41 +2628,69 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
>>   		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
>>   	static const u8 stopsoi768[] =
>>   		{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
>> -	u8 data;
>> -	const u8 *sn9c1xx;
>> +	u8 reg01;
>> +	u8 reg17;
>>
>> -	data = 0x0b;
>> +	reg01 = sd->reg01;
>> +	reg17 = sd->reg17&  ~SEN_CLK_EN;
>>   	switch (sd->sensor) {
>> +	case SENSOR_ADCM1700:
>> +	case SENSOR_PO2030N:
>> +	case SENSOR_SP80708:
>> +		reg01 |= LED;
>> +		reg_w1(gspca_dev, 0x01, reg01);
>> +		reg01&= ~(LED | V_TX_EN);
>> +		reg_w1(gspca_dev, 0x01, reg01);
>> +/*		reg_w1(gspca_dev, 0x02, 0x??);	 * LED off ? */
>> +		break;
>>   	case SENSOR_GC0307:
>> -		data = 0x29;
>> +		reg01 |= LED | S_PDN_INV;
>> +		reg_w1(gspca_dev, 0x01, reg01);
>> +		reg01&= ~(LED | V_TX_EN | S_PDN_INV);
>
> Touching at S_PDN_INV here seems wrong. sd->reg01 has already the S_PDN_INV
> value stored there, for devices that require it.
>
> The right thing would be to use S_PWR_DN. If you got this from the original
> driver USB dump, my guess is that the developer of the original driver got
> the wrong bit by mistake. Of course, I may be wrong here.
>
>
>> +		reg_w1(gspca_dev, 0x01, reg01);
>>   		break;
>>   	case SENSOR_HV7131R:
>> +		reg01&= ~V_TX_EN;
>> +		reg_w1(gspca_dev, 0x01, reg01);
>>   		i2c_w8(gspca_dev, stophv7131);
>> -		data = 0x2b;
>>   		break;
>>   	case SENSOR_MI0360:
>>   	case SENSOR_MI0360B:
>> +		reg01&= ~V_TX_EN;
>> +		reg_w1(gspca_dev, 0x01, reg01);
>> +/*		reg_w1(gspca_dev, 0x02, 0x40);	  * LED off ? */
>>   		i2c_w8(gspca_dev, stopmi0360);
>> -		data = 0x29;
>>   		break;
>> -	case SENSOR_OV7648:
>> -		i2c_w8(gspca_dev, stopov7648);
>> -		/* fall thru */
>>   	case SENSOR_MT9V111:
>> -	case SENSOR_OV7630:
>> +	case SENSOR_OM6802:
>>   	case SENSOR_PO1030:
>> -		data = 0x29;
>> +		reg01&= ~V_TX_EN;
>> +		reg_w1(gspca_dev, 0x01, reg01);
>> +		break;
>> +	case SENSOR_OV7630:
>> +	case SENSOR_OV7648:
>> +		reg01&= ~V_TX_EN;
>> +		reg_w1(gspca_dev, 0x01, reg01);
>> +		i2c_w8(gspca_dev, stopov7648);
>> +		break;
>> +	case SENSOR_OV7660:
>> +		reg01&= ~V_TX_EN;
>> +		reg_w1(gspca_dev, 0x01, reg01);
>>   		break;
>>   	case SENSOR_SOI768:
>>   		i2c_w8(gspca_dev, stopsoi768);
>> -		data = 0x29;
>>   		break;
>>   	}
>> -	sn9c1xx = sn_tb[sd->sensor];
>> -	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
>> -	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
>> -	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
>> -	reg_w1(gspca_dev, 0x01, data);
>> +
>> +	reg01 |= SCL_SEL_OD;
>> +	reg_w1(gspca_dev, 0x01, reg01);
>> +	reg01 |= S_PWR_DN;		/* sensor power down */
>> +	reg_w1(gspca_dev, 0x01, reg01);
>> +	reg_w1(gspca_dev, 0x17, reg17);
>> +	reg01&= ~SYS_SEL_48M;		/* clock 24MHz */
>> +	reg_w1(gspca_dev, 0x01, reg01);
>> +	reg01 |= LED;
>> +	reg_w1(gspca_dev, 0x01, reg01);
>>   	/* Don't disable sensor clock as that disables the button on the cam */
>>   	/* reg_w1(gspca_dev, 0xf1, 0x01); */
>>   }
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 6/6] gspca - sonixj: Better handling of the bridge registers 0x01 and 0x17
  2010-12-13 13:27 ` Mauro Carvalho Chehab
  2010-12-13 18:44   ` Hans de Goede
@ 2010-12-13 19:15   ` Jean-Francois Moine
  1 sibling, 0 replies; 5+ messages in thread
From: Jean-Francois Moine @ 2010-12-13 19:15 UTC (permalink / raw)
  To: Mauro Carvalho Chehab; +Cc: Linux Media Mailing List

On Mon, 13 Dec 2010 11:27:24 -0200
Mauro Carvalho Chehab <mchehab@redhat.com> wrote:

> >  	case SENSOR_OV7660:
> >  		init = ov7660_sensor_param1;
> > -		if (sd->bridge == BRIDGE_SN9C120) {
> > -			if (mode) {		/* 320x240 - 160x120 */
> > -				reg17 = 0xa2;
> > -				reg1 = 0x44;	/* 48 Mhz, video trf eneble */
> > -			}
> > -		} else {
> > -			reg17 = 0x22;
> > -			reg1 = 0x06;	/* 24 Mhz, video trf eneble
> > -					 * inverse power down */
> > -		}  
> 
> I'm not sure about this... On my tests with the two devices I have
> with ov7660 (sn9c105 and sn9c120), the original driver uses 48 MHz
> for all resolutions.

Hi Mauro,

You are right, I will fix that in the next version.

Regards.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 6/6] gspca - sonixj: Better handling of the bridge registers 0x01 and 0x17
@ 2010-12-14 19:17 Jean-François Moine
  0 siblings, 0 replies; 5+ messages in thread
From: Jean-François Moine @ 2010-12-14 19:17 UTC (permalink / raw)
  To: Linux Media Mailing List, Mauro Carvalho Chehab

The initial values of the registers 0x01 and 0x17 are taken from the sensor
table at capture start and updated according to the flag PDN_INV.

Their values are updated at each step of the capture initialization and
memorized for reuse in capture stop.

This patch also fixed automatically some bad hardcoded values of these
registers.

Signed-off-by: Jean-François Moine <moinejf@free.fr>

diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index a75f7ec..901ca81 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -63,6 +63,8 @@ struct sd {
 #define QUALITY_DEF 80
 	u8 jpegqual;			/* webcam quality */
 
+	u8 reg01;
+	u8 reg17;
 	u8 reg18;
 	u8 flags;
 
@@ -2306,8 +2308,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
+	u8 reg01, reg17;
 	u8 reg0102[2];
-	u8 reg1, reg17;
 	const u8 *sn9c1xx;
 	const u8 (*init)[8];
 	const u8 *reg9a;
@@ -2341,10 +2343,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	/* sensor clock already enabled in sd_init */
 	/* reg_w1(gspca_dev, 0xf1, 0x00); */
-	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
+	reg01 = sn9c1xx[1];
+	if (sd->flags & PDN_INV)
+		reg01 ^= S_PDN_INV;		/* power down inverted */
+	reg_w1(gspca_dev, 0x01, reg01);
 
 	/* configure gpio */
-	reg0102[0] = sn9c1xx[1];
+	reg0102[0] = reg01;
 	reg0102[1] = sn9c1xx[2];
 	if (gspca_dev->audio)
 		reg0102[1] |= 0x04;	/* keep the audio connection */
@@ -2370,95 +2375,49 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
 
+	reg17 = sn9c1xx[0x17];
 	switch (sd->sensor) {
-	case SENSOR_ADCM1700:
-		reg_w1(gspca_dev, 0x01, 0x43);
-		reg_w1(gspca_dev, 0x17, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		break;
 	case SENSOR_GC0307:
-		msleep(50);
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x22);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		msleep(50);
-		break;
-	case SENSOR_MI0360B:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		break;
-	case SENSOR_MT9V111:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x61);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
+		msleep(50);		/*fixme: is it useful? */
 		break;
 	case SENSOR_OM6802:
 		msleep(10);
 		reg_w1(gspca_dev, 0x02, 0x73);
-		reg_w1(gspca_dev, 0x17, 0x60);
+		reg17 |= SEN_CLK_EN;
+		reg_w1(gspca_dev, 0x17, reg17);
 		reg_w1(gspca_dev, 0x01, 0x22);
 		msleep(100);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x17, 0x64);
-		reg_w1(gspca_dev, 0x17, 0x64);
-		reg_w1(gspca_dev, 0x01, 0x42);
+		reg01 = SCL_SEL_OD | S_PDN_INV;
+		reg17 &= MCK_SIZE_MASK;
+		reg17 |= 0x04;		/* clock / 4 */
+		break;
+	}
+	reg01 |= SYS_SEL_48M;
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg17 |= SEN_CLK_EN;
+	reg_w1(gspca_dev, 0x17, reg17);
+	reg01 &= ~S_PWR_DN;		/* sensor power on */
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg01 &= ~SYS_SEL_48M;
+	reg_w1(gspca_dev, 0x01, reg01);
+
+	switch (sd->sensor) {
+	case SENSOR_HV7131R:
+		hv7131r_probe(gspca_dev);	/*fixme: is it useful? */
+		break;
+	case SENSOR_OM6802:
 		msleep(10);
-		reg_w1(gspca_dev, 0x01, 0x42);
+		reg_w1(gspca_dev, 0x01, reg01);
 		i2c_w8(gspca_dev, om6802_init0[0]);
 		i2c_w8(gspca_dev, om6802_init0[1]);
 		msleep(15);
 		reg_w1(gspca_dev, 0x02, 0x71);
 		msleep(150);
 		break;
-	case SENSOR_OV7630:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0xe2);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		break;
-	case SENSOR_OV7648:
-		reg_w1(gspca_dev, 0x01, 0x63);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		break;
-	case SENSOR_PO1030:
-	case SENSOR_SOI768:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		break;
-	case SENSOR_PO2030N:
-	case SENSOR_OV7660:
-		reg_w1(gspca_dev, 0x01, 0x63);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		break;
 	case SENSOR_SP80708:
-		reg_w1(gspca_dev, 0x01, 0x63);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x62);
-		reg_w1(gspca_dev, 0x01, 0x42);
 		msleep(100);
 		reg_w1(gspca_dev, 0x02, 0x62);
 		break;
-	default:
-/*	case SENSOR_HV7131R: */
-/*	case SENSOR_MI0360: */
-/*	case SENSOR_MO4000: */
-		reg_w1(gspca_dev, 0x01, 0x43);
-		reg_w1(gspca_dev, 0x17, 0x61);
-		reg_w1(gspca_dev, 0x01, 0x42);
-		if (sd->sensor == SENSOR_HV7131R)
-			hv7131r_probe(gspca_dev);
-		break;
 	}
 
 	/* initialize the sensor */
@@ -2487,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	}
 	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
 	switch (sd->sensor) {
-	case SENSOR_GC0307:
-		reg17 = 0xa2;
-		break;
-	case SENSOR_MT9V111:
-	case SENSOR_MI0360B:
-		reg17 = 0xe0;
-		break;
-	case SENSOR_ADCM1700:
-	case SENSOR_OV7630:
-		reg17 = 0xe2;
-		break;
-	case SENSOR_OV7648:
-		reg17 = 0x20;
-		break;
-	case SENSOR_OV7660:
-	case SENSOR_SOI768:
-		reg17 = 0xa0;
-		break;
-	case SENSOR_PO1030:
-	case SENSOR_PO2030N:
-		reg17 = 0xa0;
+	case SENSOR_OM6802:
+/*	case SENSOR_OV7648:		* fixme: sometimes */
 		break;
 	default:
-		reg17 = 0x60;
+		reg17 |= DEF_EN;
 		break;
 	}
 	reg_w1(gspca_dev, 0x17, reg17);
@@ -2557,95 +2497,67 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	init = NULL;
 	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
-	if (mode)
-		reg1 = 0x46;	/* 320x240: clk 48Mhz, video trf enable */
-	else
-		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */
-	reg17 = 0x61;		/* 0x:20: enable sensor clock */
+	reg01 |= SYS_SEL_48M | V_TX_EN;
+	reg17 &= ~MCK_SIZE_MASK;
+	reg17 |= 0x02;			/* clock / 2 */
 	switch (sd->sensor) {
 	case SENSOR_ADCM1700:
 		init = adcm1700_sensor_param1;
-		reg1 = 0x46;
-		reg17 = 0xe2;
 		break;
 	case SENSOR_GC0307:
 		init = gc0307_sensor_param1;
-		reg17 = 0xa2;
-		reg1 = 0x44;
+		break;
+	case SENSOR_HV7131R:
+	case SENSOR_MI0360:
+		if (mode)
+			reg01 |= SYS_SEL_48M;	/* 320x240: clk 48Mhz */
+		else
+			reg01 &= ~SYS_SEL_48M;	/* 640x480: clk 24Mhz */
+		reg17 &= ~MCK_SIZE_MASK;
+		reg17 |= 0x01;			/* clock / 1 */
 		break;
 	case SENSOR_MI0360B:
 		init = mi0360b_sensor_param1;
-		reg1 &= ~0x02;		/* don't inverse pin S_PWR_DN */
-		reg17 = 0xe2;
 		break;
 	case SENSOR_MO4000:
-		if (mode) {
-/*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
-			reg1 = 0x06;	/* clk 24Mz */
-		} else {
-			reg17 = 0x22;	/* 640 MCKSIZE */
-/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
+		if (mode) {			/* if 320x240 */
+			reg01 &= ~SYS_SEL_48M;	/* clk 24Mz */
+			reg17 &= ~MCK_SIZE_MASK;
+			reg17 |= 0x01;		/* clock / 1 */
 		}
 		break;
 	case SENSOR_MT9V111:
 		init = mt9v111_sensor_param1;
-		if (mode) {
-			reg1 = 0x04;	/* 320 clk 48Mhz */
-		} else {
-/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
-			reg17 = 0xc2;
-		}
 		break;
 	case SENSOR_OM6802:
 		init = om6802_sensor_param1;
-		reg17 = 0x64;		/* 640 MCKSIZE */
+		if (!mode) {			/* if 640x480 */
+			reg17 &= ~MCK_SIZE_MASK;
+			reg17 |= 0x01;		/* clock / 4 */
+		}
 		break;
 	case SENSOR_OV7630:
 		init = ov7630_sensor_param1;
-		reg17 = 0xe2;
-		reg1 = 0x44;
 		break;
 	case SENSOR_OV7648:
 		init = ov7648_sensor_param1;
-		reg17 = 0x21;
-/*		reg1 = 0x42;		 * 42 - 46? */
+		reg17 &= ~MCK_SIZE_MASK;
+		reg17 |= 0x01;			/* clock / 1 */
 		break;
 	case SENSOR_OV7660:
 		init = ov7660_sensor_param1;
-		if (sd->bridge == BRIDGE_SN9C120) {
-			if (mode) {		/* 320x240 - 160x120 */
-				reg17 = 0xa2;
-				reg1 = 0x44;	/* 48 Mhz, video trf eneble */
-			}
-		} else {
-			reg17 = 0x22;
-			reg1 = 0x06;	/* 24 Mhz, video trf eneble
-					 * inverse power down */
-		}
 		break;
 	case SENSOR_PO1030:
 		init = po1030_sensor_param1;
-		reg17 = 0xa2;
-		reg1 = 0x44;
 		break;
 	case SENSOR_PO2030N:
 		init = po2030n_sensor_param1;
-		reg1 = 0x46;
-		reg17 = 0xa2;
 		break;
 	case SENSOR_SOI768:
 		init = soi768_sensor_param1;
-		reg1 = 0x44;
-		reg17 = 0xa2;
 		break;
 	case SENSOR_SP80708:
 		init = sp80708_sensor_param1;
-		if (mode) {
-/*??			reg1 = 0x04;	 * 320 clk 48Mhz */
-		} else {
-			reg1 = 0x46;	 /* 640 clk 48Mz */
-			reg17 = 0xa2;
-		}
 		break;
 	}
 
@@ -2695,7 +2607,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	setjpegqual(gspca_dev);
 
 	reg_w1(gspca_dev, 0x17, reg17);
-	reg_w1(gspca_dev, 0x01, reg1);
+	reg_w1(gspca_dev, 0x01, reg01);
+	sd->reg01 = reg01;
+	sd->reg17 = reg17;
 
 	sethvflip(gspca_dev);
 	setbrightness(gspca_dev);
@@ -2717,41 +2631,64 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
 	static const u8 stopsoi768[] =
 		{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
-	u8 data;
-	const u8 *sn9c1xx;
+	u8 reg01;
+	u8 reg17;
 
-	data = 0x0b;
+	reg01 = sd->reg01;
+	reg17 = sd->reg17 & ~SEN_CLK_EN;
 	switch (sd->sensor) {
+	case SENSOR_ADCM1700:
 	case SENSOR_GC0307:
-		data = 0x29;
+	case SENSOR_PO2030N:
+	case SENSOR_SP80708:
+		reg01 |= LED;
+		reg_w1(gspca_dev, 0x01, reg01);
+		reg01 &= ~(LED | V_TX_EN);
+		reg_w1(gspca_dev, 0x01, reg01);
+/*		reg_w1(gspca_dev, 0x02, 0x??);	 * LED off ? */
 		break;
 	case SENSOR_HV7131R:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
 		i2c_w8(gspca_dev, stophv7131);
-		data = 0x2b;
 		break;
 	case SENSOR_MI0360:
 	case SENSOR_MI0360B:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
+/*		reg_w1(gspca_dev, 0x02, 0x40);	  * LED off ? */
 		i2c_w8(gspca_dev, stopmi0360);
-		data = 0x29;
 		break;
-	case SENSOR_OV7648:
-		i2c_w8(gspca_dev, stopov7648);
-		/* fall thru */
 	case SENSOR_MT9V111:
-	case SENSOR_OV7630:
+	case SENSOR_OM6802:
 	case SENSOR_PO1030:
-		data = 0x29;
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
+		break;
+	case SENSOR_OV7630:
+	case SENSOR_OV7648:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
+		i2c_w8(gspca_dev, stopov7648);
+		break;
+	case SENSOR_OV7660:
+		reg01 &= ~V_TX_EN;
+		reg_w1(gspca_dev, 0x01, reg01);
 		break;
 	case SENSOR_SOI768:
 		i2c_w8(gspca_dev, stopsoi768);
-		data = 0x29;
 		break;
 	}
-	sn9c1xx = sn_tb[sd->sensor];
-	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
-	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
-	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
-	reg_w1(gspca_dev, 0x01, data);
+
+	reg01 |= SCL_SEL_OD;
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg01 |= S_PWR_DN;		/* sensor power down */
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg_w1(gspca_dev, 0x17, reg17);
+	reg01 &= ~SYS_SEL_48M;		/* clock 24MHz */
+	reg_w1(gspca_dev, 0x01, reg01);
+	reg01 |= LED;
+	reg_w1(gspca_dev, 0x01, reg01);
 	/* Don't disable sensor clock as that disables the button on the cam */
 	/* reg_w1(gspca_dev, 0xf1, 0x01); */
 }
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-12-14 19:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-14 19:17 [PATCH 6/6] gspca - sonixj: Better handling of the bridge registers 0x01 and 0x17 Jean-François Moine
  -- strict thread matches above, loose matches on Subject: below --
2010-12-13 13:04 Jean-Francois Moine
2010-12-13 13:27 ` Mauro Carvalho Chehab
2010-12-13 18:44   ` Hans de Goede
2010-12-13 19:15   ` Jean-Francois Moine

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).