176 * 144,
.bytesperline = 176,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
+ .priv = 9
}, {
320,
240,
320 * 240,
.bytesperline = 320,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
+ .priv = 8
}, {
352,
288,
352 * 288,
.bytesperline = 352,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
+ .priv = 9
}, {
640,
480,
640 * 480,
.bytesperline = 640,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
+ .priv = 9
}
};
int ov9650_start(struct sd *sd)
{
+ u8 data;
int i, err = 0;
struct cam *cam = &sd->gspca_dev.cam;
+ int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
+ int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
+ int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
+ int hor_offs = OV9650_LEFT_OFFSET;
+
+ if (width <= 320)
+ hor_offs /= 2;
err = ov9650_init(sd);
if (err < 0)
return err;
+ /* Synthesize the vsync/hsync setup */
for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) {
if (res_init_ov9650[i][0] == BRIDGE)
err = m5602_write_bridge(sd, res_init_ov9650[i][1],
if (err < 0)
return err;
- switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, ((ver_offs >> 8) & 0xff));
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 2 && !err; i++) {
+ err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
+ }
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (hor_offs >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, ((width + hor_offs) >> 8) & 0xff);
+ if (err < 0)
+ return err;
+
+ err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, ((width + hor_offs) & 0xff));
+ if (err < 0)
+ return err;
+
+ switch (width) {
case 640:
PDEBUG(D_V4L2, "Configuring camera for VGA mode");
- for (i = 0; i < ARRAY_SIZE(VGA_ov9650) && !err; i++) {
- if (VGA_ov9650[i][0] == SENSOR) {
- u8 data = VGA_ov9650[i][2];
+ data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
- err = m5602_write_sensor(sd,
- VGA_ov9650[i][1], &data, 1);
- } else {
- err = m5602_write_bridge(sd, VGA_ov9650[i][1],
- VGA_ov9650[i][2]);
- }
- }
break;
case 352:
PDEBUG(D_V4L2, "Configuring camera for CIF mode");
- for (i = 0; i < ARRAY_SIZE(CIF_ov9650) && !err; i++) {
- if (CIF_ov9650[i][0] == SENSOR) {
- u8 data = CIF_ov9650[i][2];
+ data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
- err = m5602_write_sensor(sd,
- CIF_ov9650[i][1], &data, 1);
- } else {
- err = m5602_write_bridge(sd, CIF_ov9650[i][1],
- CIF_ov9650[i][2]);
- }
- }
break;
case 320:
PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
- for (i = 0; i < ARRAY_SIZE(QVGA_ov9650) && !err; i++) {
- if (QVGA_ov9650[i][0] == SENSOR) {
- u8 data = QVGA_ov9650[i][2];
+ data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
- err = m5602_write_sensor(sd,
- QVGA_ov9650[i][1], &data, 1);
- } else {
- err = m5602_write_bridge(sd, QVGA_ov9650[i][1],
- QVGA_ov9650[i][2]);
- }
- }
break;
case 176:
PDEBUG(D_V4L2, "Configuring camera for QCIF mode");
- for (i = 0; i < ARRAY_SIZE(QCIF_ov9650) && !err; i++) {
- if (QCIF_ov9650[i][0] == SENSOR) {
- u8 data = QCIF_ov9650[i][2];
- err = m5602_write_sensor(sd,
- QCIF_ov9650[i][1], &data, 1);
- } else {
- err = m5602_write_bridge(sd, QCIF_ov9650[i][1],
- QCIF_ov9650[i][2]);
- }
- }
- break;
+ data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
+ OV9650_RAW_RGB_SELECT;
+ err = m5602_write_sensor(sd, OV9650_COM7, &data, 1);
+ break;
}
return err;
}
#define OV9650_SOFT_SLEEP (1 << 4)
#define OV9650_OUTPUT_DRIVE_2X (1 << 0)
+#define OV9650_LEFT_OFFSET 0x62
+
#define GAIN_DEFAULT 0x14
#define RED_GAIN_DEFAULT 0x70
#define BLUE_GAIN_DEFAULT 0x20
{BRIDGE, M5602_XB_SIG_INI, 0x01}
};
-static const unsigned char VGA_ov9650[][3] =
-{
- /* Moves the view window in a vertical orientation */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, /* 640 + 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0xe2},
-
- {SENSOR, OV9650_COM7, OV9650_VGA_SELECT |
- OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT},
-};
-
-static const unsigned char CIF_ov9650[][3] =
-{
- /* Moves the view window in a vertical orientation */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x20}, /* 288 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x62}, /* 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 352 + 98 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0xc2},
-
- {SENSOR, OV9650_COM7, OV9650_CIF_SELECT |
- OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT},
-};
-
-static const unsigned char QVGA_ov9650[][3] =
-{
- /* Moves the view window in a vertical orientation */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0xf0}, /* 240 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 50 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x01}, /* 320 + 50 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x71},
-
- {SENSOR, OV9650_COM7, OV9650_QVGA_SELECT |
- OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT},
-};
-
-static const unsigned char QCIF_ov9650[][3] =
-{
- /* Moves the view window in a vertical orientation */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x09},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x90}, /* 144 */
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x31}, /* 48 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, /* 176 + 49 */
- {BRIDGE, M5602_XB_HSYNC_PARA, 0xe1},
-
- {SENSOR, OV9650_COM7, OV9650_QCIF_SELECT |
- OV9650_RGB_SELECT |
- OV9650_RAW_RGB_SELECT},
-};
-
#endif