aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/sonixj.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-09-03 15:47:59 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-09-03 17:36:48 -0400
commit05b809c702bf297690c63ea78ee117c4dc909028 (patch)
treee4fd7d6ec50f51f86f75f30376412f49e71620c7 /drivers/media/video/gspca/sonixj.c
parent41b469745f6218efb22bec4e3940b085ffb97216 (diff)
V4L/DVB (8709): gspca: Fix initialization and controls of sn9x110 - ov7630.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/sonixj.c')
-rw-r--r--drivers/media/video/gspca/sonixj.c199
1 files changed, 97 insertions, 102 deletions
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 47737bf04c6a..b17aaa45270f 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -59,6 +59,7 @@ struct sd {
59#define SENSOR_OV7648 5 59#define SENSOR_OV7648 5
60#define SENSOR_OV7660 6 60#define SENSOR_OV7660 6
61 unsigned char i2c_base; 61 unsigned char i2c_base;
62 __u8 regf1;
62}; 63};
63 64
64/* V4L2 controls supported by the driver */ 65/* V4L2 controls supported by the driver */
@@ -78,7 +79,8 @@ static struct ctrl sd_ctrls[] = {
78 .type = V4L2_CTRL_TYPE_INTEGER, 79 .type = V4L2_CTRL_TYPE_INTEGER,
79 .name = "Brightness", 80 .name = "Brightness",
80 .minimum = 0, 81 .minimum = 0,
81 .maximum = 0xffff, 82#define BRIGHTNESS_MAX 0xffff
83 .maximum = BRIGHTNESS_MAX,
82 .step = 1, 84 .step = 1,
83#define BRIGHTNESS_DEF 0x7fff 85#define BRIGHTNESS_DEF 0x7fff
84 .default_value = BRIGHTNESS_DEF, 86 .default_value = BRIGHTNESS_DEF,
@@ -92,7 +94,8 @@ static struct ctrl sd_ctrls[] = {
92 .type = V4L2_CTRL_TYPE_INTEGER, 94 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "Contrast", 95 .name = "Contrast",
94 .minimum = 0, 96 .minimum = 0,
95 .maximum = 127, 97#define CONTRAST_MAX 127
98 .maximum = CONTRAST_MAX,
96 .step = 1, 99 .step = 1,
97#define CONTRAST_DEF 63 100#define CONTRAST_DEF 63
98 .default_value = CONTRAST_DEF, 101 .default_value = CONTRAST_DEF,
@@ -240,27 +243,16 @@ static const __u8 *sn_tb[] = {
240 sn_ov7660 243 sn_ov7660
241}; 244};
242 245
243static const __u8 regsn20[] = { 246static const __u8 gamma_def[] = {
244 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 247 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
245 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 248 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
246}; 249};
247static const __u8 regsn20_sn9c325[] = {
248 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
249 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
250};
251 250
252static const __u8 reg84[] = { 251static const __u8 reg84[] = {
253 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, 252 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
254 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, 253 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
255/* 0x00, 0x00, 0x00, 0x00, 0x00 */ 254 0xf7, 0x0f, 0x00, 0x00, 0x00
256 0xf7, 0x0f, 0x0a, 0x00, 0x00
257};
258static const __u8 reg84_sn9c325[] = {
259 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
260 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
261 0xf8, 0x0f, 0x00, 0x00, 0x00
262}; 255};
263
264static const __u8 hv7131r_sensor_init[][8] = { 256static const __u8 hv7131r_sensor_init[][8] = {
265 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, 257 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
266 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, 258 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
@@ -411,7 +403,7 @@ static const __u8 ov7630_sensor_init[][8] = {
411 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10}, 403 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
412/* win: delay 20ms */ 404/* win: delay 20ms */
413 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, 405 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
414/* win: loop on 2 wwrite, 1 read */ 406/* win: i2c_r from 00 to 80 */
415 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, 407 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
416 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10}, 408 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
417 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10}, 409 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
@@ -446,9 +438,11 @@ static const __u8 ov7630_sensor_init[][8] = {
446 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, 438 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, 439 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, 440 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
441/* */
449 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, 442 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
450 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, 443 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
451 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, 444 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
445/* */
452 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10}, 446 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
453 {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, 447 {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10},
454 {} 448 {}
@@ -778,7 +772,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
778 static const __u8 regd4[] = {0x60, 0x00, 0x00}; 772 static const __u8 regd4[] = {0x60, 0x00, 0x00};
779 773
780 reg_w1(gspca_dev, 0xf1, 0x00); 774 reg_w1(gspca_dev, 0xf1, 0x00);
781 reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/ 775 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
782 776
783 /* configure gpio */ 777 /* configure gpio */
784 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 778 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
@@ -805,6 +799,13 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
805 reg_w1(gspca_dev, 0x17, 0x64); 799 reg_w1(gspca_dev, 0x17, 0x64);
806 reg_w1(gspca_dev, 0x01, 0x42); 800 reg_w1(gspca_dev, 0x01, 0x42);
807 break; 801 break;
802/*jfm: from win trace */
803 case SENSOR_OV7630:
804 reg_w1(gspca_dev, 0x01, 0x61);
805 reg_w1(gspca_dev, 0x17, 0xe2);
806 reg_w1(gspca_dev, 0x01, 0x60);
807 reg_w1(gspca_dev, 0x01, 0x40);
808 break;
808 case SENSOR_OV7648: 809 case SENSOR_OV7648:
809 reg_w1(gspca_dev, 0x01, 0x43); 810 reg_w1(gspca_dev, 0x01, 0x43);
810 reg_w1(gspca_dev, 0x17, 0xae); 811 reg_w1(gspca_dev, 0x17, 0xae);
@@ -870,9 +871,20 @@ static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
870{ 871{
871 int i = 0; 872 int i = 0;
872 873
873 i2c_w8(gspca_dev, ov7630_sensor_init[i]); 874 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
875 i++;
876 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
874 i++; 877 i++;
875 msleep(20); 878 msleep(20);
879 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
880 i++;
881 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
882 i++;
883 msleep(20);
884 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
885 i++;
886/*jfm:win i2c_r from 00 to 80*/
887
876 while (ov7630_sensor_init[i][0]) { 888 while (ov7630_sensor_init[i][0]) {
877 i2c_w8(gspca_dev, ov7630_sensor_init[i]); 889 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
878 i++; 890 i++;
@@ -917,6 +929,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
917 sd->bridge = id->driver_info >> 16; 929 sd->bridge = id->driver_info >> 16;
918 sd->sensor = id->driver_info >> 8; 930 sd->sensor = id->driver_info >> 8;
919 sd->i2c_base = id->driver_info; 931 sd->i2c_base = id->driver_info;
932 sd->regf1 = 0; /*jfm: was 1 in v1*/
920 933
921 sd->qindex = 4; /* set the quantization table */ 934 sd->qindex = 4; /* set the quantization table */
922 sd->brightness = BRIGHTNESS_DEF; 935 sd->brightness = BRIGHTNESS_DEF;
@@ -969,7 +982,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
969 break; 982 break;
970 } 983 }
971 984
972 reg_w1(gspca_dev, 0xf1, 0x01); 985 reg_w1(gspca_dev, 0xf1, sd->regf1);
973 986
974 return 0; 987 return 0;
975} 988}
@@ -1051,6 +1064,28 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
1051 return expo; 1064 return expo;
1052} 1065}
1053 1066
1067/* this function is used for sensors o76xx only */
1068static void setbrightcont(struct gspca_dev *gspca_dev)
1069{
1070 struct sd *sd = (struct sd *) gspca_dev;
1071 unsigned val;
1072 __u8 reg84_full[13];
1073
1074 memset(reg84_full, 0, sizeof reg84_full);
1075 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */
1076 reg84_full[2] = val;
1077 reg84_full[0] = (val + 1) / 2;
1078 reg84_full[4] = (val + 1) / 5;
1079 if (val > BRIGHTNESS_DEF)
1080 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1081 / BRIGHTNESS_MAX;
1082 else
1083 val = 0;
1084 reg84_full[10] = val; /* 00..1f */
1085 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1086}
1087
1088/* sensor != ov76xx */
1054static void setbrightness(struct gspca_dev *gspca_dev) 1089static void setbrightness(struct gspca_dev *gspca_dev)
1055{ 1090{
1056 struct sd *sd = (struct sd *) gspca_dev; 1091 struct sd *sd = (struct sd *) gspca_dev;
@@ -1082,6 +1117,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1082 reg_w1(gspca_dev, 0x96, k2); 1117 reg_w1(gspca_dev, 0x96, k2);
1083} 1118}
1084 1119
1120/* sensor != ov76xx */
1085static void setcontrast(struct gspca_dev *gspca_dev) 1121static void setcontrast(struct gspca_dev *gspca_dev)
1086{ 1122{
1087 struct sd *sd = (struct sd *) gspca_dev; 1123 struct sd *sd = (struct sd *) gspca_dev;
@@ -1175,24 +1211,11 @@ static void sd_start(struct gspca_dev *gspca_dev)
1175 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1211 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1176 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1212 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1177 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); 1213 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1178 switch (sd->bridge) { 1214 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1179 case BRIDGE_SN9C325: 1215 for (i = 0; i < 8; i++)
1180 reg_w(gspca_dev, 0x20, regsn20_sn9c325, 1216 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1181 sizeof regsn20_sn9c325);
1182 for (i = 0; i < 8; i++)
1183 reg_w(gspca_dev, 0x84, reg84_sn9c325,
1184 sizeof reg84_sn9c325);
1185 reg_w1(gspca_dev, 0x9a, 0x0a);
1186 reg_w1(gspca_dev, 0x99, 0x60);
1187 break;
1188 default:
1189 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1190 for (i = 0; i < 8; i++)
1191 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1192 reg_w1(gspca_dev, 0x9a, 0x08); 1217 reg_w1(gspca_dev, 0x9a, 0x08);
1193 reg_w1(gspca_dev, 0x99, 0x59); 1218 reg_w1(gspca_dev, 0x99, 0x59);
1194 break;
1195 }
1196 1219
1197 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1220 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1198 if (mode) 1221 if (mode)
@@ -1272,8 +1295,18 @@ static void sd_start(struct gspca_dev *gspca_dev)
1272 1295
1273 reg_w1(gspca_dev, 0x17, reg17); 1296 reg_w1(gspca_dev, 0x17, reg17);
1274 reg_w1(gspca_dev, 0x01, reg1); 1297 reg_w1(gspca_dev, 0x01, reg1);
1275 setbrightness(gspca_dev); 1298 switch (sd->sensor) {
1276 setcontrast(gspca_dev); 1299 case SENSOR_HV7131R:
1300 case SENSOR_MI0360:
1301 case SENSOR_MO4000:
1302 case SENSOR_OM6802:
1303 setbrightness(gspca_dev);
1304 setcontrast(gspca_dev);
1305 break;
1306 default: /* OV76xx */
1307 setbrightcont(gspca_dev);
1308 break;
1309 }
1277 setautogain(gspca_dev); 1310 setautogain(gspca_dev);
1278} 1311}
1279 1312
@@ -1311,7 +1344,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1311 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); 1344 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1312 reg_w1(gspca_dev, 0x01, sn9c1xx[1]); 1345 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1313 reg_w1(gspca_dev, 0x01, data); 1346 reg_w1(gspca_dev, 0x01, data);
1314 reg_w1(gspca_dev, 0xf1, 0x01); 1347 reg_w1(gspca_dev, 0xf1, sd->regf1);
1315} 1348}
1316 1349
1317static void sd_stop0(struct gspca_dev *gspca_dev) 1350static void sd_stop0(struct gspca_dev *gspca_dev)
@@ -1409,72 +1442,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1409 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1442 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1410} 1443}
1411 1444
1412static unsigned int getexposure(struct gspca_dev *gspca_dev)
1413{
1414 struct sd *sd = (struct sd *) gspca_dev;
1415 __u8 hexpo, mexpo, lexpo;
1416
1417 switch (sd->sensor) {
1418 case SENSOR_HV7131R:
1419 /* read sensor exposure */
1420 i2c_r5(gspca_dev, 0x25);
1421 return (gspca_dev->usb_buf[0] << 16)
1422 | (gspca_dev->usb_buf[1] << 8)
1423 | gspca_dev->usb_buf[2];
1424 case SENSOR_MI0360:
1425 /* read sensor exposure */
1426 i2c_r5(gspca_dev, 0x09);
1427 return (gspca_dev->usb_buf[0] << 8)
1428 | gspca_dev->usb_buf[1];
1429 default:
1430/* case SENSOR_MO4000: */
1431 i2c_r5(gspca_dev, 0x0e);
1432 hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
1433 mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
1434 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1435 PDEBUG(D_CONF, "exposure %d",
1436 (hexpo << 10) | (mexpo << 2) | lexpo);
1437 return (hexpo << 10) | (mexpo << 2) | lexpo;
1438#if 0
1439/*jfm: not called*/
1440/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
1441/* case SENSOR_OV7660: */
1442 /* read sensor exposure */
1443 i2c_r5(gspca_dev, 0x04);
1444 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1445 lexpo = gspca_dev->usb_buf[0] & 0x02;
1446 i2c_r5(gspca_dev, 0x08);
1447 mexpo = gspca_dev->usb_buf[2];
1448 return (hexpo << 10) | (mexpo << 2) | lexpo;
1449#endif
1450 }
1451 /* not reached */
1452}
1453
1454static void getbrightness(struct gspca_dev *gspca_dev)
1455{
1456 struct sd *sd = (struct sd *) gspca_dev;
1457
1458 /* hardcoded registers seem not readable */
1459 switch (sd->sensor) {
1460 case SENSOR_HV7131R:
1461 sd->brightness = getexposure(gspca_dev) >> 4;
1462 break;
1463 case SENSOR_MI0360:
1464 case SENSOR_MO4000:
1465 case SENSOR_OM6802:
1466 sd->brightness = getexposure(gspca_dev) << 4;
1467 break;
1468 }
1469}
1470
1471static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1445static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1472{ 1446{
1473 struct sd *sd = (struct sd *) gspca_dev; 1447 struct sd *sd = (struct sd *) gspca_dev;
1474 1448
1475 sd->brightness = val; 1449 sd->brightness = val;
1476 if (gspca_dev->streaming) 1450 if (gspca_dev->streaming) {
1477 setbrightness(gspca_dev); 1451 switch (sd->sensor) {
1452 case SENSOR_HV7131R:
1453 case SENSOR_MI0360:
1454 case SENSOR_MO4000:
1455 case SENSOR_OM6802:
1456 setbrightness(gspca_dev);
1457 break;
1458 default: /* OV76xx */
1459 setbrightcont(gspca_dev);
1460 break;
1461 }
1462 }
1478 return 0; 1463 return 0;
1479} 1464}
1480 1465
@@ -1482,7 +1467,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1482{ 1467{
1483 struct sd *sd = (struct sd *) gspca_dev; 1468 struct sd *sd = (struct sd *) gspca_dev;
1484 1469
1485 getbrightness(gspca_dev);
1486 *val = sd->brightness; 1470 *val = sd->brightness;
1487 return 0; 1471 return 0;
1488} 1472}
@@ -1492,8 +1476,19 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1492 struct sd *sd = (struct sd *) gspca_dev; 1476 struct sd *sd = (struct sd *) gspca_dev;
1493 1477
1494 sd->contrast = val; 1478 sd->contrast = val;
1495 if (gspca_dev->streaming) 1479 if (gspca_dev->streaming) {
1496 setcontrast(gspca_dev); 1480 switch (sd->sensor) {
1481 case SENSOR_HV7131R:
1482 case SENSOR_MI0360:
1483 case SENSOR_MO4000:
1484 case SENSOR_OM6802:
1485 setcontrast(gspca_dev);
1486 break;
1487 default: /* OV76xx */
1488 setbrightcont(gspca_dev);
1489 break;
1490 }
1491 }
1497 return 0; 1492 return 0;
1498} 1493}
1499 1494