|
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
|
|
|
struct sd {
|
|
|
struct gspca_dev gspca_dev; /* !! must be the first item */
|
|
|
|
|
|
- int avg_lum;
|
|
|
+ atomic_t avg_lum;
|
|
|
unsigned int exposure;
|
|
|
|
|
|
unsigned short brightness;
|
|
@@ -148,55 +148,58 @@ static struct v4l2_pix_format vga_mode[] = {
|
|
|
|
|
|
/*Data from sn9c102p+hv71331r */
|
|
|
static const __u8 sn_hv7131[] = {
|
|
|
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
|
|
|
- 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11,
|
|
|
-/* rega regb regc regd rege regf reg10 reg11 */
|
|
|
- 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */
|
|
|
-/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
|
|
|
- 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00,
|
|
|
-/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
|
|
+ 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
|
|
+/* reg8 reg9 rega regb regc regd rege regf */
|
|
|
+ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
|
|
|
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
|
|
+ 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
|
|
|
+/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
|
|
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
};
|
|
|
|
|
|
static const __u8 sn_mi0360[] = {
|
|
|
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
|
|
|
- 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d,
|
|
|
-/* rega regb regc regd rege regf reg10 reg11 */
|
|
|
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00,
|
|
|
-/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
|
|
|
- 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00,
|
|
|
-/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
|
|
+ 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
|
|
+/* reg8 reg9 rega regb regc regd rege regf */
|
|
|
+ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
|
|
|
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
|
|
+ 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
|
|
|
+/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
|
|
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
};
|
|
|
|
|
|
static const __u8 sn_mo4000[] = {
|
|
|
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
|
|
|
- 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81,
|
|
|
-/* reg9 rega regb regc regd rege regf reg10 reg11*/
|
|
|
- 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
|
|
|
-/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
|
|
|
- 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00,
|
|
|
-/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b,
|
|
|
- 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7,
|
|
|
- 0xd3, 0xdf, 0xea, 0xf5
|
|
|
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
|
|
+ 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
|
|
|
+/* reg8 reg9 rega regb regc regd rege regf */
|
|
|
+ 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
|
|
+ 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
|
|
|
+/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
|
|
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
};
|
|
|
|
|
|
static const __u8 sn_ov7648[] = {
|
|
|
- 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65,
|
|
|
- 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82,
|
|
|
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
|
|
+ 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
|
|
+/* reg8 reg9 rega regb regc regd rege regf */
|
|
|
+ 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
|
|
|
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
|
|
+ 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
|
|
|
+/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
|
|
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
};
|
|
|
|
|
|
static const __u8 sn_ov7660[] = {
|
|
|
-/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
|
|
|
- 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81,
|
|
|
-/* reg9 rega regb regc regd rege regf reg10 reg11*/
|
|
|
- 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
|
|
|
-/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
|
|
|
- 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00,
|
|
|
-/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
|
|
|
+ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
|
|
|
+/* reg8 reg9 rega regb regc regd rege regf */
|
|
|
+ 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
|
|
|
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
|
|
|
+ 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
|
|
|
+/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
|
|
|
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
};
|
|
|
|
|
|
/* sequence specific to the sensors - !! index = SENSOR_xxx */
|
|
@@ -212,10 +215,6 @@ static const __u8 regsn20[] = {
|
|
|
0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
|
|
|
0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
|
|
|
};
|
|
|
-static const __u8 regsn20_sn9c120[] = {
|
|
|
- 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90,
|
|
|
- 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff
|
|
|
-};
|
|
|
static const __u8 regsn20_sn9c325[] = {
|
|
|
0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
|
|
|
0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
|
|
@@ -227,21 +226,6 @@ static const __u8 reg84[] = {
|
|
|
/* 0x00, 0x00, 0x00, 0x00, 0x00 */
|
|
|
0xf7, 0x0f, 0x0a, 0x00, 0x00
|
|
|
};
|
|
|
-static const __u8 reg84_sn9c120_1[] = {
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
- 0x00, 0x00, 0x0c, 0x00, 0x00
|
|
|
-};
|
|
|
-static const __u8 reg84_sn9c120_2[] = {
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
- 0x00, 0x00, 0x0c, 0x02, 0x3b
|
|
|
-};
|
|
|
-static const __u8 reg84_sn9c120_3[] = {
|
|
|
- 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f,
|
|
|
- 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f,
|
|
|
- 0xf5, 0x0f, 0x0c, 0x02, 0x3b
|
|
|
-};
|
|
|
static const __u8 reg84_sn9c325[] = {
|
|
|
0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
|
|
|
0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
|
|
@@ -360,17 +344,15 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|
|
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
|
|
|
/* (delay 20ms) */
|
|
|
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
|
|
|
- /* Outformat ?? rawRGB */
|
|
|
+ /* Outformat = rawRGB */
|
|
|
{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
|
|
|
- {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
|
|
|
-/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */
|
|
|
+ {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
|
|
|
/* GAIN BLUE RED VREF */
|
|
|
{0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
|
|
|
/* COM 1 BAVE GEAVE AECHH */
|
|
|
{0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
|
|
|
{0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
|
|
|
- {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10},
|
|
|
-/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */
|
|
|
+ {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
|
|
|
/* AECH CLKRC COM7 COM8 */
|
|
|
{0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
|
|
|
{0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
|
|
@@ -379,8 +361,8 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|
|
{0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
|
|
|
{0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
|
|
|
/* BOS GBOS GROS ROS (BGGR offset) */
|
|
|
- {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10},
|
|
|
-/* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */
|
|
|
+/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
|
|
|
+ {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
|
|
|
/* AEW AEB VPT BBIAS */
|
|
|
{0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
|
|
|
/* GbBIAS RSVD EXHCH EXHCL */
|
|
@@ -407,9 +389,9 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|
|
{0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
|
|
|
/* LCC1 LCC2 LCC3 LCC4 */
|
|
|
{0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
|
|
|
- {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10},
|
|
|
+ {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
|
|
|
{0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
|
|
|
- /* band gap reference [0..3] DBLV */
|
|
|
+ /* band gap reference [0:3] DBLV */
|
|
|
{0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
|
|
|
{0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
|
|
|
{0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
|
|
@@ -419,37 +401,35 @@ static const __u8 ov7660_sensor_init[][8] = {
|
|
|
{0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
|
|
|
{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
|
|
|
{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
|
|
|
- {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
+ {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
|
|
|
/****** (some exchanges in the win trace) ******/
|
|
|
- {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
|
|
|
+ {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
|
|
|
/* bits[3..0]reserved */
|
|
|
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
|
|
|
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
/* VREF vertical frame ctrl */
|
|
|
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
- {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */
|
|
|
- {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
- {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
-/* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */
|
|
|
- {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10},
|
|
|
- {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10},
|
|
|
+ {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
|
|
|
+ {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
|
|
|
+ {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
|
|
|
+ {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
|
|
|
+/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
|
|
|
/****** (some exchanges in the win trace) ******/
|
|
|
{0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
|
|
|
- {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */
|
|
|
- {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
- {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
- {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},
|
|
|
+ {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
|
|
|
+ {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
|
|
|
+ {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
|
|
|
+/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
|
|
|
/****** (some exchanges in the win trace) ******/
|
|
|
-/**********startsensor KO if changed !!****/
|
|
|
+/******!! startsensor KO if changed !!****/
|
|
|
{0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
|
|
|
{0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
|
|
|
{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
|
|
|
{0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
|
|
|
-/* here may start the isoc exchanges */
|
|
|
{}
|
|
|
};
|
|
|
-/* reg0x04 reg0x07 reg 0x10 */
|
|
|
-/* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */
|
|
|
+/* reg 0x04 reg 0x07 reg 0x10 */
|
|
|
+/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
|
|
|
|
|
|
static const __u8 ov7648_sensor_init[][8] = {
|
|
|
{0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
|
|
@@ -680,13 +660,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
|
|
|
const __u8 *reg9a;
|
|
|
static const __u8 reg9a_def[] =
|
|
|
{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
|
|
|
- static const __u8 reg9a_sn9c120[] = /* from win trace */
|
|
|
- {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
|
|
|
static const __u8 reg9a_sn9c325[] =
|
|
|
{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
|
|
|
+ static const __u8 regd4[] = {0x60, 0x00, 0x00};
|
|
|
|
|
|
reg_w1(gspca_dev, 0xf1, 0x00);
|
|
|
- reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/
|
|
|
+ reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/
|
|
|
|
|
|
/* configure gpio */
|
|
|
reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
|
|
@@ -696,25 +675,17 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
|
|
|
case BRIDGE_SN9C325:
|
|
|
reg9a = reg9a_sn9c325;
|
|
|
break;
|
|
|
- case BRIDGE_SN9C120:
|
|
|
- reg9a = reg9a_sn9c120;
|
|
|
- break;
|
|
|
default:
|
|
|
reg9a = reg9a_def;
|
|
|
break;
|
|
|
}
|
|
|
reg_w(gspca_dev, 0x9a, reg9a, 6);
|
|
|
|
|
|
- reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */
|
|
|
+ reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
|
|
|
|
|
|
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
|
|
|
|
|
|
switch (sd->bridge) {
|
|
|
- case BRIDGE_SN9C120: /* from win trace */
|
|
|
- reg_w1(gspca_dev, 0x01, 0x61);
|
|
|
- reg_w1(gspca_dev, 0x17, 0x20);
|
|
|
- reg_w1(gspca_dev, 0x01, 0x60);
|
|
|
- break;
|
|
|
case BRIDGE_SN9C325:
|
|
|
reg_w1(gspca_dev, 0x01, 0x43);
|
|
|
reg_w1(gspca_dev, 0x17, 0xae);
|
|
@@ -810,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|
|
sd->contrast = CONTRAST_DEF;
|
|
|
sd->colors = COLOR_DEF;
|
|
|
sd->autogain = AUTOGAIN_DEF;
|
|
|
+ sd->ag_cnt = -1;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -823,10 +796,11 @@ static int sd_open(struct gspca_dev *gspca_dev)
|
|
|
|
|
|
/* setup a selector by bridge */
|
|
|
reg_w1(gspca_dev, 0xf1, 0x01);
|
|
|
- reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
|
|
|
- reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
|
|
|
reg_r(gspca_dev, 0x00, 1);
|
|
|
+ reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
|
|
|
+ reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
|
|
|
regF1 = gspca_dev->usb_buf[0];
|
|
|
+ PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
|
|
|
switch (sd->bridge) {
|
|
|
case BRIDGE_SN9C102P:
|
|
|
if (regF1 != 0x11)
|
|
@@ -937,15 +911,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|
|
sd->exposure = setexposure(gspca_dev, expo);
|
|
|
break;
|
|
|
case SENSOR_MI0360:
|
|
|
- expo = sd->brightness >> 4;
|
|
|
- sd->exposure = setexposure(gspca_dev, expo);
|
|
|
- break;
|
|
|
case SENSOR_MO4000:
|
|
|
expo = sd->brightness >> 4;
|
|
|
sd->exposure = setexposure(gspca_dev, expo);
|
|
|
break;
|
|
|
- case SENSOR_OV7660:
|
|
|
- return; /*jfm??*/
|
|
|
}
|
|
|
|
|
|
k2 = sd->brightness >> 10;
|
|
@@ -958,8 +927,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|
|
__u8 k2;
|
|
|
__u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
|
|
|
|
|
|
- if (sd->sensor == SENSOR_OV7660)
|
|
|
- return; /*jfm??*/
|
|
|
k2 = sd->contrast;
|
|
|
contrast[2] = k2;
|
|
|
contrast[0] = (k2 + 1) >> 1;
|
|
@@ -981,20 +948,32 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|
|
reg_w1(gspca_dev, 0x05, data);
|
|
|
}
|
|
|
|
|
|
+static void setautogain(struct gspca_dev *gspca_dev)
|
|
|
+{
|
|
|
+ struct sd *sd = (struct sd *) gspca_dev;
|
|
|
+
|
|
|
+ switch (sd->sensor) {
|
|
|
+ case SENSOR_HV7131R:
|
|
|
+ case SENSOR_MO4000:
|
|
|
+ case SENSOR_MI0360:
|
|
|
+ if (sd->autogain)
|
|
|
+ sd->ag_cnt = AG_CNT_START;
|
|
|
+ else
|
|
|
+ sd->ag_cnt = -1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/* -- start the camera -- */
|
|
|
static void sd_start(struct gspca_dev *gspca_dev)
|
|
|
{
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
|
int i;
|
|
|
- __u8 data;
|
|
|
- __u8 reg1;
|
|
|
- __u8 reg17;
|
|
|
+ __u8 reg1, reg17, reg18;
|
|
|
const __u8 *sn9c1xx;
|
|
|
int mode;
|
|
|
static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
|
|
|
static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
|
|
|
- static const __u8 CA_sn9c120[] =
|
|
|
- { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
|
|
|
static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
|
|
|
static const __u8 CE_sn9c325[] =
|
|
|
{ 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */
|
|
@@ -1002,9 +981,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|
|
sn9c1xx = sn_tb[(int) sd->sensor];
|
|
|
configure_gpio(gspca_dev, sn9c1xx);
|
|
|
|
|
|
-/*fixme:jfm this sequence should appear at end of sd_start */
|
|
|
-/* with
|
|
|
- reg_w1(gspca_dev, 0x01, 0x44); */
|
|
|
+/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
|
|
|
reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
|
|
|
reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
|
|
|
reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
|
|
@@ -1016,20 +993,16 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|
|
reg_w1(gspca_dev, 0xc7, 0x00);
|
|
|
reg_w1(gspca_dev, 0xc8, 0x50);
|
|
|
reg_w1(gspca_dev, 0xc9, 0x3c);
|
|
|
-/*fixme:jfm end of ending sequence */
|
|
|
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
|
|
|
switch (sd->bridge) {
|
|
|
case BRIDGE_SN9C325:
|
|
|
- data = 0xae;
|
|
|
- break;
|
|
|
- case BRIDGE_SN9C120:
|
|
|
- data = 0xa0;
|
|
|
+ reg17 = 0xae;
|
|
|
break;
|
|
|
default:
|
|
|
- data = 0x60;
|
|
|
+ reg17 = 0x60;
|
|
|
break;
|
|
|
}
|
|
|
- reg_w1(gspca_dev, 0x17, data);
|
|
|
+ reg_w1(gspca_dev, 0x17, reg17);
|
|
|
reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
|
|
|
reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
|
|
|
reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
|
|
@@ -1044,20 +1017,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|
|
reg_w1(gspca_dev, 0x9a, 0x0a);
|
|
|
reg_w1(gspca_dev, 0x99, 0x60);
|
|
|
break;
|
|
|
- case BRIDGE_SN9C120:
|
|
|
- reg_w(gspca_dev, 0x20, regsn20_sn9c120,
|
|
|
- sizeof regsn20_sn9c120);
|
|
|
- for (i = 0; i < 2; i++)
|
|
|
- reg_w(gspca_dev, 0x84, reg84_sn9c120_1,
|
|
|
- sizeof reg84_sn9c120_1);
|
|
|
- for (i = 0; i < 6; i++)
|
|
|
- reg_w(gspca_dev, 0x84, reg84_sn9c120_2,
|
|
|
- sizeof reg84_sn9c120_2);
|
|
|
- reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
|
|
|
- sizeof reg84_sn9c120_3);
|
|
|
- reg_w1(gspca_dev, 0x9a, 0x05);
|
|
|
- reg_w1(gspca_dev, 0x99, 0x5b);
|
|
|
- break;
|
|
|
default:
|
|
|
reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
|
|
|
for (i = 0; i < 8; i++)
|
|
@@ -1107,22 +1066,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|
|
/* reg1 = 0x44; */
|
|
|
/* reg1 = 0x46; (done) */
|
|
|
} else {
|
|
|
- reg17 = 0xa2; /* 640 */
|
|
|
- reg1 = 0x40;
|
|
|
+ reg17 = 0x22; /* 640 MCKSIZE */
|
|
|
+ reg1 = 0x06;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
reg_w(gspca_dev, 0xc0, C0, 6);
|
|
|
+ reg_w(gspca_dev, 0xca, CA, 4);
|
|
|
switch (sd->bridge) {
|
|
|
- case BRIDGE_SN9C120: /*jfm ?? */
|
|
|
- reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
|
|
|
- break;
|
|
|
- default:
|
|
|
- reg_w(gspca_dev, 0xca, CA, 4);
|
|
|
- break;
|
|
|
- }
|
|
|
- switch (sd->bridge) {
|
|
|
- case BRIDGE_SN9C120: /*jfm ?? */
|
|
|
case BRIDGE_SN9C325:
|
|
|
reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
|
|
|
break;
|
|
@@ -1133,19 +1084,19 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
|
|
}
|
|
|
|
|
|
/* here change size mode 0 -> VGA; 1 -> CIF */
|
|
|
- data = 0x40 | sn9c1xx[0x18] | (mode << 4);
|
|
|
- reg_w1(gspca_dev, 0x18, data);
|
|
|
+ reg18 = sn9c1xx[0x18] | (mode << 4);
|
|
|
+ reg_w1(gspca_dev, 0x18, reg18 | 0x40);
|
|
|
|
|
|
reg_w(gspca_dev, 0x100, qtable4, 0x40);
|
|
|
reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
|
|
|
|
|
|
- data = sn9c1xx[0x18] | (mode << 4);
|
|
|
- reg_w1(gspca_dev, 0x18, data);
|
|
|
+ reg_w1(gspca_dev, 0x18, reg18);
|
|
|
|
|
|
reg_w1(gspca_dev, 0x17, reg17);
|
|
|
reg_w1(gspca_dev, 0x01, reg1);
|
|
|
setbrightness(gspca_dev);
|
|
|
setcontrast(gspca_dev);
|
|
|
+ setautogain(gspca_dev);
|
|
|
}
|
|
|
|
|
|
static void sd_stopN(struct gspca_dev *gspca_dev)
|
|
@@ -1168,12 +1119,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|
|
i2c_w8(gspca_dev, stopmi0360);
|
|
|
data = 0x29;
|
|
|
break;
|
|
|
- case SENSOR_MO4000:
|
|
|
- break;
|
|
|
case SENSOR_OV7648:
|
|
|
data = 0x29;
|
|
|
break;
|
|
|
default:
|
|
|
+/* case SENSOR_MO4000: */
|
|
|
/* case SENSOR_OV7660: */
|
|
|
break;
|
|
|
}
|
|
@@ -1193,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-static void setautogain(struct gspca_dev *gspca_dev)
|
|
|
+static void do_autogain(struct gspca_dev *gspca_dev)
|
|
|
{
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
|
- /* Thanks S., without your advice, autobright should not work :) */
|
|
|
int delta;
|
|
|
- int expotimes = 0;
|
|
|
+ int expotimes;
|
|
|
__u8 luma_mean = 130;
|
|
|
__u8 luma_delta = 20;
|
|
|
|
|
|
- delta = sd->avg_lum;
|
|
|
+ /* Thanks S., without your advice, autobright should not work :) */
|
|
|
+ if (sd->ag_cnt < 0)
|
|
|
+ return;
|
|
|
+ if (--sd->ag_cnt >= 0)
|
|
|
+ return;
|
|
|
+ sd->ag_cnt = AG_CNT_START;
|
|
|
+
|
|
|
+ delta = atomic_read(&sd->avg_lum);
|
|
|
+ PDEBUG(D_FRAM, "mean lum %d", delta);
|
|
|
if (delta < luma_mean - luma_delta ||
|
|
|
delta > luma_mean + luma_delta) {
|
|
|
switch (sd->sensor) {
|
|
@@ -1214,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
|
|
sd->exposure = setexposure(gspca_dev,
|
|
|
(unsigned int) (expotimes << 8));
|
|
|
break;
|
|
|
- case SENSOR_MO4000:
|
|
|
- case SENSOR_MI0360:
|
|
|
+ default:
|
|
|
+/* case SENSOR_MO4000: */
|
|
|
+/* case SENSOR_MI0360: */
|
|
|
expotimes = sd->exposure;
|
|
|
expotimes += (luma_mean - delta) >> 6;
|
|
|
if (expotimes < 0)
|
|
@@ -1228,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* scan the URB packets */
|
|
|
+/* This function is run at interrupt level. */
|
|
|
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|
|
struct gspca_frame *frame, /* target */
|
|
|
__u8 *data, /* isoc packet */
|
|
@@ -1244,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|
|
frame, data, sof + 2);
|
|
|
if (sd->ag_cnt < 0)
|
|
|
return;
|
|
|
- if (--sd->ag_cnt >= 0)
|
|
|
- return;
|
|
|
- sd->ag_cnt = AG_CNT_START;
|
|
|
/* w1 w2 w3 */
|
|
|
/* w4 w5 w6 */
|
|
|
/* w7 w8 */
|
|
@@ -1261,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|
|
/* w5 */
|
|
|
avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
|
|
|
avg_lum >>= 4;
|
|
|
- sd->avg_lum = avg_lum;
|
|
|
- PDEBUG(D_PACK, "mean lum %d", avg_lum);
|
|
|
- setautogain(gspca_dev);
|
|
|
+ atomic_set(&sd->avg_lum, avg_lum);
|
|
|
return;
|
|
|
}
|
|
|
if (gspca_dev->last_packet_type == LAST_PACKET) {
|
|
@@ -1300,6 +1255,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev)
|
|
|
(hexpo << 10) | (mexpo << 2) | lexpo);
|
|
|
return (hexpo << 10) | (mexpo << 2) | lexpo;
|
|
|
default:
|
|
|
+/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
|
|
|
/* case SENSOR_OV7660: */
|
|
|
/* read sensor exposure */
|
|
|
i2c_r5(gspca_dev, 0x04);
|
|
@@ -1318,14 +1274,12 @@ static void getbrightness(struct gspca_dev *gspca_dev)
|
|
|
/* hardcoded registers seem not readable */
|
|
|
switch (sd->sensor) {
|
|
|
case SENSOR_HV7131R:
|
|
|
-/* sd->brightness = 0x7fff; */
|
|
|
sd->brightness = getexposure(gspca_dev) >> 4;
|
|
|
break;
|
|
|
case SENSOR_MI0360:
|
|
|
sd->brightness = getexposure(gspca_dev) << 4;
|
|
|
break;
|
|
|
case SENSOR_MO4000:
|
|
|
-/* sd->brightness = 0x1fff; */
|
|
|
sd->brightness = getexposure(gspca_dev) << 4;
|
|
|
break;
|
|
|
}
|
|
@@ -1391,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
|
|
|
|
sd->autogain = val;
|
|
|
- if (val)
|
|
|
- sd->ag_cnt = AG_CNT_START;
|
|
|
- else
|
|
|
- sd->ag_cnt = -1;
|
|
|
+ if (gspca_dev->streaming)
|
|
|
+ setautogain(gspca_dev);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1418,6 +1370,7 @@ static const struct sd_desc sd_desc = {
|
|
|
.stop0 = sd_stop0,
|
|
|
.close = sd_close,
|
|
|
.pkt_scan = sd_pkt_scan,
|
|
|
+ .dq_callback = do_autogain,
|
|
|
};
|
|
|
|
|
|
/* -- module initialisation -- */
|