?? ov511.c
字號(hào):
goto out;#endif break; case SEN_SAA7111A: rc = ov51x_i2c_write(ov511, 0x0d, (val + 32768) >> 8); if (rc < 0) goto out; break; default: PDEBUG(3, "Unsupported with this sensor"); rc = -EPERM; goto out; } rc = 0; /* Success */ ov511->hue = val;out: if (ov511_restart(ov511) < 0) return -EIO; return rc;}/* Gets sensor's hue (red/blue balance) setting */static intsensor_get_hue(struct usb_ov511 *ov511, unsigned short *val){ int rc; switch (ov511->sensor) { case SEN_OV7610: case SEN_OV6620: case SEN_OV6630: rc = ov51x_i2c_read(ov511, OV7610_REG_BLUE); if (rc < 0) return rc; else *val = rc << 8; break; case SEN_OV7620: rc = ov51x_i2c_read(ov511, 0x7a); if (rc < 0) return rc; else *val = rc << 8; break; case SEN_SAA7111A: *val = ov511->hue; break; default: PDEBUG(3, "Unsupported with this sensor"); return -EPERM; } PDEBUG(3, "%d", *val); ov511->hue = *val; return 0;}/* -------------------------------------------------------------------------- */static inline intsensor_set_picture(struct usb_ov511 *ov511, struct video_picture *p){ int rc; PDEBUG(4, "sensor_set_picture"); ov511->whiteness = p->whiteness; /* Don't return error if a setting is unsupported, or rest of settings * will not be performed */ rc = sensor_set_contrast(ov511, p->contrast); if (FATAL_ERROR(rc)) return rc; rc = sensor_set_brightness(ov511, p->brightness); if (FATAL_ERROR(rc)) return rc; rc = sensor_set_saturation(ov511, p->colour); if (FATAL_ERROR(rc)) return rc; rc = sensor_set_hue(ov511, p->hue); if (FATAL_ERROR(rc)) return rc; return 0;}static inline intsensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p){ int rc; PDEBUG(4, "sensor_get_picture"); /* Don't return error if a setting is unsupported, or rest of settings * will not be performed */ rc = sensor_get_contrast(ov511, &(p->contrast)); if (FATAL_ERROR(rc)) return rc; rc = sensor_get_brightness(ov511, &(p->brightness)); if (FATAL_ERROR(rc)) return rc; rc = sensor_get_saturation(ov511, &(p->colour)); if (FATAL_ERROR(rc)) return rc; rc = sensor_get_hue(ov511, &(p->hue)); if (FATAL_ERROR(rc)) return rc; p->whiteness = 105 << 8; /* Can we get these from frame[0]? -claudio? */ p->depth = ov511->frame[0].depth; p->palette = ov511->frame[0].format; return 0;}// FIXME: Exposure range is only 0x00-0x7f in interlace mode/* Sets current exposure for sensor. This only has an effect if auto-exposure * is off */static inline intsensor_set_exposure(struct usb_ov511 *ov511, unsigned char val){ int rc; PDEBUG(3, "%d", val); if (ov511->stop_during_set) if (ov511_stop(ov511) < 0) return -EIO; switch (ov511->sensor) { case SEN_OV6620: case SEN_OV6630: case SEN_OV7610: case SEN_OV7620: case SEN_OV7620AE: case SEN_OV8600: rc = ov51x_i2c_write(ov511, 0x10, val); if (rc < 0) goto out; break; case SEN_KS0127: case SEN_KS0127B: case SEN_SAA7111A: PDEBUG(3, "Unsupported with this sensor"); return -EPERM; default: err("Sensor not supported for set_exposure"); return -EINVAL; } rc = 0; /* Success */ ov511->exposure = val;out: if (ov511_restart(ov511) < 0) return -EIO; return rc;}/* Gets current exposure level from sensor, regardless of whether it is under * manual control. */static intsensor_get_exposure(struct usb_ov511 *ov511, unsigned char *val){ int rc; switch (ov511->sensor) { case SEN_OV7610: case SEN_OV6620: case SEN_OV6630: case SEN_OV7620: case SEN_OV7620AE: case SEN_OV8600: rc = ov51x_i2c_read(ov511, 0x10); if (rc < 0) return rc; else *val = rc; break; case SEN_KS0127: case SEN_KS0127B: case SEN_SAA7111A: val = 0; PDEBUG(3, "Unsupported with this sensor"); return -EPERM; default: err("Sensor not supported for get_exposure"); return -EINVAL; } PDEBUG(3, "%d", *val); ov511->exposure = *val; return 0;}/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */static inline void ov51x_led_control(struct usb_ov511 *ov511, int enable){ PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); if (ov511->bridge == BRG_OV511PLUS) ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_LED_CTL, enable ? 1 : 0); else if (ov511->bridge == BRG_OV518 || ov511->bridge == BRG_OV518PLUS) ov511_reg_write_mask(ov511->dev, OV518_REG_GPIO_OUT, enable ? 0x02 : 0x00, 0x02); return;}/* Matches the sensor's internal frame rate to the lighting frequency. * Valid frequencies are: * 50 - 50Hz, for European and Asian lighting * 60 - 60Hz, for American lighting * * Tested with: OV7610, OV7620, OV7620AE, OV6620 * Unsupported: KS0127, KS0127B, SAA7111A * Returns: 0 for success */static intsensor_set_light_freq(struct usb_ov511 *ov511, int freq){ int sixty; PDEBUG(4, "%d Hz", freq); if (freq == 60) sixty = 1; else if (freq == 50) sixty = 0; else { err("Invalid light freq (%d Hz)", freq); return -EINVAL; } switch (ov511->sensor) { case SEN_OV7610: ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80); ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac); ov51x_i2c_write_mask(ov511, 0x13, 0x10, 0x10); ov51x_i2c_write_mask(ov511, 0x13, 0x00, 0x10); break; case SEN_OV7620: case SEN_OV7620AE: case SEN_OV8600: ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80); ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac); ov51x_i2c_write_mask(ov511, 0x76, 0x01, 0x01); break; case SEN_OV6620: case SEN_OV6630: ov51x_i2c_write(ov511, 0x2b, sixty?0xa8:0x28); ov51x_i2c_write(ov511, 0x2a, sixty?0x84:0xa4); break; case SEN_KS0127: case SEN_KS0127B: case SEN_SAA7111A: PDEBUG(5, "Unsupported with this sensor"); return -EPERM; default: err("Sensor not supported for set_light_freq"); return -EINVAL; } ov511->lightfreq = freq; return 0;}/* If enable is true, turn on the sensor's banding filter, otherwise turn it * off. This filter tries to reduce the pattern of horizontal light/dark bands * caused by some (usually fluorescent) lighting. The light frequency must be * set either before or after enabling it with ov51x_set_light_freq(). * * Tested with: OV7610, OV7620, OV7620AE, OV6620. * Unsupported: KS0127, KS0127B, SAA7111A * Returns: 0 for success */static inline intsensor_set_banding_filter(struct usb_ov511 *ov511, int enable){ int rc; PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B || ov511->sensor == SEN_SAA7111A) { PDEBUG(5, "Unsupported with this sensor"); return -EPERM; } rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x04:0x00, 0x04); if (rc < 0) return rc; ov511->bandfilt = enable; return 0;}/* If enable is true, turn on the sensor's auto brightness control, otherwise * turn it off. * * Unsupported: KS0127, KS0127B, SAA7111A * Returns: 0 for success */static inline intsensor_set_auto_brightness(struct usb_ov511 *ov511, int enable){ int rc; PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B || ov511->sensor == SEN_SAA7111A) { PDEBUG(5, "Unsupported with this sensor"); return -EPERM; } rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x10:0x00, 0x10); if (rc < 0) return rc; ov511->auto_brt = enable; return 0;}/* If enable is true, turn on the sensor's auto exposure control, otherwise * turn it off. * * Unsupported: KS0127, KS0127B, SAA7111A * Returns: 0 for success */static inline intsensor_set_auto_exposure(struct usb_ov511 *ov511, int enable){ PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); switch (ov511->sensor) { case SEN_OV7610: ov51x_i2c_write_mask(ov511, 0x29, enable?0x00:0x80, 0x80); break; case SEN_OV6620: case SEN_OV7620: case SEN_OV7620AE: case SEN_OV8600: ov51x_i2c_write_mask(ov511, 0x13, enable?0x01:0x00, 0x01); break; case SEN_OV6630: ov51x_i2c_write_mask(ov511, 0x28, enable?0x00:0x10, 0x10); break; case SEN_KS0127: case SEN_KS0127B: case SEN_SAA7111A: PDEBUG(5, "Unsupported with this sensor"); return -EPERM; default: err("Sensor not supported for set_auto_exposure"); return -EINVAL; } ov511->auto_exp = enable; return 0;}/* Modifies the sensor's exposure algorithm to allow proper exposure of objects * that are illuminated from behind. * * Tested with: OV6620, OV7620 * Unsupported: OV7610, OV7620AE, KS0127, KS0127B, SAA7111A * Returns: 0 for success */static intsensor_set_backlight(struct usb_ov511 *ov511, int enable){ PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); switch (ov511->sensor) { case SEN_OV7620: case SEN_OV8600: ov51x_i2c_write_mask(ov511, 0x68, enable?0xe0:0xc0, 0xe0); ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08); ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02); break; case SEN_OV6620: ov51x_i2c_write_mask(ov511, 0x4e, enable?0xe0:0xc0, 0xe0); ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08); ov51x_i2c_write_mask(ov511, 0x0e, enable?0x80:0x00, 0x80); break; case SEN_OV6630: ov51x_i2c_write_mask(ov511, 0x4e, enable?0x80:0x60, 0xe0); ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08); ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02); break; case SEN_OV7610: case SEN_OV7620AE: case SEN_KS0127: case SEN_KS0127B: case SEN_SAA7111A: PDEBUG(5, "Unsupported with this sensor"); return -EPERM; default: err("Sensor not supported for set_backlight"); return -EINVAL; } ov511->backlight = enable; return 0;}/* Returns number of bits per pixel (regardless of where they are located; * planar or not), or zero for unsupported format. */static inline int ov511_get_depth(int palette){ switch (palette) { case VIDEO_PALETTE_GREY: return 8; case VIDEO_PALETTE_RGB565: return 16; case VIDEO_PALETTE_RGB24: return 24; case VIDEO_PALETTE_YUV422: return 16; case VIDEO_PALETTE_YUYV: return 16; case VIDEO_PALETTE_YUV420: return 12; case VIDEO_PALETTE_YUV422P: return 16; /* Planar */ case VIDEO_PALETTE_YUV420P: return 12; /* Planar */ default: return 0; /* Invalid format */ }}/* Bytes per frame. Used by read(). Return of 0 indicates error */static inline long int get_frame_length(struct ov511_frame *frame){ if (!frame) return 0; else return ((frame->width * frame->height * ov511_get_depth(frame->format)) >> 3);}static intmode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height, int mode, int sub_flag, int qvga){ int clock; /******** Mode (VGA/QVGA) and sensor specific regs ********/ switch (ov511->sensor) { case SEN_OV7610: ov51x_i2c_write(ov511, 0x14, qvga?0x24:0x04);// FIXME: Does this improve the image quality or frame rate?#if 0 ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20); ov51x_i2c_write(ov511, 0x24, 0x10); ov51x_i2c_write(ov511, 0x25, qvga?0x40:0x8a); ov51x_i2c_write(ov511, 0x2f, qvga?0x30:0xb0); ov51x_i2c_write(ov511, 0x35, qvga?0x1c:0x9c);#endif break; case SEN_OV7620:// ov51x_i2c_write(ov511, 0x2b, 0x00); ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84); ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20); ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a); ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60); ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40); ov51x_i2c_write_mask(ov511, 0x67, qvga?0xf0:0x90, 0xf0); ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20); break; case SEN_OV7620AE:// ov51x_i2c_write(ov511, 0x2b, 0x00); ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84);// FIXME: Enable this once 7620AE uses 7620 initial settings#if 0 ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20); ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a); ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60); ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40); ov51x_i2c_write_mask(ov511, 0x67, qvga?0xb0:0x90, 0xf0); ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20);#endif break; case
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -