diff options
Diffstat (limited to 'drivers/media/video/gspca/spca561.c')
-rw-r--r-- | drivers/media/video/gspca/spca561.c | 192 |
1 files changed, 54 insertions, 138 deletions
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 3c9288019e9..c99c5e34e21 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -141,38 +141,38 @@ static const struct v4l2_pix_format sif_072a_mode[] = { #define SPCA561_OFFSET_WIN1GBAVE 14 #define SPCA561_OFFSET_FREQ 15 #define SPCA561_OFFSET_VSYNC 16 -#define SPCA561_OFFSET_DATA 1 #define SPCA561_INDEX_I2C_BASE 0x8800 #define SPCA561_SNAPBIT 0x20 #define SPCA561_SNAPCTRL 0x40 -static const __u16 rev72a_init_data1[][2] = { +static const u16 rev72a_reset[][2] = { {0x0000, 0x8114}, /* Software GPIO output data */ {0x0001, 0x8114}, /* Software GPIO output data */ {0x0000, 0x8112}, /* Some kind of reset */ + {} +}; +static const __u16 rev72a_init_data1[][2] = { {0x0003, 0x8701}, /* PCLK clock delay adjustment */ {0x0001, 0x8703}, /* HSYNC from cmos inverted */ {0x0011, 0x8118}, /* Enable and conf sensor */ {0x0001, 0x8118}, /* Conf sensor */ {0x0092, 0x8804}, /* I know nothing about these */ {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ - {0x000d, 0x8805}, /* sensor default setting */ {} }; -static const __u16 rev72a_init_sensor1[][2] = { - /* ms-win values */ - {0x0001, 0x0018}, /* 0x01 <- 0x0d */ - {0x0002, 0x0065}, /* 0x02 <- 0x18 */ - {0x0004, 0x0121}, /* 0x04 <- 0x0165 */ - {0x0005, 0x00aa}, /* 0x05 <- 0x21 */ - {0x0007, 0x0004}, /* 0x07 <- 0xaa */ - {0x0020, 0x1502}, /* 0x20 <- 0x1504 */ - {0x0039, 0x0010}, /* 0x39 <- 0x02 */ - {0x0035, 0x0049}, /* 0x35 <- 0x10 */ - {0x0009, 0x100b}, /* 0x09 <- 0x1049 */ - {0x0028, 0x000f}, /* 0x28 <- 0x0b */ - {0x003b, 0x003c}, /* 0x3b <- 0x0f */ - {0x003c, 0x0000}, /* 0x3c <- 0x00 */ +static const u16 rev72a_init_sensor1[][2] = { + {0x0001, 0x000d}, + {0x0002, 0x0018}, + {0x0004, 0x0165}, + {0x0005, 0x0021}, + {0x0007, 0x00aa}, + {0x0020, 0x1504}, + {0x0039, 0x0002}, + {0x0035, 0x0010}, + {0x0009, 0x1049}, + {0x0028, 0x000b}, + {0x003b, 0x000f}, + {0x003c, 0x0000}, {} }; static const __u16 rev72a_init_data2[][2] = { @@ -190,15 +190,10 @@ static const __u16 rev72a_init_data2[][2] = { {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ {0x0001, 0x8200}, /* OprMode to be executed by hardware */ - {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */ - {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ - {0x0001, 0x8200}, /* OprMode to be executed by hardware */ - {0x0010, 0x8660}, /* Compensation memory stuff */ - {0x0018, 0x8660}, /* Compensation memory stuff */ - - {0x0004, 0x8611}, /* R offset for white balance */ - {0x0004, 0x8612}, /* Gr offset for white balance */ - {0x0007, 0x8613}, /* B offset for white balance */ +/* from ms-win */ + {0x0000, 0x8611}, /* R offset for white balance */ + {0x00fd, 0x8612}, /* Gr offset for white balance */ + {0x0003, 0x8613}, /* B offset for white balance */ {0x0000, 0x8614}, /* Gb offset for white balance */ /* from ms-win */ {0x0035, 0x8651}, /* R gain for white balance */ @@ -206,8 +201,8 @@ static const __u16 rev72a_init_data2[][2] = { {0x005f, 0x8653}, /* B gain for white balance */ {0x0040, 0x8654}, /* Gb gain for white balance */ {0x0002, 0x8502}, /* Maximum average bit rate stuff */ - {0x0011, 0x8802}, + {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ {0x0081, 0x8702}, /* Master clock output enable */ @@ -218,104 +213,15 @@ static const __u16 rev72a_init_data2[][2] = { {0x0003, 0x865c}, /* Vertical offset for valid lines */ {} }; -static const __u16 rev72a_init_sensor2[][2] = { - /* ms-win values */ - {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */ - {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */ - {0x0005, 0x002f}, /* 0x05 <- 0x2f */ - {0x0006, 0x0000}, /* 0x06 <- 0 */ - {0x000a, 0x0002}, /* 0x0a <- 2 */ - {0x0009, 0x1061}, /* 0x09 <- 0x1061 */ - {0x0035, 0x0014}, /* 0x35 <- 0x14 */ - {} -}; -static const __u16 rev72a_init_data3[][2] = { - {0x0030, 0x8112}, /* ISO and drop packet enable */ -/*fixme: should stop here*/ - {0x0000, 0x8112}, /* Some kind of reset ???? */ - {0x0009, 0x8118}, /* Enable sensor and set standby */ - {0x0000, 0x8114}, /* Software GPIO output data */ - {0x0000, 0x8114}, /* Software GPIO output data */ - {0x0001, 0x8114}, /* Software GPIO output data */ - {0x0000, 0x8112}, /* Some kind of reset ??? */ - {0x0003, 0x8701}, - {0x0001, 0x8703}, - {0x0011, 0x8118}, - {0x0001, 0x8118}, - /***************/ - {0x0092, 0x8804}, - {0x0010, 0x8802}, - {0x000d, 0x8805}, - {0x0001, 0x8801}, - {0x0000, 0x8800}, - {0x0018, 0x8805}, - {0x0002, 0x8801}, - {0x0000, 0x8800}, - {0x0065, 0x8805}, - {0x0004, 0x8801}, - {0x0001, 0x8800}, - {0x0021, 0x8805}, - {0x0005, 0x8801}, - {0x0000, 0x8800}, - {0x00aa, 0x8805}, - {0x0007, 0x8801}, /* mode 0xaa */ - {0x0000, 0x8800}, - {0x0004, 0x8805}, - {0x0020, 0x8801}, - {0x0015, 0x8800}, /* mode 0x0415 */ - {0x0002, 0x8805}, - {0x0039, 0x8801}, - {0x0000, 0x8800}, - {0x0010, 0x8805}, - {0x0035, 0x8801}, - {0x0000, 0x8800}, - {0x0049, 0x8805}, - {0x0009, 0x8801}, - {0x0010, 0x8800}, - {0x000b, 0x8805}, - {0x0028, 0x8801}, - {0x0000, 0x8800}, - {0x000f, 0x8805}, - {0x003b, 0x8801}, - {0x0000, 0x8800}, - {0x0000, 0x8805}, - {0x003c, 0x8801}, - {0x0000, 0x8800}, - {0x0002, 0x8502}, - {0x0039, 0x8801}, - {0x0000, 0x8805}, - {0x0000, 0x8800}, - - {0x0087, 0x8700}, /* overwrite by start */ - {0x0081, 0x8702}, - {0x0000, 0x8500}, -/* {0x0010, 0x8500}, -- Previous line was this */ - {0x0002, 0x865b}, - {0x0003, 0x865c}, - /***************/ - {0x0003, 0x8801}, /* 0x121-> 289 */ - {0x0021, 0x8805}, - {0x0001, 0x8800}, - {0x0004, 0x8801}, /* 0x165 -> 357 */ - {0x0065, 0x8805}, - {0x0001, 0x8800}, - {0x0005, 0x8801}, /* 0x2f //blanking control colonne */ - {0x002f, 0x8805}, - {0x0000, 0x8800}, - {0x0006, 0x8801}, /* 0x00 //blanking mode row */ - {0x0000, 0x8805}, - {0x0000, 0x8800}, - {0x000a, 0x8801}, /* 0x01 //0x02 */ - {0x0001, 0x8805}, - {0x0000, 0x8800}, - {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock +static const u16 rev72a_init_sensor2[][2] = { + {0x0003, 0x0121}, + {0x0004, 0x0165}, + {0x0005, 0x002f}, /* blanking control column */ + {0x0006, 0x0000}, /* blanking mode row*/ + {0x000a, 0x0002}, + {0x0009, 0x1061}, /* setexposure times && pixel clock * 0001 0 | 000 0110 0001 */ - {0x0061, 0x8805}, /* 61 31 */ - {0x0008, 0x8800}, /* 08 */ - {0x0035, 0x8801}, /* 0x14 - set gain general */ - {0x001f, 0x8805}, /* 0x14 */ - {0x0000, 0x8800}, - {0x000e, 0x8112}, /* white balance - was 30 */ + {0x0035, 0x0014}, {} }; @@ -460,6 +366,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg) reg_r(gspca_dev, 0x8803, 1); if (!gspca_dev->usb_buf[0]) return; + msleep(10); } while (--retry); } @@ -479,6 +386,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) reg_r(gspca_dev, 0x8805, 1); return ((int) value << 8) | gspca_dev->usb_buf[0]; } + msleep(10); } while (--retry); return -1; } @@ -541,7 +449,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ sd->chip_revision = id->driver_info; @@ -572,11 +479,13 @@ static int sd_init_12a(struct gspca_dev *gspca_dev) static int sd_init_72a(struct gspca_dev *gspca_dev) { PDEBUG(D_STREAM, "Chip revision: 072a"); + write_vector(gspca_dev, rev72a_reset); + msleep(200); write_vector(gspca_dev, rev72a_init_data1); write_sensor_72a(gspca_dev, rev72a_init_sensor1); write_vector(gspca_dev, rev72a_init_data2); write_sensor_72a(gspca_dev, rev72a_init_sensor2); - write_vector(gspca_dev, rev72a_init_data3); + reg_w_val(gspca_dev->dev, 0x8112, 0x30); return 0; } @@ -731,11 +640,18 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) int Clck; int mode; + write_vector(gspca_dev, rev72a_reset); + msleep(200); + write_vector(gspca_dev, rev72a_init_data1); + write_sensor_72a(gspca_dev, rev72a_init_sensor1); + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (mode) { default: -/* case 0: - case 1: */ + case 0: + Clck = 0x27; /* ms-win 0x87 */ + break; + case 1: Clck = 0x25; break; case 2: @@ -745,13 +661,14 @@ static int sd_start_72a(struct gspca_dev *gspca_dev) Clck = 0x21; break; } - reg_w_val(dev, 0x8500, mode); /* mode */ reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ - reg_w_val(dev, 0x8112, 0x10 | 0x20); + reg_w_val(dev, 0x8702, 0x81); + reg_w_val(dev, 0x8500, mode); /* mode */ + write_sensor_72a(gspca_dev, rev72a_init_sensor2); setcontrast(gspca_dev); /* setbrightness(gspca_dev); * fixme: bad values */ - setwhite(gspca_dev); setautogain(gspca_dev); + reg_w_val(dev, 0x8112, 0x10 | 0x20); return 0; } @@ -867,12 +784,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { /* sequence number */ + len--; + switch (*data++) { /* sequence number */ case 0: /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - data += SPCA561_OFFSET_DATA; - len -= SPCA561_OFFSET_DATA; if (data[1] & 0x10) { /* compressed bayer */ gspca_frame_add(gspca_dev, FIRST_PACKET, @@ -893,8 +809,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, case 0xff: /* drop (empty mpackets) */ return; } - data++; - len--; gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } @@ -1197,8 +1111,10 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - if (usb_register(&sd_driver) < 0) - return -1; + int ret; + ret = usb_register(&sd_driver); + if (ret < 0) + return ret; PDEBUG(D_PROBE, "registered"); return 0; } |