static int vv6410_init(struct sd *sd) { int err = 0, i; for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { /* if NULL then len contains single value */ if (stv_bridge_init[i].data == NULL) { err = stv06xx_write_bridge(sd, stv_bridge_init[i].start, stv_bridge_init[i].len); } else { int j; for (j = 0; j < stv_bridge_init[i].len; j++) err = stv06xx_write_bridge(sd, stv_bridge_init[i].start + j, stv_bridge_init[i].data[j]); } } if (err < 0) return err; err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, ARRAY_SIZE(vv6410_sensor_init)); return (err < 0) ? err : 0; }
static int st6422_start(struct sd *sd) { int err, packet_size; struct cam *cam = &sd->gspca_dev.cam; s32 *sensor_settings = sd->sensor_priv; struct usb_host_interface *alt; struct usb_interface *intf; intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); if (!alt) { PDEBUG(D_ERR, "Couldn't get altsetting"); return -EIO; } packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); err = stv06xx_write_bridge(sd, 0x15c1, packet_size); if (err < 0) return err; if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) err = stv06xx_write_bridge(sd, 0x1505, 0x0f); else err = stv06xx_write_bridge(sd, 0x1505, 0x02); if (err < 0) return err; err = st6422_set_brightness(&sd->gspca_dev, sensor_settings[BRIGHTNESS_IDX]); if (err < 0) return err; err = st6422_set_contrast(&sd->gspca_dev, sensor_settings[CONTRAST_IDX]); if (err < 0) return err; err = st6422_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]); if (err < 0) return err; err = st6422_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); if (err < 0) return err; PDEBUG(D_STREAM, "Starting stream"); return 0; }
static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val) { int err; struct sd *sd = (struct sd *) gspca_dev; s32 *sensor_settings = sd->sensor_priv; sensor_settings[CONTRAST_IDX] = val; if (!gspca_dev->streaming) return 0; /* Val goes from 0 -> 15 */ PDEBUG(D_V4L2, "Set contrast to %d\n", val); err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val); if (err < 0) return err; /* commit settings */ err = stv06xx_write_bridge(sd, 0x143f, 0x01); return (err < 0) ? err : 0; }
static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val) { int err; struct sd *sd = (struct sd *) gspca_dev; s32 *sensor_settings = sd->sensor_priv; sensor_settings[BRIGHTNESS_IDX] = val; if (!gspca_dev->streaming) return 0; /* val goes from 0 -> 31 */ PDEBUG(D_V4L2, "Set brightness to %d", val); err = stv06xx_write_bridge(sd, 0x1432, val); if (err < 0) return err; /* commit settings */ err = stv06xx_write_bridge(sd, 0x143f, 0x01); return (err < 0) ? err : 0; }
static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val) { int err; struct sd *sd = (struct sd *) gspca_dev; s32 *sensor_settings = sd->sensor_priv; sensor_settings[EXPOSURE_IDX] = val; if (!gspca_dev->streaming) return 0; PDEBUG(D_V4L2, "Set exposure to %d\n", val); err = stv06xx_write_bridge(sd, 0x143d, val & 0xff); if (err < 0) return err; err = stv06xx_write_bridge(sd, 0x143e, val >> 8); if (err < 0) return err; /* commit settings */ err = stv06xx_write_bridge(sd, 0x143f, 0x01); return (err < 0) ? err : 0; }
static int vv6410_stop(struct sd *sd) { int err; /* Turn off LED */ err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_OFF); if (err < 0) return err; err = stv06xx_write_sensor(sd, VV6410_SETUP0, VV6410_LOW_POWER_MODE); if (err < 0) return err; PDEBUG(D_STREAM, "Halting stream"); return (err < 0) ? err : 0; }
static int vv6410_start(struct sd *sd) { int err; struct cam *cam = &sd->gspca_dev.cam; u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv; if (priv & VV6410_CROP_TO_QVGA) { PDEBUG(D_CONF, "Cropping to QVGA"); stv06xx_write_sensor(sd, VV6410_XENDH, 320 - 1); stv06xx_write_sensor(sd, VV6410_YENDH, 240 - 1); } else { stv06xx_write_sensor(sd, VV6410_XENDH, 360 - 1); stv06xx_write_sensor(sd, VV6410_YENDH, 294 - 1); } if (priv & VV6410_SUBSAMPLE) { PDEBUG(D_CONF, "Enabling subsampling"); stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); stv06xx_write_bridge(sd, STV_X_CTRL, 0x06); stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10); } else { stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01); stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a); stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20); } /* Turn on LED */ err = stv06xx_write_bridge(sd, STV_LED_CTRL, LED_ON); if (err < 0) return err; err = stv06xx_write_sensor(sd, VV6410_SETUP0, 0); if (err < 0) return err; PDEBUG(D_STREAM, "Starting stream"); return 0; }
static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val) { int err; struct sd *sd = (struct sd *) gspca_dev; s32 *sensor_settings = sd->sensor_priv; sensor_settings[GAIN_IDX] = val; if (!gspca_dev->streaming) return 0; PDEBUG(D_V4L2, "Set gain to %d", val); /* Set red, green, blue, gain */ err = stv06xx_write_bridge(sd, 0x0509, val); if (err < 0) return err; err = stv06xx_write_bridge(sd, 0x050a, val); if (err < 0) return err; err = stv06xx_write_bridge(sd, 0x050b, val); if (err < 0) return err; /* 2 mystery writes */ err = stv06xx_write_bridge(sd, 0x050c, 0x2a); if (err < 0) return err; err = stv06xx_write_bridge(sd, 0x050d, 0x01); if (err < 0) return err; /* commit settings */ err = stv06xx_write_bridge(sd, 0x143f, 0x01); return (err < 0) ? err : 0; }
static int st6422_init(struct sd *sd) { int err = 0, i; const u16 st6422_bridge_init[][2] = { { STV_ISO_ENABLE, 0x00 }, /* disable capture */ { 0x1436, 0x00 }, { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ { 0x143a, 0xF9 }, /* 0x00-0x0F contrast */ { 0x0509, 0x38 }, /* R */ { 0x050a, 0x38 }, /* G */ { 0x050b, 0x38 }, /* B */ { 0x050c, 0x2A }, { 0x050d, 0x01 }, { 0x1431, 0x00 }, /* 0x00-0x07 ??? */ { 0x1433, 0x34 }, /* 160x120, 0x00-0x01 night filter */ { 0x1438, 0x18 }, /* 640x480 */ /* 18 bayes */ /* 10 compressed? */ { 0x1439, 0x00 }, /* anti-noise? 0xa2 gives a perfect image */ { 0x143b, 0x05 }, { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */ /* shutter time 0x0000-0x03FF */ /* low value give good picures on moving objects (but requires much light) */ /* high value gives good picures in darkness (but tends to be overexposed) */ { 0x143e, 0x01 }, { 0x143d, 0x00 }, { 0x1442, 0xe2 }, /* write: 1x1x xxxx */ /* read: 1x1x xxxx */ /* bit 5 == button pressed and hold if 0 */ /* write 0xe2,0xea */ /* 0x144a */ /* 0x00 init */ /* bit 7 == button has been pressed, but not handled */ /* interrupt */ /* if(urb->iso_frame_desc[i].status == 0x80) { */ /* if(urb->iso_frame_desc[i].status == 0x88) { */ { 0x1500, 0xd0 }, { 0x1500, 0xd0 }, { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */ { 0x1501, 0xaf }, /* high val-> light area gets darker */ /* low val -> light area gets lighter */ { 0x1502, 0xc2 }, /* high val-> light area gets darker */ /* low val -> light area gets lighter */ { 0x1503, 0x45 }, /* high val-> light area gets darker */ /* low val -> light area gets lighter */ { 0x1505, 0x02 }, /* 2 : 324x248 80352 bytes */ /* 7 : 248x162 40176 bytes */ /* c+f: 162*124 20088 bytes */ { 0x150e, 0x8e }, { 0x150f, 0x37 }, { 0x15c0, 0x00 }, { 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */ { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ { 0x143f, 0x01 }, /* commit settings */ }; for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) { err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0], st6422_bridge_init[i][1]); } return err; }