diff options
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_core.c | 4 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.c | 118 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.h | 82 |
3 files changed, 76 insertions, 128 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index bae7aa6..0d84a12 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c @@ -51,7 +51,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data) address, *i2c_data); /* usb_control_msg(...) returns the number of bytes sent upon success, - mask that and return zero upon success instead*/ + mask that and return zero instead*/ return (err < 0) ? err : 0; } @@ -76,7 +76,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data) 4, M5602_URB_MSG_TIMEOUT); /* usb_control_msg(...) returns the number of bytes sent upon success, - mask that and return zero upon success instead */ + mask that and return zero instead */ return (err < 0) ? err : 0; } diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 292f2d4..15288a1 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c @@ -180,7 +180,7 @@ static struct v4l2_pix_format ov9650_modes[] = { 176 * 144, .bytesperline = 176, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 + .priv = 9 }, { 320, 240, @@ -190,7 +190,7 @@ static struct v4l2_pix_format ov9650_modes[] = { 320 * 240, .bytesperline = 320, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 + .priv = 8 }, { 352, 288, @@ -200,7 +200,7 @@ static struct v4l2_pix_format ov9650_modes[] = { 352 * 288, .bytesperline = 352, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 + .priv = 9 }, { 640, 480, @@ -210,7 +210,7 @@ static struct v4l2_pix_format ov9650_modes[] = { 640 * 480, .bytesperline = 640, .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 + .priv = 9 } }; @@ -295,13 +295,22 @@ int ov9650_init(struct sd *sd) 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], @@ -315,70 +324,87 @@ int ov9650_start(struct sd *sd) 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; } diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h index ca0e42e..cc39d76 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.h +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h @@ -120,6 +120,8 @@ #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 @@ -335,84 +337,4 @@ static const unsigned char res_init_ov9650[][3] = {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 |